多Agent协作驱动量化工作台:从盘前到盘后的自动化闭环实践
做量化最累的不是写策略而是把一份策略从想法变成每天能自动运行、还能持续赚钱的系统。市面上各种框架能解决回测和执行但真正把盘前准备、盘中监控、盘后归因串成一条完整流水线的方案很少见。所以我自建了 QuantBot——一个以多个 AI-Agent 协作驱动的量化工作台目标很朴素每天开盘前数据自动备好、信号自动算好交易时间机器自动执行和盯盘收盘后自动生成绩效报告并沉淀经验。这篇文章就聊聊我把这套闭环拆成哪些模块、每个模块用到了什么技术以及踩过的坑。这是一个实打实的工程落地总结不是理论科普。量化交易本身是数据、信号、执行、风控的层层配合而 AI-Agent 的价值不在于“替我想策略”而在于“替我把流程盯住”。我会从设计动机讲起再到架构、通信、实现细节最后把稳定性问题和排查思路也一并交代清楚。如果你也在用 Python 搭建量化系统或者对多 Agent 协作的实际应用感兴趣这篇应该能给你不少可以直接抄作业的细节。1. 从单打独斗到多Agent协作量化工作台的前世今生1.1 传统量化流程的三处隐性成本作为量化研究者我早期的工作方式完全就是“人肉 Agent”早上爬起来先跑数据同步手动执行 ETL 脚本然后打开回测系统看昨夜的信号自己还需要检查数据有没有缺口真正开盘时更是紧张盯着盘口的同时还要手动管理仓位收盘后还得花一两个小时写复盘笔记对比预期和实际。这套流程最大的问题不是每件事有多难而是每一步都需要有人盯着且状态分散在脑海里无法沉淀。尤其是当策略数量从一套增加到十几套“人肉调度”的出错率就指数上升。所谓“隐性成本”指的是那些不会立刻亏损、但长期消耗精力和注意力的环节。比如数据源偶尔晚到如果没及时发现直接用残缺数据生成信号可能开盘就给你一个错误仓位。又比如盘后归因时因为手工记录缺了一档交易日志怎么想不明白今天的亏损到底是市场原因还是执行原因。这些看不见的成本比策略本身更容易击穿你的风险底线。1.2 为什么是多个AI-Agent而不是一个超级Agent很多人听到“AI-Agent”会下意识觉得应该训练一个大模型让它在盘前盘后做所有事情。但实际从工程角度看多 Agent 协作的最大价值是“职责隔离”和“故障隔离”。量化工作台里不同类型任务的输入输出差异非常大盘前要做的是批量数据处理和特征计算盘中是秒级响应的实时决策盘后则是长文本报告生成和策略回归分析。如果让一个 Agent 全部承担它的上下文长度、技能组合和容错策略都会纠缠在一起出问题时很难定位。多个 Agent 协作还能做到并发盘前数据 Agent 可以在等待行情数据的同时让另一个 Agent 去做昨日日志扫描两者互不阻塞。更重要的是每个 Agent 可以被赋予独立的工具权限和资源限制例如盘中执行 Agent 只能调用交易接口和行情接口无法触达报告模板目录权限边界清晰安全上也更稳。1.3 QuantBot到底想解决什么问题QuantBot 并不是要做一台“永不亏损的自动提款机”——这是最初就定下的边界。我把它定位成一个把量化投研流程中重复、琐碎、容易遗漏的环节自动化掉的工作台让人的精力集中在策略逻辑和风险判断上。它通过多个 AI-Agent 协作将盘前数据准备、盘中监控执行、盘后归因分析串联成一个自动化闭环减少人工介入的窗口同时保留人工否决的出口。这套设计的核心其实不是“AI 多聪明”而是“流水线有多顺”。所以整篇文章我会先讲清楚闭环的各个节点怎么拆再讲 Agent 之间的通信和仲裁最后分享一些实际部署中的坑。如果你是量化研究员、全栈开发者或者只是想了解多 Agent 系统怎么落地到垂直行业这篇都应该对你有帮助。2. 盘前-盘中-盘后QuantBot的闭环设计与信号流转2.1 盘前Agent群数据清理、信号生成与组合预检QuantBot 的一天从前一天晚上或当天早上六点开始。盘前 Agent 群由三个子 Agent 组成数据管家、信号工、风控预检。数据管家负责对接各类数据源包括行情快照、财务数据、新闻情绪因子等。它先把原始文件拉取到本地然后执行质量校验比如检查时间戳是否连续、字段是否有缺失、复权因子是否匹配。遇到异常数据数据管家不会直接丢弃而是生成一条“数据异常说明”推送到状态总线供其他 Agent 决策时参考。这一步很关键宁可让策略因为数据警告而降低仓位也不能让它强行在残缺数据上运行。信号工 Agent 读取数据管家产出的标准化特征库加载策略参数计算当日各标的的预测信号和预期仓位。由于不同策略的时间尺度不同信号工会把信号按日频、分钟频、事件驱动三类分开存储并打上时间戳。如果信号结果超出历史分位数范围它还会标记为“异常信号”等待人工或仲裁 Agent 确认。风控预检 Agent 则是整套流程的第一道闸门。它拿到信号工的输出后会对照账户的持仓上限、行业暴露限制、单票止损阈值等约束条件生成一份“当日可交易清单”。如果某一个信号触发了限制预检 Agent 会直接降级或剔除并把原因写入当天的决策日志。这份日志也是盘后归因的重要输入之一。2.2 盘中Agent群行情订阅、订单执行与异常熔断开盘后盘中 Agent 群开始接管。这个时段的节奏和盘前完全不同不能等批量任务跑完再反应必须是事件驱动。行情订阅 Agent 持续监听交易所或行情提供商的实时推送维护一个约 200 毫秒级别延迟的全局行情快照。它每隔一小段时间把快照写入 Redis Stream供其他 Agent 消费。为了降低网络抖动的影响它还维护了一个简单的数据质量分如果连续异常超过 N 秒就对外广播“行情降级”事件。订单执行 Agent 是盘中真正和交易接口打交道的角色。它订阅信号工发送的实时交易信号再结合行情快照里的盘口数据决定以限价单还是市价单提交以及拆单策略。执行 Agent 内部有一套“信号-订单”状态机从“新信号”到“已提交”到“已成交/已撤销”每个状态迁移都会记录日志。这样做的好处是即使交易接口偶发超时也能根据状态机做重试或回滚而不是重复下单一堆废单。最后异常熔断 Agent 实时监控所有 Agent 的健康状态和账户资金曲线。一旦发现回撤超过预设阈值、行情数据长时间中断、成交回报异常等情况它会发送熔断指令让订单执行 Agent 暂停新开仓同时通过企业微信或钉钉机器人通知我。宁可错过机会也不能让一条失控的链路把账户拖下水。2.3 盘后Agent群绩效归因、日志挖掘与策略迭代收盘后的任务虽然不紧急但价值密度很高。我用三个 Agent 把盘后流程自动化了。绩效归因 Agent 从账户结算数据和订单日志出发计算今日、近一周、近一月的最主要的收益贡献来源拆解成市场因子收益、行业因子收益、选股 alpha 和交易成本等部分。这里可以用 qlib 或自研的多因子归因模块但重点是要把归因结果落成结构化的 JSON方便下一步生成报告使用。日志挖掘 Agent 会读取当天的所有 Agent 对话记录、错误堆栈、信号警告、数据异常事件自动总结出“今天流程中有哪些异常可能对结果产生什么影响”。我早期觉得这项工作最不重要但后来发现很多优化灵感正来自这些散落角落的日志。比如它曾经自动发现某个分钟级策略在上午十点左右总会因为数据延迟错过最佳下单窗口这直接推动了后续对行情源的切换。策略迭代 Agent 则更像一名“研究助手”。它读取绩效归因和日志挖掘的结果与历史策略版本对比生成一版“策略调优建议”比如建议调整某个参数或者增加一个过滤条件。不过它没有权限直接改动实盘策略只会提交一个候选补丁由我在第二天盘前审核。这样既利用了 LLM 的分析能力又不至于让 AI 在无人监管下自动进化策略——这条边界我始终没松口。2.4 闭环设计的核心原则状态机驱动与事件总线整个盘前-盘中-盘后闭环能串起来靠的是两个底层设计状态机和事件总线。每个 Agent 都围绕一个明确的状态机运行。盘前信号工的状态可能是“等待数据”“计算中”“已完成”“异常重试”盘中执行 Agent 的状态则从“监听信号”到“执行中”再到“完成”。状态机让每个 Agent 的每一步行为可预测也方便外部监控 Agent 随时探测每个环节卡在何处。事件总线则是 Agent 之间通信的中枢。我使用 Redis Stream 实现每个 Agent 既是生产者也是消费者发布的事件包括“数据就绪”“信号更新”“订单回报”“熔断触发”等。其他 Agent 根据订阅规则自动响应这样闭环不是串行等待而是事件驱动的流水线。环节与环节之间的“边界”也很重要。盘前 Agent 产出的是“计划”盘中的 Agent 只负责“执行和微调”盘后 Agent 则专注“总结和学习”。计划、执行、总结之间通过文件或消息传递但不会互相越权改写对方的产物。这种边界设计让闭环即使某个环节出错也能快速定位到具体模块不会形成一团乱麻。3. 多Agent协作的骨架通信协议、记忆共享与仲裁机制3.1 Agent之间怎么“说话”选Redis Stream而不是直接调API在多 Agent 系统里Agent 之间最忌讳的是大量同步点对点调用。如果盘中执行 Agent 直接 HTTP 调用信号工的接口拿信号一旦信号工响应慢了执行 Agent 就会跟着卡住。我在 QuantBot 里统一采用异步消息队列选用 Redis Stream 作为通信总线主要看中四点天然支持多消费者组盘中执行 Agent 和数据倾斜校验 Agent 可以同时订阅同一个信号主题消息可回溯日志挖掘 Agent 可以消费历史消息复盘消息持久化到磁盘宕机重启后不会丢未处理事件Redis 本身就是系统早已引入的组件运维成本低。每个事件都带着全局唯一的 message_id、发送 Agent、目标主题、时间戳和载荷。比如信号工发布的信号事件载荷里包含标的代码、信号方向、预期仓位、有效期。执行 Agent 消费到事件后先做一次幂等校验再进入订单状态机。通过这种异步事件流盘前和盘中的 Agent 彻底解耦最后一个环节执行慢也不会阻塞前面的 Agent。3.2 让每个Agent“记忆”一致全局状态快照与局部存储多 Agent 系统一个很难缠的问题是“记忆一致”。盘前 Agent 计算的组合权重如果只存在自己的局部文件里盘中的执行 Agent 就不知道权重来源导致权限判断错误。我为此设计了两层存储第一层是全局状态快照存储在 Redis 中用 Hash 结构保存当前交易日几个关键状态字段例如signal_date、target_positions、risk_limit_version、is_halted。每个 Agent 在决策前先读取快照确认当前系统处于哪个阶段快照每天开盘前重建盘中只允许特定 Agent 更新比如盘中执行 Agent 可以更新last_order_time但只有盘前信号工能更新target_positions。第二层是 Agent 自己的局部存储一般是本地 SQLite 表或 Parquet 文件用来存各 Agent 运行过程中的中间产物比如信号工的特征计算结果、执行 Agent 的逐笔订单记录、日志挖掘 Agent 的文本摘要。局部存储不参与全局仲裁只服务于自身分析和报告。这种“全局快照局部存储”的模式避免了所有 Agent 共用一个超大数据库的写冲突和性能瓶颈也保持了每个 Agent 职责的独立性。3.3 决策冲突时听谁的基于角色与优先级的仲裁规则多 Agent 协作中必然碰到冲突场景。最常见的冲突是信号工给出强烈买入信号但风控预检 Agent 认为当前行业暴露已经超标两者结论相反。QuantBot 不会让两个 Agent 辩论出个结果——那太耗时且不可控。我在系统中设计了“仲裁 Agent”通过优先级规则做快速决策。仲裁规则按角色定义第一优先级是熔断 Agent 的指令涉及账户级风险时可以直接否决所有其他 Agent 的建仓建议 第二优先级是风控预检 Agent 的约束它受限于硬性风险参数比如单票仓位上限 第三优先级是数据管家 Agent 的数据质量提示如果数据质量分低于阈值决策需要降级 最后才是信号工和市场行情 Agent 的主动信号。仲裁结果会带上reason字段记录触发规则的原因。这样即使某个信号被否决我们也知道它是因为风控、数据还是行情原因被否的。另一个常见冲突是多个策略对同一标的同时给出反向信号QuantBot 通过“策略优先级当日预测置信度”加权排序只保留一个最优方向避免自成交与仓位抵消。3.4 一个完整的Agent任务序列实例为了把上面的设计串起来举一个完整的例子。假设今天是交易日早上 6:30数据管家 Agent 被定时调度唤醒拉取昨夜行情和新闻因子校验通过后发布data_ready事件信号工 Agent 消费该事件计算多个策略的信号发布signal_ready事件附带当日目标组合风控预检 Agent 消费信号发现某个信号行业暴露超标将其标记为rejected并附上原因随后发布plan_ready事件9:15盘前阶段结束状态机进入“盘中”阶段。行情订阅 Agent 开始实时推送行情事件9:30某策略信号触达盘中条件信号工 Agent 发布intraday_signal事件执行 Agent 消费后在行情快照上检查盘口提交限价单成交回报事件进入订单状态机执行 Agent 更新持仓状态并发布order_filled事件12:30午间熔断 Agent 发现回撤超过阈值发布halt事件执行 Agent 停止新开仓15:00盘后任务启动绩效归因 Agent 读取订单和账户数据生成归因 JSON日志挖掘 Agent 汇总当天所有事件策略迭代 Agent 生成调优建议等待人工审核。整个过程中所有事件都有时间戳和来源任何一环出了问题都能通过消息回溯定位。4. 核心模块实现要点与工具选型从数据管道到订单执行链路4.1 为什么用Python做底座以及AI-Agent框架怎么选QuantBot 的核心代码库用 Python 3.11 编写。原因不多解释量化生态最成熟的库都在 Python 这边比如 pandas、numpy、statsmodels、qlib 等。而 AI-Agent 这部分我没有直接上一个特别重的框架而是用 LangChain 的 Agent 组件作为基础在它之上封装了一层自己的行业 Agent 类。选择 LangChain 而不是纯手写 LLM 调用的原因是它对工具调用和记忆管理有现成的抽象能让 Agent 快速调用 Python 函数、SQL 查询和外部 API。不过我要提醒的是不要被框架的“链”概念捆住手脚。在 QuantBot 里每个 Agent 的 prompt 都很短核心逻辑仍然放在代码里LLM 主要承担“总结、解释、生成建议”这类文本任务而不是直接输出交易决策。以目前的 LLM 稳定性让大模型直接写下单指令风险太高更适合做辅助分析。4.2 盘前数据管道构建的四个重点盘前数据管道是所有自动化的基础如果数据质量不行后面所有 Agent 都白搭。我总结了四个重点一是数据源冗余。主行情源和备份行情源都用独立进程管理主源不可用时自动切换备份源并发布data_source_switched事件提示当日数据可能有细微差异。二是字段标准化。不同数据源的字段命名千奇百怪我在入口加了一个 schema 映射层统一转成内部标准格式字段名、时间格式、复权方式都保持一致。这样下游 Agent 永远不会因为字段名不同而出错。三是特征计算增量更新。历史因子库一次性计算好存 Parquet 文件每天只增量计算新交易日的数据能极大压缩盘前准备时间。一次全量重算要 20 分钟增量计算只需 2 分钟。四是数据版本管理。每个交易日的特征集都带一个data_version字段例如20250601_v1。如果当天发现数据源有误可以通过版本回滚重跑。这个设计在盘后归因时特别有用能精准复原当时用的哪版数据。4.3 盘中执行器的低延迟链路从信号到订单盘中执行器对延迟要求很高但也不是要追求微秒级毕竟我们不搞高频。我的目标是全链路从信号事件到订单请求发出控制在 500 毫秒以内。这条链路的瓶颈往往不是 Python 本身而是不必要的等待。执行 Agent 订阅 Redis Stream 的信号事件后先在内存中维护一张“活跃信号表”避免每次都查数据库。然后它需要获取最新盘口此时不是去查行情数据库而是直接读取行情订阅 Agent 写入共享内存的行情快照。快速沪深两市的盘口快照加起来不到几十兆常驻内存完全可行。订单提交后执行 Agent 会进入一个最多 3 秒的等待窗口等待交易所回报。如果超时它会查询订单状态接口确认是否已经成交而不是盲目撤销或重复提交。由于不同券商的接口差异很大我在这里抽象了一层OrderGateway接口把市价单、限价单、撤单、查单都封装成统一方法方便切换不同券商。盘中执行器的另一个细节是限价单的“超价”设置如果信号方向是买入我会把限价设为对手价的合理溢价比例比如 0.1%保证能快速成交又不至于滑点太大。4.4 盘后分析管道的搭建从结算单到归因报告盘后分析管道技术上相对简单但信息组织要清晰。绩效归因 Agent 从结算单和订单表中读取数据后先计算每日收益曲线再用 Brinson 模型把超额收益拆解为配置收益和选股收益进一步归因到行业和风格因子。这里需要注意不同策略的时间周期不同按日频计算时要用复权净值不能直接用简单收益率。日志挖掘 Agent 会消费当天 Redis Stream 里的所有事件按 Agent 分组生成一份按时间排序的流水摘要并标记其中的 ERROR 和 WARN 级别事件。它再调 LLM 做一次“因果叙事”总结比如“今日下午交易时段因行情订阅 Agent 检测到数据延迟超过 5 秒触发了降级事件导致 14:30 后两个策略停止产生新信号”。这种自由文本总结并不是给人直接看的而是辅助我快速找到问题。报告输出方面我把盘后报告设计成一份 HTML 文件包含当日自动生成的归因图表、策略信号统计、异常事件时间线以及策略迭代 Agent 的调优建议。整份报告直接在浏览器中打开无需额外部署 Web 服务。如果当天不想开电脑也可以通过企业微信机器人把核心摘要推送出来。5. 实测中的坑与应对多Agent量化工作台的稳定性笔记5.1 Agent“自作主张”改策略参数的问题与约束上线初期我犯过一个印象很深的错误策略迭代 Agent 在盘后生成建议时直接生成了一版修改过参数的策略文件并临时替换了盘前加载的文件。第二天开盘前我还没检查信号工 Agent 就加载了这版未经审核的参数结果那天的组合里多了一只我根本不想持有的标的所幸当天波动不大没有造成亏损。此后我在所有 Agent 的工具权限里做了一条硬约束策略迭代 Agent 只能生成候选补丁到指定的suggestions/目录不能写入实盘策略路径实盘策略目录的写入权限只保留给人工操作。同时每个盘前 Agent 在加载策略文件后会计算一次文件哈希和前一天比较如果发现变化且没有对应审核记录就直接拒绝启动并告警。这就是“Agent 能做主但不能越界做主”的落地方式。5.2 盘中数据延迟与Agent超时导致的漏单有一段时间盘中执行 Agent 偶尔会漏掉几单信号排查了 Log 才发现信号工在发布信号事件时由于当时 CPU 负载太高Redis Stream 的写入出现了超过 1 秒的抖动而执行 Agent 当时的超时设置是 500 毫秒它等不到信号就直接跳过该事件了。最后的结果是执行 Agent 没有触发订单但信号工那边的状态仍然显示“已发布”两边状态不一致。修复方案有两个层面先用消息确认机制替代单纯等待执行 Agent 消费后写入 ack信号工看到未 ack 的信号不会标记为完成同时把事件监听的阻塞超时从 500 毫秒放宽到 2 秒而把真正的风险控制放在熔断 Agent 端而不是靠 Agent 之间的调用超时来卡风险。这个教训让我明白在多 Agent 系统里超时设置必须按事件类型分开配置不能一刀切。5.3 盘后报告和实盘状态不一致问题出在哪一个让我头疼了半天的问题是某天盘后报告上的持仓和券商后台实际持仓不一致差额正好是一只股票但当天没有任何委托记录。后来发现是风控预检 Agent 在盘前把这只标的从可交易清单中剔除了但持仓清理 Agent 并没有被告知要清掉它而盘中也没有相关信号于是一直留到了收盘。报告里的“当日持仓”来自持仓清理 Agent 的视图所以看起来是空的但账户里还有。这个问题的根源在于不同的 Agent 用了不同的“持仓视图”盘中执行 Agent 用的是实时账户持仓盘后归因 Agent 用的却是组合视图。后来我统一了持仓数据来源所有 Agent 都从同一个持仓同步服务读取账户实际持仓任何 Agent 需要做“假设持仓”时必须显式加上virtual标记。自此之后盘后报告和实盘状态再没有对不上过。5.4 容错设计级联失败、消息重试与降级策略多 Agent 系统最怕的是级联失败一个 Agent 卡住导致依赖它的 Agent 全部超时然后超时又导致后续事件积压。我在系统中做了三层容错第一层是消息重试。消费者处理消息失败时不立即抛弃而是进入重试队列最多重试三次每次间隔递增5 秒、30 秒、2 分钟。超过三次则进入死信队列由维护 Agent 每天盘后汇总死信并告警。第二层是 Agent 健康检查与自动重启。每个 Agent 都有独立的 systemd 服务或 Docker 容器外部监控脚本每隔 30 秒发送探活请求连续失败三次就自动重启并在重启后从全局状态快照恢复现场。第三层是降级策略。当某个数据源连续失败时数据管家 Agent 直接切换备份源并降低数据质量分当订单服务不可用时执行 Agent 自动转为“模拟成交”模式只记录信号不实际下单并持续发送告警直到服务恢复。降级不是禁赛而是保证流程不中断同时让人知道系统处于“半自动”状态。6. 部署建议与后续演进6.1 用Docker Compose编排全套Agent服务我把 QuantBot 的各个 Agent 模块容器化统一用 Docker Compose 编排。服务清单大致是数据管家、信号工、风控预检、行情订阅、订单执行、熔断监控、绩效归因、日志挖掘、策略迭代、Redis、RabbitMQ备用总线、MySQL元数据、MinIO特征与报告存储。每个服务都设置了独立的资源限制比如盘中执行 Agent 的 CPU 配额高一些盘后的日志挖掘 Agent 则可以让出 CPU。日志统一输出到 stdout由 Docker 的 json-file 驱动收集最终汇入 Loki搭配 Grafana 面板查看每个 Agent 的消息吞吐和错误率。用容器编排最大的好处是任何一个 Agent 崩溃后重启不会污染宿主机的环境也方便整体迁移。6.2 回测-模拟盘-实盘的平滑过渡Agent配置的三种档位QuantBot 支持三种运行模式历史回测、模拟盘中、实盘。三种模式的区别只在交易网关层的实现——同一个信号工 Agent 可以无缝切换。回测模式下行情订阅 Agent 从历史数据文件重放行情订单执行 Agent 则把订单发往一个虚拟撮合引擎用当时的盘口数据模拟成交。模拟盘模式下行情订阅 Agent 连接实时行情但订单执行 Agent 发往模拟账户。实盘模式则直接连接券商接口。三种模式切换通过一个环境变量控制这样我从不会因为切换工具链引入额外的 bug。需要提醒的是即便有了完善的回测和模拟盘实盘上线前我还是会先跑两周“影子模式”即盘中 Agent 只读行情和信号真实交易手动控制把系统所有消息和输出 dump 下来和人工决策对比。这样能提前暴露出很多只在实盘数据流下才出现的问题。6.3 下一个版本从QuantBot到多策略Agent平台QuantBot 目前是围绕“一套闭环”设计的下一步我打算把它扩展成多策略 Agent 平台。不同策略组可以各自拥有一套 Agent 集群共享底层的行情订阅、数据管家和 Redis 总线但各自拥有独立的信号工、风控预检和绩效归因。这样既保留了各策略组的隔离性又能复用公共基础设施。另外我还想加入一个“知识 Agent”专门沉淀历史周报、异常处理和优化经验让后来加入的 Agent 能继承历史知识。LLM 在这里的作用是检索和总结而不是替人做决定。这个方向还在迭代中等跑出一个稳定的版本我会把核心架构图和数据流再写一篇详细说明。最后说一点个人感受。做完 QuantBot 之后最大的变化不是交易结果变得更好了而是我每天从反复机械的流程里挣出了两三个小时的整块时间可以用来看文献、调策略、甚至什么都不想。多 Agent 协作在量化里其实是一次生产力工具的升级而不是玄学。关键是把 Agent 的边界、通信和容错设计清楚让它在可控的范围内发挥主观能动性。如果你也在折腾量化工作台建议从小处开始先自动化盘后报告再逐步往前推进一步一口啃系统会越来越听话。