8 min read

InvestPilot — 一个治得住大模型幻觉的投研框架

Table of Contents

最近做了个叫 InvestPilot 的自动化投研流程项目。过去这阵子,我用 Claude Code 的 agent 能力,搭了一个深度基本面投研框架。它不追求”AI 帮你选股”,而是想解决一个更难的问题:怎么让大模型在跑一套严谨的投研流程时,不胡说八道。

为什么做这个

先说背景。我是二级市场的深度基本面投资者,投资风格偏向高赔率、寻找 0–3 个月能兑现的预期差。

用大模型做投研,大家应该都试过。痛点也都很清楚:

  • 它会编数字。PE、EPS、净利润,张口就来,而且看起来特别自信。
  • 它会口径混乱。一会儿用 trailing PE,一会儿用 forward PE;同业对比表里 T+1 和 T+2 混着算,比出来全是错的。
  • 它会跳步、自嗨。你让它做分析,它跑着跑着就宣布”我做完了”,但你回头看中间环节根本没做扎实。
  • 它给结论很痛快,但不可证伪。“我看好这只股票”——那什么情况下你会改口?它说不上来。

本质问题是:大模型是一个很会说话、但缺乏纪律的实习生。 你给它自由度,它就给你一个看起来很专业的幻觉。

所以我想试试:能不能用软件工程的纪律,给它套上一层硬约束,逼着它老老实实把一套投研 SOP 跑完?

这就是 InvestPilot。下面是它的几个核心设计。

一、它长什么样

整体是一个搭在 Claude Code 上的 agent harness。流程是把卖方研究所的深度投研 SOP,拆成 9 步(加一个前置筛选门):

Step 0  快速筛选(Gate:PASS / WATCH / 全研)


Step 1  业务深研  ──┐
Step 2  竞争壁垒  ──┤  串行,前一步没完成,后一步别想启动
Step 3  边际变化  ──┤
Step 4  假设矩阵  ──┤  ← 15 项校验 gate,过不去就 block
Step 5  财务建模  ──┤
Step 6  蒙特卡洛  ──┤
Step 7  赔率策略  ──┤
Step 8  独立审计  ──┤
Step 9  投委会评审 ──┘  ← 自动生成 HTML / Markdown 报告

支撑这套流程的,是 prompts/ 下 10 份加起来 3293 行的 prompt 模板,和 src/ 下 2.1 万行 Python(含 1.5 万行测试)。

一句话定位:它把”投研 SOP”编译成了一个带依赖图的状态机,让大模型只能沿着合规的路径走。

二、几个我自己觉得有点意思的设计

设计 1:把投研 SOP 编译成状态机

这是整个框架我最满意的一块。

每个 step 都有强制的三段式动作:

# 开始前
python -m src.cli workflow {workspace} start --step 5

# 写完产物后
python -m src.cli workflow {workspace} complete --step 5 --artifact step5_financial_model.md

# 缺料就阻塞
python -m src.cli workflow {workspace} block --step 5 --reason "..."

所有 step 的元数据(依赖关系、必须产物、校验门、所属阶段)都定义在一个 step_contracts.json 契约文件里,workflow 守卫、报告生成、各类校验器全部读这一个文件——单一事实源

效果就是:Step 7 想跑,但 Step 6 没完成?门都没有。 agent 没法跳步、没法幻觉式地宣布完成。

我之前的判断是:别信任 agent 的自我汇报,用代码强制约束它的行为边界。

设计 2:“自计算估值”——从源头切数字幻觉

大模型做投研最容易翻车的地方,是数字。新闻里说 PE 30 倍,研报里说 35 倍,某 API 返回 28 倍——LLM 抄哪个都行,但口径可能完全对不上。

所以我在 prompt 里立了一条铁律(用 🚨 标着,提示 agent 这是硬规则):

所有估值指标必须自计算。 PE、PB、PS、EV/EBITDA 必须从原始数据算出来,禁止引用新闻、研报、第三方 API 的现成值。每次计算必须标注:价格值与日期、EPS/BPS/营收值与来源、公式、source: calculated

并且明令禁止 trailing PE 和 forward PE 混用、T+1 和 T+2 混用、同业对比口径不一致。

这条规则简单粗暴,但效果很好——等于从源头切断了 LLM 投研最常见的错误来源。

设计 3:“禁止裸增长率”——逼出可证伪的假设

这是方法论上我最较真的一条。

在 Step 4 假设研究里,我规定:

一条光秃秃的增长率 % 是硬错误。每条收入预测必须拆解成 2–4 个可量化的驱动因子(比如”销量 × ASP”或”门店数 × 同店收入”),每个驱动因子要有 contribution_pct(贡献占比,求和须等于该分部增速)和至少一个 evidence_id(证据编号)。

为什么这么较真?因为这一步的输出,会直接喂给 Step 6 的蒙特卡洛模拟。

如果你只输入”明年收入增长 15%“,蒙特卡洛照样会煞有介事地跑出 P10/P50/P90 的分布图,看起来精确无比——但这是 garbage in, garbage out。 一堆精密的数字掩盖了输入端的拍脑袋。

逼着 agent 把”15%“拆成”销量 +8% × ASP +6.5%“,并要求每个因子挂上证据,本质是把”拍脑袋”逼成”可证伪”

设计 4:蒙特卡洛 + t-Copula + Kelly——概率思维

大多数”AI 估值”给一个目标价就完事了。我想给的是一个分布

