尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

多Agent协作构建AI投资团队:QuantBot架构与实战解析

多Agent协作构建AI投资团队:QuantBot架构与实战解析 1. 为什么给自己做一整个“AI 投资团队”做 QuantBot 的起因其实挺直接的我自己平时会关注一些市场数据也写过不少脚本去抓行情、算指标但慢慢发现一个很尴尬的问题——单靠一两个策略脚本根本覆盖不了“看宏观、盯行业、读财报、控风险、下决策”这一整条链路。我想要的不是又一个指标回测工具而是一个能像真实投研团队一样分工协作的系统。于是就有了 QuantBot一个由多个 AI Agent 组成的量化投资协作体。市面上很多量化框架擅长“算”但它们不擅长“读”和“想”。比如让程序去读一份几百页的年报、去理解一条宏观政策对某个板块的传导路径传统因子模型基本无能为力。LLM 的出现让“读”和“想”这件事变得可行再加上 Agent 可以调用工具、访问数据、互相校验我才觉得时机成熟了——可以用大模型把投研流程里的“信息获取、分析判断、风险控制、执行决策”串起来。这篇文章不是要教你抄一个一模一样的系统而是想完整拆解 QuantBot 的设计思路、架构分工、实现细节和踩坑记录。适合谁看如果你对 AI Agent 开发感兴趣或者正在做量化研究、想用大模型改造自己的投研流程这篇文章应该能给你一些可落地的参考。2. 整体设计为什么“团队”比“单一大模型”靠谱2.1 单一大模型做投资决策的问题一开始我也试过最简单的方案把所有数据丢给一个大模型直接问“该不该买”“目标价多少”。实测下来问题非常突出。首先是上下文窗口有限。一家公司的财报动辄几十页再加上历史行情、行业新闻、宏观数据一轮对话塞进去模型很快就“忘了”前面的内容或者开始答非所问。其次是角色混乱。让同一个模型既做乐观的研究员又做谨慎的风控官它很容易在两种角色之间摇摆。比如刚分析完“这只股票基本面优秀”转过脸问它风险它又开始说“但也要注意风险”——说了等于没说。更关键的是无法追溯。如果模型直接给出一个结论你根本不知道它依赖了哪些数据、做了哪些推理、在哪里可能出现偏差。投资决策最怕的不是犯错而是不知道错在哪里。2.2 用多智能体模拟投研团队分工QuantBot 的核心思路是把投资决策流程拆成五个角色每个角色由一个独立的 Agent 承担数据采集 Agent情报员负责抓取行情、财报、新闻、宏观数据并把非结构化文本转成结构化信息。研究分析 Agent研究员基于采集到的数据做基本面分析、行业对比、估值判断输出研究报告。风险控制 Agent风控官独立审查研究员的结论检查数据是否有缺失、逻辑是否有漏洞、风险是否被忽略。组合管理 Agent基金经理综合研究和风控的意见决定仓位比例、买入卖出时机。复盘 Agent投后分析师定期回顾决策结果对比预期和实际生成复盘报告反馈给其他 Agent 优化后续决策。这五个角色不是简单的“串行问答”而是通过一个工作流引擎协作。数据采集完成后会触发研究分析研究报告会同时发给风控和组合管理风控有“否决权”组合管理需要给出明确的仓位和理由。这样做的好处很明显每个 Agent 的职责单一Prompt 可以写得更精准决策过程有迹可循每一个结论都能追溯到具体的输入数据和分析逻辑某个环节出错时可以单独修复而不影响整个系统。2.3 技术选型背后的取舍用 LangChain 还是自研工作流我一开始用了 LangChain但后来发现对于这种固定流程的场景自研一个简单的状态机反而更可控。因为投资流程是相对确定的不需要太多动态规划自己写成本低、排错快。用开源模型还是 API我本地跑了 Qwen 和 Llama 做数据清洗和情感分析但核心研究和风控用的是商用 API。原因很简单本地模型在长文档理解和多步推理上暂时还比不上头部商用模型而投资分析对推理质量要求很高。为了成本控制我会用小模型做预处理大模型做深度分析。用 Python 还是其他语言Python生态太强了pandas 做数据处理、backtrader 做回测、FastAPI 做服务封装基本一条龙。3. 核心功能与实现细节3.1 数据层让 Agent “看得见”真实世界没有数据Agent 就是纸上谈兵。QuantBot 的数据层主要解决三个问题数据从哪来、怎么存、怎么让 Agent 高效“读懂”。我用的是“公开数据源 定时任务”的组合。行情数据通过免费的行情接口获取财报和公告则是定时抓取公开披露信息新闻舆情用 RSS 加爬虫补充。数据统一清洗后存入本地数据库SQLite 加 Parquet 文件兼顾轻量和性能。这里有一个容易被忽视的难点非结构化数据的处理。财报是 PDF新闻是网页公告是表格Agent 不能直接读原始格式。我的做法是先用一个小模型做 OCR 和版面解析把 PDF 转成 Markdown再用规则加模型把关键财务指标抽取成 JSON。这个环节的准确性直接影响后续所有 Agent 的质量值得花大力气。比如“营业收入”在财报里可能有“营业总收入”“营收”等不同叫法还有“本期”和“上年同期”的区分。我用了一套字段映射规则加二次校验先按正则抽候选人再用小模型判断哪个才是“本期营业收入”。实测下来准确率在刚开始只有 70% 左右加了人工标注样本微调后能到 90% 以上。3.2 研究分析 Agent长上下文与结构化输出研究分析 Agent 是 QuantBot 里最重的一个模块它的输入是数据层整理好的财报 Markdown、行情数据和新闻摘要输出是一份结构化的研究报告。我采用“分块阅读、逐步归纳”的方式来应对长文档。先让 Agent 分块总结每部分内容再把总结汇总成几个维度盈利能力、成长性、财务健康度、行业位置、近期催化因素。这一步用的是带 JSON 输出约束的 Prompt返回结果是一个严格的 JSON 对象方便下游直接解析。Prompt 的设计我反复调了很多版几个关键经验明确输出 schema用 few-shot 示例固定结构最稳妥的方式是给模型一个“填表”任务而不是开放式的“写报告”任务。要求模型在每一项判断后都附上数据来源版本号或数据片段便于追溯。比如“应收账款周转天数从XX天上升到XX天来源2023年财报P12”。禁止模型做没有数据支撑的“想象”。我专门加了一条指令如果某项数据缺失必须明确写“数据缺失”而不是编造一个合理值。研究分析做完后会生成一个“标的画像”JSON包含评分、关键指标、风险点、催化剂等字段。这个 JSON 是后续所有 Agent 的数据基础。3.3 风控 Agent用“对抗式审阅”降低模型幻觉风控 Agent 是我觉得最有价值也最难做好的模块。它的任务不是重复研究分析而是“挑刺”。我会让它从以下维度审阅研究报告数据一致性研究报告中使用的财务数据与原始财报是否一致有没有张冠李戴逻辑完整性从数据到结论的推理链条是否成立有没有跳跃风险遗漏是否只讲了好的一面而忽略了流动性、行业政策、竞争格局等风险极端情况如果核心假设不成立最坏情况下会怎样为了减少大模型的“惯性认同”我的做法是用对抗式 Prompt。风控 Agent 拿到的指令是“你是首席风险官你的职责是推翻研究员的结论找出一切可能的问题”并且要求它先列出质疑点再给结论而不是先给结论再补充理由。连带地我在风控环节设了一个“置信度”评分。如果风控对某项数据的置信度低于阈值系统会触发数据复核流程——重新调用数据采集 Agent 去核对原始来源或者标记为“低置信度”并降低该标的最大仓位上限。实体对齐也是一个很实际的问题。“贵州茅台”在新闻里可能叫“茅台”“贵州茅台酒股份有限公司”“600519”如果不对齐研究 Agent 很可能把 A 公司的新闻安到 B 公司头上。我用了一个简单的别名表加向量匹配的组合方案实测对 A 股主要标的效果很好。3.4 组合管理 Agent决策与仓位计算组合管理 Agent 是最后一个“拍板”的角色。它拿到研究分析报告、风控意见和历史交易记录输出具体的操作指令。输出指令是一个结构化 JSON包含标的、方向买/卖/持有、仓位占比、目标价、止损价、操作理由。仓位计算我引入了凯利公式的简化版本。假设某次交易有 p 的概率盈利、b 为赔率那么最优仓位比例 f (bp - 1) / b。但实际中 p 和 b 都是模型估计的误差很大所以我会设置仓位上限单标的仓位不超过 25%作为保护。这里有一个关键设计组合管理 Agent 不能直接访问市场实时行情只能依赖数据层提供的快照。这个“信息隔离”是为了避免模型因为短期价格波动做出情绪化决策让它更专注于基于基本面的中长期判断。3.5 复盘模块让系统能“吃一堑长一智”做完一笔交易后复盘 Agent 会在一段时间后对比当时的预测和实际走势生成复盘报告。内容包括预测是否准确、偏差来自哪里数据问题逻辑问题市场风格切换、下次可以怎么改进。复盘报告的结论会写回知识库作为后续 Agent 的参考。比如某个行业“降本增效”逻辑在市场不好时往往不奏效如果复盘 Agent 发现了这个规律会被记录在一个“经验教训”文档里后续研究 Agent 分析类似标的时会被提示参考。这一步是我觉得 QuantBot 最有“团队感”的地方。传统的量化策略是一堆死代码而 QuantBot 通过复盘和知识库更新有了持续进化的能力。4. 实操过程从零搭建 QuantBot 真实记录4.1 第一步明确最小可用版本MVP范围做这类系统最怕一开始就想做“大而全”。我的经验是先找出一个最核心的业务闭环跑通后再扩展。QuantBot 的 MVP 我定义为“对单一标的比如贵州茅台做研报分析 风控审核 仓位建议”。只支持一个标的、一周更新一次、不接入实盘交易只输出建议。跑通这个闭环后再逐步扩展多标的、日频、模拟交易。4.1.1 定义数据流这个阶段我画了一张最基础的数据流图确保每个模块的输入输出都明确数据采集 Agent → 原始数据库 → 数据清洗 → 研究报告 JSON → 风控审核 JSON → 组合决策 JSON → 复盘记录每个环节的数据格式我都在项目启动第一天就定死了宁可后面改也比一开始乱传强。4.1.2 定义技术栈编程语言Python 3.11数据存储SQLite结构化数据、本地 JSON/Parquet中间结果Agent 框架自研状态机 Prompt 模板管理LLM 接入统一封装 OpenAI 兼容接口方便切换模型服务部署FastAPI 提供 Web 界面Process Scheduler 做定时任务4.1.3 规划安全性投资建议必须免责。QuantBot 的所有输出都在界面上标明“仅供研究学习不构成投资建议”。同时我配置了 API 访问频率限制和成本监控防止某个 Agent 的意外死循环把 API 额度耗光。4.2 第二步搭建数据采集层数据采集用 Python 的 requests 加 BeautifulSoup配合 APScheduler 做定时任务。目标不要求实时推送所以一天更新一次完全够用。典型的数据获取代码如下import requests from bs4 import BeautifulSoup import json def fetch_financial_report(stock_code): # 这里以某个公开披露页面为例实际中可能需要处理验证码和分页 url fhttps://example.com/financial/{stock_code} resp requests.get(url, timeout10, headers{User-Agent: Mozilla/5.0}) soup BeautifulSoup(resp.text, html.parser) # 提取关键表格转换成 pandas DataFrame 后再序列化为 JSON table soup.find(table, {class: financial-data}) data parse_table_to_json(table) return data需要注意不是所有 Source 都稳定。我的做法是每一类数据源都写一个 adapter统一返回标准化格式。这样即使某个数据源挂了也不会影响其他数据导入。4.2.1 财报解析的细节坑财报 PDF 转成文本后有很多格式噪声。比如表格会变成一行一行的文本数字之间的分隔符不统一。我后来总结了一个最佳实践先用 PyMuPDF 把 PDF 按页面转成图片再用 OCR 模型识别表格结构而不是直接提取文本。虽然多了一步但对表格型数据的还原度高了一个档次。4.3 第三步Agent Prompt 设计实战Prompt 是整个 QuantBot 的灵魂。同一个模型Prompt 写得好不好效果差别非常大。分享一下我在研究 Agent 上的最终版本核心逻辑4.3.1 系统提示词System Prompt你是 QuantBot 研究团队的高级分析师。你以严谨、客观、数据驱动的方式工作。 你的输入是经过清洗的财报数据和市场信息你的输出必须严格遵循给定的 JSON Schema。 注意 1. 只使用输入数据中明确存在的信息不要推测或编造。 2. 对于缺失的数据在对应字段中写入数据缺失不要自动填默认值。 3. 对每项判断都给出数据支持并注明数据来源。 4. 如果某项数据存在重大不一致或异常在高亮风险区域标明。4.3.2 用户提示词User Prompt请分析以下财务数据输出 JSON。 【财报摘要】 {financial_summary} 【行情数据】 {market_data} 【JSON Schema】 {json_schema}这个设计把角色、任务、约束、输出格式四件事分开说清楚。实践中最有效的技巧是用“负面约束”明确告诉模型不要做什么这比正面要求更有效。4.3.3 引入“思考草稿”机制我让模型在输出最终 JSON 前先生成一段“思考草稿”chain-of-thought放在一个隐藏字段里然后基于草稿生成最终结果。这么做能显著提升分析质量但会增加 token 消耗所以只对研究 Agent 和风控 Agent 启用。4.4 第四步状态机工作流实现工作流我用一个非常轻量的状态机实现不需要引入重型框架。核心就是一个 Python 字典来定义状态转移workflow { 采集完成: [研究分析], 研究完成: [风控审核], 风控否决: [重新研究, 终止], 风控通过: [组合决策], 组合决策完成: [执行/输出], }每个状态对应一个执行函数函数内部处理输入输出并把结果写入数据库。如果某个状态执行失败比如 API 超时状态机会自动重试三次然后进入错误处理流程。这个流程简单可靠排错时也能很方便地看到卡在了哪一步。4.4.1 并发与异步的坑一开始我天真地以为多 Agent 之间可以用异步并发提高效率后来发现大模型 API 的调用很容易触发限流而且多个 Agent 同时写数据库会有锁竞争。最终方案是数据采集阶段用并发IO 密集分析阶段用串行确保顺序和可追踪。这个取舍让整体系统稳定了一个量级。4.5 第五步回测与模拟验证QuantBot 的核心输出是决策建议但决策对错不能靠感觉需要一套回测机制。我用 backtrader 做了简化回测把 QuantBot 每天的决策记录转成“模拟交易”假设按决策价成交扣除手续费和滑点最后计算累计收益率、最大回撤、夏普比率等指标。回测框架的核心代码片段import backtrader as bt class QuantBotStrategy(bt.Strategy): def __init__(self): self.decision_log {} # 从数据库加载决策记录 def next(self): date self.datas[0].datetime.date(0) if date in self.decision_log: decision self.decision_log[date] if decision[action] buy: self.buy(sizecalculate_position(decision[weight])) elif decision[action] sell: self.sell(sizecalculate_position(decision[weight]))回测结果只是参考不能过度优化。我在回测里刻意没有加入“未来函数”也不允许模型看到当日收盘后的信息来做当日决策这是一个底线原则。5. 实测结果与关键发现5.1 用历史数据做“模拟盘”验证我选取了过去两年几个主要宽基指数的成分股池每个月让 QuantBot 做一次调仓建议然后用历史行情做模拟交易。9个月的模拟运行结果显示QuantBot 的累计收益率大致跑赢了基准指数但最大回撤也略高。更让我关注的是它的几个行为特征现金比例控制较好。在几次急跌行情中风控 Agent 会主动建议降低仓位系统整体回撤被控制住了。频繁交易的问题依然存在。有些月份调仓过于频繁手续费和滑点吃掉了不少收益后来不得不在组合管理 Agent 的 Prompt 里加入“每次调仓时考虑交易成本”的约束。复盘模块的价值开始显现。有几笔亏损交易在复盘中被归因为“财报数据更新延迟导致使用了过期数据”后来我在数据层增加了“财报发布时间戳”校验情况明显改善。5.2 不同模型的对比观察我对比了 GPT-4o、Claude 和本地部署的 Qwen-72B 在同样任务上的表现。本地模型在数据清洗和实体对齐任务上基本够用成本低且数据不出本地适合做前处理。商用模型在“从数据到结论的推理”上明显更强但偶尔会出现“迎合用户”的情况。如果 Prompt 暗示某个标的是好公司模型往往会更积极。对抗式风控 Prompt 能在一定程度上对冲这个倾向。推理速度是瓶颈。一次完整的单标的研报分析 风控审核 决策调用大模型 API 需要大约两分钟多标的场景下需要串行排队。这个延迟在做日频级别是完全够用的但想做分钟级别就太慢了。5.3 成本分析API 调用成本是量化 Agent 系统不可回避的问题。我做了粗略统计单次单标的完整分析流程数据清洗 研究 风控 决策大约消耗 4 万到 6 万 token。如果每天分析 20 个标的一个月的 API 成本大约是 100 到 300 美元取决于模型。这个成本对个人玩家来说不便宜但对专业机构来说完全可以接受。优化策略有几个方向使用小型模型做预处理对财报做增量更新而不是每次全量分析引入缓存机制对同一个标的短期内多次调用时直接复用中间结果。5.4 核心结论QuantBot 能做和不能做的事做完整套系统后我对它的能力边界有了比较清楚的认识。能做快速处理大量公开信息、生成结构化的投研报告、用对抗式机制降低单一模型偏见、保持决策过程的完整可追溯性。不能做预测短期股价、处理市场情绪突变、克服数据本身的滞后性。QuantBot 的本质是把“信息处理自动化”而不是“预测未来”。6. 常见问题与避坑指南6.1 数据问题财报数据抓取不稳定这几乎是绕不开的坑。公开数据源经常改版、反爬策略收紧、字段名称不一致、历史数据缺失。我的排查思路是给数据采集模块做“健康检查”每次抓取后统计行数和关键字段缺失率异常时自动告警。不同数据源相互校验。同一指标用两个源交叉比对如果差异超过阈值就标记为“可疑数据”并在报告中降权。保留原始文件备份。不要只存处理后的数据原始 PDF、HTML 都要存档方便回溯。6.2 模型问题大模型“一本正经地胡说八道”这是所有 LLM 应用的老大难。在投资领域幻觉的代价非常高。我的防线是在数据层给每个数据片段加来源 ID研究 Agent 在报告中引用数据时必须附带来源 ID。风控 Agent 专门做一致性检查比对报告中的数字和原始数据源。这一层能拦住相当一部分幻觉。对于低置信度的数据不设定性结论只标“数据缺失”或“无法判断”。6.3 Agent 问题多智能体之间互相“传染”错误多智能体系统最头疼的问题是错误会被逐级放大。数据采集阶段的一个小错误经过研究、风控、决策到最终输出时可能变成一个完全不可信的结论。我的处理办法是“置信度标签逐级传递”。数据层给每一条数据打置信度研究 Agent 在报告中汇总整体置信度风控 Agent 如果发现置信度不足就直接质疑组合管理 Agent 在决策时看到低置信度会降低仓位上限。通过这种方式错误虽然不能完全消除但会被系统显式地标记出来不会被静默传递。6.4 工程问题API 调用超时与成本失控LLM API 不是 100% 可靠的经常有超时和限流。我在工作流里做了三个保护机制超时重试 指数退避。第一次失败等 1 秒第二次等 4 秒第三次等 16 秒最多重试 3 次。每次调用前预估 token 用量设置告警阈值。如果某次分析任务的 token 消耗超过预估 50%系统会发通知提醒。成本上限熔断。设置每日 API 成本上限超过后自动切换到备用模型或暂停新任务。这在多标的、长时间运行时非常重要。6.5 一个隐藏很深的坑时序数据穿越回测中最危险的 bug 是时序穿越。比如用 2024 年的财报数据去做 2023 年的决策这在数据流水线里太容易发生了。原因是财报发布时间和数据所属期不是同一个时间。比如 2023 年的年报可能到 2024 年 4 月才发布如果用发布时间过滤就会漏掉如果按所属期过滤就会穿越。我的解决办法是数据库里同时保存“公告日期”和“报告期”Agent 在做某一天的决策时只能查询公告日期小于等于当天的数据。这个逻辑我用单元测试专门覆盖不让任何 Agent 直接裸查数据库。6.6 常见问题速查表问题现象排查思路财报数据缺失严重研究报告里“数据缺失”字段过多检查数据源是否改版、解析脚本是否匹配新格式模型输出非预期格式JSON 解析失败检查 Prompt 中 Schema 示例是否清晰考虑用 function calling风控形同虚设风控结果与研究结论几乎一致加强对抗性指令要求先列反驳点再给结论回测过拟合回测收益极高但实盘不行检查是否有前视偏差增加样本外时间段测试成本飙升API 账单比预期高很多检查是否有死循环调用开启中间结果缓存多标的运行太慢完成整个分析流程需要太久考虑并行采集、串行分析或引入小模型预处理6.7 保持项目边界清晰的建议个人做这类项目最大的风险不是技术不会而是越做越大、越做越散。建议从一开始就规定几个“不做”不做高频交易。QuantBot 的分析速度和处理能力就不适合高频强行上高频只会两头落空。不做短线情绪预测。模型对市场情绪的捕捉不可靠不如只关注中长期基本面。不做杠杆和衍生品。风控 Agent 还不足以驾驭复杂衍生品风险连模拟交易都不建议开这些品种。不做全自动化实盘。至少在早期所有决策都需要人工审核确认后再执行。这个“人在回路”的设计既是对系统的保护也是对自己的保护。7. 后续规划与个人体会项目做到这个阶段我越来越觉得 QuantBot 的价值不在于“赚钱”而在于把投资研究这个高度依赖经验和个人判断的过程变成了一个可拆分、可验证、可迭代的工程系统。下一步我准备做三件事一是接入更多类型的另类数据比如供应链数据、专利数据让研究 Agent 有更多的信息维度二是引入强化学习来优化组合管理 Agent 的仓位分配策略让它从历史复盘中自主学习三是把前端界面做得更易用一些方便记录人工审核意见形成更完整的决策闭环。最后分享一点个人的实际感受做 AI 投资团队最容易低估的是数据工程和评测体系的复杂度。市面上大多数教程都在教你调 Prompt但真正决定系统上限的往往是数据质量、评测方法和工程可靠性。QuantBot 走到今天最花时间的不是写 Agent 代码而是处理脏数据、设计对抗式评测集、和各种奇怪的边界条件作斗争。如果你也想做一个类似的项目我的建议是先用一个标的、一个狭小的业务场景跑通闭环再谈扩展。不要一开始就追求“全自动”“多标的”“实时”那只会让你陷入无穷无尽的调试泥潭。投资是一条长跑做 AI 投资系统也是。
返回列表