关于 arize-prompt-optimization
arize-prompt-optimization 是利用 Arize 追踪数据、数据集和实验结果改进 LLM 提示词的技能。它帮助团队提取提示词、分析反馈与失败案例、修订文本,并比较不同实验的结果。
主要功能
- 01从追踪 Span 提取提示词
- 02分析标注和评估结果
- 03关联数据集与实验输出
- 04指导提示词修订和变量检查
- 05比较提示词实验并检查回退
适用场景
- 01从追踪反馈中定位提示词问题
- 02用数据集示例修订提示词
- 03比较基线与修订版提示词结果
- 04部署前检查模板变量
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ arize-ai/ arize-skills --skill arize-prompt-optimization安装后在 Claude Code 中输入/arize-prompt-optimization确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/ax-profiles.mdax-setup.mdoptimization-meta-prompt.md详细介绍
Arize 提示词优化技能
SPACE—--space标志接受空间名称(例如,my-workspace)或 base64 空间ID(例如,U3BhY2U6...)。使用ax spaces get NAME确认已知名称;ax spaces list用于人工浏览。
相关技能
- arize-prompts:使用
ax prompts在 Prompt Hub 中创建提示词、管理版本并添加标签(JSON 消息、提供商、production等标签)。如果要将产物存放在 Arize 中,请使用此技能;如果要根据追踪、数据集和实验改进提示词文本,请使用下文的 arize-prompt-optimization。
概念
提示词在追踪数据中的位置
LLM 应用会生成遵循 OpenInference 语义约定的 span。根据 span 类型和插桩方式,提示词会存储在不同的 span 属性中:
| 列 | 包含内容 | 使用场景 |
|---|---|---|
attributes.llm.input_messages | 采用基于角色格式的结构化聊天消息(system、user、assistant、tool) | 聊天型 LLM 提示词的首选来源 |
attributes.llm.input_messages.roles | 角色数组:system、user、assistant、tool | 提取各条消息的角色 |
attributes.llm.input_messages.contents | 消息内容字符串数组 | 提取消息文本 |
attributes.input.value | 序列化的提示词或用户问题(通用,适用于所有 span 类型) | 没有结构化消息时的备用来源 |
attributes.llm.prompt_template.template | 带有 {variable} 占位符的模板(例如,"Answer {question} using {context}") | 应用使用提示词模板时 |
attributes.llm.prompt_template.variables | 模板变量值(JSON 对象) | 查看代入模板的值 |
attributes.output.value | 模型响应文本 | 查看 LLM 生成的内容 |
attributes.llm.output_messages | 结构化模型输出(包括工具调用) | 检查工具调用响应 |
根据 Span 类型查找提示词
- LLM span(
attributes.openinference.span.kind = 'LLM'):检查attributes.llm.input_messages中的结构化聊天消息,或检查attributes.input.value中的序列化提示词。检查attributes.llm.prompt_template.template中的模板。 - Chain/Agent span:
attributes.input.value包含用户问题。实际的 LLM 提示词位于子 LLM span 上——沿追踪树向下查找。 - Tool span:
attributes.input.value包含工具输入,attributes.output.value包含工具结果。提示词通常不在此处。
性能信号列
这些列包含用于优化的反馈数据:
| 列模式 | 来源 | 含义 |
|---|---|---|
annotation.<name>.label | 人工审核者 | 分类等级(例如,correct、incorrect、partial) |
annotation.<name>.score | 人工审核者 | 数值质量评分(例如,0.0 - 1.0) |
annotation.<name>.text | 人工审核者 | 对等级的自由格式说明 |
eval.<name>.label | LLM-as-judge 评估 | 自动分类评估 |
eval.<name>.score | LLM-as-judge 评估 | 自动数值评分 |
eval.<name>.explanation | LLM-as-judge 评估 | 评估给出该评分的原因——对优化最有价值 |
attributes.input.value | 追踪数据 | 输入 LLM 的内容 |
attributes.output.value | 追踪数据 | LLM 生成的内容 |
{experiment_name}.output | 实验运行 | 特定实验的输出 |
前提条件
直接执行任务——运行所需的 ax 命令。不要事先检查版本、环境变量或配置文件。
如果 ax 命令失败,请根据错误进行排查:
command not found或版本错误 → 参阅 references/ax-setup.md401 Unauthorized/ 缺少 API 密钥 → 运行ax profiles show检查当前配置文件。如果配置文件缺失或 API 密钥不正确,请按照 references/ax-profiles.md 创建或更新配置文件。如果用户没有自己的密钥,请引导他们前往 https://app.arize.com/admin > API Keys- Space 未知 → 参阅 Space
- Project 不明确 → 询问用户,或运行
ax projects list -o json --limit 100并将结果作为可选项展示 - LLM 提供商调用失败(缺少提供商凭据)→ 运行
ax ai-integrations list --space SPACE检查是否有平台托管的凭据。如果没有,请使用 arize-ai-provider-integration 技能——绝不要要求用户在聊天中粘贴提供商密钥。 - **安全:**绝不要读取
.env文件,也不要在文件系统中搜索凭据。例外:非机密的ARIZE_SPACE_ID行(参阅 Space)。使用ax profiles管理 Arize 凭据,使用ax ai-integrations管理 LLM 提供商密钥。绝不要要求用户在聊天中粘贴机密信息。缺少凭据时,请参阅 references/ax-profiles.md。
必须先询问用户的情况
仍应优先使用 ax 查询,而不是提出开放式问题:使用 ax projects get NAME --space SPACE 或 ax datasets get NAME --space SPACE 确认已知名称(list 用于人工浏览)。如果仍无法继续(例如,用户提供的名称匹配多个项目、trace 与 experiment 的路径不明确,或操作范围可能造成破坏),不要直接开始提问——当 arize-instrumentation 因范围或确认问题而暂停时,请采用相同的明确表述方式:
- 说明已找到该技能,例如:我在此仓库中找到了 arize-prompt-optimization 技能(如有帮助,可补充
skills/arize-prompt-optimization/SKILL.md)。 - 然后明确暂停,例如:调用该技能前,我需要先确认几个问题:
- 只提出阻碍此技能下一步
ax操作所必需的最少问题,并使用编号或简短项目符号列出。
阶段 1:提取当前提示词
查找包含提示词的 LLM spans
# Sample LLM spans (where prompts live)
ax spans export PROJECT --space SPACE --filter "attributes.openinference.span.kind = 'LLM'" -l 10 --stdout
# Filter by model
ax spans export PROJECT --space SPACE --filter "attributes.llm.model_name = 'gpt-4o'" -l 10 --stdout
# Filter by span name (e.g., a specific LLM call)
ax spans export PROJECT --space SPACE --filter "name = 'ChatCompletion'" -l 10 --stdout
导出 trace 以检查提示词结构
# Export all spans in a trace
ax spans export PROJECT --space SPACE --trace-id TRACE_ID --stdout > spans.json
# Export a single span
ax spans export PROJECT --space SPACE --span-id SPAN_ID
从导出的 JSON 中提取提示词
# Extract structured chat messages (system + user + assistant)
jq '.[0] | {
messages: .attributes.llm.input_messages,
model: .attributes.llm.model_name
}' spans.json
# Extract the system prompt specifically
jq '[.[] | select(.attributes.llm.input_messages.roles[]? == "system")] | .[0].attributes.llm.input_messages' spans.json
# Extract prompt template and variables
jq '.[0].attributes.llm.prompt_template' spans.json
# Extract from input.value (fallback for non-structured prompts)
jq '.[0].attributes.input.value' spans.json
将提示词重建为消息
获取 span 数据后,将提示词重建为消息数组:
[
{"role": "SYSTEM", "content": "You are a helpful assistant that..."},
{"role": "USER", "content": "Given {input}, answer the question: {question}"}
]
如果 span 包含 attributes.llm.prompt_template.template,则该提示词使用变量。保留这些占位符({variable} 或 {{variable}})——它们会在运行时替换。
阶段 2:收集性能数据
从 traces 收集(生产环境反馈)
# Find error spans -- these indicate prompt failures
ax spans export PROJECT --space SPACE \
--filter "status_code = 'ERROR' AND attributes.openinference.span.kind = 'LLM'" \
-l 20 --stdout
# Find spans with low eval scores
ax spans export PROJECT --space SPACE \
--filter "annotation.correctness.label = 'incorrect'" \
-l 20 --stdout
# Find spans with high latency (may indicate overly complex prompts)
ax spans export PROJECT --space SPACE \
--filter "attributes.openinference.span.kind = 'LLM' AND latency_ms > 10000" \
-l 20 --stdout
# Export error traces for detailed inspection
ax spans export PROJECT --space SPACE --trace-id TRACE_ID
从数据集和实验收集
# Export a dataset (ground truth examples)
ax datasets export DATASET_NAME --space SPACE
# -> dataset_*/examples.json
# Export experiment results (what the LLM produced)
ax experiments export EXPERIMENT_NAME --dataset DATASET_NAME --space SPACE
# -> experiment_*/runs.json
合并数据集和实验数据以进行分析
按 example_id 联接两个文件,以查看输入、输出和评估结果:
# Count examples and runs
jq 'length' dataset_*/examples.json
jq 'length' experiment_*/runs.json
# View a single joined record
jq -s '
.[0] as $dataset |
.[1][0] as $run |
($dataset[] | select(.id == $run.example_id)) as $example |
{
input: $example,
output: $run.output,
evaluations: $run.evaluations
}
' dataset_*/examples.json experiment_*/runs.json
# Find failed examples (where eval score < threshold)
jq '[.[] | select(.evaluations.correctness.score < 0.5)]' experiment_*/runs.json
确定优化目标
查找失败中反复出现的模式:
- 将输出与真实值进行比较:LLM 输出与预期结果有哪些差异?
- 阅读评估说明:
eval.*.explanation会说明失败的原因 - 检查注释文本:人工反馈会描述具体问题
- 查找冗长程度不匹配的情况:输出是否比真实值过长或过短?
- 检查格式是否符合要求:输出是否采用了预期格式?
阶段 3:优化提示词
优化元提示词
填写 references/optimization-meta-prompt.md 中的三个占位符,并将其发送给你的 LLM(GPT-4o、Claude 等),以生成改进版提示词。
准备性能数据
将记录整理为 JSON 数组,然后粘贴到模板中:
# From dataset + experiment: join and select relevant columns
jq -s '
.[0] as $ds |
[.[1][] | . as $run |
($ds[] | select(.id == $run.example_id)) as $ex |
{
input: $ex.input,
expected: $ex.expected_output,
actual_output: $run.output,
eval_score: $run.evaluations.correctness.score,
eval_label: $run.evaluations.correctness.label,
eval_explanation: $run.evaluations.correctness.explanation
}
]
' dataset_*/examples.json experiment_*/runs.json
# From exported spans: extract input/output pairs with annotations
jq '[.[] | select(.attributes.openinference.span.kind == "LLM") | {
input: .attributes.input.value,
output: .attributes.output.value,
status: .status_code,
model: .attributes.llm.model_name
}]' spans.json
应用修订后的提示词
LLM 返回修订后的消息数组后:
- 并排比较原始提示词和修订后的提示词
- 验证所有模板变量均已保留
- 检查格式说明是否完整
- 全面部署前,先用几个示例进行测试
第 4 阶段:迭代
优化循环
1. Extract prompt -> Phase 1 (once)
2. Run experiment -> ax experiments create ...
3. Export results -> ax experiments export EXPERIMENT_NAME --dataset DATASET_NAME --space SPACE
4. Analyze failures -> jq to find low scores
5. Run meta-prompt -> Phase 3 with new failure data
6. Apply revised prompt
7. Repeat from step 2
衡量改进
# Compare scores across experiments
# Experiment A (baseline)
jq '[.[] | .evaluations.correctness.score] | add / length' experiment_a/runs.json
# Experiment B (optimized)
jq '[.[] | .evaluations.correctness.score] | add / length' experiment_b/runs.json
# Find examples that flipped from fail to pass
jq -s '
[.[0][] | select(.evaluations.correctness.label == "incorrect")] as $fails |
[.[1][] | select(.evaluations.correctness.label == "correct") |
select(.example_id as $id | $fails | any(.example_id == $id))
] | length
' experiment_a/runs.json experiment_b/runs.json
对比两个提示词的 A/B 测试
- 针对同一数据集创建两个实验,分别使用不同版本的提示词
- 导出两者:
ax experiments export EXP_A --dataset DATASET_NAME --space SPACE,然后对EXP_B执行相同操作 - 比较平均分数、失败率以及具体示例的结果变化
- 检查是否出现回归——即使用提示词 A 时通过、使用提示词 B 时失败的示例
提示词工程最佳实践
编写或修订提示词时,请遵循以下做法:
| 技巧 | 适用场景 | 示例 |
|---|---|---|
| 提供清晰、详细的说明 | 输出含糊或偏离主题 | "将情感分类为以下选项之一,且只能选择一个:positive、negative、neutral" |
| 将说明放在开头 | 模型忽略后面的说明 | 将任务描述放在示例之前 |
| 分步骤说明 | 复杂的多步骤流程 | "先提取实体,再对每个实体分类,最后总结" |
| 指定具体角色 | 需要保持风格或语气一致 | "你是一位面向机构投资者撰写分析报告的高级金融分析师" |
| 使用分隔符标记 | 各部分容易混在一起 | 使用 ---、### 或 XML 标签,将输入与说明分开 |
| 使用少样本示例 | 需要明确输出格式 | 展示 2-3 组模拟输入和输出 |
| 指定输出长度 | 回复过长或过短 | "请用恰好 2-3 句话作答" |
| 提供推理说明 | 准确性至关重要 | "回答前请逐步思考" |
| 说明「不知道」时该如何作答 | 存在幻觉风险 | "如果答案不在提供的上下文中,请说『我没有足够的信息』" |
变量保留
优化使用模板变量的提示词时:
- 单花括号(
{variable}):Python f-string / Jinja 风格。Arize 中最常见。 - 双花括号(
{{variable}}):Mustache 风格。框架要求时使用。 - 优化过程中,绝不要添加或删除变量占位符
- 绝不要重命名变量——运行时替换依赖变量的准确名称
- 添加少样本示例时,请使用字面值,而不是变量占位符
工作流
优化包含失败记录的跟踪数据中的提示词
- 一次性导出完整的失败跟踪数据:
ax traces export PROJECT --space SPACE --filter "status_code = 'ERROR'" -l 5 --stdout > failing.json - 从 LLM 跨度中提取提示词(如果存在,则使用出错的 LLM 跨度;否则使用第一个 LLM 跨度):
jq '[.[] | select(.attributes.openinference.span.kind == "LLM")] | (map(select(.status_code == "ERROR"))[0] // .[0]) | { messages: .attributes.llm.input_messages, template: .attributes.llm.prompt_template, output: .attributes.output.value, error: .attributes.exception.message }' failing.json - 根据错误消息或输出,确定失败原因
- 在优化元提示词(第 3 阶段)中填入提示词和错误上下文
- 应用修订后的提示词
使用数据集和实验进行优化
- 导出数据集和实验(运行
ax experiments list --dataset DATASET_NAME --space SPACE可查找未知名称):ax datasets export DATASET_NAME --space SPACE ax experiments export EXPERIMENT_NAME --dataset DATASET_NAME --space SPACE - 准备用于元提示词的关联数据
- 运行优化元提示词
- 使用修订后的提示词创建新实验,以衡量改进效果
调试生成错误格式的提示词
- 导出输出格式错误的跨度:
ax spans export PROJECT --space SPACE \ --filter "attributes.openinference.span.kind = 'LLM' AND annotation.format.label = 'incorrect'" \ -l 10 --stdout > bad_format.json - 查看 LLM 的实际输出与预期输出之间的差异
- 在提示词中添加明确的格式说明(JSON 架构、示例、分隔符)
- 常见修复方法:添加少样本示例,展示准确的目标输出格式
减少 RAG 提示词中的幻觉
- 查找模型出现幻觉的跟踪数据:
ax spans export PROJECT --space SPACE \ --filter "annotation.faithfulness.label = 'unfaithful'" \ -l 20 --stdout - 导出并检查检索器和 LLM 的跨度:
ax spans export PROJECT --space SPACE --trace-id TRACE_ID --stdout > spans.json jq '[.[] | {kind: .attributes.openinference.span.kind, name, input: .attributes.input.value, output: .attributes.output.value}]' spans.json - 检查检索到的上下文是否确实包含答案
- 在系统提示词中添加依据说明:"只能使用提供的上下文中的信息。如果答案不在上下文中,请如实说明。"
故障排查
| 问题 | 解决方案 |
|---|---|
ax: command not found | 请参阅 references/ax-setup.md |
No profile found | 尚未配置任何配置文件。请参阅 references/ax-profiles.md 创建一个配置文件。 |
Span 上没有 input_messages | 检查 Span 类型——Chain/Agent Span 会将提示词存储在子 LLM Span 上,而不是自身 |
提示词模板为 null | 并非所有插桩都会生成 prompt_template。请改用 input_messages 或 input.value |
| 优化后变量丢失 | 确认修改后的提示词保留了原始提示词中的所有 {var} 占位符 |
| 优化效果变差 | 检查是否过拟合——元提示词可能记住了测试数据。确保少样本示例为合成数据 |
| 没有评估/标注列 | 先运行评估(通过 Arize UI 或 SDK),然后重新导出 |
| 找不到实验输出列 | 列名为 {experiment_name}.output——通过 ax experiments get 检查确切的实验名称 |
jq 解析 Span JSON 时出错 | 确保目标文件路径正确(例如,使用 --stdout > spans.json 生成的 spans.json) |