mcpField
A
arize-prompt-optimization

arize-prompt-optimization

github.com/arize-aiAgent 工作流673.3k 次安装6 天前更新
代码仓库

关于 arize-prompt-optimization

arize-prompt-optimization 是利用 Arize 追踪数据、数据集和实验结果改进 LLM 提示词的技能。它帮助团队提取提示词、分析反馈与失败案例、修订文本,并比较不同实验的结果。

主要功能

  1. 01从追踪 Span 提取提示词
  2. 02分析标注和评估结果
  3. 03关联数据集与实验输出
  4. 04指导提示词修订和变量检查
  5. 05比较提示词实验并检查回退

适用场景

  1. 01从追踪反馈中定位提示词问题
  2. 02用数据集示例修订提示词
  3. 03比较基线与修订版提示词结果
  4. 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.md
ax-setup.md
optimization-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>.labelLLM-as-judge 评估自动分类评估
eval.<name>.scoreLLM-as-judge 评估自动数值评分
eval.<name>.explanationLLM-as-judge 评估评估给出该评分的原因——对优化最有价值
attributes.input.value追踪数据输入 LLM 的内容
attributes.output.value追踪数据LLM 生成的内容
{experiment_name}.output实验运行特定实验的输出

前提条件

直接执行任务——运行所需的 ax 命令。不要事先检查版本、环境变量或配置文件。

如果 ax 命令失败,请根据错误进行排查:

  • command not found 或版本错误 → 参阅 references/ax-setup.md
  • 401 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 因范围或确认问题而暂停时,请采用相同的明确表述方式:

  1. 说明已找到该技能,例如:我在此仓库中找到了 arize-prompt-optimization 技能(如有帮助,可补充 skills/arize-prompt-optimization/SKILL.md)。
  2. 然后明确暂停,例如:调用该技能前,我需要先确认几个问题:
  3. 只提出阻碍此技能下一步 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
确定优化目标

查找失败中反复出现的模式:

  1. 将输出与真实值进行比较:LLM 输出与预期结果有哪些差异?
  2. 阅读评估说明:eval.*.explanation 会说明失败的原因
  3. 检查注释文本:人工反馈会描述具体问题
  4. 查找冗长程度不匹配的情况:输出是否比真实值过长或过短?
  5. 检查格式是否符合要求:输出是否采用了预期格式?

阶段 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 返回修订后的消息数组后:

  1. 并排比较原始提示词和修订后的提示词
  2. 验证所有模板变量均已保留
  3. 检查格式说明是否完整
  4. 全面部署前,先用几个示例进行测试

第 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 测试
  1. 针对同一数据集创建两个实验,分别使用不同版本的提示词
  2. 导出两者:ax experiments export EXP_A --dataset DATASET_NAME --space SPACE,然后对 EXP_B 执行相同操作
  3. 比较平均分数、失败率以及具体示例的结果变化
  4. 检查是否出现回归——即使用提示词 A 时通过、使用提示词 B 时失败的示例

提示词工程最佳实践

编写或修订提示词时,请遵循以下做法:

技巧适用场景示例
提供清晰、详细的说明输出含糊或偏离主题"将情感分类为以下选项之一,且只能选择一个:positive、negative、neutral"
将说明放在开头模型忽略后面的说明将任务描述放在示例之前
分步骤说明复杂的多步骤流程"先提取实体,再对每个实体分类,最后总结"
指定具体角色需要保持风格或语气一致"你是一位面向机构投资者撰写分析报告的高级金融分析师"
使用分隔符标记各部分容易混在一起使用 ---、### 或 XML 标签,将输入与说明分开
使用少样本示例需要明确输出格式展示 2-3 组模拟输入和输出
指定输出长度回复过长或过短"请用恰好 2-3 句话作答"
提供推理说明准确性至关重要"回答前请逐步思考"
说明「不知道」时该如何作答存在幻觉风险"如果答案不在提供的上下文中,请说『我没有足够的信息』"
变量保留

优化使用模板变量的提示词时:

  • 单花括号({variable}):Python f-string / Jinja 风格。Arize 中最常见。
  • 双花括号({{variable}}):Mustache 风格。框架要求时使用。
  • 优化过程中,绝不要添加或删除变量占位符
  • 绝不要重命名变量——运行时替换依赖变量的准确名称
  • 添加少样本示例时,请使用字面值,而不是变量占位符

工作流

优化包含失败记录的跟踪数据中的提示词
  1. 一次性导出完整的失败跟踪数据:
    ax traces export PROJECT --space SPACE --filter "status_code = 'ERROR'" -l 5 --stdout > failing.json
    
  2. 从 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. 根据错误消息或输出,确定失败原因
  4. 在优化元提示词(第 3 阶段)中填入提示词和错误上下文
  5. 应用修订后的提示词
使用数据集和实验进行优化
  1. 导出数据集和实验(运行 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
    
  2. 准备用于元提示词的关联数据
  3. 运行优化元提示词
  4. 使用修订后的提示词创建新实验,以衡量改进效果
调试生成错误格式的提示词
  1. 导出输出格式错误的跨度:
    ax spans export PROJECT --space SPACE \
      --filter "attributes.openinference.span.kind = 'LLM' AND annotation.format.label = 'incorrect'" \
      -l 10 --stdout > bad_format.json
    
  2. 查看 LLM 的实际输出与预期输出之间的差异
  3. 在提示词中添加明确的格式说明(JSON 架构、示例、分隔符)
  4. 常见修复方法:添加少样本示例,展示准确的目标输出格式
减少 RAG 提示词中的幻觉
  1. 查找模型出现幻觉的跟踪数据:
    ax spans export PROJECT --space SPACE \
      --filter "annotation.faithfulness.label = 'unfaithful'" \
      -l 20 --stdout
    
  2. 导出并检查检索器和 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
    
  3. 检查检索到的上下文是否确实包含答案
  4. 在系统提示词中添加依据说明:"只能使用提供的上下文中的信息。如果答案不在上下文中,请如实说明。"

故障排查

问题解决方案
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)

评论

支持 Markdown