news 2026/9/14 18:12:35

DeepEval 如何用 GEPA 运行提示词优化并解读 optimization_report

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
DeepEval 如何用 GEPA 运行提示词优化并解读 optimization_report

DeepEval 如何用 GEPA 运行提示词优化并解读 optimization_report

【免费下载链接】deepevalThe LLM Evaluation Framework项目地址: https://gitcode.com/GitHub_Trending/de/deepeval

如果你有几十个 golden 用例,但不确定当前 prompt 模板该往哪个方向改,DeepEval(The LLM Evaluation Framework)里的PromptOptimizer可以用 GEPA 算法自动完成这件事:你提供 prompt、golden 列表、评分指标和一个调用你 LLM 应用的model_callback,它会自动搜索得分更高的 prompt,并返回优化结果和一份optimization_report。本文基于 Prompt Optimization Introduction 和 GEPA 算法页/prompt-optimization-gepa.mdx),给出一条可以直接照做的执行路径,以及 report 各字段的读法。

准备条件:Prompt、Golden 与 model_callback

在跑优化之前,先确认三类东西齐了:

  • Promptdeepeval.prompt.Prompt实例,包含 prompt 模板(text_template)。
  • Goldens:一组GoldenConversationalGolden实例,作为优化的对照数据。
  • model_callback:包住你 LLM 应用的回调。优化过程中deepeval会把当前候选Prompt和一条Golden传进来,你用prompt.interpolate(input=golden.input)把 golden 的输入填进模板,再调用你的应用,必须返回str——这个字符串会作为 test case 的actual_output交给 metrics 打分。
from deepeval.dataset import Golden from deepeval.metrics import AnswerRelevancyMetric from deepeval.prompt import Prompt from deepeval.optimizer import PromptOptimizer # 你要优化的 prompt prompt = Prompt(text_template="Respond to the query.") # 包住你的 LLM 应用 async def model_callback(prompt: Prompt, golden: Golden) -> str: interpolated_prompt = prompt.interpolate(input=golden.input) res = await YourApp(interpolated_prompt) # 按你应用的实际调用方式 return res optimizer = PromptOptimizer(metrics=[AnswerRelevancyMetric()], model_callback=model_callback)

两个必填参数是metrics(用于打分和反馈的 deepeval 指标列表)和model_callback。可选参数包括algorithm(默认就是GEPA())、async_configdisplay_configmutation_config

执行步骤:用 GEPA 运行一次优化

GEPA 是PromptOptimizer的默认算法(algorithm默认值为GEPA()),所以不传algorithm就已经在用 GEPA。只有想调整它的行为时才需要显式构造:

optimized_prompt = optimizer.optimize( prompt=prompt, goldens=[ Golden(input="What is Saturn?", expected_output="Saturn is a car brand."), Golden(input="What is Mercury?", expected_output="Mercury is a planet."), ], ) # 查看优化结果 print("Optimized prompt:", optimized_prompt.text_template) print("Optimization report:", optimizer.optimization_report)

optimize()有两个必填参数:promptgoldens。注意metrics是在构造PromptOptimizer时传入的(见 PromptOptimizer 源码),GEPA 页面示例里把metrics写在optimize()调用参数里的写法与当前源码签名不一致,以构造函数传参为准。

在 Python 环境中执行:

python main.py

optimize()返回最优Prompt。如果想并发运行而不阻塞主线程,文档提供了异步入口a_optimize():在 async 函数里await optimizer.a_optimize(...),再用asyncio.run驱动。

可选:自定义 GEPA 参数

需要控制搜索行为时,构造GEPA实例并传给algorithm

from deepeval.optimizer.algorithms import GEPA gepa = GEPA( iterations=10, pareto_size=5, minibatch_size=4, patience=4, random_seed=42, ) optimizer = PromptOptimizer(algorithm=gepa, metrics=[...], model_callback=model_callback)

文档列出的可选参数及默认值:

