TradingAgents-astock

simonlin1212Apache-2.0活跃维护

面向A股的多人智能体投研框架,接入龙虎榜、游资、解禁等本地数据源,让7位AI分析师按A股规则辩论并给出风险评估。

A股多Agent投研框架 — 适配A股数据源(龙虎榜/游资/解禁等),7位分析师基于A股规则的辩论决策,基于TradingAgents深度改造,适配大A。A-share multi-agent investment research framework — 7 AI analysts, bull/bear debate, risk assessment。

v0.5.22发布于 2026-10-30 23:03 UTC3,944star +16 / 7 天986fork同步于 2026-11-10 23:40 UTC

怎么上手

由 README 提炼,执行前请确认
git clone https://github.com/simonlin1212/tradingagents-astock.git
cd tradingagents-astock
pip install -e .
streamlit run web/app.py
硬件要求按 README 说明

README 未说明显存或 GPU 要求;LLM 走 API 或远程 Ollama,本地只需 Python >= 3.10 环境,无需 Docker。

支持 Apple Silicon有 Docker 镜像
下载:源码 zip·GitHub Releases(安装包)本站不镜像安装包

项目说明

由 README 自动翻译提炼

把 TradingAgents 多 Agent 辩论架构深度改造到 A 股,7 位分析师覆盖政策、游资、解禁等本土因素

面向A股的多人智能体投研框架,接入龙虎榜、游资、解禁等本地数据源,让7位AI分析师按A股规则辩论并给出风险评估。

核心能力

  • 7 位分析师含政策、游资追踪、解禁监控三个 A 股特化角色
  • 多空辩论后经研究经理研判、交易员方案与三方风险辩论出最终评级
  • 数据源全免费直连 mootdx、东财、新浪、同花顺等,无需 API Key
  • 内置 A 股交易约束:T+1、涨跌停、最小手数、ST 全覆盖
  • 双 LLM 设计,深度思考模型负责研究经理与组合经理决策

容易踩的坑

需先在项目根目录建 .env 配置 LLM API Key,每次分析约 30-50 次 LLM 调用会产生费用;用 Kimi 走 Anthropic 兼容接口时 ANTHROPIC_API_KEY 和 ANTHROPIC_BASE_URL 两个都要设,且不能用 ANTHROPIC_AUTH_TOKEN;东财接口有风控,批量分析需靠内置节流,可设 EM_MIN_INTERVAL=1.5~2 降速,否则可能临时封 IP。

内容由模型根据 README 生成,可能不完整或不准确,以官方文档为准。看原文 README

最近发版

