mcpField
A
arize-prompt-optimization

arize-prompt-optimization

github.com/githubAgent 工作流40.6k1.1k 次安装1 天前更新
代码仓库

关于 arize-prompt-optimization

面向使用 Arize 和 `ax` 命令行的团队,指导开展提示词优化。流程涵盖从 Trace 提取提示词和效果数据、修订提示词,以及通过实验测试和比较变更。

主要功能

  1. 01从 Trace Span 提取提示词
  2. 02检查标注和评估结果
  3. 03关联数据集与实验输出
  4. 04修订提示词并保留变量
  5. 05通过实验比较提示词版本

适用场景

  1. 01排查失败的 LLM Trace
  2. 02发现低分背后的提示词问题
  3. 03针对数据集测试修订版本
  4. 04比较两个版本并检查回归

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/github/awesome-copilot --skill arize-prompt-optimization

安装后在 Claude Code 中输入/arize-prompt-optimization确认已加载。

附带文件references/ax-profiles.mdreferences/ax-setup.md

详细介绍

Arize 提示词优化技能

SPACE — 所有 --space 标志和 ARIZE_SPACE 环境变量都接受空间名称(例如 my-workspace)或 base64 空间 ID(例如 U3BhY2U6...)。使用 ax spaces list 查找你的空间。

概念

提示词在追踪数据中的位置

大模型应用按照 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模型响应文本查看大模型生成了什么
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追踪数据输入到大模型的内容
attributes.output.value追踪数据大模型生成的内容
{experiment_name}.output实验运行特定实验的输出

前置条件

直接开始执行任务 —— 运行你所需要的 ax 命令。不要预先检查版本、环境变量或 profiles。

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

  • command not found 或版本错误 → 参见 references/ax-setup.md
  • 401 Unauthorized / 缺少 API key → 运行 ax profiles show 以检查当前 profile。如果 profile 缺失或 API key 有误,请按照 references/ax-profiles.md 创建/更新它。如果用户没有 key,请引导他们前往 https://app.arize.com/admin > API Keys
  • Space 未知 → 运行 ax spaces list 按名称选择,或询问用户
  • Project 不明确 → 询问用户,或运行 ax projects list -o json --limit 100 并作为可选项呈现
  • LLM 提供商调用失败(缺少 OPENAI_API_KEY / ANTHROPIC_API_KEY)→ 运行 ax ai-integrations list --space SPACE 检查是否有平台托管的凭据。如果不存在,请让用户提供 key,或通过 arize-ai-provider-integration skill 创建集成
  • 安全: 绝不要读取 .env 文件或在文件系统中搜索凭据。Arize 凭据使用 ax profiles,LLM 提供商 key 使用 ax ai-integrations。如果通过这些渠道无法获得凭据,请询问用户。

阶段 1:提取当前提示词

查找包含提示词的 LLM span
# Sample LLM spans (where prompts live)
ax spans export PROJECT --filter "attributes.openinference.span.kind = 'LLM'" -l 10 --stdout

# Filter by model
ax spans export PROJECT --filter "attributes.llm.model_name = 'gpt-4o'" -l 10 --stdout

# Filter by span name (e.g., a specific LLM call)
ax spans export PROJECT --filter "name = 'ChatCompletion'" -l 10 --stdout
导出一个 trace 以检查提示词结构
# Export all spans in a trace
ax spans export PROJECT --trace-id TRACE_ID

# Export a single span
ax spans export PROJECT --span-id SPAN_ID
从导出的 JSON 中提取提示词
# Extract structured chat messages (system + user + assistant)
jq '.[0] | {
  messages: .attributes.llm.input_messages,
  model: .attributes.llm.model_name
}' trace_*/spans.json

# Extract the system prompt specifically
jq '[.[] | select(.attributes.llm.input_messages.roles[]? == "system")] | .[0].attributes.llm.input_messages' trace_*/spans.json

