从零搭建 AI Agent:7 个必备工具系统实战
AI Agent 的核心能力不只在于”能对话”,更在于能执行操作——在计算机上运行命令、读写文件、搜索代码、编辑内容、访问网络。这些能力通过工具(Tools) 来实现。
本文带你从零开始,为 AI Agent 实现一套完整的工具系统。代码使用 Python 标准库加 BeautifulSoup(网页解析),pip install beautifulsoup4 即可运行。
什么是 Agent 工具?
工具是暴露给 LLM 的可调用函数。Agent 在推理过程中,遇到需要外部操作的任务时(比如”看看当前目录有哪些文件”),LLM 会发出一个结构化的工具调用请求,由 Agent 框架执行并返回结果。
现代 LLM(GPT-4o、Claude Sonnet、DeepSeek V3 等)都原生支持 function calling——模型输出 JSON 格式的工具调用参数,框架执行后把结果送回上下文。
7 个核心工具实现
1. Bash 执行器
最强大的工具——让 Agent 能在计算机上运行任何命令:
import subprocess
def run_bash(command: str) -> str:
result = subprocess.run(
command, shell=True,
text=True, capture_output=True
)
output = result.stdout
if result.stderr:
output += f"\nSTDERR:\n{result.stderr}"
return output or "(no output)"
⚠️ 安全提示:bash 工具权限最大,生产环境需配合沙箱使用。
2. 文件读取器
支持行号和分页,避免一次性吞掉大文件:
from pathlib import Path
def read_file(path: str, offset: int = 1, limit: int = 200) -> str:
p = Path(path)
if not p.exists():
return f"Error: file not found: {path}"
lines = p.read_text(errors="replace").splitlines()
selected = lines[offset-1:offset-1+limit]
return "\n".join(
f"{offset+i}: {line}"
for i, line in enumerate(selected)
)
3. 文件搜索(glob)
帮助 Agent 先探明目录结构:
import glob as glob_module
def glob_files(pattern: str, path: str = ".") -> str:
matches = glob_module.glob(f"{path}/**/{pattern}", recursive=True)
matches += glob_module.glob(f"{path}/{pattern}")
return "\n".join(sorted(set(matches))) or "(no matches)"
4. 内容搜索(grep)
正则搜索文件内容,返回文件名+行号+匹配行:
import re
def grep(pattern: str, path: str = ".", include: str = "*") -> str:
results = []
for fp in glob_module.glob(f"{path}/**/{include}", recursive=True):
p = Path(fp)
if not p.is_file():
continue
try:
for i, line in enumerate(p.read_text(errors="replace").splitlines(), 1):
if re.search(pattern, line):
results.append(f"{fp}:{i}: {line}")
except OSError:
pass
return "\n".join(results) or "(no matches)"
5. 文件写入器
自动创建父目录,让 Agent 不需要关心目录结构:
def write_file(path: str, content: str) -> str:
p = Path(path)
p.parent.mkdir(parents=True, exist_ok=True)
p.write_text(content)
return f"Wrote {len(content)} bytes to {path}"
6. 文件编辑器
这是最安全的修改方式——只替换特定字符串,避免全量覆写:
def edit_file(path: str, old_string: str, new_string: str) -> str:
p = Path(path)
if not p.exists():
return f"Error: file not found: {path}"
original = p.read_text()
if old_string not in original:
return f"Error: string not found"
p.write_text(original.replace(old_string, new_string, 1))
return f"Edited {path}"
7. 网页抓取器
让 Agent 能读取在线文档和网页内容:
import urllib.request
from urllib.parse import urlparse
from bs4 import BeautifulSoup
def webfetch(url: str) -> str:
parsed = urlparse(url)
if parsed.scheme not in ("http", "https"):
return f"Unsupported scheme: {parsed.scheme}"
req = urllib.request.Request(
url, headers={"User-Agent": "agent/1.0"}
)
with urllib.request.urlopen(req, timeout=15) as resp:
raw = resp.read().decode(errors="replace")
soup = BeautifulSoup(raw, "html.parser")
text = soup.get_text(separator="\n", strip=True)
return re.sub(r"\n{3,}", "\n\n", text).strip()
定义工具 Schema
有了实现还不够——Agent 需要知道每个工具是什么、做什么、参数是什么。OpenAI 风格的 function calling schema 如下:
def get_tool_schemas():
return [
{
"type": "function",
"function": {
"name": "run_bash",
"description": "Run a bash command on the user's machine and return the output.",
"parameters": {
"type": "object",
"properties": {
"command": {
"type": "string",
"description": "The bash command to execute.",
}
},
"required": ["command"],
},
},
},
# ... 其他工具同理
]
整合到 Agent 循环
将工具 schema 传入 LLM 的 tools 参数,在 Agent 循环中检测 tool_calls 并分发执行:
tools_map = {
"run_bash": run_bash,
"read_file": read_file,
"write_file": write_file,
"edit_file": edit_file,
"glob_files": glob_files,
"grep": grep,
"webfetch": webfetch,
}
response = client.chat.completions.create(
model="your-model",
messages=messages,
tools=get_tool_schemas(),
)
if response.choices[0].message.tool_calls:
for call in response.choices[0].message.tool_calls:
fn_name = call.function.name
args = json.loads(call.function.arguments)
result = tools_map[fn_name](**args)
messages.append({
"role": "tool",
"tool_call_id": call.id,
"content": str(result),
})
实战场景:用工具系统搭建编码助手
假设你的 Agent 接到一个任务:”找到项目中所有未使用的 import,并清理掉。”
Agent 的执行流程大致如下:
- glob_files(“/*.py”)** → 发现所有 Python 文件
- grep(“os”, include=”/*.py”)** → 在代码中搜索
os模块的使用 - read_file(“src/main.py”) → 读取可疑文件确认
- edit_file(“src/main.py”, “import os\n”, “”) → 删除确认未使用的导入
- 循环执行直至所有文件被审计
这个过程中,Agent 完全自主调用、验证、修正。你只需要下达目标,工具系统负责执行路径。
工具设计的 4 个原则
- 幂等性优先:同一个工具的多次调用不应产生副作用(read_file 永远是安全的,edit_file 在字符串不存在时给出明确错误)
- 渐进式风险:从最安全的工具开始暴露,将 bash 这类高权限工具放在沙箱/审批流背后
- 返回值结构一致:每个工具都返回字符串,成功返回内容,失败返回错误信息——Agent 不需要针对不同工具做不同的解析
- 保留上下文扼要:glob_files 返回行数可控的结果,read_file 默认只读 200 行——避免工具结果撑爆 LLM 上下文窗口
扩展方向
这套基础工具系统可以继续进化为更强大的 Agent 平台:
- MCP 协议接入:将每个工具包装为 MCP Server,让 Claude Desktop、Cursor 等任意 MCP 客户端都能使用
- 权限分级:为 bash 工具增加”只读模式”——只允许执行
cat、ls、grep,禁止rm、curl等写操作 - 沙箱隔离:将 bash 执行重定向到 Docker 容器或 Firecracker 微 VM,防止 Agent 操作损坏主机
- 记忆增强:将工具调用结果持久化到向量数据库,让 Agent 能”记住”之前的文件结构和代码内容
总结
这 7 个工具构成了 AI Agent 操作计算机的核心能力集。它们的设计遵循一条原则:每个工具只做一件事,但把它做好。bash 提供无限可能,文件工具提供细粒度控制,web 抓取拓展信息边界。
这套系统最大的价值不在于单个工具的实现有多精妙,而在于组合使用时的涌现能力——Agent 可以利用搜索工具找到问题、读取工具理解上下文、编辑工具实施修改、bash 工具验证结果,自主完成从诊断到修复的闭环。
在此基础上,你可以继续添加 MCP 协议支持、安全沙箱、权限分级等功能。工具系统是 Agent 能力的杠杆——投入越多,Agent 能做越多。
相关链接
- Build A Basic AI Agent From Scratch: Tools(Ruxu.dev,作者 Roger Oriol)
- OpenAI Function Calling 文档
- GitHub – rogiia
本文基于 HN 上 Roger Oriol 的系列教程编写,代码经过简化和中文适配。完整原版包含更多高级工具和错误处理细节。