参数默认值文档说明
iterations5变异尝试总次数
pareto_size3验证集D_pareto中的 golden 数,每个候选都会在这批 golden 上评分以保证公平比较
minibatch_size8每次迭代从D_feedback抽取的 golden 数,自动按可用数据截断
patience3连续拒绝该次数子代后提前停止
random_seedtime.time_ns()控制 golden 切分、minibatch 抽样、Pareto 父代选择与平局判定;固定如42才能复现
tie_breakerPREFER_CHILD平局策略,另有PREFER_ROOTRANDOM
aggregate_instancesmean_of_all把单个 prompt 的 per-golden Pareto 分数聚合成标量
reflection_model"gpt-4o-mini"生成诊断/反馈的 LLM
mutation_model"gpt-4o"重写 prompt 的 LLM
scorer自定义 scorer,通常由PromptOptimizer注入

默认random_seedtime.time_ns(),即不固定种子时每次运行结果都会不同;需要可复现的运行就固定random_seed

可选:限流配置

如果你的评测模型或 LLM 应用会触发 rate limit,给PromptOptimizerAsyncConfig

from deepeval.optimizer.configs import AsyncConfig optimizer = PromptOptimizer( metrics=[AnswerRelevancyMetric()], model_callback=model_callback, async_config=AsyncConfig(throttle_value=2, max_concurrent=5), )

throttle_value(每个 test case 的节流秒数,默认 0)和max_concurrent(并行 test case 数上限,默认 20)只在run_asyncTrue(默认)时生效。降低max_concurrent、调高throttle_value是文档推荐的限流手段。

GEPA 做了什么:理解 report 之前先懂流程

GEPA(Genetic-Pareto)不是收敛到单个“最好”的 prompt,而是维护一个多样化候选池,流程分五步:

  1. Golden 切分:把 goldens 切成互不相交的两部分——固定的验证集D_pareto(大小pareto_size)和反馈集D_feedback。prompt 基于D_feedback的反馈变异,但按D_pareto上的表现挑选,避免过拟合。
  2. Pareto 父代选择:一个 prompt 若在D_pareto上所有 golden 都不劣、至少一个更优,就“支配”另一个 prompt;不被任何 prompt 支配的构成 Pareto 前沿。父代按各 prompt“赢得最高分”的频率加权抽样,而不是总是选平均分最高的。
  3. 反馈与重写:从D_feedback抽一个 minibatch,收集诊断反馈,基线打分,再用 rewriter 生成子代 prompt。
  4. 双门验收:子代必须先在同一个 minibatch 上严格超过父代(minibatch gate),再在D_pareto上相对父代和存档内所有配置都非支配(Pareto gate)。被拒会累加连续拒绝计数,达到patience就提前结束。
  5. 终选:按聚合分数(默认均值)排名,平局由tie_breaker决定,返回获胜 prompt。

结果验证与解读 optimization_report

优化跑完后,验证路径有两条:

  1. 拿到新 promptoptimized_prompt.text_template(LIST 风格 prompt 是messages_template)就是可以直接替换线上模板的结果;DisplayConfig.show_indicator默认为True,控制台还会打印算法生成的 summary 表格。
  2. optimization_report:它挂在PromptOptimizer实例上(优化结束后赋值,见 prompt_optimizer.py):
print(optimizer.optimization_report) print(optimizer.optimization_report.optimization_id)

report 共暴露六个顶层字段(定义见 gepa.py 中 report 的组装):

字段类型怎么解读
optimization_idstr本次运行的唯一标识,文档建议在多数工作流中把它记录进日志,方便回溯
best_idstr最终获胜 prompt 配置的内部 id
accepted_iterationsList[AcceptedIteration]每个被接受的子代一条记录:parent/child的 id、moduleid,以及标量化的before/after分数——这是判断“哪一步改进有效”的直接依据
pareto_scoresDict[str, List[float]]每个配置 id 到D_pareto上逐 golden 分数列表的映射,即 GEPA 维持 Pareto 前沿所用的分数表
parentsDict[str, Optional[str]]每个配置 id 到其父 id 的映射,根配置对应None,构成所有被探索变体的祖先树
prompt_configurationsDict[str, PromptConfigSnapshot]每个配置 id 到该节点 prompt 快照的映射,含父 id 和逐模块的 TEXT/LIST prompt 内容

