8月7日,virattt 的 ai-hedge-fund 发布了 v2.2.0,这是它两周内的第四个大版本。项目现在挂在 GitHub 上 62969 颗星,README 第一行写着"This is a proof of concept for an AI-powered hedge fund"。很多人把它当成"能跑的 AI 基金"转发,但我读完它的 broker 目录后,发现了一个被星标数盖住的事实:这个系统的交易柜台只有一个模拟器,源码里没有任何真实下单的代码路径。
我做了什么:我没有跑实盘,也没装 live broker。我核查了 v2.2.0 的源码结构、pipeline 文档、broker 实现和风控模块,对照 README 和 VISION 的承诺,想搞清楚一个 62K 星的项目离真实交易到底差几步。
一个 pipeline,三种模式,但 broker 只有 sim
run_cycle.py 是整个基金的心跳,文档写得很清楚:
point-in-time data -> analysts -> blend -> risk -> execution -> record同一套代码跑三种模式——backtest 用 SimBroker,paper trade 用 PaperBroker,live 用 real broker。文档的原话是"the only thing that changes is the clock and the broker"。
问题出在 brokers 目录里只有一个实现:sim.py。SimBroker 的注释直接说明了它的行为——"Fills every order completely, exactly at the order's reference price",也就是每一笔订单都按参考价全额成交,没有滑点,没有手续费,没有部分成交。注释把滑点和成本标注为"declared future addition",意思是还没做。
这意味着 v2.2.0 的回测结果是确定性的:给定相同的订单,回测每次都走出完全相同的账本。这是它的设计目标,不是 bug。但如果你把回测曲线当成策略的盈利能力来理解,你看到的是一个零摩擦环境里的表现——现实里没有人能按收盘价全额成交。
风控是整个项目最认真的部分
risk/limits.py 是我读到的最清醒的一段代码。它的注释写了一句值得记住的原则:"Conviction requests, risk disposes"——分析师只能给信念,风控来决定最终仓位。
它做两件事:限制单个标的最大权重(max_position_pct),限制总敞口(max_gross_exposure)。两者都是硬上限,LLM 分析师不能 override。更关键的是,被风控砍掉的那部分仓位不会被重新分配到其他标的,而是留在现金里。注释解释了原因——重新分配会让风控环节增加仓位,这和它的职责正好相反。
这段设计说明作者清楚 LLM agent 在交易场景的边界在哪里。分析师输出一个 Signal(信念值加文字论述),信念值是 -1 到 +1 之间的数,portfolio construction 把信念转成目标权重,risk 再做硬性裁剪。LLM 的影响止步于 Signal,没有任何谈判空间。这是很多同类项目做不到的自律。
那些明星分析师其实是 prompt 角色扮演
signals 目录里有 buffett、munger、graham、lynch、druckenmiller 五个 LLM investor agent,外加一个 pead(盈利公告漂移)的 quant 模型。VISION 里也点明了一句话:这些 agent 是"stylized approximations of these investors' public philosophies"——对名人的公开投资理念的风格化模拟,不是真人,也不是背书。
它们的输出格式统一:一个信念值加一段文字论述。quant 模型输出同样的东西,只是背后是纯数学。两套 analyst 共享同一个接口,下游 portfolio 不需要知道信号来自 LLM 还是公式。这个设计的好处是可插拔——你可以替换掉任何一个分析师,甚至换成自己的因子模型,而不动 pipeline。
但这也意味着,明星分析师的"投资判断"质量取决于 prompt 工程和 LLM 能力,不是取决于巴菲特本人的水平。把它当成"巴菲特在帮你选股"是误读。
issue #409:62K 星项目的运行现场
我翻了 issue 区,#409 是评论最多的一条,标题是"It just keeps running and then generates an error with no info"——程序一直跑,然后报了个错,但没有任何信息。这个 issue 有 12 条评论,是开放 issue 里讨论最热的。
这和项目的 TUI 架构有关。ai-hedge-fund 用 textual 做了一个终端交互界面,aihf 命令启动后可以选标的、选策略、看回测的权益曲线画在终端里。TUI 应用的问题在于,当底层 pipeline 抛异常时,前端往往只能显示一个笼统的错误,堆栈被界面层吃掉了。对一个正在重构的项目(v2.0 到 v2.2 是架构重写),这类报错体验是阶段性的代价。
如果你要真正跑它,做好心理准备:第一次启动会要 Financial Datasets API key 和一个 LLM key(支持 Anthropic、OpenAI、DeepSeek、Google、xAI、Kimi),key 存到 ~/.hedge-fund/.env。网络或 key 不对时,报错信息可能不如你预期。
它的真正价值不在交易,在架构
读完源码我的判断是:ai-hedge-fund 值得看的不是它的交易能力——因为它明确声明不执行真实交易——而是它对"基金"这个概念的抽象。
mandate 文件把一只基金拆成策略、分析师、风控、资金、调仓节奏,标的由命令行参数传入,mandate 本身不绑定标的。CIO(资金分配器)、策略 pod、风控、执行、账本五层都可插拔。这个抽象对想搭自己研究框架的人有参考价值:你不必照搬它的分析师,但它的"策略 = 分析师组合 + 组合策略"这个拆法,比一坨脚本的 AI 交易项目干净得多。
run_cycle 的设计也值得学。一个 tick 内,数据是 point-in-time 的,held 标的没有价格时会 raise 而不是跳过——注释说"a fund that cannot price its own book has an infrastructure problem, and its NAV would be a lie"。这种对数据边界的较真,在 GitHub 交易项目里不多见。
复现前你必须检查这些
如果你打算 clone 下来跑回测,这里是我从源码和 issue 里整理的检查清单,避免你把模拟结果误读成策略能力:
回测可信度检查表
- • broker 是 SimBroker,所有订单按参考价全额成交,零滑点零手续费——回测收益是上界,不是预期
- • 没有成交约束(成交量上限、冲击成本),小市值标的的回测会严重高估
- • SimBroker 不建模保证金,cash 可以为负且可见——不要把它的仓位当真实资金占用
- • LLM cache 冷启动时首次调用是非确定性的,重跑同一回测可能第一次结果不同(prompt cache 之后才精确复现)
- • held 标的无价格会 raise,universe 标的无价格会跳过——退市/停牌处理是正常的,但要注意你的 universe 是否包含已退市标的
模拟盘上线前清单
- • 确认 PaperBroker 是否已实现(v2.2.0 源码里只看到 sim.py,live broker 同样未在仓库中找到)
- • 加入手续费和滑点后再看收益还剩多少
- • 检查分析师输出是否对单标的过度集中,风控的 max_position_pct 是否设得合理
- • 确认你的 LLM provider 不会因为 prompt 过长而截断 analyst 的论述
- • 用样本外数据跑一遍,而不是只在 README 给的 AAPL/MSFT 上验证
结论
ai-hedge-fund 值得读源码,不值得拿来交易——作者自己也是这么定位的,README 里写得很明白:educational purposes only,the system does not actually make any trades。
适合谁:想搭量化研究框架、想学可插拔架构设计、对 LLM agent 在金融场景的边界感兴趣的开发者。不适合谁:想找开箱即用的赚钱机器、把回测曲线当收益预期、需要真实下单能力的人。一个 62K 星的项目能坦诚地在 README 顶部写"这个系统不做任何交易",这本身就是一种稀缺的诚实。星标数证明的是关注度,不是它能不能帮你赚钱——这两件事在这个项目上,恰好是反的。
如果你也用 LLM agent 做过量化回测,你最头疼的是哪一步——是数据边界、还是 agent 输出的可复现性?评论区说说,下一篇我会挑一个具体环节做复现实测。
想把这个检查清单转给你身边正准备 clone 高星交易项目的朋友,他至少能少踩两个把回测当实盘的坑。
下一篇我会用 ai-hedge-fund 的架构搭一个最小可复现的 factor 验证框架,在看催更。
夜雨聆风