优化提示(实验性)
MLflow 允许您通过 MLflow 的统一接口,利用 mlflow.genai.optimize_prompt() API 将您的提示集成到高级提示优化技术中。此功能可通过利用评估指标和标记数据来帮助您自动改进提示。MLflow 内置支持诸如 DSPy 的 MIPROv2 和 GEPA 等优化算法。您还可以通过扩展 MLflow 的基础优化器类 BasePromptOptimizer 来实现自定义优化算法。
- 统一接口:通过中立的接口访问最先进的提示优化算法。
- 可扩展:通过扩展基础优化器类来创建自定义优化算法。
- 提示管理:与 MLflow 提示注册表集成,以实现可重用性、版本控制和 lineage。
- 评估:利用 MLflow 的评估功能全面评估提示性能。
优化概述
为了使用 mlflow.genai.optimize_prompt() API,您需要准备以下内容
| 组件 | 示例 |
|---|---|
| 提示 在 MLflow 中注册 | |
| 评分器 评估提示质量 | |
| 数据 输入和预期 | |
| 目标 LLM 要优化的模型 | |
| 优化器配置 优化设置 | |
开始使用
这是一个优化问答提示的简单示例
作为先决条件,您需要安装 DSPy。
$ pip install dspy>=2.6.0 mlflow>=3.1.0
然后,运行以下代码注册初始提示并对其进行优化。
import os
from typing import Any
import mlflow
from mlflow.genai.scorers import scorer
from mlflow.genai.optimize import OptimizerConfig, LLMParams
os.environ["OPENAI_API_KEY"] = "<YOUR_OPENAI_API_KEY>"
# Define a custom scorer function to evaluate prompt performance with the @scorer decorator.
# The scorer function for optimization can take inputs, outputs, and expectations arguments, but not the trace argument.
# Note that the DSPy/MIPROv2 optimizer requires metrics to receive outputs as a dict.
@scorer
def exact_match(expectations: dict[str, Any], outputs: dict[str, Any]) -> bool:
return expectations["answer"] == outputs["answer"]
# Register the initial prompt
initial_template = """
Answer to this math question: {{question}}.
Return the result in a JSON string in the format of {"answer": "xxx"}.
"""
prompt = mlflow.genai.register_prompt(
name="math",
template=initial_template,
)
# The data can be a list of dictionaries, a pandas DataFrame, or an mlflow.genai.EvaluationDataset
# It needs to contain inputs and expectations where each row is a dictionary.
train_data = [
{
"inputs": {"question": "Given that $y=3$, evaluate $(1+y)^y$."},
"expectations": {"answer": "64"},
},
{
"inputs": {
"question": "The midpoint of the line segment between $(x,y)$ and $(-9,1)$ is $(3,-5)$. Find $(x,y)$."
},
"expectations": {"answer": "(15,-11)"},
},
{
"inputs": {
"question": "What is the value of $b$ if $5^b + 5^b + 5^b + 5^b + 5^b = 625^{(b-1)}$? Express your answer as a common fraction."
},
"expectations": {"answer": "\\frac{5}{3}"},
},
{
"inputs": {"question": "Evaluate the expression $a^3\\cdot a^2$ if $a= 5$."},
"expectations": {"answer": "3125"},
},
{
"inputs": {"question": "Evaluate $\\lceil 8.8 \\rceil+\\lceil -8.8 \\rceil$."},
"expectations": {"answer": "17"},
},
]
eval_data = [
{
"inputs": {
"question": "The sum of 27 consecutive positive integers is $3^7$. What is their median?"
},
"expectations": {"answer": "81"},
},
{
"inputs": {"question": "What is the value of $x$ if $x^2 - 10x + 25 = 0$?"},
"expectations": {"answer": "5"},
},
{
"inputs": {
"question": "If $a\\ast b = 2a+5b-ab$, what is the value of $3\\ast10$?"
},
"expectations": {"answer": "26"},
},
{
"inputs": {
"question": "Given that $-4$ is a solution to $x^2 + bx -36 = 0$, what is the value of $b$?"
},
"expectations": {"answer": "-5"},
},
]
# Optimize the prompt
result = mlflow.genai.optimize_prompt(
target_llm_params=LLMParams(model_name="openai/gpt-4.1-mini"),
prompt=prompt,
train_data=train_data,
eval_data=eval_data,
scorers=[exact_match],
optimizer_config=OptimizerConfig(
num_instruction_candidates=8,
max_few_show_examples=2,
),
)
# The optimized prompt is automatically registered as a new version
print(result.prompt.uri)
在上面的示例中,平均性能分数从 0 增加到 0.5。优化过程完成后,您可以访问 MLflow 提示注册表页面并查看优化后的提示。

