第1章 系统提示与角色设定¶
学习目标¶
- 理解 System Prompt 在 LLM 调用中的核心作用与优先级机制
- 掌握专家、助手、评审三类角色设定的设计方法与适用场景
- 学会角色设定技巧:身份、能力边界、语气、约束
- 掌握上下文窗口管理策略,避免 Token 超限与信息淹没
- 能够对比不同角色设定对模型输出的实际影响
问题导入¶
某电商团队上线了一个客服 Agent,希望它能解答订单、退换货、物流等问题。第一版只给了一段很简单的 Prompt:"你是一个客服,请回答用户问题。"上线后却频频出问题:
- 用户问"帮我写一首诗",客服居然真的写了一首,偏离业务范围;
- 用户问"我的订单为什么还没到",客服回答"我是 AI,无法查询订单",毫无用处;
- 同样的问题,不同时段回答风格差异巨大,时而正式时而随意。
问题出在哪里?根本原因是没有设计好 System Prompt 和角色设定。System Prompt 决定了模型的"人格""能力边界"和"行为准则",是 Agent 稳定性的第一道防线。本章将系统讲解如何设计高质量的 System Prompt 与角色设定。
核心概念¶
1. System Prompt 的作用¶
在 OpenAI 等 LLM API 中,消息分为三类:system、user、assistant。其中 system 消息具有最高优先级,用于设定模型的整体行为框架:
- 角色定义:告诉模型"你是谁"
- 能力边界:告诉模型"你能做什么、不能做什么"
- 行为规范:告诉模型"应该怎么做"
- 语气风格:告诉模型"用什么口吻说话"
System Prompt 会被模型在每次推理时优先参考,对整个对话起"宪法"作用。
2. 角色设计的三种典型模式¶
| 模式 | 适用场景 | 特点 |
|---|---|---|
| 专家模式 | 医疗、法律、技术支持 | 深度专业、严谨、引用依据 |
| 助手模式 | 客服、办公、问答 | 通用、友好、任务导向 |
| 评审模式 | 代码审查、文案审核 | 批判性、多角度、给改进建议 |
3. 角色设定技巧¶
一个完整的角色设定通常包含以下要素:
- 身份(Identity):明确角色名称、职业、经验
- 能力边界(Capability):明确能回答与不能回答的范围
- 行为约束(Constraint):输出格式、长度、禁忌词
- 语气风格(Tone):正式/亲切/严谨
- 示例锚定(Anchoring):通过少量示例固定风格
4. 上下文窗口管理¶
LLM 的上下文窗口有限(如 GPT-4o 为 128K Token),System Prompt 会占用固定配额。管理策略:
- 精简原则:System Prompt 控制在 500-2000 Token 以内
- 分层加载:基础角色常驻,业务规则按需注入
- 动态裁剪:对话历史超过阈值时摘要压缩
- 优先级排序:重要规则放前面,模型对首尾内容更敏感
原理图¶
flowchart TB
subgraph SP["System Prompt 结构"]
A[角色身份 Identity]
B[能力边界 Capability]
C[行为约束 Constraint]
D[语气风格 Tone]
E[示例锚定 Anchoring]
end
SP --> F[模型推理引擎]
G[用户消息 User Message] --> F
H[对话历史 History] --> F
F --> I[模型输出 Response]
style A fill:#e1f5fe
style B fill:#f3e5f5
style C fill:#e8f5e9
style D fill:#fff3e0
style E fill:#fce4ec
style F fill:#fff9c4
style I fill:#c8e6c9
System Prompt 的五个要素共同构成模型的"行为宪法",与用户消息、对话历史一起送入推理引擎,决定最终输出。
示例代码¶
下面的示例展示三种不同角色设定对同一问题的不同回答效果。
"""
第1章示例:不同角色设定对比
演示专家、助手、评审三种角色 Prompt 的差异
"""
from openai import OpenAI
client = OpenAI()
def chat(system_prompt: str, user_message: str) -> str:
"""通用对话函数,便于对比不同 System Prompt"""
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": user_message},
],
temperature=0.3,
)
return response.choices[0].message.content
# ========== 1. 专家模式:法律顾问 ==========
LEGAL_EXPERT_PROMPT = """你是一名拥有 10 年执业经验的中国注册律师,专长于合同法与劳动法。
【能力边界】
- 可以回答中国内地法律问题
- 不能回答境外法律问题,需提示用户咨询当地律师
- 不能提供具体诉讼建议,只能做一般性法律分析
【行为规范】
- 回答需引用相关法条(如《民法典》第 X 条)
- 若问题信息不足,需追问而非臆测
- 输出结构:结论 + 法律依据 + 建议
【语气】严谨、客观、中立"""
# ========== 2. 助手模式:电商客服 ==========
CS_ASSISTANT_PROMPT = """你是"优品电商"的智能客服助手小优。
【职责】
- 处理订单查询、退换货、物流追踪、商品咨询
- 无法处理的问题,引导用户联系人工客服(电话 400-xxx-xxxx)
【行为规范】
- 回答前先确认用户身份(订单号或手机号)
- 每次回复不超过 200 字
- 禁止承诺未经系统确认的退款/赔偿
- 遇到投诉情绪安抚优先
【语气】亲切、耐心、专业,称呼用户为"您\""""
# ========== 3. 评审模式:代码审查 ==========
CODE_REVIEWER_PROMPT = """你是一名资深 Python 代码审查专家,负责评审团队成员提交的代码。
【审查维度】
1. 正确性:逻辑错误、边界情况
2. 可读性:命名、注释、结构
3. 安全性:注入、敏感信息泄露
4. 性能:时间/空间复杂度
【输出格式】
按以下结构输出:
- 总体评价:通过/需修改/需重写
- 问题清单:按严重程度排序(严重/一般/建议)
- 改进建议:给出具体修改示例
【语气】客观、建设性,先肯定优点再指出问题"""
if __name__ == "__main__":
question = "我买的衣服三天了还没发货,怎么办?"
print("===== 助手模式(客服)=====")
print(chat(CS_ASSISTANT_PROMPT, question))
print("\n===== 专家模式(律师)=====")
print(chat(LEGAL_EXPERT_PROMPT, "公司不签劳动合同怎么办?"))
print("\n===== 评审模式(代码审查)=====")
print(chat(CODE_REVIEWER_PROMPT, "请审查代码:def add(a,b):return a+b"))
上下文窗口管理示例¶
"""
上下文窗口管理:对话历史超过阈值时进行摘要压缩
"""
from openai import OpenAI
client = OpenAI()
MAX_HISTORY_TOKENS = 3000 # 对话历史 Token 上限
def count_tokens(text: str) -> int:
"""粗略估算 Token 数(中文约 1 字 = 1.5 Token)"""
return int(len(text) * 1.5)
def summarize_history(history: list[dict]) -> str:
"""将历史对话摘要为一段文字"""
transcript = "\n".join(
f"{m['role']}: {m['content']}" for m in history
)
resp = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": "将以下对话摘要为 200 字以内,保留关键信息。"},
{"role": "user", "content": transcript},
],
)
return resp.choices[0].message.content
def build_messages(system_prompt: str, history: list[dict], user_msg: str):
"""构建消息列表,超限时自动压缩历史"""
history_text = "".join(m["content"] for m in history)
if count_tokens(history_text) > MAX_HISTORY_TOKENS:
summary = summarize_history(history)
history = [{"role": "system", "content": f"历史摘要:{summary}"}]
return [
{"role": "system", "content": system_prompt},
*history,
{"role": "user", "content": user_msg},
]
企业案例¶
客服 Agent 角色设计¶
某大型电商公司的客服 Agent 经历了三个迭代版本:
V1(失败版):仅一句"你是客服"。问题:答非所问、越界回答、风格不稳定。
V2(改进版):加入职责与语气约束。问题:遇到投诉不会安抚,遇到退款就答应,造成损失。
V3(生产版):采用分层结构设计:
[基础角色] 身份 + 语气(常驻)
[业务规则] 各业务线 SOP(按用户意图动态加载)
[安全约束] 禁止承诺、敏感词过滤(常驻)
[示例锚定] 3-5 个典型对话示例(常驻)
V3 上线后,客服首次解决率从 45% 提升到 78%,投诉率下降 60%。关键经验:
- 角色设定不是"写一段话",而是"设计一套规则"
- 业务规则要可动态加载,避免单个 Prompt 过长
- 用少量示例锚定风格,比写一堆形容词更有效
常见问题¶
Q1:System Prompt 写多长合适?
A:建议 200-2000 Token。过短无法约束行为,过长占用上下文且模型可能"忘记"中间部分。生产环境推荐分层加载,基础角色常驻,业务规则按需注入。
Q2:模型不遵守 System Prompt 怎么办?
A:常见原因:①规则相互冲突;②规则太模糊(如"要友好"不如"称呼用户为您、回复不超过200字");③用户消息"越狱"覆盖了系统设定。解决:规则具体化、冲突排查、配合 Guardrail(见第5章)。
Q3:角色设定是否会让模型"入戏太深"产生幻觉?
A:会。例如设定"你是律师"后,模型可能编造不存在的法条。需在 Prompt 中明确"不确定时回答不知道,禁止编造法条",并用 RAG 接入真实知识库(见第6卷)。
Q4:不同模型对 System Prompt 的遵守程度一样吗?
A:不一样。GPT-4 系列对 System Prompt 遵守度较高,开源小模型相对较弱。生产环境需针对具体模型做 A/B 测试。
面试题¶
-
简答题:System Prompt 与 User Prompt 在优先级上有何区别?为什么 System Prompt 更适合放行为约束?
-
设计题:为一个"儿童教育陪伴 Agent"设计 System Prompt,需考虑安全性和趣味性。
-
分析题:以下 Prompt 有什么问题,如何改进?"你是一个好客服,要热心帮助用户解决一切问题。"
参考要点:过于模糊("好客服"无标准)、边界缺失("一切问题"易越界)、无输出规范、无能力边界声明。
- 原理题:为什么说 System Prompt 是 Agent 稳定性的"第一道防线"?请结合上下文窗口与优先级机制说明。
练习题¶
-
对比实验:使用本章示例代码,针对同一个用户问题"我买的衣服褪色了",分别用三种角色模式(专家/助手/评审)生成回答,记录输出差异并分析原因。
-
Prompt 重写:将以下模糊 Prompt 改写为生产级 System Prompt:
"你是一个翻译助手,帮用户翻译。"
要求包含:身份、能力边界、输出格式、语气、至少 1 个示例。
-
上下文管理:编写一个函数,当对话轮数超过 10 轮时,自动将前 5 轮摘要压缩,保留近 5 轮原文。
-
角色设计:为一个"程序员技术问答 Agent"设计 System Prompt,要求:能回答 Python/Java/Go 三种语言问题,不能回答非编程问题,回答需包含代码示例,遇到不确定的问题需明确说明。
小结¶
System Prompt 是与 LLM 沟通的"宪法",决定了模型的人格、能力边界和行为准则。本章核心要点:
- 角色设计有三种典型模式:专家(深度严谨)、助手(通用友好)、评审(批判建设性),根据业务场景选择。
- 角色设定五要素:身份、能力边界、行为约束、语气风格、示例锚定,缺一不可。
- 规则要具体:与其说"要友好",不如说"称呼用户为您、回复不超过200字、先安抚再解决"。
- 上下文要管理:System Prompt 控制在合理长度,对话历史超限时摘要压缩,保证关键信息不被淹没。
- 分层加载:生产级 Agent 应采用"基础角色常驻 + 业务规则动态加载"的架构。
下一章将学习 Few-shot 与模板技术,通过示例和模板化管理进一步提升 Prompt 的可控性与可维护性。