PromptMatic:通过多阶段提示优化提升大模型的指令遵循能力
论文arXiv原文:https://arxiv.org/html/2609.09153v1
摘要
提示工程的核心目标是构造能够引导大语言模型(LLM)可靠遵循复杂指令的提示词。现有的提示优化方法大多采用单阶段策略:直接对原始提示做重写、改写或搜索。这种单轮优化方式容易陷入局部最优,并且很难拆解复杂任务中多个子目标。
本文提出 PromptMatic ,一套多阶段提示优化框架,把提示优化拆分为三个有序阶段:分解(Decompose)、精炼(Refine)、验证(Validate)。
- 分解:将用户原始高级指令拆解为结构化子任务清单;
- 精炼:基于子任务清单,生成详细的分步执行提示;
- 验证:生成测试用例,检验提示词能否让模型输出满足原始需求。
PromptMatic在优化过程中可以迭代回退:如果验证阶段发现提示词失效,会回到前面阶段重新修改子任务清单或者重写提示文本。
在4个主流指令遵循基准数据集上开展实验:IFEval、MATH、GSM8K、BBH。PromptMatic相比直接使用原始提示、以及单阶段提示优化基线(AutoPrompt、DSPy、Metaprompt)获得显著提升。在IFEval(指令遵循评测集)上,相比基础模型基线提升 +10.2% ;相比最强单阶段提示优化基线提升 +4.6%。
消融实验证明:三个阶段缺一不可,验证阶段的测试用例生成是提升性能最关键的组件。PromptMatic仅通过提示优化,不需要微调模型权重,就能提升指令遵循能力。
1 引言
大语言模型在复杂指令任务上经常出现指令违背、忽略约束、遗漏子要求等问题。手工设计高质量提示词耗时、依赖经验,因此自动提示优化(Automatic Prompt Optimization, APO)成为研究热点。
现有的自动提示优化方法大多属于单阶段范式:接收用户原始指令,直接改写/搜索得到更好的提示。这类方法存在两个短板:
- 复杂指令包含多个约束、多条子要求,单轮改写容易丢失子目标,陷入局部最优;
- 缺少独立验证环节,无法判断优化后的提示是否真的满足用户原始意图。
人类编写提示词的思路通常是分步思考:先把大任务拆成子任务,再写分步指令,最后设计测试样例检查提示效果。PromptMatic借鉴这个思路,设计三阶段流水线,并且支持反馈回环:验证失败时,回溯到前面阶段重新优化。
本文主要贡献
- 提出PromptMatic多阶段提示优化框架:分解 → 精炼 → 验证,支持验证失败时回溯迭代;
- 在4个基准上验证效果,在IFEval上大幅超越单阶段提示优化方法;
- 开展消融实验,量化三个模块各自贡献,证明验证测试用例是性能增益核心来源;
- 开源代码,提供完整脚本、评测配置,支持复现全部实验。
2 相关工作
2.1 自动提示优化 APO
AutoPrompt、Metaprompt、OPRO、DSPy 等工作,使用模型自身搜索/改写提示词。DSPy通过编译提示、带反馈优化,属于单轮优化范式。这类方法大多直接对原始提示做变换,缺少显式任务分解与独立验证。
PromptMatic与之最大区别:显式多阶段拆解 + 独立测试用例验证 + 可回溯迭代。
2.2 指令遵循与提示分解
已有研究证明,将复杂指令拆成子步骤可以提升模型执行效果,但大多是模型在推理时做任务分解 ,而不是优化提示词本身。PromptMatic在提示词侧提前分解任务结构,并且用测试用例校验提示质量。
2.3 LLM测试用例生成
利用LLM生成输入输出样例来校验提示有效性,之前多用于评估模型能力。PromptMatic将其嵌入提示优化闭环,用来指导提示词迭代改进。
3 PromptMatic 方法
整体流水线:
原始用户指令 →【分解Decompose】→ 结构化子任务列表 →【精炼Refine】→ 优化后的分步提示 →【验证Validate】→ 生成测试样例,评估提示有效性
如果验证失败 → 回溯,重新执行分解或精炼;循环直到满足终止条件,或达到最大迭代次数。
3.1 阶段1:Decompose 任务分解
输入:用户原始自然语言指令 I I I
输出:结构化子任务清单 S = s 1 , s 2 , . . . , s k S = s_1, s_2, ..., s_k S=s1,s2,...,sk
提示词交给LLM,要求模型把原始指令拆成独立、可校验的子任务,提取所有约束、边界条件、输出格式要求。
示例输出结构:
- 子任务1:xxx
- 子任务2:xxx
约束清单:
- 约束A:xxx
- 约束B:输出必须JSON,不能额外解释文本
设计目标:把隐式要求显式化,避免后续写提示时遗漏约束。
3.2 阶段2:Refine 提示精炼
输入:原始指令 I I I + 子任务清单 S S S
输出:优化后的提示词 P P P
LLM基于子任务清单,编写详细分步提示,把所有子任务、约束、输出规则嵌入提示文本。可以加入思考指引、格式要求、禁止行为。
本阶段输出的是给任务模型使用的最终提示,不是思考草稿。
3.3 阶段3:Validate 验证(核心模块)
输入:原始指令 I I I、子任务清单 S S S、候选提示 P P P
输出:验证得分 + 失败案例(用于回溯)
- 生成一批测试输入样例 T = { t 1 , t 2 , . . . } \mathcal{T} = \{t_1,t_2,...\} T={t1,t2,...};
- 使用候选提示 P P P调用LLM,在测试样例上生成输出;
- 对照原始指令,评估输出是否全部满足所有子任务与约束;
- 汇总得到验证分数。
判定规则
- 高分:所有测试样例都满足全部子任务与约束;提示词合格,直接输出作为最终优化提示。
- 低分:存在测试用例违背原始指令;收集失败案例作为反馈,回溯到Decompose或者Refine阶段重新优化。
3.4 迭代回溯逻辑
Initialize P = None
for iter in 1..max_iter:
S = Decompose(I)
P_candidate = Refine(I, S)
score, failures = Validate(I, S, P_candidate)
if score >= threshold:
P = P_candidate
break
else:
# 将失败样例作为反馈,进入下一轮分解/精炼
continue
return P
可以配置两种回溯策略:
- 轻量回溯:只重新执行Refine,保留上一轮子任务清单S;
- 深度回溯:回到Decompose,重新生成子任务清单。
论文默认采用自适应策略:少量失败仅重精炼;大量失败则重新分解任务。
3.5 推理阶段使用
优化完成后,得到最终提示 P f i n a l P_{final} Pfinal。推理时不再运行分解、验证模块 ;直接将 P f i n a l P_{final} Pfinal + 用户输入送入底层任务模型做推理,无额外开销。
PromptMatic仅在提示优化阶段消耗额外模型调用;上线推理没有增加token开销。
4 实验设置
4.1 数据集
- IFEval:专门用于评估指令遵循,包含大量细粒度约束(格式、长度、关键词、禁止词等);核心评测集;
- MATH:数学推理数据集;
- GSM8K:小学数学应用题;
- BBH (BigBench Hard):复杂多步推理基准。
4.2 基线方法
- Vanilla:直接使用原始用户指令,不做任何提示优化
- AutoPrompt:基于梯度/搜索的提示优化
- OPRO:优化提示的元提示方法
- DSPy:提示编译与优化框架
- Metaprompt:元提示改写基线
4.3 模型配置
- 优化器模型(执行Decompose/Refine/Validate):GPT‑4o-mini
- 任务模型(运行下游任务,评估提示效果):Llama3‑70B-Instruct
优化器和任务模型可以使用不同模型,PromptMatic不要求两者一致。
4.4 评估指标
- IFEval:使用官方指标,统计所有约束全部满足的样本比例
- MATH / GSM8K / BBH:标准准确率(答案是否正确)
4.5 超参数
- 每轮Validate生成5个测试样例;
- 最大迭代轮次 max_iter = 3;
- 验证阈值:5个测试样例全部通过才算验证成功;
- 回溯策略:≥2个样例失败 → 深度回溯(重新Decompose);否则轻量回溯(仅Refine)。
5 实验结果
5.1 主实验结果
| Method | IFEval | MATH | GSM8K | BBH |
|---|---|---|---|---|
| Vanilla (原始提示) | 56.4 | 42.1 | 74.6 | 51.3 |
| AutoPrompt | 59.1 | 43.5 | 75.2 | 52.0 |
| OPRO | 60.3 | 44.0 | 76.1 | 52.8 |
| DSPy | 61.5 | 44.7 | 76.8 | 53.2 |
| Metaprompt | 62.0 | 45.1 | 77.3 | 53.7 |
| PromptMatic | 66.6 | 47.3 | 79.5 | 56.1 |
在IFEval上相比Vanilla提升 +10.2%;对比最强基线Metaprompt提升 +4.6%。数学与BBH推理任务同样稳定提升。
5.2 消融实验:各模块贡献
| 配置 | IFEval |
|---|---|
| PromptMatic(完整三阶段+回溯) | 66.6 |
| 移除Validate验证模块(仅Decompose+Refine) | 61.9 |
| 移除Decompose,仅Refine+Validate | 63.4 |
| 移除Decompose+Validate,仅Refine(单阶段) | 60.7 |
| 无迭代,仅一轮Decompose→Refine→Validate,不回溯 | 64.1 |
结论:
- Validate验证模块是最大增益来源,去掉后性能大幅下跌;
- Decompose任务分解带来额外收益;
- 迭代回溯可以进一步小幅提升效果。
5.3 迭代轮次分析
- 1轮迭代:64.1
- 2轮迭代:65.5
- 3轮迭代:66.6
超过3轮之后收益进入平台期,token成本持续上升,因此论文选用max_iter=3。
5.4 跨模型迁移实验
使用GPT‑4o-mini作为优化器,优化出来的提示,直接迁移到另外两个任务模型:Llama3‑8B-Instruct、Mistral‑Large。
优化后的提示具备良好跨模型泛化:在新模型上依然保持稳定增益,说明PromptMatic学到的是通用提示结构,不是针对特定模型的过拟合提示。
5.5 定性案例(IFEval样例)
原始指令:
写一段100词左右文本,必须包含单词"nebula",禁止使用任何逗号。
Vanilla提示:模型经常漏掉禁止逗号约束。
PromptMatic分解子任务:
- 文本长度≈100词
- 必须包含 nebula
- 约束:不能出现逗号
验证阶段自动生成测试样例,发现模型输出出现逗号 → 回溯重写提示,在提示里加粗强调禁止逗号约束。最终优化后的提示大幅减少约束违反。
6 讨论
6.1 优势
- 无需微调权重,纯提示层面优化,低成本;
- 显式拆解复杂指令,减少隐式约束丢失;
- 自带独立测试校验,能发现提示词本身缺陷;
- 生成的提示具备跨模型泛化。
6.2 代价
提示优化阶段会消耗额外LLM调用(Decompose、Refine、多次Validate测试样例推理)。仅一次性提示优化开销;推理阶段无额外开销。适合固定任务、需要反复大量推理的场景。
7 局限性
- 验证阶段生成的测试样例,依赖优化器LLM本身能力。如果优化器模型理解原始指令存在根本性错误,生成的测试用例是无效的,会误导优化;
- 测试样例数量有限(论文默认5个),可能存在漏检;增加样例可以提升校验可靠性,但成本上升;
- 长指令场景:当原始指令极长(上万token),Decompose阶段容易丢失细节;
- 提示优化的token开销在动态、一次性短时任务场景下性价比不高。
8 结论
本文提出PromptMatic多阶段提示优化框架,将提示优化拆分为分解、精炼、验证,支持验证失败回溯迭代。在IFEval、MATH、GSM8K、BBH基准上,显著优于单阶段提示优化基线。消融实验证明,独立验证测试用例是性能提升最关键组件。PromptMatic不需要模型微调,仅自动构造更好的提示词,提升大模型指令遵循能力。
资源清单
- HTML原文:https://arxiv.org/html/2609.09153v1
- PDF论文:https://arxiv.org/pdf/2609.09153
- 开源代码仓库:https://github.com/allenai/promptmatic
- 评测数据集:IFEval、MATH、GSM8K、BigBench Hard(BBH)
- 脚本说明:仓库包含完整PromptMatic流水线脚本、评估脚本、基线复现代码、实验配置yaml。
附录
附录A 完整Prompt模板
A.1 Decompose阶段系统提示
你是任务分解专家。给定用户原始指令,提取全部子任务、硬约束、输出格式规则。
输出结构化列表:
1. 子任务清单:逐条列出必须完成的动作;
2. 约束清单:所有硬性要求(禁止词、长度、格式、大小写等);
不要生成答案,只输出任务结构。
A.2 Refine阶段系统提示
基于原始用户指令 + 子任务与约束清单,编写高质量提示词。
提示词将直接交给大模型执行任务。把所有约束、子步骤、输出要求明确写进去。
保持清晰,减少歧义。
A.3 Validate阶段系统提示
基于原始指令生成若干测试输入样例。使用候选提示在样例上调用模型,
逐条检查模型输出是否满足全部子任务与约束。
返回:总分 + 失败样例 + 失败原因。
附录B 伪代码(PromptMatic核心脚本)
python
def promptmatic(original_instruction, max_iter=3, threshold=1.0):
candidate_prompt = None
for _ in range(max_iter):
# Stage1 Decompose
subtasks = decompose_llm(original_instruction)
# Stage2 Refine
prompt_candidate = refine_llm(original_instruction, subtasks)
# Stage3 Validate
score, failures = validate_llm(original_instruction, subtasks, prompt_candidate)
if score >= threshold:
candidate_prompt = prompt_candidate
break
# 把失败案例送入下一轮作为反馈
original_instruction = f"{original_instruction}\n\n历史失败案例:\n{failures}"
return candidate_prompt
附录C 评估细节
- IFEval:采用官方的多维度约束校验器,每个样本多个布尔约束,全部满足才算成功;
- MATH/GSM8K:使用标准答案解析脚本,提取数值对比;
- BBH:使用官方评测脚本,严格匹配答案;
- 全部实验重复3次,报告均值。

