用 Amazon Bedrock 同时优化提示词并完成多模型迁移

2026-07-30 26 预计阅读时间: 1 分钟
来源: aws.amazon.com AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:10 分钟

更换大模型往往不是修改一个模型 ID 那么简单。同一条提示词在不同模型上的指令遵循、输出格式、延迟和成本都可能变化,团队通常要反复改写提示词并运行评测。Amazon Bedrock Advanced Prompt Optimization 将这段流程集中起来:一次可以面向最多 5 个模型优化提示词,并比较原始版本与优化版本在质量、延迟和成本上的表现。

模型迁移为什么会卡在提示词上

成熟应用里的提示词通常包含角色定义、任务说明、上下文、约束条件和输出格式。它们可能已经针对当前模型的行为做过大量微调,例如:

  • 用特定措辞强调 JSON 输出,避免模型添加解释文字。
  • 用少样本示例约束分类标签或字段顺序。
  • 通过较长的系统指令减少遗漏,但同时增加输入 token 和延迟。
  • 针对某个模型的指令遵循特点安排约束的位置。

迁移到新模型后,这些经验不一定继续有效。新模型可能用更短的提示词达到相同质量,也可能需要更明确的边界、示例或输出模式。如果只比较几条人工挑选的输入,很容易把偶然结果误判为整体提升。

Advanced Prompt Optimization 的关键价值不只是“改写提示词”,而是把候选模型和候选提示词放进同一个比较过程。最多同时覆盖 5 个模型,意味着团队可以同时回答两个问题:哪一个模型更适合当前任务,以及每个模型应该使用什么提示词。

用质量、延迟和成本做三维决策

模型迁移不能只看回答是否“更聪明”。生产决策至少需要三类指标:

维度 建议观察项 常见风险
质量 正确率、格式通过率、事实一致性、人工评分 测试集过小或只包含简单样本
延迟 中位数、P95、超时率 平均值掩盖长尾请求
成本 输入 token、输出 token、单任务估算成本 优化后输出变长,抵消模型单价优势

平台提供原始提示词与优化提示词之间的对比,但评测数据仍然决定结果是否可信。建议从真实流量中抽取经过脱敏的样本,并覆盖正常输入、边界情况、长上下文和容易失败的请求。对于客服回复、内容审核等任务,还应把安全性和合规性加入质量评分。

不要急着选出所有指标上的“总冠军”。面向在线交互的功能可能优先考虑 P95 延迟;批处理任务更关注单位成本;高风险决策则应该为质量设置硬门槛,再在合格候选中比较成本。

可以这样实践:建立一个迁移前的本地基线

下面的 Python 脚本使用 Amazon Bedrock Runtime 的 Converse API,对多个模型运行同一组样本,记录响应、延迟和 token 用量。它不是 Advanced Prompt Optimization 服务接口的替代品,而是一个可复制的迁移基线工具:先保存当前表现,再将平台生成的优化提示词放回脚本复测。

运行前需要配置 AWS 凭证、启用目标模型访问权限,并安装最新版 Boto3。把 BEDROCK_MODEL_IDS 改成当前区域可用的模型 ID,最多可填写 5 个,以便和优化任务保持一致。

python -m venv .venv
source .venv/bin/activate
pip install --upgrade boto3

export AWS_REGION=us-east-1
export BEDROCK_MODEL_IDS='model-id-a,model-id-b'
python compare_prompts.py

创建 compare_prompts.py

import json
import os
import time
from statistics import median

import boto3

REGION = os.getenv("AWS_REGION", "us-east-1")
MODEL_IDS = [
    value.strip()
    for value in os.environ["BEDROCK_MODEL_IDS"].split(",")
    if value.strip()
]

if not 1 <= len(MODEL_IDS) <= 5:
    raise SystemExit("BEDROCK_MODEL_IDS must contain between 1 and 5 model IDs")

SYSTEM_PROMPT = """You classify support requests.
Return JSON only, using this schema:
{"category": "billing|technical|account", "urgent": true|false}
Do not add fields or explanatory text.
"""

SAMPLES = [
    "I was charged twice for the same subscription.",
    "Production API calls started returning 503 errors.",
    "I cannot reset my password and need access today.",
]

client = boto3.client("bedrock-runtime", region_name=REGION)
results = []

for model_id in MODEL_IDS:
    latencies = []
    input_tokens = 0
    output_tokens = 0

    for sample in SAMPLES:
        started = time.perf_counter()
        response = client.converse(
            modelId=model_id,
            system=[{"text": SYSTEM_PROMPT}],
            messages=[
                {
                    "role": "user",
                    "content": [{"text": sample}],
                }
            ],
            inferenceConfig={"temperature": 0, "maxTokens": 100},
        )
        elapsed_ms = (time.perf_counter() - started) * 1000
        usage = response.get("usage", {})
        text = response["output"]["message"]["content"][0]["text"]

        try:
            parsed = json.loads(text)
            format_valid = set(parsed) == {"category", "urgent"}
        except (json.JSONDecodeError, TypeError):
            format_valid = False

        latencies.append(elapsed_ms)
        input_tokens += usage.get("inputTokens", 0)
        output_tokens += usage.get("outputTokens", 0)
        results.append(
            {
                "model_id": model_id,
                "input": sample,
                "output": text,
                "format_valid": format_valid,
                "latency_ms": round(elapsed_ms, 1),
            }
        )

    print(
        json.dumps(
            {
                "model_id": model_id,
                "median_latency_ms": round(median(latencies), 1),
                "input_tokens": input_tokens,
                "output_tokens": output_tokens,
            },
            ensure_ascii=False,
        )
    )

with open("bedrock-comparison.json", "w", encoding="utf-8") as output_file:
    json.dump(results, output_file, ensure_ascii=False, indent=2)

脚本故意不硬编码价格。不同模型和区域的价格可能变化,应根据测试时适用的 Bedrock 定价,将输入、输出 token 分别换算成成本。质量部分也不应只依赖 format_valid:实际项目可以加入标准答案、规则评分或人工复核。

把优化过程接入发布流程

一个稳妥的迁移周期可以分成四步:

  1. 固定评测集和当前提示词,保存质量、P50/P95 延迟及 token 基线。
  2. 在 Advanced Prompt Optimization 中选择最多 5 个候选模型,生成并比较优化结果。
  3. 将候选提示词放入隔离环境,用同一评测集复测,并人工检查高风险样本。
  4. 先进行小流量灰度发布,同时保留旧模型和旧提示词作为回退路径。

提示词、模型 ID、推理参数和评测集版本应当一起纳入版本控制。只记录“提示词已优化”无法复现实验;至少还要保存温度、最大输出 token、模型版本、测试时间和评分规则。

采用时要守住的边界

自动优化可以把数周的逐模型调试压缩到更短的周期,但它不会替代领域验收。评测集存在偏差时,优化过程可能放大偏差;质量评分不覆盖安全要求时,更高的综合得分也不能证明结果可以上线。

落地前可以检查以下事项:

  • 候选数量不超过 5 个,并确认它们在目标区域和账户中可用。
  • 原始与优化提示词使用完全相同的评测样本和推理参数。
  • 成本计算同时包含输入与输出 token,而不是只比较模型单价。
  • 延迟查看分位数和失败率,而不是只看平均值。
  • 对关键业务样本进行人工复核,并准备可立即执行的回退方案。

把 Advanced Prompt Optimization 当作候选生成和统一比较工具,再用真实业务数据、自动化回归和灰度发布完成验证,模型迁移才能从一次性的提示词实验变成可重复的工程流程。


相关推荐