# Extract prompt template and variables
jq '.[0].attributes.llm.prompt_template' trace_*/spans.json

# Extract from input.value (fallback for non-structured prompts)
jq '.[0].attributes.input.value' trace_*/spans.json
将提示词重建为 messages

一旦有了 span 数据,将提示词重建为 messages 数组:

[
  {"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 \
  --filter "status_code = 'ERROR' AND attributes.openinference.span.kind = 'LLM'" \
  -l 20 --stdout

# Find spans with low eval scores
ax spans export PROJECT \
  --filter "annotation.correctness.label = 'incorrect'" \
  -l 20 --stdout

# Find spans with high latency (may indicate overly complex prompts)
ax spans export PROJECT \
  --filter "attributes.openinference.span.kind = 'LLM' AND latency_ms > 10000" \
  -l 20 --stdout

# Export error traces for detailed inspection
ax spans export PROJECT --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:优化提示词

优化元提示词

使用此模板生成提示词的改进版本。填入三个占位符,并将其发送给你的 LLM(GPT-4o、Claude 等):

You are an expert in prompt optimization. Given the original baseline prompt
and the associated performance data (inputs, outputs, evaluation labels, and
explanations), generate a revised version that improves results.

ORIGINAL BASELINE PROMPT
========================

{PASTE_ORIGINAL_PROMPT_HERE}

========================

PERFORMANCE DATA
================

The following records show how the current prompt performed. Each record
includes the input, the LLM output, and evaluation feedback:

{PASTE_RECORDS_HERE}

================

HOW TO USE THIS DATA

1. Compare outputs: Look at what the LLM generated vs what was expected
2. Review eval scores: Check which examples scored poorly and why
3. Examine annotations: Human feedback shows what worked and what didn't
4. Identify patterns: Look for common issues across multiple examples
5. Focus on failures: The rows where the output DIFFERS from the expected
   value are the ones that need fixing

ALIGNMENT STRATEGY

- If outputs have extra text or reasoning not present in the ground truth,
  remove instructions that encourage explanation or verbose reasoning
- If outputs are missing information, add instructions to include it
- If outputs are in the wrong format, add explicit format instructions
- Focus on the rows where the output differs from the target -- these are
  the failures to fix

RULES

Maintain Structure:
- Use the same template variables as the current prompt ({var} or {{var}})
- Don't change sections that are already working
- Preserve the exact return format instructions from the original prompt

Avoid Overfitting:
- DO NOT copy examples verbatim into the prompt
- DO NOT quote specific test data outputs exactly
- INSTEAD: Extract the ESSENCE of what makes good vs bad outputs
- INSTEAD: Add general guidelines and principles
- INSTEAD: If adding few-shot examples, create SYNTHETIC examples that
  demonstrate the principle, not real data from above

Goal: Create a prompt that generalizes well to new inputs, not one that
memorizes the test data.

OUTPUT FORMAT

Return the revised prompt as a JSON array of messages:

[
  {"role": "system", "content": "..."},
  {"role": "user", "content": "..."}
]

Also provide a brief reasoning section (bulleted list) explaining:
- What problems you found
- How the revised prompt addresses each one
准备性能数据

在粘贴到模板之前,将记录格式化为 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
}]' trace_*/spans.json
应用修订后的提示词

在 LLM 返回修订后的 messages 数组后:

  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 和 ax experiments export EXP_B
  3. 比较平均分数、失败率和具体示例的翻转情况
  4. 检查回归 —— 使用提示词 A 通过但使用提示词 B 失败的示例

提示词工程最佳实践

在编写或修改提示词时,请应用以下实践:

