如果你正在用 Opik 做 LLM 评测和优化,那么迟早会遇到一组看起来很技术、但实际上并不难理解的概念:Optimizer、Candidate、Metric、Optimization Run、Trial、Round,还有 Prompt model 和 Optimizer model。它们像是同一台机器上的不同零件,单独看可能有点抽象,串起来之后就会发现,整套流程其实非常直观。
这篇文章不打算堆砌术语,而是从实际使用的角度,把 Opik Agent Optimizer 的核心概念讲清楚。无论你是刚接触 Prompt 优化,还是已经跑过几轮优化实验,都可以把它当作一份"概念地图",随时回来查漏补缺。

一、先弄明白:Agent Optimization 和 Prompt Optimization 是什么
在 Opik 里,Agent Optimization 指的是一个系统化的过程:不断改进和评估基于语言模型的应用程序,包括它的 Prompt、配置以及整体设计,目的是让性能尽可能好。它不是"改一次 Prompt 就完事",而是一个迭代循环:持续测试、用数据驱动调整、结合更高级的评估技术,一轮一轮把效果推上去。
而 Prompt Optimization 是 Agent Optimization 中非常关键的一个子集。它关注的东西更聚焦:如何改进给大语言模型(LLM)的指令,也就是 Prompt,让模型输出更准确、更稳定、更高效。因为 Prompt 是我们和 LLM 交互、引导 LLM 的主要方式,所以优化 Prompt 几乎是提升任何 LLM 应用或 Agent 的基础功。
Opik Agent Optimizer 同时支持这两件事:
- 直接优化单个 Prompt 字符串;
- 优化更复杂的 Agent 结构,比如包含多个 Prompt、Few-shot 示例、工具调用的场景。
换句话说,它既能帮你"把一句话写得更好",也能帮你"把一整套多步骤的智能体流程调得更顺"。
二、关键术语拆解:每个零件到底干什么
下面这些术语,是理解 Opik Agent Optimizer 的核心。我们一个一个来看。
1. Optimizer:优化算法本身
Optimizer 是 Opik Agent Optimizer SDK 里的专门算法,用来提升 Prompt 的效果。每个 Optimizer 都有自己的策略和可配置参数,面向不同的优化目标。
目前常见的 Optimizer 包括:
- MetaPromptOptimizer:通过元提示的方式改进 Prompt;
- FewShotBayesianOptimizer:结合 Few-shot 示例和贝叶斯方法进行优化;
- EvolutionaryOptimizer:用进化式策略,多代迭代筛选更优候选;
- HRPO(Hierarchical Adaptive Optimizer):分层自适应优化,适合更复杂的结构。
你可以把它们理解成不同的"教练"。有的教练擅长抠细节,有的教练擅长从大量样本里找规律,有的教练则喜欢让多个方案互相竞争、优胜劣汰。选择哪个 Optimizer,取决于你的任务类型、数据量和优化目标。
2. ChatPrompt:被优化的对象
ChatPrompt 是你要优化的对象。它包含你的聊天消息,以及一些变量占位符。这些占位符会在每个样本上被替换成不同的值。
比如,一个客服机器人的 ChatPrompt 可能是这样的:
- System:你是一个专业的客服助手,请根据用户问题给出准确回答。
- User:{{user_question}}
这里的 {``{user_question}} 就是变量占位符。每次拿一条数据来评估时,它都会被替换成真实问题。ChatPrompt 的好处是,它把"固定的指令"和"变化的数据"分开了,优化器只需要关注指令部分,而不必重新发明整个交互结构。
更多细节可以参考 API Reference 中的 ChatPrompt 部分。
3. Candidate:优化器产出的"候选方案"
Candidate 是优化器生成的一个具体 Prompt,或者一组多 Prompt 的打包方案。它会进入评估环节,被打分、被比较。
每个 Candidate 都对应一组明确的:
- 消息(messages);
- 参数(parameters);
- 工具配置(tool configuration)。
你可以把 Candidate 想象成"参赛选手"。优化器每提出一个方案,就是一个 Candidate。优化过程就是让这些选手在数据集上跑一遍,看谁得分高。最终胜出的 Candidate,往往就是你要拿去生产环境用的那个 Prompt。
4. Metric:怎么衡量好坏
Metric 定义了如何衡量一个 Prompt 的表现。它本质上是一个对象,里面包含度量函数。这个函数需要接受两个参数:
dataset_item:一个字典,包含数据集条目的键;llm_output:LLM 的响应内容。
然后,它应该返回一个 ScoreResult 对象,或者一个浮点数(float)。
这听起来有点技术,但实际用起来很灵活。比如,你可以写一个 Metric 来判断回答是否包含关键信息,或者是否和标准答案语义相似,或者是否满足某种格式要求。Metric 的作用就是告诉优化器:"什么样的输出算好,什么样的算差。"
没有 Metric,优化器就不知道往哪个方向努力。所以,定义一个好的 Metric,往往比选一个强大的 Optimizer 还重要。
5. Dataset:优化用的数据集
Dataset 是数据条目的集合,通常包含输入和期望输出(ground truth)。它用来引导和评估 Prompt 优化过程。
这里有一个非常关键的最佳实践:把数据拆成训练集和验证集。
- 训练集:优化器用它来分析失败案例、生成改进方案;
- 验证集:用来评估 Candidate,防止过拟合。
为什么这么做?因为如果优化器一直看着同一批数据调 Prompt,它很容易"背答案"。在训练集上分数很高,换一批数据就崩了。训练集和验证集分开,才能看出一个 Candidate 是不是真的泛化能力强。
关于 Dataset 的更多内容,可以参考 Datasets 和 Define datasets 相关文档。
6. Optimization Run:一次完整的优化执行
Optimization Run 是一次 Prompt 优化过程的单次执行,使用一套特定配置。比如,你调用一次 optimizer.optimize_prompt(...),就算一次 Run。
每次 Run 都会被记录在 Opik 里,作为一个 Optimization Run。它内部会包含多个 Round、Trial 和 Candidate 评估。你可以把它理解成"一次完整的实验记录"。从实验追踪的角度看,Run 是最外层的容器。
7. Optimization Trial:一次候选评估
每个 Optimization Run 都由一个或多个 Optimization Trial 组成。一个 Trial 对应的是:在选定的数据集切片上评估一个 Candidate。
数据集切片可以是:
- 全量数据;
- 采样数据;
- 小批量(minibatch)数据。
在 Opik UI 里,你可以查看每个 Trial 的 Prompt、得分和推理历史。这对于理解优化器到底在做什么、为什么某个 Candidate 表现更好,非常有帮助。
Trial 是优化过程中最细粒度的"实验单元"。如果你把 Run 比作一整季比赛,Trial 就是其中一场比赛,Candidate 就是上场的选手,Metric 就是裁判的打分规则。
8. Optimization Round:一轮逻辑迭代
Optimization Round 是 Run 内部的一个逻辑迭代。在一轮里,优化器会:
- 提出一个或多个 Candidate;
- 对它们进行评估;
- 根据结果决定下一轮 Candidate。
有些 Optimizer 会显式地暴露 Round,比如进化式优化器和分层优化器;有些则采用更简单的 Trial-by-Trial 循环,不强调 Round 的概念。
Round 的意义在于,它把优化过程分成了"代"。每一代都比上一代更有希望接近目标。你可以通过 Round 来观察优化器是否在收敛,是否陷入了局部最优。
9. Prompt model:用来评估 Prompt 的模型
Prompt model 是用来评估 Prompt 的模型。换句话说,它就是你把 Prompt 用上去的那个模型,应该和你实际应用里使用的模型保持一致。
配置方式是通过 ChatPrompt(model="provider/model-name")。比如,如果你的应用用的是某个厂商的某个型号,那么 Prompt model 也应该设成同一个。
为什么必须一致?因为不同模型对同一个 Prompt 的反应可能完全不同。你用 A 模型优化出来的 Prompt,放到 B 模型上可能效果很差。所以,评估环境和生产环境要尽量对齐。
10. Optimizer model:用来优化 Prompt 的模型
Optimizer model 是用来优化 Prompt 的模型。它是优化器内部用来改进你 Prompt 的模型。
这里有一个很实用的建议:用你所能拿到的最强大的模型来做优化。因为优化器模型越强,它提出的改进方案往往越有洞察力。虽然这会增加一些成本,但通常值得。
配置方式是通过 Optimizer 的 model 参数。注意,它和 Prompt model 是两个不同的东西:
| 对比项 | Prompt model | Optimizer model |
|---|---|---|
| 作用 | 评估 Prompt 的效果 | 改进 Prompt 本身 |
| 使用场景 | 和你的应用保持一致 | 尽量用最强模型 |
| 配置位置 | ChatPrompt(model=...) |
Optimizer 的 model 参数 |
| 是否必须一致 | 应与生产环境一致 | 不需要和 Prompt model 一致 |
很多人第一次接触时会混淆这两个模型。记住一句话:Prompt model 是"考生",Optimizer model 是"辅导老师"。辅导老师可以比考生强很多,这很正常。
三、把这些概念串起来:一次典型的优化流程
理解了单个术语之后,我们来看它们是如何协作的。
假设你要优化一个客服问答 Agent。你可以按下面的步骤来:
- 准备数据集
收集一批用户问题和标准答案,拆成训练集和验证集。 - 定义 ChatPrompt
写出初始的 System 指令和 User 模板,用变量占位符表示用户问题。 - 定义 Metric
写一个函数,判断模型回答是否准确、是否包含关键信息、是否符合语气要求。返回 ScoreResult 或 float。 - 选择 Optimizer
根据任务特点,选 MetaPromptOptimizer、FewShotBayesianOptimizer、EvolutionaryOptimizer 或 HRPO。 - 配置 Prompt model 和 Optimizer model
Prompt model 用你线上实际使用的模型;Optimizer model 用你能拿到的最强模型。 - 运行优化
调用optimizer.optimize_prompt(...),开始一次 Optimization Run。 - 观察 Round 和 Trial
在 Opik UI 里查看每一轮、每一次 Trial 的 Prompt、得分和推理历史。 - 选出最佳 Candidate
根据验证集上的表现,选出泛化能力最好的 Candidate。 - 迭代
如果效果还不够,调整 Metric、数据集或 Optimizer 配置,再来一轮。
整个过程中,Run 是容器,Round 是迭代轮次,Trial 是评估单元,Candidate 是参赛方案,Metric 是裁判,Dataset 是题库,Prompt model 是考生,Optimizer model 是教练。每个概念都有明确的分工,组合起来就是一套完整的优化流水线。
四、为什么训练集和验证集拆分这么重要
这一点值得单独拿出来说,因为它直接决定了优化结果能不能用。
假设你只有一套数据,优化器在这套数据上不断调整 Prompt,直到每个样本都答对。看起来分数很高,但一到真实场景就露馅。这就是过拟合。
训练集和验证集拆分之后,优化器在训练集上分析失败、生成改进方案,然后到验证集上检验。验证集相当于"模拟考试",它的题目优化器没见过。只有在验证集上也表现好的 Candidate,才更可能在真实环境中稳定发挥。
所以,不要为了省事跳过这一步。数据拆分是防止自欺欺人的第一道防线。
五、常见误区与最佳实践
在实际使用 Opik Agent Optimizer 时,有几个误区很常见。
误区一:Prompt model 和 Optimizer model 用同一个。
不是不可以,但没必要。Optimizer model 应该尽量强,Prompt model 应该和线上一致。两者目标不同。
误区二:Metric 随便写。
Metric 是优化的指挥棒。如果 Metric 不能反映业务目标,优化器就会朝着错误的方向努力。比如,你只测回答长度,模型可能学会说废话。
误区三:不做训练/验证拆分。
前面已经说过,这是过拟合的温床。
误区四:只看最终分数,不看 Trial 历史。
Opik UI 里的 Trial 历史很有价值。它能告诉你优化器尝试了哪些方向、哪些失败了、哪些有潜力。理解过程,比只看结果更重要。
最佳实践总结:
- 数据拆成训练集和验证集;
- Metric 要能反映真实业务目标;
- Prompt model 与生产环境一致;
- Optimizer model 尽量用最强模型;
- 从简单 Optimizer 开始,逐步复杂;
- 利用 UI 查看 Trial 和 Round 的细节;
- 每次 Run 都记录下来,方便对比。
六、下一步可以看什么
如果你已经理解了这些核心概念,接下来可以:
- 探索具体的 Optimizers,了解不同算法的细节;
- 查看 FAQ,解决常见问题和故障排查;
- 阅读 API Reference,掌握详细配置选项;
- 跑一跑 Example Projects & Cookbooks 里的 Colab Notebook,亲手体验完整流程。
概念是地图,真正跑起来才是上路。Opik Agent Optimizer 的设计初衷,就是让 Prompt 优化和 Agent 优化不再靠猜,而是有数据、有记录、有迭代。希望这篇文章能帮你把这张地图看清楚,接下来怎么走,就看你自己的任务和目标了。