Py学习  »  Python

一文看懂 python版本Claude Code 的 Tool 调用,附加一个案例解读整个调用流程

算法狗 • 4 天前 • 54 次点击  

claw-code(当然是claude code的python实现)应该是史上最快的git仓库了,得益于claude code的被开源,这个项目火爆起来啦

Claw Code 项目是一个基于净室 (Clean-room) 策略的反向重建工程。该工程旨在解决原始 TypeScript 智能体治理框架代码泄露问题,并采用 Python 与 Rust 双主轴架构进行重写。其核心目标是构建一个深度理解并实现智能体工作流机制的系统。

主要目录与文件结构说明:

  • rust/:强类型、高并发生产环境构建端,采用 Rust Workspace 架构。
    • crates/api/:负责大模型网络交互与流式流转的 API 客户端模块。
    • crates/runtime/:系统生命周期主循环,负责会话管理与工具层分发调度。
    • crates/claw-cli/:原生命令行交互应用入口。
    • crates/plugins/:支持外部插件与管道钩入的拓展系统。
    • crates/commands/:斜杠命令配置处理系统。
    • crates/server/:HTTP/SSE 异步服务节点。
    • crates/lsp/:与代码语言服务器通信的集成客户端。
    • crates/tools/:核心工具体系的设计契约与实现模块。
    • crates/compat-harness/:为原有编辑器结构提供兼容层。
  • src/:Python 端原理重组验证沙盒。包含 reference_data/ 目录,用于存放原版架构 JSON 镜像,以及各类控制策略预留位,如 assistant/ hooks/memdir/ 等。
  • tests/:针对 Python 模拟子系统(例如调度器连通度)的验证测试集。
  • assets/:存放系统在终端运行时的效果图等依赖资源。
  • 根目录核心文件:
    • CLAW.md / PARITY.md:定义工程范式,并用于指导模型自身的开发方向。
    • README.md:项目溯源纪实文档与操作引导。

1. Tool 的接口与模型设计

在 Python 与 Rust 双主轴重构基底中,工具系统 (Tool System) 处于被严格调度与验证的核心地位。其设计架构在 rust/crates/tools/src/lib.rs 中得以体现:

  • 注册管理结构 (GlobalToolRegistry):负责本地内建工具与外部拓展工具的全局收纳管理,并处理别名化与映射操作。
  • 工具规约定义 (ToolSpec):每个工具需声明以下属性:
    • name:唯一的工具调用标识。
    • description:大模型使用的提示语与解释信息。
    • input_schema :强类型 JSON Schema,用于约束所有入参字段与枚举参数。
    • required_permission:执行所需的权限级别,用于系统拦截判定。
  • 权限级别枚举 (PermissionMode):工具划分为 ReadOnlyWorkspaceWrite 及 DangerFullAccess 三个层次,以此实现沙盒化的操作流控。

2. 工具的数量统计

  • 旧版本快照 ( tools_snapshot.json):在原有的 TypeScript 工程快照中,工具层包含接近 30 余个抽象类模块。
  • 重构后的现代化 Rust MVP 版本:通过精简重组,定义了 19 个具有高泛用性与原子性的操作端点。这些端点通过 mvp_tool_specs() 作为内置工具,并辅以可动态挂载的 Plugin 系统,在保留原功能的同时,显著降低了底层管理负担。

3. 分类与实现功能 (以 MVP 版本核心端点为例)

根据 ToolSpec 的刻画,当前工具系统可划分为五大功能板块:

3.1. 文件操作类 (Workspace Files)

  • read_file / write_file:基础读写操作。
  • edit_file:针对代码行的高效精准重写与替换。
  • glob_search:工作区内的正则语法路径匹配。
  • grep_search:支持多上下文结构查询的内容探索。

3.2. 系统/终端执行类 (Execution)

  • bash:执行工作区内的 Shell 命令,并配有超时、后台执行选项与沙盒避障控制。
  • PowerShell:专门适配于 Windows 环境的 PowerShell 终端调用。
  • REPL:在 REPL 子进程中隔离执行代码段。
  • Sleep:提供执行流的延缓和等待,并释放不必要的计算进程锁定。

