TradingAgents 多智能体量化交易框架:LangGraph 协作与辩论机制解析
1. 从零理解 TradingAgents 到底在解决什么问题第一次看到 TradingAgents 这个项目名我脑子里蹦出来的不是又一个量化框架而是终于有人把多智能体这套东西往交易研究上搬了。量化交易这个圈子单打独斗的策略研究员太多了一个人盯数据、写因子、回测、调参、写报告累得要死不说还容易陷入思维定式。TradingAgents 的核心思路很直接既然一个分析师会累会偏那就搞一屋子虚拟分析师分工协作让它们互相辩论、互相纠错最后给出一个更靠谱的交易判断。这个框架本质上是一个基于多智能体协作的量化交易研究框架底层用 LangGraph 做智能体编排用 LLM 做每个智能体的大脑。它要解决的问题是传统量化研究流程中从数据获取、基本面分析、技术面分析、情绪分析到最终决策往往是割裂的、串行的、单视角的。TradingAgents 把这些环节拆成不同的智能体角色让它们像一家真实的交易公司那样运作——有分析师团队、有研究员、有交易员、有风控甚至还有基金经理拍板。适合谁来参考如果你是有一定 Python 基础、对量化交易有基本认知、又想了解多智能体怎么落地到金融场景的开发者这个框架非常值得拆。如果你只是想找个现成的策略跑实盘那它可能不是你的菜——它更像一个研究框架重点在研究两个字帮你把分析流程结构化、智能化而不是直接给你一个赚钱机器。我先把话说在前头TradingAgents 这类框架的价值不在于它能不能立刻帮你赚钱而在于它提供了一套可复用的多智能体协作范式。你把这套范式吃透了迁移到其他领域——比如舆情分析、供应链决策、甚至内容审核——都是通的。这才是它真正值得研究的地方。2. 整体架构设计与多智能体角色拆解2.1 为什么选 LangGraph 而不是普通 LangChain Chain这是很多人第一个会问的问题LangChain 和 LangGraph 到底啥区别为什么 TradingAgents 要用 LangGraph我用一个生活化的类比来解释。LangChain 的 Chain 就像一条流水线A 做完传给 BB 做完传给 C单向、线性、不可回头。而 LangGraph 把整个流程建模成一张有向图节点是智能体或工具边是流转条件你可以让流程循环、分支、并行、甚至根据中间结果动态决定下一步走哪。量化交易研究恰恰需要这种能力。举个例子技术面分析师给出看多信号但情绪分析师发现市场恐慌指数飙升这时候流程不能傻乎乎地继续往下走而应该回到辩论环节让两个智能体再吵一轮。这种回头路在 LangChain 的线性 Chain 里做起来非常别扭但在 LangGraph 里就是一个条件边的事。具体到 TradingAgents 的图结构大致有这么几层数据层节点负责拉取行情、财报、新闻、社交媒体情绪等原始数据分析师节点组基本面分析师、技术面分析师、情绪分析师、新闻分析师各自独立产出观点研究员节点组看多研究员和看空研究员针对分析师结论进行多空辩论交易员节点综合辩论结果产出具体交易提案风控节点对交易提案进行风险评估可能打回重来基金经理节点最终拍板决定是否执行提示LangGraph 的核心概念是 State状态在节点间流转每个节点读取 State、修改 State、返回更新。理解这一点整个框架的代码就好读了。2.2 多智能体角色是怎么分工的TradingAgents 最精彩的地方就是角色设计。它不是随便找几个 prompt 套个壳而是真的模拟了一家交易公司的组织架构。我把它拆成四层来看第一层分析师团队Analyst Team这一层负责看。基本面分析师盯着财报、市盈率、营收增长这些硬指标技术面分析师看 K 线、均线、MACD、RSI 这些技术指标情绪分析师爬新闻和社交平台判断市场情绪是贪婪还是恐惧新闻分析师则专门处理突发事件比如某公司突然换 CEO、某行业出了新政策。每个分析师都是独立的 LLM 智能体有自己的 system prompt、自己的工具集、自己的输出格式。它们之间不直接通信而是把结论写进共享 State供下游读取。第二层研究员团队Researcher Team这一层负责辩。看多研究员Bull Researcher和看空研究员Bear Researcher会拿到分析师团队的结论然后各自站在自己的立场上找论据、挑毛病。看多的会说技术面金叉了基本面也超预期必须买看空的会反驳情绪指标已经到极端贪婪了历史上这种位置回调概率大。这个辩论环节通常会来回好几轮每一轮双方都能看到对方的论点然后针对性反驳。这种设计的好处是强制暴露分歧避免单一视角的盲区。第三层交易员Trader辩论结束后交易员智能体登场。它的任务是把前面所有的分析、辩论浓缩成一个可执行的交易提案包括方向买/卖/持有、仓位建议、入场点、止损点、目标价。交易员不是简单投票而是要综合权衡各方论据的强度。第四层风控与基金经理Risk Manager Fund Manager风控智能体对交易提案做压力测试如果市场反向波动 5% 会怎样当前仓位是否过于集中流动性够不够如果风控不通过提案会被打回交易员重新调整。基金经理则是最终决策者它有权否决整个提案也有权批准执行。这套架构的精妙之处在于制衡。分析师可能偏乐观研究员辩论能拉回来交易员可能激进风控能压住风控可能过于保守基金经理能从全局视角做最终判断。多层制衡比单个 LLM 一次性输出结论要可靠得多。2.3 共享状态State的设计哲学多智能体协作最容易踩的坑就是信息孤岛——每个智能体各说各话最后拼不起来。TradingAgents 用 LangGraph 的 State 机制解决这个问题。State 本质上是一个贯穿整个图执行的字典里面存着所有中间产物原始数据、各分析师的报告、辩论记录、交易提案、风控意见、最终决策。每个节点执行时读取自己需要的字段执行完把新结果写回去。我实测下来State 设计有几个关键点字段要结构化不要塞一坨自由文本而是用明确的 key比如fundamental_report、technical_report、debate_history方便下游精准读取保留历史辩论记录要累积不能覆盖否则后面的智能体看不到完整上下文控制体积State 太大会拖慢每次 LLM 调用的速度因为很多框架会把整个 State 塞进 prompt。该摘要的要摘要该截断的要截断注意State 里如果存了超长的原始新闻文本每次调用 LLM 都会重复消耗 token成本会爆炸。我的做法是在数据层节点就把长文本压缩成结构化摘要再写入 State。3. 核心细节解析与实操要点3.1 LLM 选型与 Temperature 参数的门道TradingAgents 里每个智能体都要调 LLM但不是所有智能体都该用同一个模型、同一套参数。这是很多人忽略的细节。先说模型选型。分析师团队需要处理大量文本、做细致推理建议用能力强的模型交易员和基金经理需要做决策对推理深度要求高而一些格式转换、数据清洗的辅助节点用便宜的小模型就够了。全用一个顶级模型跑成本会让你怀疑人生。再说 Temperature。这个参数控制 LLM 输出的随机性取值 0 到 1有些模型支持到 2。原理是这样的模型输出下一个 token 时会先算出一个概率分布Temperature 就是用来调节这个分布的陡峭程度。Temperature 越低分布越尖锐高概率的 token 更容易被选中输出越确定、越保守Temperature 越高分布越平坦低概率 token 也有机会被选中输出越随机、越有创造性。具体到 TradingAgents 的各个角色我的配置经验是智能体角色建议 Temperature理由基本面分析师0.2 - 0.3需要严谨不能瞎编数字技术面分析师0.1 - 0.2指标计算必须准确情绪分析师0.4 - 0.5需要一定灵活性解读模糊情绪看多/看空研究员0.6 - 0.7辩论需要发散思维找角度交易员0.3 - 0.4决策要稳但也要有判断力风控0.1 - 0.2必须保守宁可错杀基金经理0.3综合权衡适度灵活这个表不是拍脑袋来的。我踩过的坑是一开始所有角色都用 0.7结果基本面分析师开始编造财报数据技术面分析师算出的指标前后矛盾。后来把分析类角色的 Temperature 压到 0.2 左右输出立刻稳定了。而辩论类角色如果 Temperature 太低两边会说出几乎一样的话辩论就失去意义了。3.2 数据 API 的选择与接入量化交易研究数据是命根子。TradingAgents 需要的数据大致分四类行情数据OHLCV、基本面数据财报、估值、新闻数据、社交媒体情绪数据。关于量化交易用的数据 API 最好的是什么这个问题没有标准答案取决于你的市场、预算和精度要求。我按经验给个参考行情数据如果做美股常见的选择有 Polygon、Alpha Vantage、Yahoo Finance免费但有限流做 A 股的话Tushare、AkShare 是社区里用得比较多的基本面数据Financial Modeling Prep、SimFin 提供结构化财报新闻数据NewsAPI、GNews 可以拉标题和摘要情绪数据可以自己爬社交平台也可以用现成的情绪指数接入时有个关键设计数据获取要封装成工具Tool而不是硬编码在智能体里。LangGraph 支持给节点绑定工具智能体通过 function calling 的方式调用。这样做的好处是你想换数据源只改工具实现不用动智能体逻辑。# 数据工具封装示例伪代码结构 from langchain.tools import tool tool def get_stock_price(ticker: str, start: str, end: str) - dict: 获取指定股票在时间区间内的行情数据 # 这里接你的数据 API data your_data_api.fetch_ohlcv(ticker, start, end) return { ticker: ticker, prices: data, summary: f{ticker} 区间涨跌幅 {calc_return(data):.2%} }提示工具返回结果一定要做摘要化处理。原始行情数据动辄几百行直接塞给 LLM 既浪费 token 又干扰判断。我通常只返回关键统计量区间涨跌幅、波动率、最大回撤、当前价相对均线位置。3.3 Prompt 工程让每个智能体入戏多智能体框架里prompt 就是智能体的人格设定。TradingAgents 的每个角色都需要精心设计的 system prompt明确它的身份、职责、输出格式、约束条件。我总结了一个好用的 prompt 模板结构身份声明你是谁你在什么团队你的职责是什么输入说明你会收到哪些信息任务描述你要产出什么输出格式严格规定 JSON 或 Markdown 结构约束条件不能做什么比如不能编造数据、不能给出超出能力范围的建议示例给一两个 few-shot 例子效果立竿见影举个看多研究员的 prompt 片段你是一家量化交易公司的资深看多研究员。你的职责是 基于分析师团队提供的报告构建支持买入或持有的最强论据。 你会收到 - 基本面分析报告 - 技术面分析报告 - 情绪分析报告 - 看空研究员的论点如果有 你必须 1. 只使用提供的报告中出现的数据不得编造 2. 针对看空方的每个论点给出反驳 3. 输出格式为 JSON{thesis: ..., evidence: [...], rebuttal: [...]}这里有个细节明确禁止编造数据这条约束极其重要。LLM 在辩论时为了赢很容易编出听起来合理但实际不存在的数据。我实测发现不加这条约束看多研究员会凭空说出该公司上季度营收增长 47%这种数字而实际报告里根本没提。3.4 辩论机制的实现细节辩论是 TradingAgents 的灵魂但实现起来有几个坑。第一个坑是轮次控制。辩论不能无限进行否则会死循环。通常设 2-3 轮就够了再多边际收益递减还烧钱。LangGraph 里可以用条件边判断轮次超过阈值就跳出循环进入下一阶段。第二个坑是论点去重。辩论几轮后双方容易重复之前的论点。我的做法是在 prompt 里明确要求不得重复你之前已经提出的论点必须提出新的角度或针对对方最新论点的反驳。第三个坑是收敛判断。什么时候辩论算够了可以设一个简单的规则如果连续一轮双方都没有提出新论点就提前结束。或者让一个裁判智能体判断辩论是否已经充分。# 辩论轮次控制逻辑伪代码 def should_continue_debate(state): if state[debate_round] MAX_ROUNDS: return end_debate if state[last_round_had_new_points] False: return end_debate return continue_debate4. 实操过程与核心环节实现4.1 环境搭建与依赖安装先把环境跑起来。TradingAgents 这类项目通常依赖 Python 3.10核心依赖包括 langgraph、langchain、langchain-openai或其他模型 SDK、pandas、以及数据 API 的客户端库。# 创建虚拟环境 python -m venv trading_env source trading_env/bin/activate # Windows 用 trading_env\Scripts\activate # 安装核心依赖 pip install langgraph langchain langchain-openai pandas numpy pip install yfinance # 如果做美股这个免费好用关于 LangGraph 的安装很多人搜langgraph 如何安装、langgraph 菜鸟教程其实它就是个普通 pip 包装完就能用。真正需要花时间的是理解它的 StateGraph、Node、Edge 这几个概念。注意LangGraph 版本迭代很快API 时有变化。建议锁定版本比如pip install langgraph0.2.x避免今天跑通的代码明天就报错。4.2 构建第一个智能体节点我建议从最简单的单节点开始跑通了再往上加。先定义一个 State然后写一个分析师节点。from typing import TypedDict, Annotated from langgraph.graph import StateGraph, END import operator class TradingState(TypedDict): ticker: str fundamental_report: str technical_report: str debate_history: Annotated[list, operator.add] trade_proposal: str final_decision: str def fundamental_analyst(state: TradingState): ticker state[ticker] # 调用数据工具获取基本面数据 data fetch_fundamental_data(ticker) # 调用 LLM 生成分析报告 report llm.invoke(build_fundamental_prompt(ticker, data)) return {fundamental_report: report.content}这里Annotated[list, operator.add]是个关键技巧它告诉 LangGraph这个字段在多个节点更新时要累加而不是覆盖。辩论历史就靠这个机制累积。4.3 组装完整的图单节点跑通后开始组装。核心是把各个节点用边连起来并在需要分支的地方加条件边。workflow StateGraph(TradingState) # 添加节点 workflow.add_node(fundamental, fundamental_analyst) workflow.add_node(technical, technical_analyst) workflow.add_node(sentiment, sentiment_analyst) workflow.add_node(bull_researcher, bull_researcher) workflow.add_node(bear_researcher, bear_researcher) workflow.add_node(trader, trader) workflow.add_node(risk_manager, risk_manager) workflow.add_node(fund_manager, fund_manager) # 设置入口 workflow.set_entry_point(fundamental) # 分析师并行LangGraph 支持 fan-out workflow.add_edge(fundamental, technical) workflow.add_edge(technical, sentiment) # 进入辩论循环 workflow.add_edge(sentiment, bull_researcher) workflow.add_edge(bull_researcher, bear_researcher) workflow.add_conditional_edges( bear_researcher, should_continue_debate, {continue_debate: bull_researcher, end_debate: trader} ) # 交易与风控 workflow.add_edge(trader, risk_manager) workflow.add_conditional_edges( risk_manager, risk_check, {approved: fund_manager, rejected: trader} ) workflow.add_edge(fund_manager, END) app workflow.compile()这段代码是整个框架的骨架。跑起来之后你可以用app.invoke({ticker: AAPL})触发一次完整的研究流程。4.4 参数计算与仓位建议交易员智能体产出提案时涉及一些具体的参数计算。这部分不能全交给 LLM 拍脑袋最好用代码算好再喂给它。仓位计算常用的是凯利公式的简化版。假设你判断某笔交易的胜率是 p盈亏比是 b那么最优仓位比例 f (p × (b1) - 1) / b。比如胜率 55%盈亏比 2:1f (0.55 × 3 - 1) / 2 0.325即 32.5% 仓位。实际用的时候要打个折比如乘以 0.5 的安全系数。止损点可以用 ATR平均真实波幅来定。比如当前价 100ATR 是 2设 2 倍 ATR 止损就是 96。这样止损位会随市场波动率自适应比固定百分比科学。目标价结合技术面的阻力位和基本面的估值中枢来定取两者中较保守的那个。这些算好后作为结构化数据传给交易员智能体让它在此基础上做最终判断而不是让它从零开始编。4.5 输出结构化与 JSON 修复LLM 返回 JSON 不稳定是老大难问题。你要求它返回 JSON它可能给你返回带 markdown 代码块的、带解释文字的、甚至字段名拼错的。搜修复 llm 返回 json 的 java 库的人不少Python 这边也有对应方案。我的处理策略是三层防护Prompt 层明确要求只返回 JSON不要任何其他文字并给示例解析层用json.loads前先做清洗去掉 json 标记截取第一个{到最后一个}重试层解析失败就把错误信息塞回 prompt让 LLM 重新生成最多重试 2 次import json import re def parse_llm_json(text: str) - dict: # 去掉 markdown 代码块标记 text re.sub(rjson\s*|\s*, , text) # 截取 JSON 主体 start text.find({) end text.rfind(}) if start -1 or end -1: raise ValueError(未找到 JSON 内容) return json.loads(text[start:end1])如果用的是支持 structured output 的模型比如 OpenAI 的 JSON mode 或 function calling优先用官方能力比正则清洗靠谱得多。5. 常见问题与排查技巧实录5.1 智能体跑偏了怎么办最常见的现象某个分析师智能体开始输出和任务无关的内容或者反复说车轱辘话。排查思路是这样的先看 prompt 是不是太长太杂。prompt 超过一定长度后LLM 对后面的指令注意力会下降。我的经验是把核心约束放在 prompt 的开头和结尾中间放背景信息。再看 State 里是不是混入了脏数据。比如某个工具返回了报错信息被原样写进 State下游智能体读到一堆错误堆栈自然就懵了。工具返回前一定要做异常处理返回结构化的成功/失败标志。最后看 Temperature 是不是太高。分析类角色 Temperature 超过 0.5输出就开始飘。5.2 辩论陷入死循环两个研究员吵起来没完或者互相复读。解决办法硬性限制最大轮次比如 3 轮在 prompt 里要求必须针对对方最新论点不得重复加一个新论点检测如果一轮下来没有新内容强制结束5.3 Token 消耗过大多智能体框架的 token 消耗是单智能体的好几倍因为每个节点都要把上下文塞进 prompt。控制成本的手段问题解决手段State 太大数据层做摘要只传关键统计量重复传全文辩论时只传论点摘要不传完整报告模型太贵辅助节点换小模型调用太频繁缓存数据获取结果同一 ticker 不重复拉我实测一个完整流程跑下来如果用顶级模型单次成本可能到几毛到几块钱。做研究可以接受但如果要批量跑几百只股票成本就很可观了。这时候该用便宜模型的地方千万别手软。5.4 数据 API 限流与失败重试免费数据 API 基本都有限流。我的做法是加一层带指数退避的重试import time def fetch_with_retry(func, max_retries3, base_delay1): for i in range(max_retries): try: return func() except RateLimitError: if i max_retries - 1: raise time.sleep(base_delay * (2 ** i))同时把成功获取的数据缓存到本地比如 SQLite 或 parquet 文件同一交易日同一股票不重复拉。5.5 常见问题速查表现象可能原因排查方向智能体输出格式错乱prompt 约束不清检查输出格式说明和示例辩论无新意Temperature 太低调到 0.6-0.7分析编造数据未禁止编造prompt 加硬约束流程卡住不结束条件边逻辑错检查 should_continue 函数JSON 解析失败模型输出不规范加清洗层和重试成本失控State 过大摘要化 换小模型提示调试多智能体系统最好的办法是把每一步的 State 打印出来。LangGraph 支持 stream 模式可以实时看到每个节点的输入输出定位问题非常快。6. 从 TradingAgents 延伸出去的思考把 TradingAgents 跑通之后我发现这套多智能体协作范式其实可以迁移到很多场景。核心可复用的东西有三个角色分工的设计方法、基于 State 的信息流转机制、辩论与制衡的决策逻辑。比如做内容审核可以设计合规审核员事实核查员语气评估员三个智能体互相制衡做供应链决策可以让成本分析师风险分析师交付分析师辩论。只要你的任务需要多视角、需要制衡、需要结构化决策这套框架就能套。关于langchain 和 langgraph 都过时了吗这种问题我的看法是工具会迭代但多智能体协作这个方向不会过时。LangGraph 只是当前比较好用的一个编排工具未来可能有更好的但你理解了 State 流转、条件边、循环控制这些底层概念换任何工具都能快速上手。最后分享一个我踩过的坑一开始我追求全自动想让整个流程无人干预地跑完并直接下单。后来发现LLM 在金融决策上的可靠性还不足以支撑真金白银的操作。TradingAgents 这类框架目前最合理的定位是辅助研究——它帮你把分析流程结构化、把多视角观点整理清楚但最终决策还是得人来拍板。把它当成一个不知疲倦的初级研究助理而不是一个能替你赚钱的黑盒心态就对了。