跳到主要内容

TradingAgents — 架构与原理

30 秒导读: TradingAgents 把一家真实交易公司的分工搬进代码——一群各有专长的 LLM agent(基本面、情绪、新闻、技术分析师 → 多空研究员辩论 → 交易员 → 激进/保守/中性三方风险辩论 → 组合经理)围绕“某只票在某天该买/持/卖”接力协作,最后给出一个五档评级。它用 LangGraph 编排整个流程,并在每一步强制 agent“只引用工具返回的真实数据”,专门对付 LLM 编造价格和公司身份的老毛病。

本项目子系统多、机制密,单文件讲不下,因此拆成 6 章。本页是 Layer 0(这是什么)+ Layer 1(顶层全景)+ 阅读地图;想深入某个机制,按下方地图跳章。


1. 这是什么(零基础也能懂)

一句话定义: TradingAgents 是一个多 agent 的 LLM 金融交易研究框架——用一队分工明确的语言模型 agent,模拟一家交易公司“开会做决策”的全过程,输出一份对某只标的的交易建议。

解决什么问题 / 给谁用:

单个 LLM 直接问“NVDA 现在该买吗”,答案往往是一坨没有依据、还可能编数字的空话。真实交易公司不是一个人拍脑袋,而是分工 + 互相质疑:分析师取数、研究员多空对辩、风控三方把关、组合经理拍板。TradingAgents 就是把这套“角色 + 流程 + 相互制衡”用代码固化下来。

  • 给谁用: 做 AI-for-finance 研究的人、想学“多 agent 协作怎么落地”的工程师。
  • 重要免责声明(项目自己反复强调): 它是研究框架,不是投资建议,成绩随模型、温度、数据质量大幅波动(README + tauric.ai/disclaimer)。

它能做什么(功能):

  • 针对一个 (标的, 日期) 跑完整分析流水线,产出分析师报告、辩论记录、最终决策。
  • 支持股票和加密两种资产模式(CLI 从 ticker 自动识别)。
  • 接 20+ 家 LLM 厂商(OpenAI / Anthropic / Google / xAI / DeepSeek / Groq / 本地 Ollama …)。
  • 数据可切厂商(yfinance / Alpha Vantage / FRED / Polymarket)。
  • 记忆过去决策、等真实行情出来后回看自己对没对、把教训喂回下一次分析。
  • 崩了能从上次成功的节点续跑。

用起来什么样: 最小的编程入口只有几行(main.py:12-16):

from tradingagents.default_config import DEFAULT_CONFIG
from tradingagents.graph.trading_graph import TradingAgentsGraph

ta = TradingAgentsGraph(debug=True, config=DEFAULT_CONFIG.copy())
_, decision = ta.propagate("NVDA", "2024-05-10") # 跑完整个 agent 团队
print(decision) # -> "Buy" / "Overweight" / "Hold" / "Underweight" / "Sell"

也有一个富交互的终端界面(python -m cli.main),实时显示每个 agent 的状态、报告、token 消耗。

一句话直觉/类比: 把它想成一家微缩交易公司的自动跑图——每个 LLM 是一名员工,LangGraph 是把员工按流程连起来的“工位图和传送带”,而框架花最大力气做的一件事是:盯着每个员工,不许他们凭空编数字


2. 顶层全景(它大概怎么转)

2.1 主线:一次 propagate() 从头到尾

整条流水线是一个 LangGraph 状态机:一个共享的 AgentState 字典在节点间流动,每个节点(agent)读它需要的字段、写回自己的产出。流程分四个阶段接力:

输入: (标的 ticker, 交易日 date, 资产类型)


┌─────────────────────────────────────────────────────────────┐
│ 阶段一 · 分析师团队(按选择顺序串行,各自带工具循环取数) │
│ 市场分析师 → 情绪分析师 → 新闻分析师 → 基本面分析师 │
│ 每人: LLM 想要数据就调工具 → 工具返回 → 再想 → 写出报告 │
└─────────────────────────────────────────────────────────────┘
│ 四份报告写进 state

