
Agent 框架后端低代码RAG【免费下载链接】yao✨ All your agents and workspaces in one place, on every device you own. Track tasks on a board, accessible from desktop, mobile, browser, or API. Self-hosted.项目地址https://gitcode.com/gh_mirrors/ya/yao点击查看免费下载导读本文基于仓库中的设计提案 ANTHROPIC_PROVIDER_PROPOSAL.md系统讲解 Yao Agent 如何摆脱借道 OpenAI 兼容层 URL 字符串猜测的脆弱方案通过新增原生anthropicconnector 类型与独立 Provider直接对接 Claude Messages API。读完本文你将掌握Anthropic 与 OpenAI 两类 API 在端点、鉴权、请求/响应结构上的差异connector 层与 provider 层的分阶段改造方案以及当前仓库中该方案的实际落地实现与测试验证方式。背景为什么需要原生 Anthropic 支持Yao Agent 的 LLM 接入层位于agent/llm/其核心入口是 llm.go 中的New()它委托给 factory.go 的SelectProvider()完成 Provider 选择。在设计提案成文时仓库存在两个根本性的架构缺陷连接器层没有类型区分所有 LLM 连接器都声明type: openaifactory.go通过conn.Is(connector.OPENAI)判断时永远为真Anthropic 无法在连接器层面被识别。基于 URL 的检测脆弱且错误系统依赖硬编码的 URL 模式如anthropic.com调用DetectAPIFormat()猜测 API 格式一旦走代理、自定义域名或兼容网关就会失效属于把运行时猜测当架构设计的反模式。结合源码看这一判断在 factory.go 中仍然留有痕迹DetectAPIFormat()如今优先读取连接器类型但当类型无法区分时仍会退化为对host字符串的子串匹配anthropic.com、api.kimi.com/coding、deepseek.com这正是提案所批评的脆弱路径。问题核心两套 API 协议的七处差异Anthropic Claude API 与 OpenAI 兼容 API 并非简单的换一个 URL而是从端点到数据结构的全面差异。提案将其归纳为三类核心不兼容维度OpenAI 兼容 APIAnthropic Messages API端点/v1/chat/completions/v1/messages鉴权头Authorization: Bearer tokenx-api-key: key另需anthropic-version系统提示词messages数组中的role: system消息顶层独立字段system最大输出长度max_tokens可选max_tokens必填流式格式data: {...}SSE 单事件多事件 SSEmessage_start、content_block_start等工具调用tool_calls/function对象tool_usecontent block inputJSON响应结构choices[].messagecontent[]content blocks正是这些差异决定了用 OpenAI 协议头去请求 Anthropic 端点必然失败也决定了必须有一层专门的格式转换逻辑。方案总览两阶段改造提案给出了清晰的落地路径将改造拆成两个互不依赖的阶段Phase 1: gou/connector —— 新增 anthropic 连接器类型 Phase 2: yao/agent/llm —— 新增 anthropic Provider 与消息转换第一阶段解决识别问题让连接器在声明时就能自我表达第二阶段解决翻译问题让 OpenAI 格式的对话上下文能够无损映射为 Anthropic 协议。Phase 1连接器层新增anthropic类型提案规划在连接器包中新增类型常量并新建独立的连接器实现目录const ( // ... existing types ANTHROPIC 7 // New connector type )对应的连接器 DSL 也随之出现第一种原生写法{ label: Claude Sonnet 4.5, type: anthropic, options: { model: claude-sonnet-4-5, key: $ENV.ANTHROPIC_API_KEY, capabilities: { vision: claude, tool_calls: true, streaming: true } } }其中options各字段的含义与默认值如下hostAPI 地址默认https://api.anthropic.com支持通过自定义域名或代理网关覆盖model模型标识如claude-sonnet-4-5、claude-haiku-4-5-20251001后者已在测试中实际使用见下文测试一节keyAPI 密钥支持$ENV.XXX环境变量引用避免密钥硬编码versionAPI 版本号默认2024-01-01提案——需要说明的是当前源码 anthropic.go 中实际默认值为2023-06-01并允许通过setting[version]覆盖配置时建议显式声明capabilitiesvision、tool_calls、streaming等模型能力开关供上层能力适配器读取。从仓库现状看type: anthropic的写法已在多处落地验证测试代码 anthropic_supplement_test.go 中直接以该 DSL 构造连接器llmprovider/presets.yml中也存在type: anthropic的预设条目如 OpenCode Go、超算互联网 Token Plan 等第三方 Anthropic 兼容端点。Phase 2Provider 层的协议翻译提案规划的 Provider 结构体形态如下type Provider struct { *base.Provider adapters []adapters.CapabilityAdapter } func New(conn connector.Connector, capabilities *Capabilities) *Provider func (p *Provider) Stream(ctx, messages, options, handler) (*CompletionResponse, error) func (p *Provider) Post(ctx, messages, options) (*CompletionResponse, error)这一设计完全对齐了当前仓库中 Provider 体系的能力适配器架构详见 providers/README.mdProvider 只负责 API 通信格式能力适配器ToolCall、Vision、Audio、Reasoning负责模型能力。Anthropic Provider 与 OpenAI Provider 共用同一套base.Provider见 base.go与同一批适配器唯一不同的是请求体与响应解析逻辑。消息转换从 OpenAI 格式到 Anthropic 格式提案给出了最关键的转换规则——OpenAI 的system消息必须剥离为顶层字段// OpenAI format: // {role: system, content: ...} // {role: user, content: ...} // Anthropic format: // system: ... (separate field) // messages: [{role: user, content: ...}]这一规则在实际实现 buildRequestBody 中得到完整落地遍历消息时role system的消息被拼接进systemContent多条系统消息以\n\n连接并跳过消息数组其余消息进入messages。此外实现还处理了三种 OpenAI 体系特有而 Anthropic 没有的形态多模态内容[]context.ContentPart数组中的text与image_url分片被转换为 Anthropic 的text/imagecontent block其中 base64 data URL 会解析出media_type与data普通 URL 则走source.type url见 convertImagePart工具结果OpenAI 的role: tool消息被改写为role: usertool_resultcontent block并通过tool_use_id关联到对应的工具调用助手工具调用OpenAI 的assistant消息携带tool_calls时拆解为texttool_use两种 content blockArgumentsJSON 字符串会被反序列化为input对象。请求体构建与必填参数Anthropic 要求max_tokens必填这与 OpenAI 的宽松语义不同。实际实现给出了完整的取值优先级链anthropic.gomaxTokens : 4096 // default if options.MaxTokens ! nil { maxTokens *options.MaxTokens } else if options.MaxCompletionTokens ! nil { maxTokens *options.MaxCompletionTokens } else if mt, ok : setting[max_tokens].(int); ok mt 0 { maxTokens mt } // 连接器声明的 MaxOutputTokens 作为上限兜底其余请求体字段同样遵循OpenAI 语义 → Anthropic 语义的映射temperature、top_p直传stop映射为stop_sequencesOpenAI 的tools含function.parameters转换为 Anthropic 的toolsinput_schematool_choice的auto/none/required/function-name分别映射为{type:auto}、{type:none}、{type:any}与{type:tool,name:...}见 convertTools连接器设置中的thinking等扩展参数则经白名单过滤后合并进请求体。HTTP 鉴权头三个头一个都不能少提案明确列出 Anthropic 的鉴权要求实际实现完全一致req.SetHeader(Content-Type, application/json) req.SetHeader(x-api-key, apiKey) // Not Bearer token req.SetHeader(anthropic-version, 2024-01-01)实现还在此基础上做了更精细的兼容setAnthropicAuthHeaders 会优先读取LLMConnector.GetAuthMode()——若连接器声明为AuthAPIKey则使用api-key头AuthBearer则退回Authorization: Bearer默认情况下使用 Anthropic 标准的x-api-key同时设置Accept: text/event-stream流式必需与User-Agent: YaoEngine/version。SSE 事件解析与 OpenAI 完全不同的流协议OpenAI 的流式响应是单一类型的data:事件而 Anthropic 是六种生命周期事件的有序序列提案给出了完整清单event: message_start event: content_block_start event: content_block_delta event: content_block_stop event: message_delta event: message_stop当前实现anthropic.go对每个事件的处理都落在streamAccumulator状态机上message_start记录消息id、model、role并累计input_tokens用量content_block_start按块类型分发——thinking块开启思考流text块开启文本流tool_use块则登记工具调用骨架id、name并立即发送一条与 OpenAI 兼容的ChunkToolCall起始消息供上层 CUI 解析工具名content_block_delta处理三种增量——text_delta累积文本并推送ChunkTextthinking_delta累积思考内容并推送ChunkThinkinginput_json_delta累积工具参数的partial_json并推送ChunkToolCall增量content_block_stop/message_stop结束当前消息块发送ChunkMessageEndmessage_delta捕获stop_reason与output_tokens完成用量统计error/ping前者向 handler 推送错误后者作为保活心跳被忽略。流结束后累积的内容被组装为统一的 CompletionResponseAnthropic 的stop_reasonend_turn/max_tokens/tool_use/stop_sequence经 mapStopReason 映射为 OpenAI 语义的stop/length/tool_calls工具调用块按索引排序后填入ToolCalls。这意味着上层对话引擎可以完全无感知地消费两种协议。非流式Post路径则直接解析NonStreamResponse按content[]块类型拆分出Content、ReasoningContent与ToolCallsanthropic.go。工厂接入类型优先URL 兜底提案规划的SelectProvider改造方案——直接以conn.Is(connector.ANTHROPIC)分流——已完整落地于 factory.goapiFormat : DetectAPIFormat(conn) switch apiFormat { case openai: return openai.New(conn, options.Capabilities), nil case anthropic: return anthropic.New(conn, options.Capabilities), nil default: return openai.New(conn, options.Capabilities), nil }DetectAPIFormat()的判定顺序是先查连接器类型connector.ANTHROPIC→anthropicconnector.OPENAI→openai类型无法区分时再退回 URL 子串猜测最终默认 OpenAI。这一顺序保证了新连接器靠类型、老连接器靠兼容的双轨并存。可靠性设计重试、退避与中断作为生产级实现Anthropic Provider 在 Stream 与 Post 中都内置了完整的重试机制最多 3 次尝试失败后按1s → 2s → 4s指数退避退避期间持续监听上下文取消与强制中断信号任意时刻用户中断都能立即生效isRetryableError 只对超时、连接断开、EOF与 HTTP 429/5xx 等瞬时故障重试其余错误直接失败。非 SSE 的错误响应如网关返回 JSON 错误体也会被独立缓冲并解析为可读的错误信息。测试策略与源码验证提案规划的测试分三层当前仓库均有对应实现单元/集成测试覆盖消息转换与请求构建的核心路径。mock_integration_test.go 通过connector.Select(anthropic.mock)验证流式回显TestLLMMockAnthropicStreamEcho与一次性补全TestLLMMockAnthropicPost流式细节测试anthropic_supplement_test.go 以claude-haiku-4-5-20251001模型验证基础流式TestAnthropicStreamBasic、工具调用流式TestAnthropicStreamWithToolCalls以及失败重试路径TestAnthropicStreamRetry其中连接器 DSL 即为type: anthropic的真实写法端到端测试e2e_test.go 的TestE2EAnthropicHaiku通过connector.Select(anthropic.haiku)发起真实 API 调用需要有效的测试密钥。需要说明的是连接器层常量与解析实现位于外部依赖github.com/yaoapp/gou不在本仓库范围内本仓库内可直接验证的是 Provider 层anthropic/ 目录与工厂分流逻辑。迁移路径与兼容策略提案明确了三条迁移原则对已上线的应用完全友好向后兼容现有type: openai的连接器继续按 OpenAI 兼容协议工作行为不变新连接器用新类型直连 Claude 时声明type: anthropic获得类型级别的校验与正确的协议解析代理服务不受影响OpenRouter、AWS Bedrock 等提供 OpenAI 兼容端点的服务继续使用type: openai无需改动。备选方案对比与取舍提案还评估了仅在 yao 层做 URL 检测的替代方案即当时的现状优点是无需改动连接器层缺点是脆弱、架构上不正确、缺少连接器级校验。结论明确——拒绝该方案。从当前 factory.go 的实现可以看出URL 检测已退化为类型判断之后的兜底手段而非主路径这正是提案结论落地的体现。实施工作量参考提案给出了改造规模的估算可作为类似架构改造的排期参考组件文件数代码量估算工作量连接器层anthropic3~250 行2-3 小时Provider 层anthropic2~600 行4-6 小时测试4~400 行2-3 小时合计9~1250 行8-12 小时从最终实现规模看仅 Provider 层单文件即达千行级别anthropic.go可见协议翻译与 SSE 状态机是最重的部分。总结Yao Agent 对 Anthropic 的原生支持遵循了一条清晰的演进路径先在连接器层引入type: anthropic类型声明解决识别问题再在 Provider 层实现消息转换、请求构建、鉴权头与 SSE 解析解决翻译问题最后通过类型优先、URL 兜底的工厂分流保证新老连接器并存。这一方案将此前依赖 URL 字符串猜测的脆弱逻辑替换为类型明确、可校验、可测试的架构且能力适配器体系让 Anthropic 与 OpenAI 共享同一套工具调用、视觉、推理处理管线。对于需要在 Yao Agent 中接入 Claude 或其他 Anthropic 兼容网关如llmprovider/presets.yml中收录的第三方端点的开发者直接按文中 DSL 声明type: anthropic连接器即可获得完整的原生协议支持。赞分享Agent 框架后端低代码RAG【免费下载链接】yao✨ All your agents and workspaces in one place, on every device you own. Track tasks on a board, accessible from desktop, mobile, browser, or API. Self-hosted.项目地址https://gitcode.com/gh_mirrors/ya/yao点击查看免费下载相关推荐VoltAgent Anthropic AI Provider 完整指南在 Agent 中接入 Claude 模型与弃用迁移实践VoltAgent Anthropic AI Provider 完整指南在 Agent 中接入 Claude 模型与弃用迁移实践 本文围绕 VoltAgent人工智能AI AgentAgent 框架后端多智能体RAG工具调用Agent 记忆Agent 工作流AI 评测MCP 服务MCP Clients语音Genkit Go 的 Anthropic 插件基于原生 Messages API 接入 Claude 模型Genkit Go 的 Anthropic 插件基于原生 Messages API 接入 Claude 模型 导读 本文讲解 Genkit Go 生态中 go人工智能大模型后端AI AgentRAG工具调用VoltAgent 接入 Anthropic Claude 模型Provider 配置、模型路由与完整示例解析VoltAgent 接入 Anthropic Claude 模型Provider 配置、模型路由与完整示例解析 本文基于 VoltAgent 官方配方文档 w人工智能AI AgentAgent 框架后端多智能体RAG工具调用Agent 记忆Agent 工作流AI 评测MCP 服务MCP Clients语音上一篇如何实现多物种基因簇比较分析Clinker工具为你提供自动化可视化解决方案下一篇BilibiliCommentScraper基于Selenium的B站全量评论数据采集方案创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考