实际读法:大多数时候直接取optimized_prompt.text_template并使用即可。需要深入时,用best_idprompt_configurations里找到获胜节点的完整 prompt 文本;用parents沿祖先链回溯它的演化路径;用accepted_iterations里各条记录的before/after确认每一步被接受时分数确实提升了;pareto_scores则告诉你获胜 prompt 是在哪些 golden 上强、哪些上弱。文档明确说这些字段适合“重建搜索树、可视化 prompt 跨迭代演化、调试某个配置为何被选为best_id”这类场景。

早停与其他运行现象

  • 若某轮子代被 Pareto gate 拒绝,会累计连续拒绝计数;计数达到patience(默认 3)时搜索提前停止,不会跑满全部iterations(默认 5)。运行中如果看到类似early stop (patience=3)的状态说明,即触发了这条路径。
  • DisplayConfig.announce_ties默认为False;设为True后,GEPA 检测到配置间平局时会打印一行提示。
  • 优化开始前如果发生错误(如model_callback内部抛错),PromptOptimizer会以DeepEvalError中断并在状态行给出[GEPA] ... halted形式的信息(见 错误处理逻辑),此时检查你的 callback 是否正确调用了 LLM 应用并返回字符串。

限制与注意事项

  • 文档只覆盖了PromptOptimizer的 Python 用法,未提供命令行或离线批处理入口,主路径就是上述脚本形式。
  • 两个 LLM 分工不同:reflection_model(默认gpt-4o-mini)负责诊断,mutation_model(默认gpt-4o)负责重写,两者都可以在GEPA(...)构造时覆盖。
  • goldens 会被切成D_paretoD_feedback两份互斥集合,minibatch_size超出D_feedback可用量时会自动截断;因此 golden 数量太少时反馈信号会受限。
  • a_optimize()optimize()是同步/异步两种入口,二选一即可,不要在同步上下文里嵌套再调asyncio.run

跑通一次后,optimized_promptoptimization_report就是本次任务的完整产出:前者用于替换模板,后者(尤其optimization_idbest_idaccepted_iterations)用于归档和复盘这次搜索为什么收敛到该 prompt。

【免费下载链接】deepevalThe LLM Evaluation Framework项目地址: https://gitcode.com/GitHub_Trending/de/deepeval

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/14 18:12:29

静态分析突破变种UPX脱壳:原理与实践

1. 项目概述:UPX脱壳的困境与突破逆向工程领域里,UPX作为老牌压缩壳一直以其高压缩比和开源特性著称。但近年来出现的变种UPX壳让不少逆向分析人员头疼——传统动态调试方法不仅需要搭建复杂环境,还经常遇到反调试陷阱。我在分析某金融类恶意…

作者头像 李华
网站建设 2026/9/14 18:11:17

MyBatis-Plus多数据源配置实战与优化

1. 多数据源配置的核心价值与应用场景在真实的企业级应用开发中,单数据源往往难以满足复杂的业务需求。我经历过多个需要同时对接Oracle财务库和MySQL业务库的项目,也处理过读写分离场景下的数据一致性问题。MyBatis-Plus的多数据源方案之所以备受青睐&a…

作者头像 李华
网站建设 2026/9/14 18:11:12

测试转产品经理:从质量防线到产品决策的升维指南

干了六年测试,转型产品经理半年,回头再看这段职业跃迁,我想说一句可能有点得罪人的话:测试转产品经理,根本不是跨界,更像是被埋没的潜力股终于找到正确打开方式。你要是现在正在测项目、写用例、跑自动化、…

作者头像 李华
网站建设 2026/9/14 18:09:25

C++初赛模拟卷精讲:从基础语法到算法思维的全方位考点解析

1. 卷面设计与考点分布分析1.1 这套模拟卷的定位这几年我带选手备赛全国青少年信息素养大赛算法应用主题赛,最大的感受就是:初赛不仅要考“会不会写代码”,更考验选手在限定时间内能不能快速判断考点、避开常见坑。C赛项的初赛模拟卷&#xf…

作者头像 李华