┌─────────────────────────────────────────────────────────────┐
│ 阶段二 · 研究员辩论(多空来回,有限轮) │
│ 多头研究员 ⇄ 空头研究员 → 研究经理裁决,出“投资计划” │
└─────────────────────────────────────────────────────────────┘
│ investment_plan

┌─────────────────────────────────────────────────────────────┐
│ 阶段三 · 交易员 │
│ 把投资计划落成一个可执行的交易提案(买/持/卖 + 入场/止损) │
└─────────────────────────────────────────────────────────────┘
│ trader_investment_plan

┌─────────────────────────────────────────────────────────────┐
│ 阶段四 · 风险三方辩论 + 组合经理 │
│ 激进 → 保守 → 中性(轮流开火,有限轮) │
│ → 组合经理拍板: 五档评级 + 执行摘要 + 投资论点 │
└─────────────────────────────────────────────────────────────┘


输出: final_trade_decision(整段决策) + 一个五档评级

怎么读这张图: 从上到下是时间顺序,四个阶段严格接力;阶段一内部每个分析师有个“想→取数→再想”的小循环,阶段二/四内部是有限轮的辩论循环。循环怎么被“数着轮数”掐断,见第 1 章

2.2 部件一句话职责

部件干什么在哪个文件
TradingAgentsGraph总编排器:建 LLM、建图、跑图、写盘、触发反思tradingagents/graph/trading_graph.py
GraphSetup把 agent 节点和边组装成 LangGraph 工作流tradingagents/graph/setup.py
ConditionalLogic条件路由:分析师是否再取数、辩论是否再来一轮tradingagents/graph/conditional_logic.py
AgentState在全图流动的共享状态(TypedDict)tradingagents/agents/utils/agent_states.py
各 agent 工厂每个角色一个 create_* 闭包,返回图节点函数tradingagents/agents/**
数据工具 + 厂商路由get_stock_data 等工具,按配置路由到 yfinance/AV…tradingagents/dataflows/interface.py
TradingMemoryLog + Reflector记决策、等行情、算 alpha、写反思tradingagents/agents/utils/memory.pygraph/reflection.py
LLM 客户端层一套接口接所有厂商tradingagents/llm_clients/**

2.3 三条值得记住的“暗线”

项目真正的工程价值不在“调用模型”,而在三条贯穿全图的暗线,后面各章会展开:

  1. 防幻觉是第一目标。 运行开始就用 yfinance 确定“这票到底是哪家公司”注入所有 agent;市场分析师被强制先拉一份确定性核验快照当唯一真值(market_data_validator.py)。
  2. 万物可路由、失败要响。 数据厂商是一条显式的链,绝不偷偷 fallback 到你没选的厂商;没数据就返回一个明确的 NO_DATA_AVAILABLE 哨兵,让 agent 说“查不到”而不是编。
  3. 决策要复盘。 每次决策先记为 pending,等真实行情出来后再算收益/alpha、生成反思,喂回下一次同标的分析。

3. 阅读地图(建议顺序)

顺序章节讲什么什么时候读
101-orchestration.mdLangGraph 图怎么搭、状态怎么流、两个辩论循环怎么掐断、崩溃路由防护想懂“整体怎么转起来”先读这章
202-agents-debate.md12 个 agent 各自的 prompt 与产出、辩论机制、结构化输出、消息清理想懂“每个角色具体做什么”
303-data-tools.md厂商路由、符号归一化、核验快照、grounded 情绪分析想懂“数据从哪来、怎么防编造”
404-memory-checkpoint.md两阶段记忆日志、alpha 反思、per-ticker checkpoint 续跑想懂“它怎么复盘、怎么续跑”
505-llm-providers.md多厂商抽象、工厂+注册表、能力表、结构化输出降级想懂“怎么一套代码接所有模型”
606-craft-and-map.md巧妙之处、边界与局限、横向对比、代码地图想带走“精华”和跳源码的索引

版本锚点:本套文档基于 commit 01477f9(v0.3.1)。所有 file:line 引用以该提交为准。