Prompt Optimization Guide:在 agents24 中构建可度量的 LLM Prompt 优化工程体系
本指南以 llm-application-dev 插件的 prompt-engineering-patterns 技能中的 prompt-optimization.md 为骨架,系统讲解如何把"写 prompt"升级为"工程化优化 prompt":从建立基线、迭代优化、A/B 测试,到 Token/延迟/准确率三类优化策略、性能指标体系、失败分析与版本回滚。读者将掌握一套可复制、可量化的 Prompt 优化方法论,并结合仓库内的可运行脚本 optimize-prompt.py 与 /prompt-optimize 命令在实际项目中落地。
为什么需要系统化的 Prompt 优化
在 agents24 仓库的 LLM 应用开发生态中,prompt-engineer 智能体的核心职责之一就是"基于经验性能数据系统性迭代"并"强调 Prompt 系统的可复现性与版本控制"。单纯的"凭感觉改 prompt"无法回答三个关键问题:
- 改动是否真的带来了提升,还是随机波动?
- 优化是否同时损害了延迟、成本(Token 数)或一致性?
- 出问题时能否回滚到上一个可用版本?
prompt-optimization.md 给出的答案是一套完整闭环:建立基线 → 迭代优化 → A/B 验证 → 失败分析 → 版本管理。这套流程在该技能中被定义为四大核心能力之一(Iterative refinement workflows、A/B testing prompt variations、Measuring prompt performance metrics、Reducing token usage while maintaining quality),见 SKILL.md。
系统性优化流程
1. 基线建立:没有基线就没有优化
优化的第一步永远是在未改动的 prompt 上测量当前表现,作为后续所有迭代的对照基准。参考 prompt-optimization.md 中的 establish_baseline:
def establish_baseline(prompt, test_cases):
results = {
'accuracy': 0,
'avg_tokens': 0,
'avg_latency': 0,
'success_rate': 0
}
for test_case in test_cases:
response = llm.complete(prompt.format(**test_case['input']))
results['accuracy'] += evaluate_accuracy(response, test_case['expected'])
results['avg_tokens'] += count_tokens(response)
results['avg_latency'] += measure_latency(response)
results['success_rate'] += is_valid_response(response)
# Average across test cases
n = len(test_cases)
return {k: v/n for k, v in results.items()}
基线函数的四个维度对应了仓库脚本中实际被跟踪的指标。在 optimize-prompt.py 的可运行实现里,evaluate_prompt 通过 ThreadPoolExecutor 并行跑测试用例,聚合出 avg_accuracy、avg_latency、p95_latency、avg_tokens、success_rate 五个指标(见该文件的 PromptOptimizer.evaluate_prompt 方法):
return {
'avg_accuracy': np.mean(metrics['accuracy']),
'avg_latency': np.mean(metrics['latency']),
'p95_latency': np.percentile(metrics['latency'], 95),
'avg_tokens': np.mean(metrics['token_count']),
'success_rate': np.mean(metrics['success_rate'])
}
注意脚本中的 calculate_accuracy 采用了混合匹配策略:先做精确匹配(忽略大小写的字符串相等),若失败则退化为词重叠率(response 词集合与 expected 词集合的交集除以 expected 词数)。这是基线评估中值得借鉴的实用技巧——LLM 输出极少逐字命中,需要容忍同义表达。
2. 迭代优化工作流
优化的核心循环可以用一个流程表示:
Initial Prompt → Test → Analyze Failures → Refine → Test → Repeat
参考文档中的 PromptOptimizer 类给出了循环的完整逻辑:
class PromptOptimizer:
def __init__(self, initial_prompt, test_suite):
self.prompt = initial_prompt
self.test_suite = test_suite
self.history = []
def optimize(self, max_iterations=10):
for i in range(max_iterations):
# Test current prompt
results = self.evaluate_prompt(self.prompt)
self.history.append({
'iteration': i,
'prompt': self.prompt,
'results': results
})
# Stop if good enough
if results['accuracy'] > 0.95:
break
# Analyze failures
failures = self.analyze_failures(results)
# Generate refinement suggestions
refinements = self.generate_refinements(failures)
# Apply best refinement
self.prompt = self.select_best_refinement(refinements)
return self.get_best_prompt()
该设计有两个工程要点:
- 历史留痕:每一轮迭代的 prompt 与指标都被追加进
history,这为事后回溯"哪个改动带来了提升"提供了数据依据。 - 提前终止:当准确率超过 0.95 时立即停止,避免为边际收益浪费 Token 与时间。
仓库中的 optimize-prompt.py 将这一概念落地为可执行版本(PromptOptimizer.optimize,默认 max_iterations=5),并加入了两个真实工程中必须考虑的优化点:
- 变体生成:
generate_variations会生成最多 3 种 prompt 变体——追加格式指令、追加"step by step"指令、追加验证步骤、精简措辞、补充示例——然后逐一评估并挑选准确率最高的变体继续迭代。 - 提前收敛:如果所有变体都不优于当前 prompt(
best_variation == current_prompt),立即停止优化,避免对确定性生成的相同变体做重复的无效评估。
脚本内置了演示用例(main() 中的情感分类测试集与 MockLLMClient),直接运行 python scripts/optimize-prompt.py 即可观察完整的优化过程,并将结果导出为 optimization_results.json。
3. A/B 测试框架:让改进经得起统计检验
单次指标上升可能是偶然。参考文档提供了基于 50/50 随机分流与独立样本 t 检验的 A/B 框架:
class PromptABTest:
def __init__(self, variant_a, variant_b):
self.variant_a = variant_a
self.variant_b = variant_b
def run_test(self, test_queries, metrics=['accuracy', 'latency']):
results = {
'A': {m: [] for m in metrics},
'B': {m: [] for m in metrics}
}
for query in test_queries:
# Randomly assign variant (50/50 split)
variant = 'A' if random.random() < 0.5 else 'B'
prompt = self.variant_a if variant == 'A' else self.variant_b
response, metrics_data = self.execute_with_metrics(
prompt.format(query=query['input'])
)
for metric in metrics:
results[variant][metric].append(metrics_data[metric])
return self.analyze_results(results)
def analyze_results(self, results):
from scipy import stats
analysis = {}
for metric in results['A'].keys():
a_values = results['A'][metric]
b_values = results['B'][metric]
# Statistical significance test
t_stat, p_value = stats.ttest_ind(a_values, b_values)
analysis[metric] = {
'A_mean': np.mean(a_values),
'B_mean': np.mean(b_values),
'improvement': (np.mean(b_values) - np.mean(a_values)) / np.mean(a_values),
'statistically_significant': p_value < 0.05,
'p_value': p_value,
'winner': 'B' if np.mean(b_values) > np.mean(a_values) else 'A'
}
return analysis
这套框架的关键设计值得展开:
- 随机分流:每条查询独立以 50% 概率落入 A 或 B 变体,保证两组查询分布可比。
- p 值门槛:以
p_value < 0.05作为显著性判定,只有"统计上显著"的提升才被采纳——这正是 SKILL.md 中"Validate Significance: Use statistical tests for A/B comparisons"最佳实践的实现。 - 相对改进率:
improvement以 (B 均值 − A 均值) / A 均值计算,可跨指标对比投入产出。
该技能的姊妹文档 few-shot-learning.md 中还提供了针对"示例集合"本身的 A/B 测试(ExampleSetTester.compare_example_sets),说明同一套统计思路可以复用到优化流程的各个环节。在生产部署层面,prompt-optimize.md 命令进一步给出了发布策略:金丝雀 5% → 分阶段 10/25/50/100% → 24 小时监控期 → 以 0.8 为回滚阈值(见该命令的 rollout_strategy)。
三大优化策略
Token 缩减:直接降低延迟与成本
Token 是 LLM 调用的计费单位,精简 prompt 等于同时优化成本与延迟。参考文档提供了可机械执行的替换规则:
def optimize_for_tokens(prompt):
optimizations = [
# Remove redundant phrases
('in order to', 'to'),
('due to the fact that', 'because'),
('at this point in time', 'now'),
# Consolidate instructions
('First, ...\nThen, ...\nFinally, ...', 'Steps: 1) ... 2) ... 3) ...'),
# Use abbreviations (after first definition)
('Natural Language Processing (NLP)', 'NLP'),
# Remove filler words
(' actually ', ' '),
(' basically ', ' '),
(' really ', ' ')
]
optimized = prompt
for old, new in optimizations:
optimized = optimized.replace(old, new)
return optimized
同样的思路出现在仓库脚本 optimize-prompt.py 的 make_concise 方法中,且额外包含一条 ('in the event that', 'if') 规则。参考文档 details.md 的 "Token Efficiency" 一节给出了直观的对比:一段 150+ token 的冗长摘要指令可以压缩为约 30 token 的版本:
# After: Concise prompt (30 tokens)
concise_prompt = """Summarize the key points concisely:
{text}
Summary:"""
更激进的 Token 优化手段是提示缓存。对重复使用的系统 prompt,details.md 展示了通过 cache_control: {"type": "ephemeral"} 复用长系统提示的写法,避免每次请求都重新计费这段稳定前缀。
延迟降低:多策略并行验证
参考文档把延迟优化拆成四种可独立开关的策略,并强调"逐个测试、取最优":
def optimize_for_latency(prompt):
strategies = {
'shorter_prompt': reduce_token_count(prompt),
'streaming': enable_streaming_response(prompt),
'caching': add_cacheable_prefix(prompt),
'early_stopping': add_stop_sequences(prompt)
}
# Test each strategy
best_strategy = None
best_latency = float('inf')
for name, modified_prompt in strategies.items():
latency = measure_average_latency(modified_prompt)
if latency < best_latency:
best_latency = latency
best_strategy = modified_prompt
return best_strategy
四种策略的适用场景各不相同:
- shorter_prompt:减少输入长度,直接影响首 token 时间与总延迟。
- streaming:流式输出让用户感知延迟大幅下降(虽不改变总耗时,但提升体验)。
- caching:对稳定前缀(如系统提示)使用缓存,跳过重复的预填充计算。
- early_stopping:通过 stop 序列(如
\n\n、###或特定结束标记)让模型在任务完成后立即停止,避免输出冗余尾部内容。
注意参考文档中的"改词穷举"写法偏教学化——真实工程中应以 measure_average_latency 为基准多次采样求均值(对应脚本中的 p95_latency 指标),因为单次延迟波动很大。这与 SKILL.md 中"Latency: Response time (P50, P95, P99)"的成功指标口径一致。
准确率提升:针对失败模式定向修复
准确率提升不应靠盲目堆砌指令,而要"对症下药"。参考文档给出了按失败类型定向追加约束的策略:
def improve_accuracy(prompt, failure_cases):
improvements = []
# Add constraints for common failures
if has_format_errors(failure_cases):
improvements.append("Output must be valid JSON with no additional text.")
# Add examples for edge cases
edge_cases = identify_edge_cases(failure_cases)
if edge_cases:
improvements.append(f"Examples of edge cases:\n{format_examples(edge_cases)}")
# Add verification step
if has_logical_errors(failure_cases):
improvements.append("Before responding, verify your answer is logically consistent.")
# Strengthen instructions
if has_ambiguity_errors(failure_cases):
improvements.append(clarify_ambiguous_instructions(prompt))
return integrate_improvements(prompt, improvements)
该方法与仓库脚本的 generate_variations 形成了互补:脚本侧重"穷举常见增强模板",参考文档侧重"基于失败证据的选择性增强"。实际工程中应当把两者结合——先用失败分析定位问题类别,再选择对应的增强手段,避免一次性叠加过多约束导致模型行为漂移。这也呼应了最佳实践中"Change One Thing"(一次只改一个变量)的原则。
性能指标体系
核心指标定义
参考文档定义了四个最常用的核心指标,其实现可在 prompt-optimization.md 的 PromptMetrics 类中找到:
- accuracy(准确率):
sum(r == gt) / len(responses),简单精确匹配;实际使用时可参照 optimize-prompt.py 的词重叠降级策略。 - consistency(一致性):统计"相同输入得到相同输出"的比例——将相同输入的多次响应归组,计算每组中出现频率最高响应的占比,再对所有组取平均。这是衡量 prompt 稳定性的关键指标,对应 SKILL.md 中"Consistency: Reproducibility across similar inputs"。
- token_efficiency(Token 效率):
平均 prompt Token + 平均响应 Token,直接反映单请求成本。 - latency_p95(P95 延迟):
np.percentile(latencies, 95),用分位数而非平均值刻画尾部延迟,避免被少数慢请求掩盖真实体验。
自动化综合评估
单指标评估会掩盖维度间的权衡,参考文档提供了多指标综合评估函数 evaluate_prompt_comprehensively。其核心设计是每个测试用例跑 3 次,从而在一次评估中同时得到:
- accuracy:取 3 次运行中的最佳准确率(
max(accuracies)),衡量"模型有能力做对"; - consistency:通过 3 次响应间的相似度(
calculate_similarity)衡量稳定性; - success_rate:要求 3 次全部有效(
all(is_valid(r) for r in runs)),衡量可靠性; - latency 与 tokens:逐次记录后聚合,最终输出
avg_accuracy、avg_consistency、p95_latency、avg_tokens、success_rate五个汇总值。
这种"多轮采样"设计值得在实际评测中沿用:3 次采样是成本与统计意义之间的务实折中。
失败分析:优化的起点
优化本质上是对失败的修复。参考文档提供的 FailureAnalyzer 将失败分为六类:format_errors(格式错误)、factual_errors(事实错误)、logic_errors(逻辑错误)、incomplete_responses(回答不完整)、hallucinations(幻觉)、off_topic(跑题),并为每类失败给出带优先级的修复建议:
class FailureAnalyzer:
def categorize_failures(self, test_results):
categories = {
'format_errors': [],
'factual_errors': [],
'logic_errors': [],
'incomplete_responses': [],
'hallucinations': [],
'off_topic': []
}
for result in test_results:
if not result['success']:
category = self.determine_failure_type(
result['response'],
result['expected']
)
categories[category].append(result)
return categories
def generate_fixes(self, categorized_failures):
fixes = []
if categorized_failures['format_errors']:
fixes.append({
'issue': 'Format errors',
'fix': 'Add explicit format examples and constraints',
'priority': 'high'
})
if categorized_failures['hallucinations']:
fixes.append({
'issue': 'Hallucinations',
'fix': 'Add grounding instruction: "Base your answer only on provided context"',
'priority': 'critical'
})
if categorized_failures['incomplete_responses']:
fixes.append({
'issue': 'Incomplete responses',
'fix': 'Add: "Ensure your response fully addresses all parts of the question"',
'priority': 'medium'
})
return fixes
其中的优先级设计(幻觉为 critical、格式错误为 high、不完整为 medium)揭示了优化优先级判断:正确性 > 格式 > 完整性。与失败分类配套,参考文档 few-shot-learning.md 提供了"错误导向的示例选择"(ErrorGuidedSelector)——针对已知失败模式挑选展示正确处理的示例加入 prompt,与这里的 generate_fixes 形成前后衔接:先分类失败,再选择是"加约束"还是"加示例"来修复。
版本控制与回滚
Prompt 是软件资产,必须像代码一样被版本管理。参考文档的 PromptVersionControl 是这一思想的朴素实现:
class PromptVersionControl:
def __init__(self, storage_path):
self.storage = storage_path
self.versions = []
def save_version(self, prompt, metadata):
version = {
'id': len(self.versions),
'prompt': prompt,
'timestamp': datetime.now(),
'metrics': metadata.get('metrics', {}),
'description': metadata.get('description', ''),
'parent_id': metadata.get('parent_id')
}
self.versions.append(version)
self.persist()
return version['id']
def rollback(self, version_id):
if version_id < len(self.versions):
return self.versions[version_id]['prompt']
raise ValueError(f"Version {version_id} not found")
def compare_versions(self, v1_id, v2_id):
v1 = self.versions[v1_id]
v2 = self.versions[v2_id]
return {
'diff': generate_diff(v1['prompt'], v2['prompt']),
'metrics_comparison': {
metric: {
'v1': v1['metrics'].get(metric),
'v2': v2['metrics'].get(metric),
'change': v2['metrics'].get(metric, 0) - v1['metrics'].get(metric, 0)
}
for metric in set(v1['metrics'].keys()) | set(v2['metrics'].keys())
}
}
该类的三个方法对应版本管理的三个核心诉求:
- save_version:为每个版本记录 prompt、时间戳、关联指标与描述,
parent_id字段支持追溯演化树(哪个版本源自哪个版本); - rollback:按版本号直接取回旧 prompt,是线上事故时的救命机制;
- compare_versions:同时输出文本 diff 与指标对比,让"改了什么"与"效果如何"一一对应。
在更完整的工程形态中,prompt-optimize.md 命令展示了版本化发布的标准做法(PromptVersion 类的 rollout_strategy):语义化版本号、金丝雀/分阶段发布、回滚阈值与监控周期。在生产环境,建议直接使用 Git 管理 prompt 文件,并把每次 A/B 实验的指标快照一并提交,保证"任何版本都可复现"。
八条最佳实践
参考文档总结了八条优化实践,这里结合仓库证据逐条说明落地方式:
- 建立基线(Establish Baseline):改动前必测,否则无法判断改进是否真实。对应 optimize-prompt.py 中
optimize方法对当前 prompt 的首次评估。 - 一次只改一件事(Change One Thing):隔离变量才能准确归因,防止多个改动互相抵消或叠加放大。
- 充分测试(Test Thoroughly):使用多样、有代表性的测试集。参考 prompt-optimize.md 的测试协议建议:20 个用例中 10 个典型、5 个边界、3 个对抗性、2 个越界场景。
- 记录指标(Track Metrics):日志化每次实验的 prompt 与指标。脚本通过
results_history与export_results(导出 JSON)实现。 - 验证显著性(Validate Significance):A/B 对比必须用统计检验(t 检验、p < 0.05),见前文
PromptABTest。 - 记录变更(Document Changes):写清"改了什么、为什么改",SKILL.md 的最佳实践第 8 条"Document Intent"与此一致。
- 全部版本化(Version Everything):保证任何时刻可回滚,见
PromptVersionControl。 - 监控生产(Monitor Production):上线后持续评估,SKILL.md 列出的 KPI(Accuracy、Consistency、Latency、Token Usage、Success Rate)即为生产监控的最小指标集。
四个高杠杆优化模式
参考文档给出四个立即可用的模式化改写,是"从差 prompt 到好 prompt"的最短路径:
模式 1:加结构(Add Structure)
Before: "Analyze this text"
After: "Analyze this text for:\n1. Main topic\n2. Key arguments\n3. Conclusion"
把开放式任务拆成编号子任务,明确输出骨架,显著降低跑题率。
模式 2:加示例(Add Examples)
Before: "Extract entities"
After: "Extract entities\n\nExample:\nText: Apple released iPhone\nEntities: {company: Apple, product: iPhone}"
"展示优于描述"(Show, Don't Tell)。仓库为此提供了开箱即用的示例库 few-shot-examples.json,涵盖情感分类、实体抽取、代码生成、文本分类、数据转换、问答、摘要、SQL 生成八类任务,可直接粘贴复用。
模式 3:加约束(Add Constraints)
Before: "Summarize this"
After: "Summarize in exactly 3 bullet points, 15 words each"
约束越具体,输出越可控。约束可以是数量(3 条要点)、长度(每点 15 词)、格式(JSON、YAML)或语气。
模式 4:加验证(Add Verification)
Before: "Calculate..."
After: "Calculate... Then verify your calculation is correct before responding."
强制模型自我校验,可有效拦截算术错误与逻辑漏洞。该模式在 details.md 中被扩展为完整的 "Chain-of-Thought with Self-Verification" 模板——要求模型按 ## Steps → ## Answer → ## Verification 三段式输出,并在脚本 optimize-prompt.py 的变体生成中作为固定策略之一("Verify your answer before responding.")。
工具链与落地建议
参考文档末尾列出了优化工作所需的基础工具:prompt diff 工具、自动化测试运行器、指标看板、A/B 测试框架、Token 计数工具、延迟分析器。在 agents24 仓库中,这些能力被组织为一条完整的落地链路:
- 技能入口:通过 SKILL.md 的
/prompt-engineering-patterns技能(描述中明确覆盖 "optimize a prompt"、"improve prompt performance" 等触发词)调用整套方法论。 - 命令入口:通过
llm-application-dev插件的/prompt-optimize命令(见 prompt-optimize.md),传入 prompt 文本或文件,按"分析现状 → CoT 增强 → Few-shot 植入 → Constitutional AI 自审 → 模型特化 → RAG 集成 → 评估框架 → 生产部署"八步流水线产出生产级 prompt 与优化报告。 - 脚本验证:用 optimize-prompt.py 对候选 prompt 做自动化迭代与 A/B 比较,
compare_prompts方法可直接输出两个 prompt 的胜者与改进幅度。 - 模板与示例复用:从 prompt-template-library.md(分类、抽取、生成、转换、分析、问答、SQL 等全套模板)与 few-shot-examples.json 快速起步。
需要说明的是,本文介绍的方法论与脚本均以"评估与优化 prompt 本身"为边界:所有流程都围绕测试、度量、版本化展开,不涉及修改仓库内容。实际使用时,将上述工具集成到自己的 LLM 应用开发流水线中,即可把 prompt 从"一次性文案"升级为"可持续迭代的工程资产"。
结语
Prompt 优化不是玄学,而是一套可度量的工程流程:用基线回答"现在怎么样",用迭代与 A/B 测试回答"改完是否更好",用失败分析回答"该改哪里",用版本控制回答"改坏了怎么办"。本文的四个优化模式、四大核心指标与八条最佳实践,加上 optimize-prompt.py 的可运行脚本,构成了一个开箱即用的最小优化闭环——建议从为自己的一个生产 prompt 建立基线开始,逐步把这套体系落地为团队的标准化流程。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0631
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
video-shotcraftAI宣传片skill,使用 Remotion 制作电影级产品视频:提供106 张镜头配方卡和可复用的视频魔板。适用于 Claude Code 与 Codex以及所有其他智能体Markdown00
HivisionIDPhotos⚡️HivisionIDPhotos: a lightweight and efficient AI ID photos tools. 一个轻量级的AI证件照制作算法。Python09
DragonOSDragonOS is an operating system developed from scratch using Rust, with Linux compatibility. It is designed for **Serverless** scenarios. 使用Rust从0自研内核,具有Linux兼容性的操作系统,面向云计算Serverless场景而设计。Rust00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00