摘要
AtomCode2Api 目前通过文本标记协议(<tool_call> 文本解析)实现第三方客户端的工具调用。该方案依赖模型指令遵循,存在随机性;模型有时会绕过协议直接使用 daemon 内置工具(对客户端不可见、无审计)。希望支持原生 tools 透传:客户端传入 tools → 代理 → daemon → 上游模型,返回标准 tool_calls,彻底替代文本协议。
使用场景
Hermes / Claude Code 等 OpenAI 兼容客户端通过 AtomCode2Api 调用 daemon,需要标准工具调用体验
工具调用需要客户端侧可见、可审计、可幂等重跑(文本协议下模型直接用 daemon 内置工具时,这些全部缺失)
现状与已确认的障碍(实测,供参考)
我已在 daemon 层做了直连验证,结论如下——直接转发 tools 字段给 daemon 是行不通的:
daemon 完全忽略请求中的 tools 参数:直连带 tools 测试,模型自述"我没有 get_weather 工具,我有的工具是 ast_grep、atomgit_issue…",随后用内置 web_search 自答。daemon 只把自己的内置工具暴露给模型。
daemon 丢弃请求的 System 字段:把协议提示词放入 System 字段后,模型明确回答"系统提示中不存在该段落"。System 注入路线走不通。
转发 tools 反而有害:daemon 会把转发的工具名暴露给模型,模型尝试原生调用时报 unknown or unmounted tool,受错误反馈干扰后放弃工具调用。
但 daemon 对上游的请求本身是标准 OpenAI 格式:config.toml 中 provider="openai",上游 llm-api.atomgit.com 为 OpenAI 兼容接口。理论上存在打通透传的可能(需 daemon 侧配合)。
期望行为
客户端发送带 tools 的 /v1/chat/completions 请求时:
tools 定义能真正到达模型,模型原生返回 tool_calls delta
客户端回传 tool result 后能继续生成,全程标准 OpenAI 协议、无文本协议痕迹
可讨论的实现方向
代理层翻译(已实现一版,可贡献代码):监听 daemon SSE 流中的 tool_start/tool_result 事件,回合结束时翻译成标准 tool_calls 返回客户端;客户端重跑工具后回传结果时,用缓存的 daemon 最终答复直接应答。我已在本地验证通过(非流式/流式/多轮均正常),可以整理成 PR。
打通 daemon 透传(根治):daemon 上游(atomcode 项目)如果支持 tools 透传或提供相关开关,AtomCode2Api 增加透传模式即可获得与官方 API 完全一致的原生体验。如作者了解 daemon 侧的口子,请指点。
MCP 挂载:daemon 是 MCP 客户端,可通过本地 MCP server 把自定义工具挂载为原生工具(局限:执行发生在 daemon 回合内,客户端侧可见性仍需方向 1 的翻译层)。
环境
平台:Windows x64
AtomCode daemon:5.0.5/5.0.6
客户端:Hermes(OpenAI 兼容)
摘要
AtomCode2Api 目前通过文本标记协议(<tool_call> 文本解析)实现第三方客户端的工具调用。该方案依赖模型指令遵循,存在随机性;模型有时会绕过协议直接使用 daemon 内置工具(对客户端不可见、无审计)。希望支持原生 tools 透传:客户端传入 tools → 代理 → daemon → 上游模型,返回标准 tool_calls,彻底替代文本协议。
使用场景
Hermes / Claude Code 等 OpenAI 兼容客户端通过 AtomCode2Api 调用 daemon,需要标准工具调用体验
工具调用需要客户端侧可见、可审计、可幂等重跑(文本协议下模型直接用 daemon 内置工具时,这些全部缺失)
现状与已确认的障碍(实测,供参考)
我已在 daemon 层做了直连验证,结论如下——直接转发 tools 字段给 daemon 是行不通的:
daemon 完全忽略请求中的 tools 参数:直连带 tools 测试,模型自述"我没有 get_weather 工具,我有的工具是 ast_grep、atomgit_issue…",随后用内置 web_search 自答。daemon 只把自己的内置工具暴露给模型。
daemon 丢弃请求的 System 字段:把协议提示词放入 System 字段后,模型明确回答"系统提示中不存在该段落"。System 注入路线走不通。
转发 tools 反而有害:daemon 会把转发的工具名暴露给模型,模型尝试原生调用时报 unknown or unmounted tool,受错误反馈干扰后放弃工具调用。
但 daemon 对上游的请求本身是标准 OpenAI 格式:config.toml 中 provider="openai",上游 llm-api.atomgit.com 为 OpenAI 兼容接口。理论上存在打通透传的可能(需 daemon 侧配合)。
期望行为
客户端发送带 tools 的 /v1/chat/completions 请求时:
tools 定义能真正到达模型,模型原生返回 tool_calls delta
客户端回传 tool result 后能继续生成,全程标准 OpenAI 协议、无文本协议痕迹
可讨论的实现方向
代理层翻译(已实现一版,可贡献代码):监听 daemon SSE 流中的 tool_start/tool_result 事件,回合结束时翻译成标准 tool_calls 返回客户端;客户端重跑工具后回传结果时,用缓存的 daemon 最终答复直接应答。我已在本地验证通过(非流式/流式/多轮均正常),可以整理成 PR。
打通 daemon 透传(根治):daemon 上游(atomcode 项目)如果支持 tools 透传或提供相关开关,AtomCode2Api 增加透传模式即可获得与官方 API 完全一致的原生体验。如作者了解 daemon 侧的口子,请指点。
MCP 挂载:daemon 是 MCP 客户端,可通过本地 MCP server 把自定义工具挂载为原生工具(局限:执行发生在 daemon 回合内,客户端侧可见性仍需方向 1 的翻译层)。
环境
平台:Windows x64
AtomCode daemon:5.0.5/5.0.6
客户端:Hermes(OpenAI 兼容)