首页
/ Prompt Optimization Guide:在 agents24 中构建可度量的 LLM Prompt 优化工程体系

Prompt Optimization Guide:在 agents24 中构建可度量的 LLM Prompt 优化工程体系

2026-09-09 14:01:13作者:董灵辛Dennis

本指南以 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_accuracyavg_latencyp95_latencyavg_tokenssuccess_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.pymake_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.mdPromptMetrics 类中找到:

  • 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_accuracyavg_consistencyp95_latencyavg_tokenssuccess_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 实验的指标快照一并提交,保证"任何版本都可复现"。

八条最佳实践

参考文档总结了八条优化实践,这里结合仓库证据逐条说明落地方式:

  1. 建立基线(Establish Baseline):改动前必测,否则无法判断改进是否真实。对应 optimize-prompt.pyoptimize 方法对当前 prompt 的首次评估。
  2. 一次只改一件事(Change One Thing):隔离变量才能准确归因,防止多个改动互相抵消或叠加放大。
  3. 充分测试(Test Thoroughly):使用多样、有代表性的测试集。参考 prompt-optimize.md 的测试协议建议:20 个用例中 10 个典型、5 个边界、3 个对抗性、2 个越界场景。
  4. 记录指标(Track Metrics):日志化每次实验的 prompt 与指标。脚本通过 results_historyexport_results(导出 JSON)实现。
  5. 验证显著性(Validate Significance):A/B 对比必须用统计检验(t 检验、p < 0.05),见前文 PromptABTest
  6. 记录变更(Document Changes):写清"改了什么、为什么改",SKILL.md 的最佳实践第 8 条"Document Intent"与此一致。
  7. 全部版本化(Version Everything):保证任何时刻可回滚,见 PromptVersionControl
  8. 监控生产(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 仓库中,这些能力被组织为一条完整的落地链路:

  1. 技能入口:通过 SKILL.md/prompt-engineering-patterns 技能(描述中明确覆盖 "optimize a prompt"、"improve prompt performance" 等触发词)调用整套方法论。
  2. 命令入口:通过 llm-application-dev 插件的 /prompt-optimize 命令(见 prompt-optimize.md),传入 prompt 文本或文件,按"分析现状 → CoT 增强 → Few-shot 植入 → Constitutional AI 自审 → 模型特化 → RAG 集成 → 评估框架 → 生产部署"八步流水线产出生产级 prompt 与优化报告。
  3. 脚本验证:用 optimize-prompt.py 对候选 prompt 做自动化迭代与 A/B 比较,compare_prompts 方法可直接输出两个 prompt 的胜者与改进幅度。
  4. 模板与示例复用:从 prompt-template-library.md(分类、抽取、生成、转换、分析、问答、SQL 等全套模板)与 few-shot-examples.json 快速起步。

需要说明的是,本文介绍的方法论与脚本均以"评估与优化 prompt 本身"为边界:所有流程都围绕测试、度量、版本化展开,不涉及修改仓库内容。实际使用时,将上述工具集成到自己的 LLM 应用开发流水线中,即可把 prompt 从"一次性文案"升级为"可持续迭代的工程资产"。

结语

Prompt 优化不是玄学,而是一套可度量的工程流程:用基线回答"现在怎么样",用迭代与 A/B 测试回答"改完是否更好",用失败分析回答"该改哪里",用版本控制回答"改坏了怎么办"。本文的四个优化模式、四大核心指标与八条最佳实践,加上 optimize-prompt.py 的可运行脚本,构成了一个开箱即用的最小优化闭环——建议从为自己的一个生产 prompt 建立基线开始,逐步把这套体系落地为团队的标准化流程。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
docsdocs
暂无描述
Markdown
899
5.83 K
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.76 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
860
1.35 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
925
1.85 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.84 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
533
601
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.37 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
395
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.04 K
525