让节点走个人 Claude Pro/Max 订阅额度,而不是按 token 计费的 Anthropic API。基于社区 PR #86(感谢 @kingxiaozhe)。默认关闭,行为不变。
背景
此前项目对 Claude 只有 anthropic provider = 走 ANTHROPIC_API_KEY 按 token 计费,没有任何走订阅的通道。本版补上 claude_agent_sdk provider:经 Claude Agent SDK 调用本机已登录的 claude,消耗订阅额度,不产生 API 账单。
能力
- 两档覆盖:
deep_think_provider_override只覆盖深度节点(Research / Portfolio Manager);再加quick_think_provider_override则含 7 个工具分析师=全节点走订阅。Web 侧栏三档。 - 工具桥接:分析师的 LangChain 工具桥接为 Agent SDK 进程内 MCP 工具,SDK 内部跑完 ReAct 循环返回最终报告,无需改图。
- 撞额度自动降级到配置的付费 provider。
- 仅供个人自用——消耗的是使用者自己账号的额度。
pip install -e ".[agentsdk]"
claude setup-token # headless/CI 需要;本机已登录 claude 则可跳过在 PR 基础上改了什么
模型默认值改用别名。 PR 默认 claude-opus-4-8,写死的完整 id 会随版本迭代过期(仓库 model_catalog 里的 anthropic 条目就已停在 4-6)。改用 claude CLI 的 opus / sonnet 别名——恒指向最新模型。quick 节点默认给 sonnet:节点数量多(7 分析师 + 辩手),订阅按额度限流,全用 opus 很快撞上限。
未采纳 PR 夹带的全局默认变更(把 llm_provider 从 openai/gpt-5.4 改成 deepseek/deepseek-v4-pro)与约 600 行贡献者自用的 specs/ / docs/codebase-context/ 脚手架文档。另外 PR 的 factory.py 基于较旧的 main,整体取用会回退 v0.2.20 的 openai_compatible provider——已改为只补 4 行路由。
审计中修掉的六条
这一版的主题是「不产生 API 账单」这个承诺要真的成立,所以每一条静默降级到计费路径的口子都得堵上:
- 🔴 凭据失效会静默降级到计费 provider。认证失败原本走
_SDKResultError→ 落进_FALLBACK_ERRORS→ 降级计费。用户开订阅模式就是为了避免账单,token 一过期就悄悄开始计费。新增_AuthError(刻意不在_FALLBACK_ERRORS里),报错直接给出claude setup-token修复步骤。实测发现有必要:OAuth token 过期时 SDK 把它翻译成
Claude Code returned an error result: success,subtype仍是"success"而is_error=True,真正原因只藏在api_retry事件与助手文本里,用户看到那句话完全无从下手。 - 401 只出现在
ResultMessage时被漏判,同样落进 fallback 静默计费。改为先判api_error_status == 401。 anthropic无法作为降级 provider(死结):护栏检测到ANTHROPIC_API_KEY就一律中止——留着 key 启动被拦,删掉 key 又会在撞额度真要降级时认证失败。改为在 Agent SDK 子进程环境里置空该变量,父进程保留供降级用,启动只告警。- 认证识别过宽:原先扫所有助手正文匹配
invalid api key等词。工具分析师会复述桥接工具的失败原文——某个行情源自己的 key 失效时正文里就可能出现这些词,会被误判成订阅失效并中止整轮分析。收窄为只在合成错误消息上匹配。 (role, content)元组消息被静默清空:Reflector.reflect_on_final_decision()传的正是元组,而消息解析只认 BaseMessage 与 dict → 两条消息双双变空串 → SDK 收到空 prompt 却照常返回内容,是「不报错的错答案」。- 降级配置的三处配错只在撞额度那一刻才炸:provider/model 未成对配置(会产生
AnthropicClient(model="deepseek-chat"))、跨 provider 时仍转发主 provider 的backend_url、降级客户端没带 callbacks(开始计费时统计反而是瞎的)。前两条改为启动即校验。
另修 Web UI「所有节点」把深度模型复制给 quick 节点、覆盖掉 sonnet 默认值的问题。
依赖
[agentsdk] 链路为 claude-agent-sdk → mcp → httpx2,不碰 httpx,与 mootdx 的 httpx<0.26 无冲突(uv lock 实测通过)。与 v0.3.1 中因结构性冲突而移除的 [google] 不同,无需单开 venv。PR 注释里「会与 mootdx 冲突」的说法已过时(mcp 已迁到 httpx2),一并订正。
测试
pytest tests/ 214 passed / 1 skipped / 45 subtests,经多轮独立代码审计至无回归。