ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Claude Code的Harness Engineering实现:02-工具系统(Tools)拆解与TaoToken接入实践

Claude Code的Harness Engineering实现:02-工具系统(Tools)拆解与TaoToken接入实践 1. 从一次工具调用失败说起Claude Code 工具系统到底在管什么Claude Code 的 Harness Engineering 里工具系统Tools是最容易被低估的一层。很多人第一次接触时以为它只是「把函数名和参数塞给模型」真正跑起来才发现模型能不能看到某个工具、参数怎么校验、权限在哪一步拦截、结果怎么回填给下一轮对话全都由工具系统决定。我试过在本地把 Read、Bash、Grep 三个工具串成一条链路中途因为 Base URL 配错导致工具定义根本没注入成功模型只能干聊一个文件都读不了。先把概念说清楚。Claude Code 的工具系统是一套「能力注册 Schema 注入 参数校验 权限检查 执行 结果格式化」的闭环。它回答两个问题模型能做什么工具定义以及模型如何安全地做权限与校验。适合谁适合正在用 Claude Code 做本地 Agent、想自己加自定义工具、或者想把工具调用接到统一 API 通道上的开发者。如果你只是用 Claude Code 写写代码不理解这层也能用但一旦你要扩展工具、排查「模型不调用工具」这类问题就必须拆开看。工具系统的核心数据结构是一个统一的 Tool 接口。它包含 name、description、inputSchemaZod、inputJSONSchema给 API 用的 JSON Schema以及 call、checkPermissions、isEnabled、isConcurrencySafe、isReadOnly、isDestructive 等方法。这个设计把「工具是什么」和「工具怎么被安全调用」绑在一个对象里注册时一次性交给运行时。工具按功能分成几类文件操作Read/Edit/Write、代码搜索Grep/Glob、命令执行Bash、网络访问WebSearch/WebFetch、任务管理TodoWrite、Agent 协作AgentTool、MCP 集成MCPTool。每类工具的权限级别不同Read 是只读、可并发Bash 是破坏性、需要确认。生命周期分六步注册 → Schema 注入 → 参数校验 → 权限检查 → 执行 → 结果格式化。注册阶段把所有工具放进工具池再按权限规则和特性开关过滤Schema 注入阶段把工具定义转成 API 能理解的 JSON参数校验用 Zod 做运行时类型检查权限检查分 Hook、规则、用户确认三层执行阶段支持同步和流式并行结果格式化把返回值转成模型能读的 tool_result。这里有个关键点工具定义是通过 API 请求的 tools 字段注入的。也就是说你的 API 通道必须能正确转发 tools 字段否则模型根本不知道有哪些工具可用。这就是为什么接入通道的 Base URL 和 Key 配置会直接影响工具系统能否工作。下一节讲怎么用 TaoToken 把这条通道配好。2. TaoToken 前置准备统一 Key 与 API 通道配置在拆工具系统之前得先把 API 通道打通。Claude Code 的工具定义、工具调用请求、工具结果回填全都走同一个 API 端点。如果通道不稳或字段被吞工具系统就是空转。TaoToken 在这里的角色是提供统一的 Key 和 API 通道让你不用为每个模型或每个工具单独配一套凭证。先拿 Key。打开 https://taotoken.net/api-keys 登录后创建一个 API Key。建议按用途分 Key比如一个给 Claude Code 本地开发用一个给 CI 用方便后面排查问题时定位。创建后复制保存页面只显示一次。Base URL 用 https://taotoken.net/api 。注意这个地址不带任何查询参数直接作为 Anthropic 兼容端点使用。Claude Code 走的是 Anthropic 协议所以配置时按 Anthropic 的方式填。模型 ID 这块要留意。Claude Code 默认会请求 claude-3-5-sonnet 或 claude-sonnet-4 这类模型名你需要在 TaoToken 的模型列表里确认对应可用模型然后在配置里显式指定。模型 ID 写错会直接报 404 或 model not found而不是工具系统的问题但现象很像「工具不工作」容易误判。配置方式有两种。第一种是环境变量适合临时验证export ANTHROPIC_BASE_URLhttps://taotoken.net/api export ANTHROPIC_API_KEYsk-你的TaoTokenKey export ANTHROPIC_MODELclaude-sonnet-4-20250514第二种是写进 Claude Code 的 settings 文件适合长期使用。路径通常在~/.claude/settings.json内容如下{ env: { ANTHROPIC_BASE_URL: https://taotoken.net/api, ANTHROPIC_API_KEY: sk-你的TaoTokenKey, ANTHROPIC_MODEL: claude-sonnet-4-20250514 } }如果你用的是 Codex 或 Cline 这类工具配置位置不同但三件套一样Base URL、Key、Model ID。Codex 的 auth.json 里填 API Keyconfig 里填 Base URL 和 ModelCline 的 MCP 配置里同样要写全这三项。缺任何一项工具调用链路都跑不通。配完后先别急着测工具先用一个最小请求确认通道通。可以用 curl 直接打 Anthropic 兼容端点curl https://taotoken.net/api/v1/messages \ -H x-api-key: sk-你的TaoTokenKey \ -H anthropic-version: 2023-06-01 \ -H content-type: application/json \ -d { model: claude-sonnet-4-20250514, max_tokens: 64, messages: [{role: user, content: ping}] }返回里有 content 字段就说明通道通了。这一步很重要因为工具系统的报错经常和通道报错混在一起先隔离变量能省很多时间。通道确认后再进工具定义和注册。3. 可复制配置工具定义 JSON 与注册片段这一节给可直接复制的配置。工具系统的注册分两层一层是工具定义本身JSON Schema一层是运行时把工具注册进工具池。先看工具定义。一个标准的工具定义长这样以 Read 工具为例{ name: Read, description: Reads a file from the local filesystem. Returns file content with line numbers., input_schema: { type: object, properties: { file_path: { type: string, description: The absolute path to the file to read }, limit: { type: integer, description: The number of lines to read, minimum: 1, maximum: 2000 }, offset: { type: integer, description: The line number to start reading from, minimum: 1 } }, required: [file_path, limit] } }这个 JSON 就是注入到 API 请求 tools 字段里的内容。注意 required 里 limit 是必填如果你自定义工具时把可选参数写进 required模型每次调用都得传容易触发参数校验失败。再看运行时注册。Claude Code 的工具池通过 getAllBaseTools 返回所有基础工具再按权限过滤export function getTools(permissionContext: ToolPermissionContext): Tool[] { let tools getAllBaseTools() tools filterToolsByDenyRules(tools, permissionContext) tools tools.filter(tool tool.isEnabled?.() ?? true) return tools }如果你要加自定义工具就在 getAllBaseTools 的返回数组里追加你的 Tool 对象。自定义工具必须实现 name、description、inputSchema、inputJSONSchema、call 五个字段checkPermissions 可选但强烈建议实现。权限规则配置片段放在 settings 里{ permissions: { allow: [ { toolName: Read, ruleContent: undefined }, { toolName: Grep, ruleContent: undefined } ], deny: [ { toolName: Bash, ruleContent: rm -rf / } ], ask: [ { toolName: Write, ruleContent: undefined } ] } }allow 里的工具直接放行deny 直接拒绝ask 需要用户确认。这个配置直接决定工具系统在权限检查阶段的行为。如果你发现某个工具模型调了但没执行先查这里是不是被 deny 了。MCP 工具的注册稍有不同它是动态创建的async function createMCPTool(serverName, toolName, inputSchema) { return { name: mcp__${serverName}__${toolName}, description: MCP tool from ${serverName}, inputSchema: zodSchemaFromJSON(inputSchema), inputJSONSchema: inputSchema, async call(input, context) { const client getMCPClient(serverName) return await client.callTool(toolName, input) } } }MCP 工具名带mcp__前缀权限检查默认走 passthrough也就是需要用户确认。如果你接的是 Cline MCP配置里同样要写全 Base URL、Key、Model ID 三件套否则 MCP 客户端连不上工具注册会静默失败。配置写完后工具定义和注册片段就齐了。下一节验证整条链路。4. 验证请求跑通工具注册到实际调用的闭环配置写完必须验证。验证分三步确认工具定义被注入、确认模型发起工具调用、确认结果正确回填。第一步确认工具定义注入。用一个带 tools 字段的请求打通道curl https://taotoken.net/api/v1/messages \ -H x-api-key: sk-你的TaoTokenKey \ -H anthropic-version: 2023-06-01 \ -H content-type: application/json \ -d { model: claude-sonnet-4-20250514, max_tokens: 256, tools: [{ name: Read, description: Reads a file, input_schema: { type: object, properties: { file_path: {type: string} }, required: [file_path] } }], messages: [{role: user, content: 读取 /tmp/test.txt 的内容}] }如果返回的 content 里出现tool_use类型的块说明工具定义注入成功模型决定调用 Read。如果返回的是纯文本说明模型没看到工具回去查 tools 字段是否被通道吞掉。第二步在 Claude Code 里跑真实链路。启动 Claude Code 后输入一个会触发工具调用的指令比如「读一下当前目录的 package.json」。观察输出里有没有工具调用日志。正常流程是模型返回 tool_use → 工具系统校验参数 → 权限检查 → 执行 Read → 结果格式化 → 回填给模型 → 模型基于结果回答。第三步确认结果回填。工具执行后结果以 tool_result 块回填{ type: tool_result, tool_use_id: toolu_xxx, content: 1\t{\n2\t \name\: \demo\\n3\t} }如果模型在下一轮能正确引用文件内容说明闭环通了。如果模型说「我没看到文件内容」检查 tool_result 是否被正确回填以及 tool_use_id 是否匹配。实测下来最容易出问题的是参数校验阶段。比如 Read 的 limit 是必填模型有时不传Zod 校验失败后返回 is_error 的 tool_result模型会重试。如果你看到模型反复调用同一个工具多半是参数校验在拦。验证通过后整条链路就通了。下一节列出常见报错和排查方法。5. 本篇常见错排查401、local proxy failed、reading choices、OAuth工具系统跑不通时报错往往不在工具本身而在通道或配置。下面按真实报错逐个排查。401 Unauthorized。这是 Key 问题。先确认 ANTHROPIC_API_KEY 填的是 TaoToken 的 Key不是其他平台的。再确认 Key 没有过期或被删。如果用的是 settings.json检查 JSON 格式有没有多逗号格式错误会导致环境变量没加载。排查命令echo $ANTHROPIC_API_KEY输出为空说明环境变量没生效检查 shell 配置或 settings 路径。local proxy failed。这个报错通常出现在本地代理或端口占用场景。先确认 Base URL 是 https://taotoken.net/api 没有多余路径。再检查本地有没有其他进程占用 Claude Code 需要的端口。如果你之前配过其他代理工具先清掉相关环境变量unset HTTP_PROXY HTTPS_PROXY ALL_PROXY然后重启 Claude Code。这个报错和工具系统无关但会表现为「工具不工作」因为请求根本没发出去。reading choices 报错。这个通常出现在响应格式不符合预期时。Claude Code 期望 Anthropic 格式的响应如果通道返回了 OpenAI 格式解析就会失败。确认 Base URL 走的是 Anthropic 兼容端点模型 ID 也是 Anthropic 系列的。如果混用了 OpenAI 格式的模型工具调用块的结构不一样会直接报 reading choices。OAuth 相关报错。Claude Code 某些版本会走 OAuth 流程。如果你用 API Key 方式接入需要在配置里显式关闭 OAuth 或指定 API Key 模式。检查 settings 里有没有残留的 OAuth token 配置清掉后重启。OAuth 报错和 Key 报错容易混区分方法是看报错里有没有 token 字样。工具不调用。模型不调用工具先查三件事tools 字段是否注入成功、工具 description 是否清晰、权限规则是否把工具 deny 了。description 太模糊模型不知道何时用权限 deny 会让工具在注册阶段就被过滤掉。参数校验反复失败。检查 input_schema 的 required 字段把可选参数从 required 里移出。再看 minimum/maximum 是否过严模型传的值可能超出范围。MCP 工具注册失败。检查 MCP 配置里的 Base URL、Key、Model ID 三件套是否齐全。Cline MCP 或 CC Switch 场景下缺任何一项都会静默失败。确认 MCP server 本身能启动再确认工具名前缀正确。排查顺序建议先确认通道通curl 最小请求再确认工具定义注入带 tools 的请求最后确认权限和执行。这样能快速定位问题在哪一层。6. 把工具系统接进你的工作流工具系统跑通后下一步是把它接进日常工作流。几个实用建议。第一按用途分 Key。本地开发、CI、MCP 各用一个 Key出问题时能快速定位是哪个环节。TaoToken 的 API Keys 页面可以管理多个 Key建议命名清晰。第二工具 description 写清楚。模型靠 description 决定何时调用工具写得太简会漏调写得太长会占 token。参考官方工具的写法一句话说清用途和返回内容。第三权限规则从宽到严。初期用 allow 放行只读工具观察模型行为后再收紧。破坏性工具始终走 ask别图省事直接 allow。第四验证链路用 curl 隔离变量。工具不工作时先用 curl 确认通道再进 Claude Code 排查。这样能避免在工具层浪费时间。第五长期编码或 Agent 场景考虑用 Coding Plan 统一管理额度。工具调用会消耗大量 token尤其是并行执行多个工具时。Coding Plan 适合需要长期跑 Agent 的场景模型对话适合临时验证API Keys 适合接入配置。工具系统的价值在于把模型能力从文本生成扩展到真实操作。理解注册、注入、校验、权限、执行、格式化这六步你就能自己扩展工具、排查问题、优化性能。整条链路的核心是通道要通、定义要对、权限要清。把这三件事做好工具系统就能稳定工作。
返回列表