技巧适用场景示例
清晰、详细的指令输出含糊或偏离主题“将情感分类为恰好以下之一:正面、负面、中性”
将指令放在开头模型忽略了后面的指令将任务描述放在示例之前
逐步拆解复杂的多步骤流程“首先抽取实体,然后对每个实体分类,最后总结”
明确的角色设定需要一致的风格/语气“你是一位资深金融分析师,为机构投资者撰写内容”
分隔符标记各部分内容混在一起使用 ---、### 或 XML 标签将输入与指令分隔开
少样本示例输出格式需要明确展示 2-3 组合成的输入/输出示例
输出长度说明回复过长或过短“用恰好 2-3 句话回答”
推理指令准确性至关重要“在回答前逐步思考”
“我不知道”准则存在幻觉风险“如果答案不在提供的上下文中,请说‘我没有足够的信息’”
变量保留

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

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

工作流

根据失败 trace 优化提示词
  1. 查找失败的 trace:
    ax traces list PROJECT --filter "status_code = 'ERROR'" --limit 5
    
  2. 导出该 trace:
    ax spans export PROJECT --trace-id TRACE_ID
    
  3. 从 LLM span 中提取提示词:
    jq '[.[] | select(.attributes.openinference.span.kind == "LLM")][0] | {
      messages: .attributes.llm.input_messages,
      template: .attributes.llm.prompt_template,
      output: .attributes.output.value,
      error: .attributes.exception.message
    }' trace_*/spans.json
    
  4. 根据错误消息或输出确定失败原因
  5. 用提示词和错误上下文填写优化元提示词(第 3 阶段)
  6. 应用修改后的提示词
使用数据集和实验进行优化
  1. 查找数据集和实验:
    ax datasets list --space SPACE
    ax experiments list --dataset DATASET_NAME --space SPACE
    
  2. 导出两者:
    ax datasets export DATASET_NAME --space SPACE
    ax experiments export EXPERIMENT_NAME --dataset DATASET_NAME --space SPACE
    
  3. 为元提示词准备连接后的数据
  4. 运行优化元提示词
  5. 使用修改后的提示词创建新实验以衡量改进效果
调试产生错误格式的提示词
  1. 导出输出格式错误的 span:
    ax spans export PROJECT \
      --filter "attributes.openinference.span.kind = 'LLM' AND annotation.format.label = 'incorrect'" \
      -l 10 --stdout > bad_format.json
    
  2. 查看 LLM 实际产生的内容与预期内容的差异
  3. 向提示词添加明确的格式指令(JSON schema、示例、分隔符)
  4. 常见修复方法:添加一个少样本示例,展示确切的期望输出格式
减少 RAG 提示词中的幻觉
  1. 查找模型产生幻觉的 trace:
    ax spans export PROJECT \
      --filter "annotation.faithfulness.label = 'unfaithful'" \
      -l 20 --stdout
    
  2. 同时导出并检查检索器 + LLM span:
    ax spans export PROJECT --trace-id TRACE_ID
    jq '[.[] | {kind: .attributes.openinference.span.kind, name, input: .attributes.input.value, output: .attributes.output.value}]' trace_*/spans.json
    
  3. 检查检索到的上下文是否实际包含答案
  4. 向系统提示词添加依据指令:“仅使用所提供上下文中的信息。如果答案不在上下文中,请如实说明。”

故障排查

问题解决方案
ax: command not found参见 references/ax-setup.md
No profile found未配置 profile。参见 references/ax-profiles.md 创建一个。
span 上没有 input_messages检查 span 类型 —— Chain/Agent span 将提示词存储在子 LLM span 上,而不是自身
提示词模板为 null并非所有插桩都会生成 prompt_template。请改用 input_messages 或 input.value
优化后变量丢失验证修改后的提示词是否保留了原始提示词中的所有 {var} 占位符
优化后效果变差检查是否过拟合 —— 元提示词可能已记住了测试数据。确保少样本示例是合成的
没有 eval/annotation 列先运行评估(通过 Arize UI 或 SDK),然后重新导出
找不到实验输出列列名为 {experiment_name}.output —— 通过 ax experiments get 检查确切的实验名称
jq 在 span JSON 上报错确保指向了正确的文件路径(例如 trace_*/spans.json)

评论

支持 Markdown