这是《从零写一个通用 Agent 内核》的第 0 步。在敲下任何一行「工具分发」代码之前,我先没写代码,纯靠对话把 tool calling 跑了一遍。

手头只有一个最朴素的 agent 循环:DeepSeek 的 OpenAI 兼容接口 + 一个 read_file 工具。我跟模型约了个「君子协定」:
复制代码You: 你是一名天气专家。当我问某地天气时,你用 get_weather(<地点>) 来回复,
然后我会告诉你那个地方的天气。AI: 明白!现在我就是你的专属天气专家,随时准备调用 get_weather(<地点>)。You: 北京天气怎么样?AI: 好的,正在为您查询北京天气,请稍等!️
get_weather(北京)
看上去模型「调用」了 get_weather。但盯着 API 返回看,有个关键细节:
这一轮的 finish_reason 是 stop,不是 tool_calls。 那行 get_weather(北京) 只是模型打印出来的一句普通文本,它压根没发起任何真正的工具调用。
那谁来「执行」这个 get_weather?我。
复制代码You: 微风小雨 ← 这一步是我在扮演 get_weather,把"查询结果"喂回去AI: 北京此刻微风伴小雨,适合披件薄外套撑伞散步~️(根据我喂的值产出最终答复)
一个完整的 tool-calling 循环就这么跑完了——只不过全程手动。
模型没真调用工具,但这正是我要的:用最原始的方式,把平时被 API 黑盒掉的过程亲手走一遍。
tool calling 听着玄,剥开只有三个角色:
| 角色 | 这场实验里是谁 | 真实 agent 里是谁 |
|---|---|---|
| 决定调用、发出调用、解读返回值 | 模型 | 模型(这层永远是模型的活) |
| 真正执行工具、把结果递回去 | 我(人肉后端) | 执行器代码 |
| 调用和结果怎么来回传递(协议) | 普通聊天文本 | tool_calls / role:tool / tool_call_id |
模型那一列从头到尾没变。变的只有中间那行——「谁来执行」和「结果怎么传回」。而这恰恰就是一个 agent 框架的全部活儿:把人肉执行器换成代码,把聊天文本换成结构化协议。
为了对照,我换个问题——这次问的是 read_file 能覆盖的事:
复制代码You: agent.py 文件是做什么的?
模型这次的返回,finish_reason 变成了 tool_calls:
复制代码tool_calls = [ read_file(arguments='{"path": "agent.py"}') ]
一次结构化的、真正的工具调用。紧接着,是我的 Python 把它执行了:
复制代码for tool_call in assistant_message.tool_calls:
tool_name = tool_call.function.name # "read_file"
tool_args = json.loads(tool_call.function.arguments) # {"path": "agent.py"}
result = read_file(**tool_args) # ← 真正的执行在这行
conversation.append({
"role": "tool",
"content": str(result),
"tool_call_id": tool_call.id, # ← 协议把结果递回去
})
结果通过 role: tool 喂回模型,模型读完文件产出分析。
同样一套循环,这次没有「我」的位置了——那个执行的人,被 read_file(**tool_args) 这行取代了。
两次运行唯一的差别:
get_weather 从没进过 tools 列表;read_file 进了 tools 列表。仅此而已,结果却天差地别:前者只能「用文字假装调用」,后者才触发真机的 tool_calls。
这也解释了为什么 prompt 里苦口婆心写一堆「你拥有以下能力」常常不管用。
这场手动实验给整个系列定了主线:
而一旦你认真去替代「那个人」,会发现人肉执行时你下意识在做、却从没显式写下来的一堆事,代码必须一件件接住:
"Error" 还是 "file not found, did you mean config.yaml?"?(前者让模型抓瞎,后者让它当场自我纠错)这些就是横切关注点:不属于任何一个具体工具,而属于「执行」这件事本身。下一篇,我们就从把它们抽出来、统一塞进一条执行管道开始——这条管道,才是决定一个 agent 到底「聪不聪明」的地基。
系列《从零写一个通用 Agent 内核》一路记录这个小核心从零长大的设计取舍。不堆术语,只讲「本来长什么样、为什么疼、然后怎么长成现在这样」。下一篇见。