一、目标:做一个「会用工具」的最小 Agent

本文不堆框架名词,只带你完成一条最小闭环:用户提出问题 → 模型决定是否调用工具 → 执行工具 → 模型基于结果回答。会用工具,才算 Agent;否则只是聊天套壳。

二、你需要准备什么

  • 一个支持 tool / function calling 的模型(云 API 或自托管均可)
  • Python 3.10+(或其他你熟悉的后端语言)
  • 一个安全的示例工具(推荐:获取天气占位、或本地「读当前时间」)

三、核心循环(伪代码)

messages = [system, user]
for step in range(MAX_STEPS):
    resp = llm.chat(messages, tools=TOOL_SPECS)
    if resp.tool_calls:
        for call in resp.tool_calls:
            result = run_tool(call.name, call.args)  # 带超时与白名单
            messages.append(tool_result(call.id, result))
        continue
    return resp.content  # 最终自然语言答案
raise TimeoutError("exceeded max steps")

三要素:工具描述(给模型看)、执行器(带权限)、步数上限(防死循环)。

四、工具描述怎么写才容易被调用

  • 名称稳定、简短(如 get_current_time)
  • description 写清「何时用 / 何时不用」
  • 参数用 JSON Schema,类型明确,必填项少而精
{
  "name": "get_current_time",
  "description": "获取服务器当前时间。当用户询问现在几点时使用。",
  "parameters": {
    "type": "object",
    "properties": {
      "timezone": {"type": "string", "description": "可选,IANA 时区"}
    }
  }
}

五、安全默认值(从第一天就打开)

  • 工具白名单;禁止任意代码执行
  • 每个工具独立超时(如 3s)
  • 对参数做校验,拒绝路径穿越与内网扫描类输入
  • 日志记录 tool 名与结果摘要,隐藏密钥

六、验证成功的标准

  1. 问「现在几点」→ 日志出现 tool_call → 回答含真实时间
  2. 问无关闲聊 → 不调用工具
  3. 故意让工具超时 → Agent 能报错或降级,而不是挂死

七、下一步怎么长成「能打的 Agent」

加上:检索工具(RAG)、业务 HTTP API、会话记忆、以及生产向的重试/降级。框架可选 Hermes / LangChain 等,但循环与安全边界应先在你脑子里清楚,再交给框架实现。

八、小结

从零搭建工具型 Agent,最小交付不是漂亮 UI,而是:可控循环 + 清晰工具协议 + 超时与白名单。跑通这一步,再谈多 Agent 与复杂工作流也不迟。