概率引擎几个设计:

  • PE/PB 用对数正态分布(严格为正、右偏);
  • 增长率/利润率用正态分布
  • 变量之间用 t-Copula 建模(自由度 6,能捕捉非高斯的尾部相依——极端情况下变量会一起崩);
  • 7 点百分位网格:P5 / P10 / P30 / P50 / P70 / P90 / P95;
  • 最后用 Kelly 半仓公式给仓位上限,Edge 评级差还要再打 5 折。

到 Step 7,用这个分布算赔率:

RRR = P(上涨) × E[上行幅度] ÷ P(下跌) × E[下行幅度]
RRR决策
> 2.0建仓
1.0–2.0等催化剂确认
< 1.0不建仓

t-Copula 的参数选择、百分位网格的粒度、Kelly 在投资实战里的边界——这些都有不少可以讨论的空间。

三、一个真实跑通的案例:名创优品(MNSO)

光说设计没意思,给你们看一个真实跑通的例子。2026 年 6 月 12 日,我用它跑了一遍名创优品(MNSO / 9896.HK),当时股价 HKD 26。

这是 Step 0 快速筛选阶段,它自己提出来的预期差:

名创优品 FY2025 营收 +26.2%,但经调整净利润仅 +6.5%——增收不增利。市场因此给了一个很低的估值(Forward PE ~9x)。我们的预期差是:如果 Q2 2026 财报能验证利润率修复(从 Q1 的 9.7% 回到全年 13.5%+),这只股票应该能迎来 PE 重估。

然后它一路推导到 Step 7,给出赔率:

指标数值
当前价HKD 26.00
P50 目标HKD 30.66
P70 目标HKD 41.15
上涨概率61.1%
下行概率38.9%
RRR3.06(超过 2.0 阈值,建议建仓)
Kelly 半仓20.6%

但我特别想强调的是它的反证检查投委会评审——这两步是这个框架区别于”AI 鼓吹手”的地方。

Step 7 的反证检查,它自己回答了”在什么条件下 RRR 会小于 1.0”:

情景一:结构性利润率恶化被证实。 Q2 经调整净利率持续低于 10%(和 Q1 的 9.7% 一样),证明直营店转型永久稀释利润率。净利率掉到 9%,EPS 跌到 ~RMB 1.5,PE 8x → 目标价 HKD 13(-50%),RRR 掉到 0.5。

情景二:永辉超市(601933.SH)扭亏逆转。 若永辉 Q1 那个 +2.87 亿利润不可持续、重回大额亏损,市场会给予永久的多元化折价,PE 压到 6-7x,RRR 跌破 1.0。

到 Step 9 投委会评审,“研究总监 AI”给出了有条件通过,而不是无脑看多:

Override Decision:Conditional Endorsement(有条件通过)

① Q2 2026 财报确认经调整净利率 ≥12% 前,仓位不超过 15%; ② 当前价位(HKD 25-26)初始只建 8%,另外 7% 要等回调到 HKD 24 或右侧 Q2 确认; ③ Q2 财报必须强制复评,经调整净利率 <12% 减仓到 5%; ④ Kill switch:任一单季经调整净利率 <9%,立即清仓。

它没有说”强烈建议满仓买入”,而是说”这是一个本质上对 Q2 利润率恢复的二元博弈,38.9% 的亏损概率是真实的”。

这一份研报,从 Step 0 筛选到 Step 9 投委会评审 + HTML 报告,是 agent 自动跑完的。完整的 5 份交付物(HTML 报告、Markdown 摘要、分布图、PE Band、敏感度热力图)都在 workspace 里。

这个案例的完整输出已经放在仓库里。

四、一个细节:它是在真实失败中迭代出来的

我不想把这篇文章写成自夸,必须说实话:这个框架一开始烂得很。

翻一下它的演化记录。最近一次完整研究(另一只股票:中芯国际 H 股)暴露了 11 个工程缺陷(FIND-029~039),其中几个是 P0 级别的:

🔴 资产负债表平衡不了:三表联动模型里,资产侧和负债+权益侧各自独立计算,没有平衡插项(plug),旧版竟然能静默容忍 30% 的不平衡。修复后引入平衡项,A=L+E 按构造成立,并加了”插项占比 >15% 就警告”的透明 gate。

🔴 重资产周期股用 PE 估值失真:那种重资产代工厂,因为折旧吞噬利润导致 PE 高达 200 多倍,用 PE×EPS 算出目标价完全失真。修复后蒙特卡洛支持 valuation_primary="pb",优先用 BPS×PB 路径。

🔴 蒙特卡洛没扣 R&D 和利息:模拟路径漏了研发费用和利息支出,导致 EPS 高估约 2.6 倍,触发对齐 gate 硬失败才发现。

这些缺陷的命名、分级(🔴P0 / 🔵P1 / 🟡P2)、回归测试的追加,都记在 _optimization_findings.md 里。当前测试基线 1061 passed / 0 failed

我分享这段是想说:一个 agent 框架成不成熟,不看 README 写得多漂亮,看它有没有一份诚实的踩坑记录。 每跑一次真实研究,都会暴露之前没想到的问题。这个迭代节奏,才是这个框架真正的价值。

结尾

最后说一句负责任的话。

InvestPilot 是一个用于教育和信息目的的研究工具。它不构成任何形式的投资建议。

它不会替你赚钱。它想做的事是:当大模型遇上一个足够严谨的流程框架,它能不能成为一个不胡来的研究伙伴,帮我们把研究做得更系统、更可证伪、更可复现。

文中提及的名创优品(MNSO / 9896.HK)相关数据,均为 InvestPilot 框架于 2026-06-12 的研究输出示例,不构成任何投资建议,市场有风险,决策需谨慎。