3.3. 外部及网络环境探测 (External Integration)

  • WebFetch:通过 URL 爬取网络内容,并将其转化为文本与格式化结构供智能体模型参考。
  • WebSearch:内置即时信息抓取引擎交互功能,通过  allowed_domains 黑白名单进行域限制。

3.4. 任务、消息与工作流调度 (Task & Agents)

  • TodoWrite:记录并刷新结构化任务清单。
  • Agent:允许切分复杂任务并启动子专用智能体代理接力处理。
  • Skill:根据目标诉求引导执行特定的本地操作指导步骤。
  • SendUserMessage:允许框架将主动探查到的内容及时通知客户端前台。
  • NotebookEdit:专门操作 Jupyter Notebook 的不同 cell。

3.5. 探查配置类 (Meta configs)

  • Config:修改及同步当前 Claw Code 的机器设置或环境变量设置。
  • ToolSearch / StructuredOutput:获取可用工具集说明以及强制约束输出 JSON 格式的工具。

4. 工具执行的 Pipeline (Execution Pipeline)

一次工具调用的全生命周期通常经历以下五个步骤:

  1. 大模型判定分析与路由匹配 (Routing / Intent Matching):引擎经过上下文理解,从  GlobalToolRegistry 中选定适宜的工具,并在智能体接口中发出包含 ToolChoice 的 Function Call
  2. 别名过滤与鉴权 (Normalization & Permission):系统接收到操作意图,调用 normalize_allowed_tools 标准化传入的各类名称,并即刻比对工具的 required_permission 上下文。若当前隔离态拦截了 DangerFullAccess 权限,则抛出 PermissionDenial
  3. 反序列化及模型化 (Deserialization):通过 from_value::,框架将接收的动态 JSON Value 转换为 Rust 中的强类型安全结构,确保非法空值或漏洞入参被过滤。
  4. 逻辑处理 (Dispatch Execution):系统核心函数  execute_tool 根据枚举项派发处理,调用底层服务实现并返回执行期结果。
  5. 回传结果编码 (Formatter/Payload Output):将产生的终端日志、文件内容等数据,通过 to_pretty_json 统一封装,反馈组装进入 ToolResultContentBlock 并发回给对话系统的大模型,开启下一轮策略。

🌟 Pipeline 执行实例剖析: bash 工具调用

以模型尝试执行终端命令 ls -la 为例,解析完整的 Pipeline 流程:

第一步:判定与输出 (Routing) 大模型构造 JSON 返回给 GlobalToolRegistry

{
  "name""bash",
  "input": {
    "command""ls -la",
    "timeout"30000
  }
}

第二步:权限与标准化 (Permission) 系统核心首先检查名称 "bash" 是否匹配内置 ToolSpec。它发现 bash 工具的 required_permission 是 DangerFullAccess。随后比对当前环境设定,若用户允许了危险级操作,则准许通过。

第三步:反序列化验证 (Deserialization) 由于该工具的 input_schema 被严格定义,系统通过 Rust 的 from_value:: 对输入进行类型投射:

struct BashCommandInput {
    command: String,            // 成功解析 "ls -la"
    timeout: Option,     // 成功解析 30000
    // ... 其他可选字段全部转为合法 Option
}

第四步:业务逻辑分派 (Dispatch Execution) 经  execute_tool("bash", input) 派发,进入真实执行流:调用本地系统的 execute_bash(input) 方法。在沙盒或隔离子进程中执行 ls -la 的系统调用,并截获标准输出与标准错误。

第五步:格式组装并回传 (Formatter) 执行结束后,将环境输出文本通过 to_pretty_json 组装成标准载体回传给大模型:

{
  "status""success",
  "stdout""total 48\ndrwxr-xr-x ...",
  "stderr"""
}

最后,该数据流汇入 ToolResultContentBlock,完成本次 bash 调用生命周期,使智能体开始研读返回的目录结构。


Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/194727