工具即双手 —— 从 Bash 到 Tool Dispatch Map

第三篇:工具即双手 ------ 从 Bash 到 Tool Dispatch Map

s01 说"一个 bash 就够了",但没人真的只用 bash 写代码。


全栈工程师 vs. 全栈工具

你说"帮我读一下 config.py 的第 10 行到第 20 行",如果 Agent 只有一个 bash 工具,它得敲:sed -n '10,20p' config.py。这当然可以。但就像你可以用螺丝刀钉钉子,但有锤子的话为什么要用螺丝刀?

这就是 s02 的核心进化:从"一个万能工具"到"一套专用工具"

Tool Dispatch Map

s02 的核心创新是一张映射表:

python 复制代码
TOOL_HANDLERS = {
    "bash":       lambda **kw: run_bash(kw["command"]),
    "read_file":  lambda **kw: run_read(kw["path"], kw.get("limit")),
    "write_file": lambda **kw: run_write(kw["path"], kw["content"]),
    "edit_file":  lambda **kw: run_edit(kw["path"], kw["old_text"], kw["new_text"]),
}

一个函数名到处理函数的直接映射。没有 if-else 森林。当模型返回工具调用时:

python 复制代码
handler = TOOL_HANDLERS.get(block.name)
output = handler(**block.input) if handler else f"Unknown tool: {block.name}"

两行代码,路由了一切。想加新工具?加一行字典条目就行。

专有工具的精妙之处

read_file 比 bash cat 好在哪里?

  1. 安全边界:safe_path() 阻止路径穿越
  2. 输出控制:limit 参数 + 50000 字符截断
  3. 友好报错:异常被捕获为字符串
  4. 语义精准:模型知道"我在读文件"

那个 safe_path 函数:

python 复制代码
def safe_path(p: str) -> Path:
    path = (WORKDIR / p).resolve()
    if not path.is_relative_to(WORKDIR):
        raise ValueError(f"Path escapes workspace: {p}")
    return path

永远、永远、永远不要相信模型的输入。

Agent Loop 没有变

python 复制代码
def agent_loop(messages: list):
    while True:
        response = client.messages.create(...)
        messages.append(response.content)
        if response.stop_reason != "tool_use":
            return
        for block in response.content:
            if block.type == "tool_use":
                handler = TOOL_HANDLERS.get(block.name)
                output = handler(**block.input)
                messages.append(tool_result)

和 s01 相比,唯一的变化就是把 run_bash 换成了 TOOL_HANDLERS.get。

这就是扩缩性的全部秘密。 你不改核心循环。你只改工具注册表。

如果说 Agent Loop 是操作系统内核,那 TOOL_HANDLERS 就是系统调用表。

从 4 个工具到 16 个工具

s02 只有 4 个工具。到了 s12,同一个 pattern 被扩展到了 16 个------基础工具、任务工具、worktree 工具、事件工具。但核心循环还是那几行,没变。

下一篇:TodoManager ------ 一个让模型自己写 TODO List 的工具,以及一个讨人厌的提醒器。

相关推荐
yaoxin52112317 小时前
434. Java 日期时间 API - Period 基于日期的时间段
java·开发语言·python
凡人叶枫17 小时前
Effective C++ 条款30:透彻了解 inlining 的里里外外
linux·开发语言·c++·嵌入式开发·effective c++
学逆向的18 小时前
C++纯虚函数
开发语言·c++·网络安全
程序员二叉18 小时前
【JUC】ThreadLocal底层原理|内存泄漏|弱引用|跨线程传递方案
java·开发语言·面试·职场和发展·juc
程序员二叉18 小时前
【JUC】线程池全套深度详解|参数|流程|拒绝策略|调优|异常处理
java·开发语言·jvm·算法·面试·juc
凡人叶枫19 小时前
Effective C++ 条款22:将成员变量声明为 private
linux·开发语言·c++
Qt程序员19 小时前
掌握 Linux 内核调度:从原理到实现(进程篇)
java·开发语言
code bean19 小时前
【LangChain】检索器完全指南:从向量检索到生产级 RAG 架构
java·开发语言·微服务
LabVIEW开发19 小时前
LabVIEW + MATLAB 混合编程:爆炸场测试数据精准采集方案
开发语言·matlab·labview
嵌入式协会202407219 小时前
(已解决)MinIO python 获取预签名出现forbidden、errornetwork等错误
java·开发语言·python