工具系统:代码块即工具调用
30 秒导读: 大多数 agent 框架把"用工具"这件事交给模型厂商的 function-calling API。gptme 反其道而行:让模型在正文里写一个代码块(比如
```shell),gptme 自己把这段文本解析出来、认出它对应哪个工具、再执行。这一章讲清楚这套"文本即调用"的机制——它的数据模型(ToolSpec)、解析器(ToolUse)、和执行管线。
本章属于 gptme 系列。想先看它整体怎么转,读 index;工具执行结果如何回灌进主循环,见 01-agent-loop;某个具体工具(shell/python/编辑/浏览)的领域逻辑,见 03-builtin-tools;执行前的确认与护栏怎么挂上去,见 05-hooks-extensibility。
1. 这是什么(零基础也能懂)
一句话定义: gptme 的"工具调用"= 模型在回复里写一段带语言标签的代码块,gptme 把它当成一次工具调用来解析和执行,而不是依赖模型 API 的结构化 function-call 通道。
它解决什么问题。 假设你想让 AI 在终端里帮你干活——跑个命令、改个文件、打开个网页。AI 本身只会"输出文本",它没有手。要让它真的动手,得有人:
- 定义"有哪些手"(有哪些工具、每个工具怎么用);
- 从 AI 的文本回复里认出"它现在想用哪只手、参数是什么";
- 真的去执行,再把结果塞回给 AI。
第 2、3 步就是本章的主角。
两条路线的分岔。 业界主流是让模型厂商替你做第 2 步——OpenAI/Anthropic 的 API 有专门的 tool_calls 字段,模型吐出结构化 JSON,你照着调函数。gptme 支持这条路(它叫 tool 格式),但默认走另一条:让模型把调用写在正文的 Markdown 代码块里,gptme 自己解析。
为什么要自己解析? 因为这样工具调用就不依赖特定模型的 API 能力——任何能输出文本的模型(哪怕是本地小模型、哪怕没有 function-calling)都能用工具;而且调用过程对人完全可读,就是一段普通的代码块。
用起来什么样。 模型想执行一条 shell 命令,它的回复里会直接出现这样一段:
我来看看当前目录有什么文件:
```shell
ls -la
```
gptme 扫描这段回复,发现 ```shell 这个语言标签对应内置的 shell 工具,于是把 ls -la 抽出来执行,把输出作为一条 system 消息接到对话后面。模型下一轮就能看到结果。
一句话直觉。 把它想成:语言标签(langtag)就是函数名,代码块正文就是参数。```shell 约等于 shell("ls -la"),只不过写成了人也能读的代码块。