4. 提示工程与模型交互基础

在Azure OpenAI平台上构建生成式AI应用,模型本身的能力只是起点,真正决定输出质量的是我们如何组织提示、如何选择参数、以及如何通过API稳定地把这些意图传递给模型。本节围绕四个相互关联的环节展开:系统提示定义角色与边界,少样本学习提供行为示范,参数调优控制生成风格,API调用则把前三者落地为可复现的工程实现。

系统提示:为模型设定稳定的行为基线

系统提示(system message)是对话中优先级最高的指令层,它不参与用户可见的对话内容,却持续约束模型的角色、语气、输出格式和拒答策略。在Azure OpenAI的Chat Completions接口中,消息数组通常以{"role": "system", "content": "..."}开头。一个有效的系统提示应包含三要素:身份定义、任务边界、输出约束。例如,为客服场景设计系统提示时,可以写成:

{
  "role": "system",
  "content": "你是Contoso公司的技术支持助手。只回答与产品使用相关的问题;遇到账户安全、退款或法律问题,回复'该问题需要人工客服处理'。回答使用简体中文,控制在120字以内,先给结论再给一步操作建议。"
}

这里“只回答……”“遇到……回复……”是边界,“先给结论再给一步操作建议”是格式约束。系统提示越具体,模型在多轮对话中漂移的概率越低。需要注意的是,系统提示并非绝对安全屏障,用户仍可能通过注入攻击绕过限制,因此生产环境应结合内容过滤和输出校验。

少样本学习:用示例代替抽象描述

当任务难以用规则描述清楚时,少样本学习(few-shot learning)比单纯增加形容词更有效。做法是在消息数组中插入若干“用户—助手”示例对,让模型从示例中归纳模式。示例应覆盖典型输入、边界输入和期望输出格式。以工单分类为例:

{"role": "user", "content": "登录时提示密码错误,但我确定密码没错"}
{"role": "assistant", "content": "类别:账户访问;优先级:高;建议:引导用户使用自助重置密码"}
{"role": "user", "content": "报表导出按钮点击后没有反应"}
{"role": "assistant", "content": "类别:功能缺陷;优先级:中;建议:收集浏览器版本与工单编号,转交前端团队"}

示例数量通常2~5个即可,过多会占用上下文窗口并增加成本。关键原则是:示例的格式必须与期望输出完全一致,示例之间不要自相矛盾,且应把最难的边界案例放在最后,因为模型对靠近当前问题的示例更敏感。

参数调优:temperature、top_p与max_tokens的协同

Azure OpenAI的Chat Completions支持多个采样参数,其中最重要的是temperature、top_p和max_tokens。temperature控制概率分布的平滑程度:值越低(如0.1~0.3),输出越确定、越适合分类和抽取;值越高(如0.7~1.0),输出越多样,适合创意写作。top_p采用核采样,通常建议只调整其中一个,另一个保持默认。max_tokens限制生成长度,过小会导致回答被截断,过大则增加延迟和费用。

下表给出常见任务的起始参数建议,实际值需通过小批量评测调整:

任务类型temperaturetop_pmax_tokens说明
结构化抽取0.11.0256追求稳定,避免自由发挥
客服问答0.31.0512兼顾准确与自然
营销文案0.81.0800鼓励多样性
代码生成0.21.01024低随机性减少语法错误

此外,frequency_penalty和presence_penalty可用于抑制重复,但不宜同时调高,否则会损害连贯性。参数调优不是一次性工作,应建立评测集,用同一批输入对比不同参数组合的输出质量。

Azure OpenAI API调用实践

在Azure上调用模型需要三个关键信息:资源终结点(endpoint)、部署名称(deployment name)和API版本。部署名称是你在Azure OpenAI Studio中为某个模型创建的部署标识,不一定等于模型名。以下Python示例使用openai库的Azure客户端:

from openai import AzureOpenAI

client = AzureOpenAI(
    azure_endpoint="https://contoso-openai.openai.azure.com/",
    api_key="<your-api-key>",
    api_version="2024-10-21"
)

response = client.chat.completions.create(
    model="gpt-4o-mini-deploy",   # 部署名称
    messages=[
        {"role": "system", "content": "你是Contoso技术支持助手,回答控制在120字内。"},
        {"role": "user", "content": "如何重置密码?"}
    ],
    temperature=0.3,
    max_tokens=256
)

print(response.choices[0].message.content)
print(response.usage)

调用时需关注response.usage中的prompt_tokens、completion_tokens和total_tokens,它们是成本核算和配额管理的基础。若返回429状态码,说明触发了速率限制,应实现指数退避重试;若返回400,通常与消息格式或参数越界有关。生产环境还应把API密钥放入Key Vault或环境变量,避免硬编码。

Azure OpenAI 提示工程与调用链路 提示构建层 System Message 角色 · 边界 · 输出格式 Few-shot 示例对 user → assistant 2~5 个,格式一致 User Message 当前实际输入 采样参数 temperature · top_p · max_tokens Azure OpenAI API chat.completions.create endpoint + deployment api_version 2024-10-21 输出与观测 choices[0].message 模型回复文本 usage 用量 prompt_tokens completion_tokens · total_tokens 异常处理 429 退避重试 · 400 检查参数 评测与迭代 固定评测集对比参数组合 根据评测结果调整提示与参数

把上述四部分串起来看:系统提示和少样本示例共同构成“输入上下文”,参数决定“采样行为”,API调用负责“传输与返回”,而usage和异常码提供“可观测性”。一个可复现的实践流程是:先用系统提示固定角色,再用2~3个示例校准格式,然后用低temperature跑通链路,最后用评测集对比不同参数组合,记录每次变更的输入、参数和输出,形成可回溯的提示版本管理。这样,提示工程就不再是凭感觉调参,而是有输入、有过程、有观测、有判断的工程实践。