请注意,DSPy/MIPROv2 优化器的优化提示期望输出为 JSON 字符串。因此,您需要在应用程序中使用 json.loads 来解析输出。有关如何加载优化后提示的信息,请参阅 加载和使用提示。
import mlflow
import json
import openai
def predict(question: str, prompt_uri: str) -> str:
prompt = mlflow.genai.load_prompt(prompt_uri)
content = prompt.format(question=question)
completion = openai.chat.completions.create(
model="gpt-4.1-mini",
messages=[{"role": "user", "content": content}],
temperature=0.1,
)
return json.loads(completion.choices[0].message.content)["answer"]
配置
您可以使用 OptimizerConfig 自定义优化过程,其中包含以下参数
- algorithm:要使用的优化算法。可以是字符串(例如,“DSPy/MIPROv2”、“DSPy/GEPA”)或自定义优化器类。默认值:“DSPy/MIPROv2”
- num_instruction_candidates:要尝试的候选指令数。默认值:6
- max_few_show_examples:在 few-shot 演示中显示示例的最大数量。默认值:6
- optimizer_llm:用于优化的 LLM。对于 GEPA,这用作反射 LM(建议:使用更强大的模型,如 GPT-4)。默认值:None(使用目标 LLM)
- extract_instructions:是否从初始提示模板中提取指令。默认值:True
- verbose:在优化过程中是否显示优化器日志。默认值:False
- autolog:是否自动记录优化参数、数据集和指标。如果设置为 True,将自动创建一个 MLflow 运行来存储它们。默认值:False
有关更多详细信息,请参阅 OptimizerConfig。
自定义优化器
MLflow 支持通过扩展基础优化器类来创建自定义提示优化算法。这允许您实现特定领域的优化策略或与其他优化库集成。
BasePromptOptimizer
对于自定义优化逻辑,请扩展 BasePromptOptimizer 类
from mlflow.genai.optimize import BasePromptOptimizer, OptimizerConfig, OptimizerOutput
from mlflow.genai.optimize.types import LLMParams
from mlflow.entities.model_registry import PromptVersion
from mlflow.genai.scorers import Scorer
from typing import Optional, Callable, Any
import pandas as pd
class CustomOptimizer(BasePromptOptimizer):
# Inherit the BasePromptOptimizer class and implement the `optimize` method.
def optimize(
self,
prompt: PromptVersion,
target_llm_params: LLMParams,
train_data: pd.DataFrame,
scorers: list[Scorer],
objective: Optional[Callable[[dict[str, Any]], float]] = None,
eval_data: Optional[pd.DataFrame] = None,
) -> OptimizerOutput:
# Implement your custom optimization logic here
optimized_template = f"Please answer accurately: {prompt.template}"
return OptimizerOutput(
optimized_prompt=optimized_template,
optimizer_name="CustomOptimizer",
final_eval_score=0.85,
initial_eval_score=0.75,
)
# Use the custom optimizer
result = mlflow.genai.optimize_prompt(
target_llm_params=LLMParams(model_name="openai/gpt-4o-mini"),
prompt=prompt,
train_data=train_data,
scorers=[exact_match],
optimizer_config=OptimizerConfig(algorithm=CustomOptimizer),
)
DSPyPromptOptimizer
对于基于 DSPy 的优化,请扩展 DSPyPromptOptimizer 类,该类提供了 DSPy 集成基础设施
import dspy
from typing import Callable
from mlflow.genai.optimize import (
DSPyPromptOptimizer,
OptimizerOutput,
format_dspy_prompt,
)
from mlflow.entities.model_registry import PromptVersion
class CustomDSPyOptimizer(DSPyPromptOptimizer):
# Inherit the DSPyPromptOptimizer class and implement the `run_optimization` method.
def run_optimization(
self,
prompt: PromptVersion,
program: dspy.Module,
metric: Callable[[dspy.Example], float],
train_data: list,
eval_data: list,
) -> OptimizerOutput:
# Use DSPy's optimization components with your custom logic
# Example using DSPy's BootstrapFewShot optimizer
optimizer = dspy.BootstrapFewShot(
metric=metric,
max_bootstrapped_demos=self.optimizer_config.max_few_show_examples,
)
# Compile the program
compiled_program = optimizer.compile(
student=program,
trainset=train_data,
)
return OptimizerOutput(
optimized_prompt=format_dspy_prompt(compiled_program),
optimizer_name="BootstrapFewShot",
)
# Use the custom DSPy optimizer
result = mlflow.genai.optimize_prompt(
target_llm_params=LLMParams(model_name="openai/gpt-4o-mini"),
prompt=prompt,
train_data=train_data,
scorers=[exact_match],
optimizer_config=OptimizerConfig(algorithm=CustomDSPyOptimizer),
)
使用自定义优化器时,请确保它们返回一个 OptimizerOutput 对象,其中包含优化后的提示和评估分数。
性能基准
我们正在积极进行基准测试。这些基准测试结果是初步的,可能会发生变化。
MLflow 提示优化可以提高您的应用程序在各种任务上的性能。以下是使用 MLflow 优化功能在多个数据集上进行测试的结果
- ARC-Challenge:ai2_arc 数据集包含一组选择题科学问题
- GSM8K:gsm8k 数据集包含一组语言多样化的中小学数学应用题
- MATH:竞赛数学问题,需要高级推理和解决问题的能力
| 数据集 | 模型 | 基线 | 优化后 |
|---|---|---|---|
| MATH | gpt-4.1o-nano | 17.25% | 18.48% |
| GSM8K | gpt-4.1o-nano | 21.46% | 49.89% |
| ARC-Challenge | gpt-4.1o-nano | 71.42% | 89.25% |
| MATH | Llama4-maverick | 33.06% | 33.26% |
| GSM8K | Llama4-maverick | 55.80% | 58.22% |
| ARC-Challenge | Llama4-maverick | 0.17% | 93.17% |
上述结果是针对 gpt-4.1o-nano 和 Llama4-maverick 使用 DSPy 的 MIPROv2 算法和默认设置进行的基准测试,并为每个任务使用了特定的评估指标。如果您使用不同的模型、配置、数据集或起始提示,结果可能会发生变化。这些结果表明 MLflow 的提示优化可以解决许多挑战,并以最小的努力带来可衡量的性能提升。
常见问题
支持的数据集格式是什么?
mlflow.genai.optimize_prompt() API 的训练和评估数据可以是字典列表、pandas DataFrame、spark DataFrame 或 mlflow.genai.EvaluationDataset。无论哪种情况,数据都需要包含输入和预期列,这些列包含输入字段和预期输出字段的字典。每个输入或预期字典可以包含原始类型、列表、嵌套字典和 Pydantic 模型。数据类型是从数据集的第一行推断出来的。
# ✅ OK
[
{
"inputs": {"question": "What is the capital of France?"},
"expectations": {"answer": "Paris"},
},
]
# ✅ OK
[
{
"inputs": {"question": "What are the three largest cities of Japan?"},
"expectations": {"answer": ["Tokyo", "Osaka", "Nagoya"]},
},
]
# ✅ OK
from pydantic import BaseModel
class Country(BaseModel):
name: str
capital: str
population: int
[
{
"inputs": {"question": "What is the capital of France?"},
"expectations": {
"answer": Country(name="France", capital="Paris", population=68000000)
},
},
]
# ❌ NG
[
{
"inputs": "What is the capital of France?",
"expectations": "Paris",
},
]
如何组合多个评分器?
虽然 mlflow.genai.optimize_prompt() API 接受多个评分器,但在优化过程中,优化器需要将它们组合成一个单一的分数。默认情况下,优化器会计算所有数值或布尔型评分器的总分数。如果您想使用自定义聚合函数或使用返回非数字值的评分器,可以将自定义聚合函数传递给 objective 参数。
@scorer
def safeness(outputs: dict[str, Any]) -> bool:
return "death" not in outputs["answer"].lower()
@scorer
def relevance(expectations: dict[str, Any], outputs: dict[str, Any]) -> bool:
return expectations["answer"] in outputs["answer"]
def objective(scores: dict[str, Any]) -> float:
if not scores["safeness"]:
return -1
return scores["relevance"]
result = mlflow.genai.optimize_prompt(
target_llm_params=LLMParams(model_name="openai/gpt-4.1-mini"),
prompt=prompt,
train_data=train_data,
eval_data=eval_data,
scorers=[safeness, relevance],
objective=objective,
)
如何创建自定义优化器?
MLflow 提供了两个基础类来创建自定义优化器
- BasePromptOptimizer:用于自定义优化逻辑。为了进行自定义,您必须实现自己的
optimize方法。 - DSPyPromptOptimizer:用于基于 DSPy 的优化。对此优化器的自定义涉及构建一个
run_optimization方法。MLflow 将处理利用您的自定义接口所需的 DSPy 设置。
当您希望完全控制优化过程时,请选择 BasePromptOptimizer,或者当您希望在自定义优化策略的同时利用 DSPy 的生态系统时,请选择 DSPyPromptOptimizer。