5 个版本v0.5.22
  1. v0.5.22最新正式版2026-10-30 · 2026-10-30 23:03 UTC

    v0.5.22

    • fix: 历史日期调用时跳过实时请求及快照写入,明确说明实时数据已略去,不输出由其生成的金额或方向信号。可选缓存先按分析日截断,再取最近 20 条;无可用记录时说明缺失,保留当天调用行为。 (#121)

    详见 CHANGELOG.md。

  2. v0.5.21v0.5.21 — 财报三表恢复 + 防未来函数 / 自定义模型 ID2026-10-11 · 2026-10-11 13:40 UTC
    查看更新说明

    基本面分析师近 5 个月拿不到的三张财报恢复了,并且回看历史日期时只给分析日之前已经公布的财报;Web 侧栏的「Custom model ID」可以正常使用。建议所有用户升级。

    修复

    • 资产负债表 / 利润表 / 现金流量表恢复(#116,#117 by @ontheway06):新浪财报接口的数据在 report_list 里,v0.2.5(2026-05-17)起的解析只认另一种结构,三张表一直静默返回「No … data found」,分析师会把「该股没有财报」当成事实。现在两种结构都认;同名科目(如两个「利息收入」)不再互相覆盖。
    • 回看历史时不再提前看到未公布的财报:原来按「报告期 ≤ 分析日」筛,分析日 07-15 会拿到 8 月才发的半年报。现在按新浪给的公告日、入库时间判断是否已公布;两个日期都被后来的报表改写时才按法定披露截止日判断;新浪 2020-03-13 给全市场的批量入库单独识别。逾期披露的公司也不会提前露出(例:300630 的 2023 年报 2024-07-05 才发,分析日 2024-05-15 看不到)。
    • 三张财报表工具的分析日期改为必填(传空日期会要求重传),提示词写明要传;回看越早取的期数越多,2016 年等较早日期也能取到;升级前记下的缺数据重试会自动补上分析日期。
    • Web「Custom model ID」(#120 by @ontheway06):DeepSeek、通义千问、GLM、MiniMax 选这一项时,原来把 custom 当模型名发给 API;现在会出现输入框,没填就拦在发起分析之前。开始分析、续跑、重新分析、错误页继续 4 条入口都覆盖。

    已知限制

    • 2020-03-13 之前的报告期,接口不保留原始公布日,只能按截止日或批量入库时间判断:提前公布的会晚看到(平安银行 2019 年报要到 2020-03-14 才放行),当年逾期披露的可能提前看到。
    • 入库时间也被后来改写过的报告期会比实际公布晚放行。
    • 较早报告期的数值可能是次年报表里重述后的对比数。

    验证

    • 全量测试 562 passed / 14 skipped / 0 failed(Python 3.12;跳过的都是没装的可选依赖),本版新增 51 条。
    • 28 处变异检查(故意改坏,测试必须变红)全部变红。
    • 真实接口实测:600519 分析日 2026-07-15 最新一期是 2026-03-31、2026-08-20 是 2026-06-30;2019-05-15 / 09-15 / 11-15 分别看到 2019 年一季报 / 半年报 / 三季报;300630、000001、920819 如 CHANGELOG 所列。
    • 发版前做了多轮独立只读复核(Opus 5.5),每轮修复后再审修复补丁:先后指出逾期披露会漏、工具日期可选、批量入库让 2019 年报表晚放行近一年、升级前的重试任务会一直失败、批量认定没限定日期、空日期不筛,都已修并补了测试。
    • 隐私扫描(gitleaks + 本机路径 / 邮箱核对):没有发现密钥或本机路径。

    升级:git pull 后重新 pip install -e .。

    完整变更见 CHANGELOG。

    本项目仅供学习研究,不构成任何投资建议。

  3. v0.5.20v0.5.20 — 超时保护补全2026-09-21 · 2026-09-21 00:30 UTC
    查看更新说明

    修复

    • 补齐 Claude Agent SDK 订阅主路径的超时保护。llm_timeout 现在同样覆盖订阅调用;单轮按配置值计时,内部工具循环按允许轮数换算总预算。
    • 超时后显式收尾 SDK 异步生成器;即使 SDK 阻塞自身事件循环或不响应取消,调用方也会通过 daemon 工作线程的有界等待返回,不再永久卡住。
    • 保持付费护栏:超时可走已配置的 fallback,认证失效仍不会静默降级到按 token 计费的 provider。
    • 为 Alpha Vantage 请求增加 30 秒网络超时,避免上游无响应时整轮分析永久等待。

    验证

    • 默认环境:512 passed / 13 skipped / 0 failed,另有 51 个 subtests 通过。
    • 安装 agentsdk 可选依赖的隔离环境:34 passed。
    • 新增 35 条超时与配置回归用例,并完成 9 项变异验证。
    • Claude Opus 5 实现与复核;Cline CLI 的 Kimi K3 独立只读审查无 P0/P1/P2。

    完整变更见 CHANGELOG.md。

  4. v0.5.19v0.5.19 — LLM 超时重试 · provider 归一化 · 远程 Ollama2026-09-20 · 2026-09-20 22:50 UTC
    查看更新说明

    本版收口社区 PR #100 的 LLM 韧性改造,并合入 PR #112 的 GLM 模型更新。重点解决网关挂起时分析永久不返回、SDK 重试移交后漏掉 408/409/429 与连接错误、降级和分角色模型拿错超时/重试参数等问题。

    修复:LLM 请求超时与重试

    • 新增 llm_timeout,默认 150 秒,覆盖所有走 LangChain 客户端的 provider,以及订阅撞额度后的降级客户端。
    • OpenAI 兼容路径的应用层重试现在覆盖 408 / 409 / 429 / 5xx 和连接类错误(含读超时)。
    • 400 / 401 / 404 / 422 等鉴权、参数错误仍在第一次失败时直接抛出。
    • 超时与重试改为按目标 provider 计算,主客户端、fallback_spec、role_llms 三个消费方分别应用。
    • 修复 llm_max_retries 为负数时 invoke() 静默返回 None。

    修复:provider 归一化与分角色模型

    • create_llm_client 在中央边界统一执行 strip().lower()。
    • "DeepSeek"、" deepseek " 等写法现在与 "deepseek" 行为一致。
    • base_url 继承、供应商私有参数过滤、韧性参数和 role 实例缓存键共用同一归一化结果。
    • 修复同一家 provider 因大小写或空格被判成跨厂商,导致 relay 地址丢失或重复创建客户端的问题。
    • 拼错的 provider(如 deepsek)仍会明确报错。

    修复:opencode.ai 流式用量统计

    opencode.ai 流式路径现在默认启用 stream_usage,避免分析完成后 tokens_in / tokens_out 静默显示为 0;用户显式传 stream_usage=False 时仍会尊重该设置。

    模型与文档

    • 合入 PR #112(by @FelixWang119):补充 GLM-5.3、GLM-5.3-Flash、GLM-5.2 模型 ID。
    • README 中英文同步补充 llm_timeout / llm_max_retries / llm_retry_delay。
    • 补充远程 Ollama 配置(#61):llm_provider=ollama,backend_url=http://<主机>:11434/v1。

    测试

    新增 38 条超时、重试、降级、provider 归一化和流式统计测试。完整测试在两套依赖环境中均为 0 failed:

    • Python 3.12.13 / openai 3.16.2 / langchain-openai 1.6.2:476 passed / 14 skipped / 48 subtests。
    • Python 3.13.13 / openai 2.48.0 / langchain-openai 1.4.1:477 passed / 13 skipped / 51 subtests。

    独立审查未发现 P0 / P1 / P2;16 类变异均能被测试验红。

    已知限制

    • 第三方网关若把错误包装成非 OpenAI SDK 异常类型,应用层重试无法识别。
    • claude_agent_sdk 订阅覆盖的主路径不经过 LangChain 客户端,因此暂不受 llm_timeout 保护;它的降级客户端已覆盖。
    • 降级 fallback_spec 不继承各家私有参数,例如 Google 的 thinking_level 或 OpenAI 的 reasoning_effort;同厂商降级会使用默认档位。

    升级

    git pull
    pip install -U .
    

    感谢 @k176060444-lgtm 和 @FelixWang119 的贡献。

  5. v0.5.18v0.5.18 — 缺失数据追踪 · 端点统一 · 辩论去重(4 PR + 1 issue)2026-09-20 · 2026-09-20 07:59 UTC
    查看更新说明

    本版合并了 4 个社区 PR 并修掉 1 个 issue,共 5 项,来自 4 位贡献者(@FelixWang119 贡献了一个 PR 和一个 issue)。有两处不向后兼容,升级前请先看这两条:

    • ⚠️ langgraph 最低版本提升到 1.0 —— 旧环境需要先 pip install -U langgraph。
    • ⚠️ glm / qwen 的默认端点统一到国内站 —— 此前 Web 侧默认走海外站的用户会改走国内站(不会坏,两站互认同一个 key,只是网络路径变了)。要指定端点请用 backend_url 或 Web 侧栏的 Base URL 显式覆盖。

    ⚠️ 兼容性:langgraph 最低版本提升至 1.0(#107,by @zhanghang02)

    缺失数据追踪在 ToolNode 上使用 wrap_tool_call,该参数从 LangGraph 1.0 起提供 (实测 0.6.11 没有)。项目依赖由 langgraph>=0.4.8 提升为 langgraph>=1.0, 用旧版 LangGraph 的用户需要先 pip install -U langgraph 再升级本项目。

    新增:缺失数据的追踪、重试与呈现(#107,by @zhanghang02)

    此前某个工具取不到数时,分析师只会在报告里含糊带过,用户既不知道哪一块缺、也无从重试。 现在 ToolNode 外面包一层记录器,把「哪个股票 / 哪天 / 哪个阶段 / 哪个工具」写进索引, 报告页可以看到缺失清单并单独重试,重试结果会被复用而不是重新调一遍模型。

    • 失败判定不只看 status:还认 [数据缺失: …] 标记和一组失败措辞。 其中 Error 开头的前缀只在 200 字以内的短响应上才算失败——新闻标题本身就可能以 Error 开头,早先的 ^Error\b 会把正常新闻判成失败。
    • 记账用 try/except 包住并吞掉异常:这一层是辅助功能,坏了也不能弄坏分析图。
    • 新增 tests/test_missing_data_tasks.py、tests/test_report_viewer_pdf_gate.py, 并把 tests/test_sentiment_data_tools.py 里校验「图里的 ToolNode 与分析师工具表一致」 的正则放宽到兼容 wrap_tool_call 在与不在两种写法——否则加了这层包装后该校验会直接失配。

    修复:同花顺一致预期在 pandas 3.x 下恒为空(#111,by @FelixWang119)

    pd.read_html(r.text) 直接传字符串字面量的用法在 pandas 2.1 起废弃、3.0 移除, 改为 pd.read_html(io.StringIO(r.text))。

    修复:百度概念板块把风控拦截说成「该股没有概念板块」(#111,by @FelixWang119)

    百度 PAE 被风控时回 HTTP 403 + {"ResultCode": 0, "Result": {"code": 403, "msg": "hit risk"}}, 外层 ResultCode 是整数 0,而正常响应是字符串 "0"——原先的 str(ResultCode) != "0" 两种都放行,于是风控响应一路走到「取不到分类」的分支,返回 No concept/block data。 一个「被拦截」的事实就这样变成「这只股票没有概念板块」喂给模型。现在单独识别 403 并如实报错。

    该接口对 python-requests 的 TLS 指纹做风控(同一时刻 curl 正常),要稳定取数需要 curl_cffi 这类浏览器指纹伪装;本次只保证失败时说实话,不做伪装。

    ⚠️ 修复:CLI 与 Web 连到不同站点,glm / qwen 统一到国内站(#113,by @FelixWang119)

    同一批 provider 的 base URL 写在两处:cli/utils.py 给 CLI 用、llm_clients/openai_client.py 的 _PROVIDER_CONFIG 给客户端兜底(Web 侧栏 Base URL 留空时生效)。v0.2.4 引入时就没对齐—— glm 一边 open.bigmodel.cn(国内)一边 api.z.ai(海外),qwen 一边 dashscope.aliyuncs.com 一边 dashscope-intl。两站互认同一个 key 且返回同一份模型列表,所以从不报错, 只是从 CLI 跑和从 Web 跑会静默走不同网络路径。其余 provider 一直是一致的。

    统一到国内站:这是 A 股特化 fork,README 中英文都让用户去 open.bigmodel.cn 申请 key, 代码理应回到文档已声明的意图上。

    可能影响你:此前依赖 Web 侧默认走海外站的用户,现在会走国内站(国内站同样对海外可用, 不会坏掉,只是路径不同)。要指定端点请用 backend_url 或 Web 侧栏的 Base URL 显式覆盖。

    新增 tests/test_provider_endpoint_consistency.py 钉住两处一致——这两个值此前零测试覆盖, 所以分裂了三个版本没人发现。

    优化:辩论历史去重与滚动窗口压缩(#109,by @SummerCaptain)

    多空 / 风险辩手每轮把完整 history 注入 prompt,同时再单独注入一次「最后一条发言」, 而那恰恰就是 history 的最后一条(五个 agent 的状态写回里,两者是同一个 argument 变量)—— 等于每轮都把最新发言塞两遍,注入 token 随轮数平方增长。去掉重复注入,零信息损失。

    同时新增 compact_history:超过 4 条发言时,早期发言压成「角色: 首句」一行,最近 4 条保留全文。 默认配置不触发(max_debate_rounds=1 → 多空 2 条、max_risk_discuss_rounds=1 → 风险 3 条), 只有调大轮数才生效,现有用户行为不变。

    修复:DeepSeek V4 不设输出上限会把网关拖到空闲超时(#103,by @k176060444-lgtm)

    V4 thinking 系不给 max_tokens 时,后端的长 reasoning 链会一直写下去,撞上网关约 3 分钟的 idle timeout 导致进程挂起。ModelCapabilities 新增 default_max_tokens,只对已实测的 V4 家族 (^deepseek-v4 匹配)兜底 8192,且仅在用户没有显式指定 max_tokens 时生效。

    这是 #100 review 结论的落地:全局 8192 会误伤 Claude / Gemini 等原生上限更高的模型, 所以预算必须挂在 capabilities 上按模型给,而不是在客户端一刀切。


    升级

    pip install -U langgraph      # ⚠️ 本版要求 >= 1.0
    git pull && pip install -U .
    

    无配置文件变化。全量测试 422 passed / 14 skipped。

    感谢 @zhanghang02、@FelixWang119、@SummerCaptain、@k176060444-lgtm 的贡献。

用户点评

登录用户的真实使用记录,可按版本和硬件筛选
共 0 条

    还没有人点评。第一个说出真实体验的人最有价值。

    README 原文

    未翻译


    为什么做这个 Fork

    原版 TradingAgents 是一个出色的多 Agent 投研框架,但它针对美股设计:数据走 Yahoo Finance / Alpha Vantage,分析师不懂 A 股制度,辩论和决策完全面向美股市场。

    本 Fork 的目标:把 TradingAgents 的多 Agent 辩论架构真正落地到 A 股,不是简单翻译,而是从数据层、Agent 角色、交易规则三个维度做深度特化。

    核心改造

    维度原版本 Fork
    数据源Yahoo Finance / Alpha Vantagemootdx + 东财 + 新浪 + 同花顺(全免费直连)
    Analyst 角色4 个(市场/情绪/新闻/基本面)7 个(+政策分析师/游资追踪/解禁监控)
    交易规则美股(T+0、无涨跌停)A 股(T+1、涨跌停、最小手数、交易时段)
    输出语言英文中文报告(内部辩论保持英文以保证推理质量)
    Alpha 基准SPY沪深 300(CSI 300)

    与上游对比

    特性原版 TradingAgents本 Fork
    许可证Apache 2.0全 Apache 2.0
    部署依赖pip install开箱即用
    A 股数据❌mootdx + 东财 + 新浪 + 同花顺(直连 HTTP)
    A 股特化角色❌政策/游资/解禁 3 个深度角色
    A 股交易约束❌T+1/涨跌停/手数/ST 全覆盖

    架构概览

    ┌─────────────────────────────────────────────────────────┐
    │                    7 Analyst 研报生成                      │
    │  Market → Social → News → Fundamentals                   │
    │  → Policy → Hot Money → Lockup                           │
    │         (每个 Analyst 带工具循环)                          │
    ├─────────────────────────────────────────────────────────┤
    │               Bull vs Bear 投研辩论                       │
    │         Bull Researcher ←→ Bear Researcher               │
    │               (最多 N 轮辩论)                             │
    ├─────────────────────────────────────────────────────────┤
    │              Research Manager 综合研判                     │
    │         (深度思考 LLM,输出投资计划)                       │
    ├─────────────────────────────────────────────────────────┤
    │                  Trader 交易方案                          │
    │         (A 股约束:T+1/涨跌停/手数)                       │
    ├─────────────────────────────────────────────────────────┤
    │        Aggressive ←→ Conservative ←→ Neutral             │
    │               三方风险辩论                                 │
    ├─────────────────────────────────────────────────────────┤
    │            Portfolio Manager 最终决策                      │
    │     (深度思考 LLM,输出评级 + 理由)                       │
    └─────────────────────────────────────────────────────────┘
    

    双 LLM 设计:

    • quick_think_llm:所有 Analyst、Researcher、Trader、Risk Debater
    • deep_think_llm:Research Manager 和 Portfolio Manager(需要综合全局信息做决策)

    7 个 Analyst 角色

    原版 4 角色(A 股适配)

    A 股特化 3 角色(新增)

    所有 7 个 Analyst 的报告会流入后续的 Bull/Bear 辩论和三方风险辩论,确保 A 股特色因素贯穿整条决策链。


    数据源

    全部免费,无需 API Key,无积分墙:

    来源协议提供内容
    mootdxTCP 7709OHLCV K 线、财务快照、F10 文本
    腾讯财经HTTP (qt.gtimg.cn)PE / PB / 市值 / 换手率(实时)
    东方财富HTTP (datacenter / push2)龙虎榜、限售解禁、板块行情、个股信息
    新浪财经HTTPK 线历史、财报三表
    同花顺HTTP (10jqka)EPS 一致预期
    财联社HTTP (cls.cn)全球财经快讯
    百度股市通HTTP (finance.pae.baidu)概念板块分类、资金流向

    完全不依赖 Tushare(积分墙)、Alpha Vantage(海外 API)、Yahoo Finance(不支持 A 股)。


    数据源优先级 & 东财防封(v0.2.11):行情 / K线 / 市值 / 财务能从 mootdx(通达信 TCP,不封 IP)或腾讯拿到的,一律走它们;东财只用于它独有的数据(龙虎榜 / 解禁 / 资金流 / 板块 / 个股新闻等)。所有东财请求统一走内置节流入口 _em_get():串行限流(默认间隔 ≥1s + 0.1~0.5s 随机抖动)+ 复用 Keep-Alive 会话,多 Agent 跑批量分析不再触发临时封 IP(东财风控实测:每秒 >5 / 并发 ≥10 / 1 分钟 ≥200 触发封禁)。批量场景可设环境变量 EM_MIN_INTERVAL=1.5~2 进一步降速。仅东财限流,mootdx / 腾讯 / 新浪 / 同花顺 / 财联社 / 百度 不受影响。

    快速开始

    1. 环境准备

    # Python >= 3.10
    git clone https://github.com/simonlin1212/tradingagents-astock.git
    cd tradingagents-astock
    pip install -e .
    
    # 如需使用 Google Gemini 模型(无 [google] extra,需显式装,见下方 FAQ):
    pip install --no-deps "langchain-google-genai>=4.0.0"
    pip install "google-genai>=1.53.0" "httpx>=0.28.1"
    
    # 如需让节点走你个人 Claude Pro/Max 订阅额度而非 API 计费(可选):
    pip install -e ".[agentsdk]"
    

    装完即可用,无需 Docker。 安装后直接跑 streamlit run web/app.py(Web UI)或 tradingagents(CLI)即可,详见下方「Web UI」「CLI 方式」两节。Docker 仅是可选的部署方式,本地开发不需要。

    2. 配置 LLM

    默认走 API Key 计费。每次分析需 30-50 次 LLM 调用。

    例外(v0.4.0 新增):装 [agentsdk] 后可让部分或全部节点经 Claude Agent SDK 走你个人 Claude Pro/Max 订阅额度,不产生 API 账单。见下方「用个人 Claude 订阅额度」。

    在项目根目录创建 .env 文件,按你选择的供应商配置:

    # ── 方案 A:MiniMax(推荐,国内直连,性价比高)──────────
    MINIMAX_API_KEY=sk-xxx
    # 申请地址:https://platform.minimaxi.com/
    
    # ── 方案 B:DeepSeek ─────────────────────────────────
    DEEPSEEK_API_KEY=sk-xxx
    # 申请地址:https://platform.deepseek.com/
    
    # ── 方案 C:智谱 GLM ─────────────────────────────────
    ZHIPU_API_KEY=xxx
    # 申请地址:https://open.bigmodel.cn/
    
    # ── 方案 D:通义千问 Qwen ────────────────────────────
    DASHSCOPE_API_KEY=sk-xxx
    # 申请地址:https://dashscope.console.aliyun.com/
    
    # ── 方案 E:OpenAI ───────────────────────────────────
    OPENAI_API_KEY=sk-xxx
    
    # ── 方案 F:Anthropic ────────────────────────────────
    ANTHROPIC_API_KEY=sk-ant-xxx
    
    # ── 方案 G:Kimi(Anthropic 兼容 API)────────────────
    ANTHROPIC_API_KEY=your-kimi-token
    ANTHROPIC_BASE_URL=https://api.kimi.com/coding/
    # ⚠️ 两个都要设。只给 key 不给端点,请求会发到 Anthropic 官方并报
    #    「401 invalid x-api-key」。端点也可以写在 config 的 backend_url 里(见下)。
    # ⚠️ 别用 ANTHROPIC_AUTH_TOKEN——那是 Claude Code CLI 的写法,本项目走 langchain,
    #    只认 ANTHROPIC_API_KEY。
    
    # ── 方案 H:任意 OpenAI 兼容网关(9Router / AI Router / 自建代理)──
    OPENAI_COMPATIBLE_API_KEY=sk-xxx     # 也接受 OPENAI_API_KEY
    BACKEND_URL=https://your-relay.example/v1   # 你的网关地址(也可在 Web 侧栏「API Base URL」填)
    

    3. 运行分析

    新建一个 Python 文件(比如项目根目录下的 run.py),把下面这段粘进去,按你选的供应商改 config 后运行 uv run python run.py。根目录自带的 main.py 就是这个示例的可运行版本,直接 uv run python main.py 也行。

    config 不是仓库里的某个配置文件,而是传给 TradingAgentsGraph(config=...) 的一个字典:只写你要覆盖的项,其余项自动取 tradingagents/default_config.py 里的默认值(完整可选项见下文「配置说明」一节)。

    from tradingagents.graph.trading_graph import TradingAgentsGraph
    
    # ── MiniMax 示例(推荐)─────────────────────────────
    config = {
        "llm_provider": "minimax",
        "deep_think_llm": "MiniMax-M2.7",
        "quick_think_llm": "MiniMax-M2.7-highspeed",
        "output_language": "Chinese",
    }
    
    # ── DeepSeek 示例 ───────────────────────────────────
    # config = {
    #     "llm_provider": "deepseek",
    #     "deep_think_llm": "deepseek-chat",
    #     "quick_think_llm": "deepseek-chat",
    #     "output_language": "Chinese",
    # }
    
    # ── Anthropic + Kimi 示例 ───────────────────────────
    # config = {
    #     "llm_provider": "anthropic",
    #     "deep_think_llm": "claude-sonnet-4-6",
    #     "quick_think_llm": "claude-sonnet-4-6",
    #     "backend_url": "https://api.kimi.com/coding/",
    #     "output_language": "Chinese",
    # }
    
    ta = TradingAgentsGraph(debug=True, config=config)
    final_state, decision = ta.propagate("688017", "2026-05-12")
    print(decision)
    

    4. CLI 方式

    tradingagents                 # 交互式 CLI
    tradingagents analyze         # 同上(默认命令)
    tradingagents performance     # 决策绩效统计(见下)
    tradingagents --help          # 查看所有选项
    

    5. 决策绩效统计(v0.5.2 新增)

    想知道这套流程过往的判断准不准,跑:

    tradingagents performance            # 人读的报告
    tradingagents performance --json     # 机器读的 JSON
    

    数据来自记忆日志:每次分析会落一条决策,下次分析同一只股票时自动拉真实行情回填收益与 alpha(对沪深 300)。统计本身零 LLM 调用,只读已经落盘的结果。

    输出的核心指标是 direction_accuracy(方向正确率)——只有它衡量判断准不准:看多要跑赢、看空要跑输才算对,Hold 不表态不计入。另外给出 up_rate(标的上涨占比)与 outperform_rate(跑赢沪深300占比),这两个只描述标的怎么走,与判断对错无关:给出卖出评级后股价下跌是判断正确,但它不会计入「上涨占比」。

    还有按评级、按标的分组,以及一项评级区分度检验——五档评级从 Buy 到 Sell,平均 alpha 是否真的单调递减。评级不单调,说明这套流程的评级没有实际区分能力。

    几点务必注意:

    • 这不是回测,也不是策略业绩。 每条记录是「某天做出的判断在固定持有期后的表现」:持有窗口互相重叠、没有仓位管理、未计交易成本与冲击成本,样本还可能有选择偏差。
    • A 股 beta 很强,跟着大盘涨不代表判断对,所以方向正确率用 alpha 口径判定,看绝对收益容易高估判断力。
    • 样本量分开算:方向正确率只统计有方向的评级,已结算总数够、但有方向的不足 20 条时,报告会单独提示这个指标仍是噪音。
    • 样本少于 20 条时报告会自己标注「这些比率基本是噪音」,不要拿三五条记录下结论。
    • 收益解析不出来的记录会被跳过而不是当成 0%——后者会把统计悄悄拉向中性。

    Web UI

    内置 Streamlit 可视化界面,支持在侧边栏选择 LLM 供应商和模型,输入股票代码即可一键分析,适合不写代码的用户。

    启动

    # 方式一:命令行启动(推荐)
    tradingagents-web
    
    # 方式二:直接运行
    streamlit run web/app.py
    

    打开浏览器访问 http://localhost:8501。

    功能

    • 配置记住:侧栏选的供应商 / 模型 / Base URL / 订阅覆盖写入 ~/.tradingagents/llm_config.json,重开标签页或重启后自动恢复(v0.5.17)
    • 模型自选:侧边栏支持 10 个 LLM 供应商切换(MiniMax/DeepSeek/Qwen/GLM/OpenAI/Anthropic/Google/xAI/OpenRouter/Ollama),外加 「OpenAI 兼容(自定义 base_url)」 一档可接任意 OpenAI 兼容网关(9Router / AI Router / 自建代理)
    • 一键分析:输入 6 位 A 股代码 + 分析日期 +「数据起始日期」(默认本月第一天,可自定义技术分析回溯区间,支持按月/自定义时段分析),点击「开始分析」
    • 实时进度:12 阶段 pipeline 实时显示(7 分析师 → 质量门控 → 辩论 → 风控 → 决策),所有已完成阶段的报告均可展开查看
    • 完整报告:信号卡片(Buy/Hold/Sell)、7 份分析师报告、多空辩论、风控评估
    • 报告导出:一键下载 Markdown(零依赖,永远可用)或 PDF 完整分析报告(PDF 自动适配 Windows/macOS/Linux 中文字体)
    • 历史记录:自动保存并展示所有历史分析

    截图


    配置说明

    所有配置通过 config 字典传入,完整选项:

    参数默认值说明
    llm_provider"minimax"LLM 提供商:minimax / deepseek / qwen / glm / openai / anthropic / google / xai / ollama
    deep_think_llm"MiniMax-M2.7"Research Manager + Portfolio Manager 用的模型
    quick_think_llm"MiniMax-M2.7-highspeed"所有 Analyst / Researcher / Trader 用的模型
    backend_urlNone自定义 API 端点 / 第三方中转网关。可在 Web UI 侧边栏填写,或用 .env 的 BACKEND_URL;方便国内通过代理访问 Claude / OpenAI。跑远程 Ollama 也是填这里:llm_provider 选 ollama、backend_url 填 http://<主机>:11434/v1,不填则默认本机 http://localhost:11434/v1(#61)
    role_llms{}可选:给单个角色指定另一家模型(如多空辩手用不同厂商),留空 = 全部沿用 quick/deep 两档,行为不变。见下方「分角色模型」 #39
    max_tokensNone单次回复的最大输出 token 数。None = 用 provider 默认值。报告写到一半就断,先调这里(不是上下文超长);也可用环境变量 TRADINGAGENTS_MAX_TOKENS。#91
    output_language"Chinese"报告输出语言(内部辩论始终英文)
    market_lookback_daysNone技术分析回溯天数(分析区间 = 起始日期 → 分析日期)。Web/CLI 由「数据起始日期」自动算出;None = 模型自选(约 30 天)。#16
    llm_timeout150单次 LLM 请求超时(秒),对所有走 LangChain 客户端的 provider 生效(openai / anthropic / google / azure 及全部 OpenAI 兼容项,订阅撞额度后的降级客户端也带)。此前没有超时:LangChain 的三个封装层(ChatOpenAI / ChatAnthropic / AzureChatOpenAI)在没给超时时都把 None 显式传给底层 SDK,而这在 httpx 里的语义是「不设超时」——挂起的网关会让分析永久卡住(进程活着、零输出、永不返回)。claude_agent_sdk 订阅覆盖的主路径不走 LangChain 客户端,v0.5.20 起由客户端自己实现同一个配置项:订阅调用的整段预算 = 本项 × 该次调用允许的模型轮数(Agent SDK 把整个工具循环跑在一次调用里,单轮调用就等于本项本身),超时按限流同样的路径降级。深度推理模型如果经常在吐出首个 token 之前就超过这个值,把它调大(#100)
    llm_max_retries3应用层重试次数,覆盖 408 / 409 / 429 / 5xx 与连接类错误(含读超时),即 OpenAI SDK 原本会重试的那一套。仅作用于走 OpenAI 兼容客户端的 provider(openai / deepseek / qwen / glm / minimax / xai / openrouter / ollama / openai_compatible):只有它们的 SDK 层重试被置 0 并交给应用层;Anthropic / Google / Azure 沿用各家 SDK 自己的重试,不碰
    llm_retry_delay5重试初始退避秒数,指数翻倍:5s → 10s → 20s
    max_debate_rounds1Bull vs Bear 辩论轮数
    max_risk_discuss_rounds1风险三方辩论轮数
    data_vendors全部 "a_stock"数据供应商路由
    checkpoint_enabledFalse启用 SQLite 断点续跑
    memory_log_max_entriesNone交易记忆最大条目数

    分角色模型(可选,v0.5.0 新增)

    默认所有角色共用 quick_think_llm / deep_think_llm 两档——大多数人只有一家模型,不需要碰这一项。

    如果你手上有多家模型,可以给单个角色单独指定。最典型的用法是让多空辩手用不同厂商的模型:同一个模型分饰多角时倾向于互相附和,换成不同底座才会真的出现反驳。

    config = {
        "llm_provider": "deepseek",          # 未单独配置的角色仍走这里
        "deep_think_llm": "deepseek-chat",
        "quick_think_llm": "deepseek-chat",
        "role_llms": {
            "bull": {"provider": "qwen",    "model": "qwen-plus"},
            "bear": {"provider": "glm",     "model": "glm-4.6"},
            # provider 省略则沿用 llm_provider,只换模型:
            "portfolio_manager": {"model": "deepseek-reasoner"},
        },
    }
    

    合法角色名(其余角色自动沿用两档默认):

    分组角色名
    7 个分析师market social news fundamentals policy hot_money lockup
    辩论与决策bull bear research_manager trader
    风险三方risk_aggressive risk_neutral risk_conservative
    其他quality_gate portfolio_manager

    几点说明:

    • 角色名写错会直接报错,不会静默忽略——否则你会以为配置生效了,实际没有。
    • 相同的 provider + model 只建一个实例,写 7 个角色不会开 7 条连接。
    • 每家 provider 用自己的 API Key 环境变量(DEEPSEEK_API_KEY / DASHSCOPE_API_KEY / ZHIPU_API_KEY …),缺哪个会指名报出来。
    • 换了 provider 时不会把 backend_url 带过去(那是给主 provider 配的端点),需要的话在该角色里单独写 backend_url。
    • 同时开着 claude_agent_sdk 订阅覆盖时,role_llms 里配的角色会绕开订阅按 token 计费,启动时会点名警告是哪几个。

    常见问题排错

    Q: 用 DeepSeek/通义/智谱,却报 OpenAIError: The api_key client option must be set ... OPENAI_API_KEY? 每个供应商用各自的环境变量,不是 OPENAI_API_KEY:DeepSeek=DEEPSEEK_API_KEY、通义=DASHSCOPE_API_KEY、智谱=ZHIPU_API_KEY、MiniMax=MINIMAX_API_KEY、xAI=XAI_API_KEY、OpenRouter=OPENROUTER_API_KEY、OpenAI 兼容(自定义)=OPENAI_COMPATIBLE_API_KEY。在项目根目录 .env 里设置对应变量后重启程序。(v0.2.12 起缺 key 会直接提示该用哪个变量名。)

    Q: 想接一个 OpenAI 兼容的第三方网关/中继(9Router、AI Router、自建代理),自定义 base_url + model? 用 「OpenAI 兼容(自定义 base_url)」 这一档(v0.2.20 新增)。Web 侧栏「LLM 供应商」选它 →「快速/深度思考模型 ID」手动填你网关支持的 model 名 →「API Base URL」填你的网关地址(如 https://your-relay.example/v1)→ .env 里设 OPENAI_COMPATIBLE_API_KEY=你的key(也接受 OPENAI_API_KEY)。CLI 方式选 OpenAI-Compatible 后会提示输入 Base URL。它走标准 Chat Completions(非 OpenAI Responses API,兼容性最好),model 名自由填、不受内置清单限制。配置方式等价:llm_provider="openai_compatible" + backend_url="<你的网关>" + deep_think_llm/quick_think_llm="<你的model>"。

    Q: 明明装了 Python 3.12/3.14,pip install -e . 却报 requires a different Python: 3.9.6 not in '>=3.10'? 报错里的 3.9.6 就是当前这个 pip 绑定的解释器版本——你装的新版本没被它用上(macOS 自带的 pip3 常指向系统 3.9)。先确认是哪个解释器在跑:

    pip3 -V                    # 末尾括号里就是它绑定的 Python
    python3.12 -m pip -V       # 换成你想用的版本再看
    

    用 python -m pip 的写法就不会认错人,推荐配合虚拟环境:

    python3.12 -m venv .venv && source .venv/bin/activate
    python -m pip install -e .
    

    Windows 用 py -3.12 -m venv .venv + .venv\Scripts\activate。(#92)

    Q: 报告写到一半就结束了,上下文明明没超长? 撞的是输出上限,不是上下文上限——模型一次回复能吐多少 token 是另一个限制。v0.4.1 起,这种截断会在日志里明确告诉你(因为达到输出上限被截断),不再是默默给你半篇报告。调大即可:config 里设 max_tokens(例如 "max_tokens": 16000),或设环境变量 TRADINGAGENTS_MAX_TOKENS=16000。

    另外,用 Kimi 等第三方模型名走 anthropic 通道时,langchain 认不出模型名,会默认一个很小的输出上限(旧版本表现为报告普遍偏短)。v0.4.1 起这种情况会自动放宽到 8192,仍不够就显式配 max_tokens。#91

    Q: 接 Kimi 报 401 invalid x-api-key? 说明请求发到了 Anthropic 官方而不是 Kimi——光给 key 没给端点。两个都要给:

    ANTHROPIC_API_KEY=你的kimi-token
    ANTHROPIC_BASE_URL=https://api.kimi.com/coding/   # 或在 config 里写 backend_url
    

    注意 ANTHROPIC_AUTH_TOKEN 在本项目里不生效(那是 Claude Code CLI 的写法),本项目走 langchain,只读 ANTHROPIC_API_KEY。v0.4.1 起,用非 Claude 模型名却没配端点会在启动时直接告诉你缺什么,而不是等 Anthropic 回一句看不懂的 401。#89

    Q: 导出 PDF 报 UnicodeEncodeError: 'latin-1' codec can't encode? 你的环境里装了旧版 fpdf(pyfpdf),它和本项目用的 fpdf2 都以 fpdf 名称导入、互相冲突。执行:pip uninstall -y fpdf && pip install "fpdf2>=2.8.6"。实在不行可改用「下载 Markdown」导出(零依赖,永远可用)。

    Q: Docker 里怎么跑 Web UI?容器启动报 Invalid value: File does not exist: web/app.py? 用 compose 里的 web 服务:docker compose up web,然后开 http://localhost:8501 。

    报这个错通常是因为命令写成了 streamlit run web/app.py——这条依赖当前工作目录,工作目录不对就找不到文件。正确的入口是 tradingagents-web(即 web.launch:main),它按 __file__ 解析 app.py 的绝对路径,跟工作目录无关。本地跑同理,装完后直接 tradingagents-web 最稳。

    Q: Docker 里导出 PDF 报「未找到中文字体」? v0.2.12 起 Dockerfile 已内置 fonts-noto-cjk,重新 docker build 即可。旧镜像可临时 apt install fonts-noto-cjk,或改用 Markdown 导出。

    Q: Docker 启动报 [Errno 13] Permission denied: /home/appuser/.tradingagents/cache? 旧版镜像里没预建数据目录,docker-compose 的命名卷挂上来时被 Docker 建成 root 属主,而容器内进程以 appuser 运行、写不进去。v0.2.14 起 Dockerfile 已预建 /home/appuser/.tradingagents(cache/logs/memory)并归属 appuser,命名卷会继承该属主。升级方式:git pull 后 docker compose build --no-cache 重建镜像;若想保留旧数据卷可先 docker run --rm -v tradingagents_data:/d alpine chown -R 1000:1000 /d 修正属主,否则 docker volume rm tradingagents_data 后重建即可。

    Q: 部分分析师报告(情绪/新闻/基本面/政策/游资/解禁)空白不显示? 这些报告由对应 Analyst 调用数据工具后生成,空报告会被自动跳过不显示。数据源本身是健康的(腾讯/mootdx/同花顺/东财实测出数);报告为空通常是所选模型 tool-call 能力弱(如部分 deepseek/minimax 轻量模型不稳定地调用工具)。建议换用 tool-call 更稳的模型(deepseek-chat / 通义 / GLM-4 / Claude / GPT 等),或重试。

    Q: 为什么没有 [google] extra 了?装 Gemini 报 httpx 冲突怎么办? v0.3.1 起移除了 [google] extra(#87)。原因:langchain-google-genai>=4.0.0 要求 google-genai>=1.53.0,而该区间内每一个 google-genai 版本都要求 httpx>=0.28.1;mootdx(核心 A 股数据源)钉死 httpx>=0.25,<0.26。没有任何版本组合能同时满足,冲突是结构性的。

    真正的问题是:uv 构建的是覆盖所有 extra 的 universal lock,所以只要这个 extra 存在,uv sync 就对所有人失败——包括从不用 Gemini 的用户。把 extra 留空更糟(pip install .[google] 会静默什么都不装,用户以为装好了)。所以直接移除,并在 google_client.py 导入失败时给出可直接执行的安装命令。

    需要 Gemini 时显式安装(mootdx 取行情走 TCP 协议、运行时根本不 import httpx,所以抬高 httpx 实测不影响取数):

    pip install --no-deps "langchain-google-genai>=4.0.0"
    pip install "google-genai>=1.53.0" "httpx>=0.28.1"
    

    或把 Gemini 与数据层分到不同 venv。最省心是用 DeepSeek / MiniMax / 通义 / OpenAI 兼容中继等,完全不涉及这个冲突。

    另澄清:litellm / mcp 不是本项目的依赖——报错里若提到它们,是你环境里其它包带来的。

    Q: 不进 CLI 交互,怎么批量跑多只标的、拿到和 CLI 一样的完整报告? 看 examples/run_cases.py:它复用 CLI 的 save_report_to_disk(),每只标的输出与 CLI 一致的 complete_report.md(分析师 / 研究 / 交易 / 风险 / 组合五个分区)+ 一份字段齐全的 summary.json。用法:uv run python examples/run_cases.py(跑全部)或 uv run python examples/run_cases.py 688017(单只);改 build_config() 切换 provider/model。


    项目结构

    TradingAgents-Astock/
    ├── tradingagents/
    │   ├── agents/
    │   │   ├── analysts/          # 7 个分析师
    │   │   │   ├── market_analyst.py
    │   │   │   ├── social_media_analyst.py
    │   │   │   ├── news_analyst.py
    │   │   │   ├── fundamentals_analyst.py
    │   │   │   ├── policy_analyst.py        # A 股特化
    │   │   │   ├── hot_money_tracker.py     # A 股特化
    │   │   │   └── lockup_watcher.py        # A 股特化
    │   │   ├── researchers/       # Bull / Bear 研究员
    │   │   ├── risk_mgmt/         # 激进 / 保守 / 中立 辩手
    │   │   ├── managers/          # Research Manager + Portfolio Manager
    │   │   ├── trader/            # Trader(A 股交易约束)
    │   │   └── utils/             # 状态定义、工具函数
    │   ├── dataflows/
    │   │   ├── a_stock.py         # A 股数据 vendor(直连 HTTP API,零第三方库)
    │   │   ├── interface.py       # 数据接口抽象层
    │   │   └── ...
    │   └── graph/
    │       ├── trading_graph.py   # 主入口:TradingAgentsGraph
    │       ├── setup.py           # LangGraph 拓扑定义
    │       ├── propagation.py     # 状态初始化与传播
    │       ├── reflection.py      # 交易反思(CSI 300 基准)
    │       └── conditional_logic.py
    ├── web/
    │   ├── app.py                 # Streamlit 主入口
    │   ├── runner.py              # 后台线程运行分析
    │   ├── progress.py            # 线程安全进度追踪
    │   ├── history.py             # 历史记录扫描
    │   ├── pdf_export.py          # PDF 报告生成
    │   ├── launch.py              # CLI 启动器
    │   └── components/            # UI 组件
    │       ├── sidebar.py         # 侧边栏(输入 + 历史)
    │       ├── progress_panel.py  # 实时进度面板
    │       └── report_viewer.py   # 报告展示
    ├── test_astock.py             # E2E 集成测试
    ├── CHANGES_FROM_UPSTREAM.md   # 与上游的完整改动记录
    ├── NOTICE                     # Apache 2.0 归属声明
    ├── LICENSE                    # Apache 2.0 许可证
    └── pyproject.toml             # 包定义与依赖
    

    致谢

    本项目基于 TauricResearch/TradingAgents 开源项目进行 A 股特化改造。感谢原作者的出色工作和 Apache 2.0 开源精神。

    原始论文:TradingAgents: Multi-Agents LLM Financial Trading Framework


    项目定位

    这是一个框架的工程实现,不是一个投资产品。

    • 它是什么:TradingAgents 论文(TauricResearch)多 Agent 架构的 A 股工程实现,用于研究与教学——研究多 Agent 辩论在金融文本上的行为、A 股数据源如何接入、结构化输出如何落地。
    • 它不是什么:不是投资顾问、不是荐股软件、不提供任何投资服务。本仓库不发布针对具体证券的分析报告、评级或买卖建议;examples/ 下只有可自行运行的脚本,没有任何预生成的个股结论。
    • 模型和数据都是你自己的:你配置自己的 LLM API key,在自己的机器上运行,产出的内容归你所有、由你判断、由你负责。项目本身不托管服务、不代为分析、不接触你的运行结果。
    • 不产出可执行价位:框架内没有建仓价 / 止损位 / 仓位 / 目标价这类输出——不是默认关闭,是代码里就没有。Trader 与 Portfolio Manager 只给方向、评级与理由。需要这类能力的使用者可以自行 fork 添加(Apache-2.0 允许),并自行承担相应责任、自行确认所在司法辖区的资质要求。

    ⚠️ 免责声明

    • 本系统产出的所有内容均由 AI 自动生成,可能存在错误或偏差
    • 本项目不构成任何投资建议;投资决策请咨询持有中国证监会颁发资质的专业机构
    • 作者不对使用本工具产生的任何投资损失承担责任
    • 股市有风险,投资需谨慎

    License

    Apache License 2.0

    本项目是 TauricResearch/TradingAgents 的 fork,继承 Apache 2.0 许可证。详见 NOTICE。

    作者: Simon 林 · X @linsizhen · 邮箱:[email protected]

    用个人 Claude 订阅额度(可选,v0.4.0 新增)

    让节点经 Claude Agent SDK 走你个人 Claude Pro/Max 订阅额度,而不是按 token 计费的 Anthropic API。

    与内置 anthropic provider 的区别:anthropic 走 ANTHROPIC_API_KEY = 按 token 计费;本 provider 走本机已登录的 claude CLI = 消耗订阅额度,不产生 API 账单。

    仅供个人自用——它消耗的是你自己账号的订阅额度。把它做成给别人用的产品需要 Anthropic 授权,不在本项目范围内。

    1. 准备
    pip install -e ".[agentsdk]"
    
    # 本机 claude 已登录即可;headless / CI 环境需要显式 token:
    claude setup-token          # 输出的 token 设为 CLAUDE_CODE_OAUTH_TOKEN
    
    # 不打算保留付费降级的话,顺手清掉(可选)
    unset ANTHROPIC_API_KEY
    

    关于 ANTHROPIC_API_KEY:它的优先级高于订阅凭据,但不会泄进 Agent SDK 子进程——客户端在子进程环境里已把它显式置空,订阅额度照常生效。父进程保留它是为了让 anthropic 仍能作为撞额度后的降级 provider(否则就成死结:留着启动被拦、删掉又在真要降级时认证失败)。启动时只告警不中止。

    2. 开启

    Web UI 侧栏「个人 Claude 订阅覆盖 (Agent SDK)」三档,或在 config 里设:

    config["deep_think_provider_override"]  = "claude_agent_sdk"   # 仅深度节点
    config["quick_think_provider_override"] = "claude_agent_sdk"   # 再加这条 = 全节点
    config["agent_sdk_model"]       = "opus"      # 深度节点
    config["agent_sdk_quick_model"] = "sonnet"    # 分析师节点
    

    模型建议填别名 opus / sonnet——claude CLI 的别名恒指向最新模型,写死 claude-opus-4-8 这类完整 id 会随版本迭代过期。完整 id 同样支持。

    3. 两条边界
    • 额度而非 token:订阅是按额度限流的。「所有节点」会把 7 个分析师 + 多空/交易员/风险辩手全压上去,跑几轮就可能撞上限——所以 agent_sdk_quick_model 默认给的是更省的 sonnet。撞额度会自动降级到你配的付费 provider(可用 agent_sdk_fallback_provider / agent_sdk_fallback_model 指定)。
    • 凭据失效不降级:OAuth token 过期时直接报错中止,不会静默降级到计费 provider——你开订阅模式就是为了避免账单,悄悄开始计费比报错更糟。报错里会给出 claude setup-token 的修复步骤。
    依赖说明

    [agentsdk] 的依赖链是 claude-agent-sdk → mcp → httpx2,不碰 httpx,与 mootdx 的 httpx<0.26 无冲突(已 uv lock 实测)——和 #87 里被移除的 [google] 情况不同,不需要单开 venv。