Skip to content

v0.4.0 — 用个人 Claude 订阅额度跑节点

Latest

Choose a tag to compare

@simonlin1212 simonlin1212 released this 31 Jul 00:01

让节点走个人 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_provideropenai/gpt-5.4 改成 deepseek/deepseek-v4-pro)与约 600 行贡献者自用的 specs/ / docs/codebase-context/ 脚手架文档。另外 PR 的 factory.py 基于较旧的 main,整体取用会回退 v0.2.20 的 openai_compatible provider——已改为只补 4 行路由。

审计中修掉的六条

这一版的主题是「不产生 API 账单」这个承诺要真的成立,所以每一条静默降级到计费路径的口子都得堵上:

  1. 🔴 凭据失效会静默降级到计费 provider。认证失败原本走 _SDKResultError → 落进 _FALLBACK_ERRORS → 降级计费。用户开订阅模式就是为了避免账单,token 一过期就悄悄开始计费。新增 _AuthError刻意不在 _FALLBACK_ERRORS 里),报错直接给出 claude setup-token 修复步骤。

    实测发现有必要:OAuth token 过期时 SDK 把它翻译成 Claude Code returned an error result: successsubtype 仍是 "success"is_error=True,真正原因只藏在 api_retry 事件与助手文本里,用户看到那句话完全无从下手。

  2. 401 只出现在 ResultMessage 时被漏判,同样落进 fallback 静默计费。改为先判 api_error_status == 401
  3. anthropic 无法作为降级 provider(死结):护栏检测到 ANTHROPIC_API_KEY 就一律中止——留着 key 启动被拦,删掉 key 又会在撞额度真要降级时认证失败。改为在 Agent SDK 子进程环境里置空该变量,父进程保留供降级用,启动只告警。
  4. 认证识别过宽:原先扫所有助手正文匹配 invalid api key 等词。工具分析师会复述桥接工具的失败原文——某个行情源自己的 key 失效时正文里就可能出现这些词,会被误判成订阅失效并中止整轮分析。收窄为只在合成错误消息上匹配。
  5. (role, content) 元组消息被静默清空Reflector.reflect_on_final_decision() 传的正是元组,而消息解析只认 BaseMessage 与 dict → 两条消息双双变空串 → SDK 收到空 prompt 却照常返回内容,是「不报错的错答案」。
  6. 降级配置的三处配错只在撞额度那一刻才炸: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,经多轮独立代码审计至无回归。