跳转到内容

02 XML 工具协议与原生工具调用

学习目标

本章要解决什么问题:Cline 如何在 40+ 模型提供商不兼容的工具调用协议下,实现统一的工具系统?XML 和原生 tool calling 如何共存?

前置知识

本章涉及工具调用协议的通用原理,建议先阅读:

下文假设你已理解四层工具系统架构和 OpenAI Function Calling 协议,直接聚焦 Cline 的具体实现。


项目实践

双协议支持架构

Cline 的工具系统同时支持两种协议,通过 useNativeToolCalls 标志在运行时切换:

为什么需要双轨? Anthropic、Ollama、LM Studio 等不支持 OpenAI 格式的原生工具调用。XML 标签是一种通用方案——将工具指令作为提示词的一部分,对模型没有格式要求。但对 OpenAI Responses API 等原生支持的提供商,使用原生协议可以获得结构化输出和 call_id 追踪能力。

ToolExecutorCoordinator 路由

工具执行采用 Coordinator 路由模式:

# 伪代码:路由流程
const result = await ToolExecutor.execute({
toolName: "write_to_file",
parameters: { path: "...", content: "..." },
approvalState: "approved" // 前置审批检查已通过
})

路由步骤

  1. 从 LLM 响应中提取工具调用(XML 或 JSON)
  2. 检查自动审批状态(autoApprove.ts
  3. Coordinator 按工具名查找 handler
  4. Handler 在 handlers/ 目录下独立实现
  5. 执行结果返回给 LLM 或用户

Plan 模式工具限制

Cline 通过 PLAN_MODE_RESTRICTED_TOOLS 列表限制 Plan 模式下可用工具集,只允许读取和提问类工具,禁止文件写入和命令执行。

并行工具调用

当模型一次返回多个工具调用时,Cline 支持并行执行(通过配置可切换为串行)。并行条件:工具之间无资源依赖和逻辑依赖。


问题与规避

陷阱场景对策
XML 标签格式错误LLM 生成未闭合的标签parseAssistantMessageV2 使用健壮解析策略,容忍部分格式错误
审批前置缺失handler 执行了未审批的操作审批检查在 Coordinator 路由之前,未通过审批不调用 handler
工具名称冲突内置工具与 MCP 工具同名MCP 工具使用 use_mcp_tool 包装,通过 server_name 区分

设计取舍

XML vs 原生协议

维度XML 标签原生 tool calling
兼容性所有模型仅支持 OpenAI Responses API 等
结构化依赖 LLM 正确生成 XMLJSON Schema 保证结构
追踪能力无 call_id有 call_id,支持并行追踪
提示词长度较长(标签占用 Token)较短(JSON Schema)

Cline 的策略:能原生就原生,否则用 XML。通过 apiFormat 字段自动选择最优协议。


参考来源

  • Cline 源码:apps/vscode/src/shared/tools.ts
  • Cline 源码:apps/vscode/src/core/task/ToolExecutor.ts
  • Cline 源码:apps/vscode/src/core/assistant-message/index.ts