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限制生成长度,过小会导致回答被截断,过大则增加延迟和费用。
下表给出常见任务的起始参数建议,实际值需通过小批量评测调整:
| 任务类型 | temperature | top_p | max_tokens | 说明 |
|---|---|---|---|---|
| 结构化抽取 | 0.1 | 1.0 | 256 | 追求稳定,避免自由发挥 |
| 客服问答 | 0.3 | 1.0 | 512 | 兼顾准确与自然 |
| 营销文案 | 0.8 | 1.0 | 800 | 鼓励多样性 |
| 代码生成 | 0.2 | 1.0 | 1024 | 低随机性减少语法错误 |
此外,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或环境变量,避免硬编码。
把上述四部分串起来看:系统提示和少样本示例共同构成“输入上下文”,参数决定“采样行为”,API调用负责“传输与返回”,而usage和异常码提供“可观测性”。一个可复现的实践流程是:先用系统提示固定角色,再用2~3个示例校准格式,然后用低temperature跑通链路,最后用评测集对比不同参数组合,记录每次变更的输入、参数和输出,形成可回溯的提示版本管理。这样,提示工程就不再是凭感觉调参,而是有输入、有过程、有观测、有判断的工程实践。