FAPO:让 Claude Code 当你的 Prompt 优化工程师
Kassianik, P. et al. FAPO: Fully Autonomous Prompt Optimization of Multi-Step LLM Pipelines. arXiv:2606.19605, 2026.
Cisco Foundation AI & Yale University.
代码:https://github.com/cisco-foundation-ai/fully-automated-prompt-optimization
一、一个常见的企业困境
你在企业里部署了一个多步 LLM pipeline:
用户问题 → 检索文档 → 重排序 → LLM 推理 → 格式化输出 → 最终答案
每个步骤都有 prompt。每个 prompt 都经过人工调优。但上线后你发现:
- 检索步骤偶尔漏掉关键文档
- 推理步骤在复杂问题上"摆烂"(abstention)
- 格式化步骤输出不符合下游系统的 schema
- 最终答案有时候冗长到没法用
传统的 prompt 优化怎么做?
手动调:工程师盯着 bad case,改 prompt,再测,再看。一个调完调下一个。 weeks 过去,指标涨了两三个点。
自动调(如 GEPA/DSPy):在单个 prompt 上跑搜索,找到更好的指令字符串。但问题是——pipeline 有多个步骤,失败可能发生在任何一环。只优化最后一个 prompt,可能掩盖了检索阶段的根本问题。
FAPO 想解决的就是这个问题:让整个 pipeline 自己诊断自己、自己优化自己。
二、FAPO 的核心哲学:渐进式升级,最小修改
FAPO 的设计遵循一个简单但深刻的直觉:
Prompt 修改是最便宜、最可控的优化。只有当证据表明 prompt 真的不够用时,才动结构。
这不是保守,而是"归因驱动的优化"——先找到问题在哪,再决定用什么级别的手术。
Level 1: Prompt 文本修改(最轻)
↓ 如果失败归因显示:prompt 无法解决这个瓶颈
Level 2: Chain 参数修改(温度、top-p、检索数量等)
↓ 如果仍然不够
Level 3: Chain 结构修改(增加步骤、改变路由、添加后处理)
这个渐进策略有三个好处:
- 可控:企业客户不喜欢"突然改了我的 pipeline 结构"
- 可解释:每一步升级都有归因报告支撑
- 低成本:prompt 改几个字,不需要重新部署服务
三、系统架构:Claude Code 当包工头
FAPO 用 Claude Code 作为优化编排层(和你用 Claude Code 写代码一样),但给它装了一套"企业级施工规范"。
3.1 三层 Agent 架构
┌─────────────────────────────────────┐
│ Optimization Agent(包工头) │
│ 读取租户手册,驱动优化循环 │
│ 决定升级到哪一层 │
└──────────┬──────────────────────────┘
│ 派遣
▼
┌─────────────────────────────────────┐
│ Step-Attribution Subagent(验尸官) │
│ 分析每一步的失败模式 │
│ 分类:prompt 可修复 vs 结构瓶颈 │
└──────────┬──────────────────────────┘
│ 提交报告
▼
┌─────────────────────────────────────┐
│ Variant-Reviewer Subagent(质检员) │
│ 检查:是否越界?是否泄露数据? │
│ 是否破坏 scorer 兼容性? │
└─────────────────────────────────────┘
Optimization Agent:像项目经理,读租户手册,定范围合同,决定这次优化走哪一层。
Step-Attribution Subagent:像法医。不是笼统说"准确率低了",而是具体到:
- 第 2 步(检索):"13 个 case 因为检索覆盖不足,prompt 里加 multi-query 可能有用"
- 第 4 步(推理):"8 个 case 因为模型 abstain,prompt 里加 must-answer 规则"
- 第 5 步(格式化):"17 个 case 输出格式不对,但归因显示根因在第 2 步检索到了无关文档"
Variant-Reviewer Subagent:像安全审计。每个 proposed change 都要过它这关:
- 范围合规?(不能改租户手册禁止改的东西)
- 数据隔离?(不能把 A 租户的数据泄露到 B 租户)
- 占位符完整?(prompt 里的变量没被意外删掉)
- Scorer 兼容?(改了输出格式后 scorer 还能不能打分?)
3.2 六步优化循环
1. 评估当前版本 → 运行 pipeline,记录每一步输入输出
2. 失败归因 → 分类失败模式,定位问题步骤
3. 提出修改 → 在允许范围内提出一个最小修改
4. 审核修改 → 质检员检查是否合规
5. 测试新变体 → 在验证集上跑分
6. 迭代或升级 → 改进了?保留。没改进?继续。Prompt 没空间了?升级结构
这个循环不是瞎试。每次提出的修改都是基于归因报告的最小有用修改。
四、防过拟合的四重护栏
自动优化最怕什么?过拟合到训练集。把 prompt 调成只为那 150 个 dev case 服务,验证集上一跑,崩。
FAPO 用了四重护栏:
1. 数据隔离
- 优化器只能看训练集的单个 case(知道具体哪里错了)
- 验证集和测试集只给聚合分数(不知道具体哪些 case)
- 防止优化器"记住"验证集答案
2. 范围约束
- 每个租户在手册里定义"什么能改、什么不能改"
- 优化器和审核器独立强制执行
- 企业客户可以说:"你可以改 prompt,但不能改我的 LangGraph 结构"
3. 迭代历史
- 结构化日志记录所有变体、分数、失败原因
- 防止优化器反复提出同一个无效修改
- 也便于人类审计:"为什么系统决定升级结构?看日志就知道"
4. 变体不可变
- 每个变体都是新文件(variant-001, variant-002...)
- 不覆盖旧的。改错了?回滚到上一个变体
- 完整的优化轨迹可复现
五、实验:18 战 15 胜
5.1 基准设置
六个基准、三个任务模型:
- HotpotQA:多跳 QA,6 节点 LangGraph 链(BM25 检索 + LLM 推理)
- HoVer:多跳事实验证,需要检索多个 Wikipedia 文档
- IFBench:指令遵循,检查输出格式是否满足约束
- Papillon:隐私意识委派,平衡答案质量和隐私泄露
- LiveBench-Math:数学题,避免 benchmark 污染
- AIME:竞赛数学题
- CTIBench-RCM:安全任务,CVE 到 CWE 分类(263 类)
模型:GPT-4.1-mini, GPT-5.4-mini, Gemma 3-12B
对比基线:GEPA(DSPy 的 prompt 优化器,只改指令字符串)
5.2 核心结果
| 基准 | 模型 | GEPA | FAPO | 提升 |
|---|---|---|---|---|
| HotpotQA | GPT-4.1-mini | 37.11% | 46.67% | +9.56pp |
| HotpotQA | GPT-5.4-mini | 49.78% | 57.44% | +7.67pp |
| HotpotQA | Gemma-3-12B | 36.44% | 45.22% | +8.78pp |
| HoVer | GPT-4.1-mini | 34.44% | 59.22% | +24.78pp ‡ |
| HoVer | GPT-5.4-mini | 45.56% | 94.11% | +48.56pp ‡ |
| HoVer | Gemma-3-12B | 30.00% | 50.22% | +20.22pp ‡ |
| IFBench | GPT-4.1-mini | 40.00% | 59.84% | +19.84pp ‡ |
| IFBench | GPT-5.4-mini | 45.56% | 84.51% | +38.95pp ‡ |
| IFBench | Gemma-3-12B | 36.22% | 64.89% | +28.67pp ‡ |
| Papillon | GPT-4.1-mini | 55.33% | 60.44% | +5.11pp |
| LiveBench-Math | GPT-4.1-mini | 24.00% | 28.00% | +4.00pp |
| AIME | GPT-4.1-mini | 16.00% | 13.78% | -2.22pp |
‡ = 升级到 pipeline 结构优化(非 prompt-only)
FAPO 赢下 15/18 组对比,11 组有统计显著性(非重叠置信区间)。平均提升 +14.1pp。
5.3 关键发现:什么时候需要升级结构?
HoVer(多跳事实验证):
- 归因发现:失败来自"检索覆盖不足"
- 升级动作:把 3 跳检索扩展到 4-5 跳,增加 multi-query BM25 和实体感知的 rescue
- 结果:+20-48pp(这是最大的提升!)
IFBench(指令遵循):
- 归因发现:格式约束失败
- 升级动作:添加确定性后处理节点(正则匹配、强制 schema)
- 结果:+20-39pp
HotpotQA(prompt-only):
- 归因发现:13 case "verbose answers" + 8 case "abstention" + 17 case "wrong answer"
- 优化动作:加 brevity 约束 + must-answer 规则
- 结果:val EM 从 39.2% → 65.7% → 70.3%
- 然后归因发现剩余失败是"检索受限(结构瓶颈)"
- 但由于 scope contract 允许的结构优化已经做完,停止
AIME(竞赛数学):
- 唯一一个 GEPA 赢的基准
- 论文分析:样本量太小(验证集只有 150 case),优化信号弱,结果在噪声范围内
- 这也说明:自动优化不是万能的,在数据稀疏的场景下可能无法稳定超越人工或简单基线
5.4 安全任务验证(CTIBench-RCM)
这是真实的企业安全任务:CVE → CWE 分类(263 类)。
- 限制:只能优化 prompt(不能改结构,符合企业安全评估协议)
- GPT-5:72.1% → 76.1%(+4.0pp,加 NVD 映射规则)
- Foundation-Sec-8B-Instruct:63.9% → 71.0%(+7.1pp,缩短 prompt + 加 NVD 规则)
- Foundation-Sec-8B-Reasoning:74.8% → 76.8%(+2.0pp)
注意:不同模型的最佳策略完全不同。GPT-5 需要详细规则,Instruct 需要短 prompt。这说明没有通用最优 prompt,优化必须是模型感知的。
六、技术要点拆解
6.1 租户模型(Tenant Model)
FAPO 的架构用了一个企业友好的概念:租户。
核心引擎(共享)
├── src/hephaestus/ # 运行器、评估、归因、 scorer
└── 通用适配器(OpenAI、Anthropic、Google...)
租户工作空间(隔离)
├── tenants/<tenant_id>/
│ ├── chain.py # 流水线代码
│ ├── prompts/ # prompt 变体
│ ├── scorer.py # 打分逻辑
│ ├── config.json # 评估配置
│ ├── playbook.md # 租户手册(最重要)
│ └── history/ # 优化历史
- 一个核心引擎可以服务多个租户
- 每个租户有自己的数据、配置、约束、优化历史
- 租户之间完全隔离(A 的 prompt 不会泄露到 B)
- 企业可以用:不同 BU 不同租户,不同客户不同租户,不同安全域不同租户
6.2 LangGraph 表示
Pipeline 用 LangGraph 表示为状态图,节点可以是 LLM 调用、代码执行、检索、工具调用。边可以是条件路由。
这让 FAPO 可以:
- 理解 pipeline 的拓扑结构(哪些步骤依赖哪些)
- 在结构升级时安全地添加/删除节点
- 记录每个节点的输入输出(归因的基础)
6.3 失败归因的逻辑
归因不是简单的"答案错了",而是分类到具体步骤和修复类型:
| 失败模式 | 可能修复 |
|---|---|
| Missing evidence | 增加检索数量、扩展检索链、multi-query |
| Unsupported abstention | 加 must-answer 规则、降低置信度阈值 |
| Verbose answer | 加 brevity 约束、输出长度限制 |
| Malformed output | 加 schema 约束、后处理节点 |
| Weak final instruction | 重写最终 prompt、加 few-shot 示例 |
| Wrong reasoning | 加 intermediate step 提示、分解问题 |
归因子 agent 用规则检查 + LLM 分析做分类。分类结果驱动优化方向。
七、局限与追问
1. 依赖 Claude Code
FAPO 的优化层是 Claude Code。这意味着你需要:
- Claude API 访问(对企业来说不是问题,但对开源复现有门槛)
- 信任 Claude 的代码编辑能力(在安全场景中,自动改代码可能引入风险)
论文也提到:"这个机制可以优化使用各种闭源或开源任务模型的 pipeline"——优化器和任务模型是分离的。但优化器本身目前绑定了 Claude。
2. AIME 的教训
在数据稀疏的场景(AIME 验证集只有 150 case),自动优化可能无法稳定超越简单基线。GEPA 在 AIME 上反而赢了。
这说明:自动优化需要足够的信号密度。如果失败模式太少或太分散,归因的统计意义不足,升级决策可能出错。
3. 结构升级的边界
虽然论文说"只在 prompt 不够时才升级结构",但结构升级本身是一个更大的决策空间。加一个新节点?改路由逻辑?加后处理?这些选择比改 prompt 复杂得多,也更容易引入不可预见的副作用。
FAPO 的护栏(范围约束、审核子 agent) mitigates 这个风险,但"允许结构升级"本身就意味着更大的优化空间可能带来更大的方差。
4. 成本
50 个变体 × 每个变体跑验证集(300 case)× 多步 pipeline(每次调用多个 LLM)——这不是免费的。虽然比人工 weeks 的工程师时间便宜,但token 消耗和 wall-clock 时间仍然不小。
论文没有给出具体的优化成本数据,这是一个值得追问的点。
八、总结:从"调 prompt"到"pipeline 自我进化"
FAPO 的意义不在于"又一个 prompt 优化工具"。
它的意义在于:
它把 prompt 优化从"手工调参"变成了"归因驱动的系统工程"。
不是"我觉得 prompt 可以改改",而是"归因报告显示 13 个 case 因为 verbose answers 失败,variant-002 加 brevity 约束后 val EM 从 39% 提升到 66%"——每一步都有证据、有日志、可审计。
更深层的是:
它承认了多步 pipeline 的复杂性——失败不是单点问题,而是系统问题。
只优化最后一个 prompt 是偷懒。真正解决问题需要:
- 看每一步的中间输出
- 找到失败的根因步骤
- 判断是 prompt 问题还是结构问题
- 用最小修改修复
- 验证修改没有破坏其他东西
这不是 prompt engineering,这是pipeline engineering。
对于企业部署来说,FAPO 的租户模型、护栏、隔离、可审计性——这些和性能提升一样重要。因为企业买的不是"更高的准确率",而是**"可控制的优化过程"**。
参考
- Kassianik, P. et al. (2026). FAPO: Fully Autonomous Prompt Optimization of Multi-Step LLM Pipelines. arXiv:2606.19605. Cisco Foundation AI & Yale University.
#论文拆解 #Prompt工程 #LLM流水线 #Agent #ClaudeCode #自动化优化 #企业AI #小凯
讨论回复
加载中...正在加载回复...
推荐
智谱 GLM-5 已上线
我正在智谱大模型开放平台 BigModel.cn 上打造 AI 应用,智谱新一代旗舰模型 GLM-5 已上线,在推理、代码、智能体综合能力达到开源模型 SOTA 水平。