概述

在使用大语言模型(如 ChatGPT)进行对话时,我们需要理解三种核心角色:system(系统)、user(用户)和 assistant(助手)。正确理解和使用这三种角色,是构建高质量 AI 对话应用的基础。

三种角色详解

system(系统角色)

定义: 系统角色用于设定对话的整体行为和上下文环境。

主要功能:

  • 🎯 明确对话的主题或领域(例如:技术支持、教育、娱乐等)
  • 👤 指示模型扮演特定角色(例如:老师、顾问、专家等)
  • 📋 设定回答的风格和规则
  • 🔧 定义模型的行为约束

特点:

  • 通常在对话开始时设置一次
  • 对整个对话过程产生持续影响
  • 不会在对话中间频繁改变

user(用户角色)

定义: 用户角色代表与系统进行交互的个体。

主要功能:

  • 💬 提出问题或请求
  • 📝 输入需要处理的信息
  • 🎤 通过文本、语音等形式与系统沟通

特点:

  • 通常是真实的人类用户或其他系统
  • 驱动对话的进展
  • 每次对话可以有多个 user 消息

assistant(助手角色)

定义: 助手角色代表模型生成的响应内容。

主要功能:

  • 🤖 理解用户输入并生成回复
  • 💡 提供信息、建议或执行操作
  • 🔄 存储模型的历史响应

特点:

  • 具有自然语言处理能力
  • 根据 system 设定的规则来生成回答
  • 可以被预先设置以提供上下文信息

实际应用示例

基础对话示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
curl -s https://api.openai.com/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR-API-KEY" \
-d '{
"model": "gpt-3.5-turbo-16k",
"messages": [
{
"role": "system",
"content": "您是足球专家,专注于提供足球相关的专业知识。"
},
{
"role": "user",
"content": "谁赢得了2018年的FIFA世界杯?"
},
{
"role": "assistant",
"content": "法国赢得了2018年的FIFA世界杯。"
},
{
"role": "user",
"content": "下一届FIFA世界杯什么时候举行?"
}
]
}'

角色说明:

  1. system:设定助手为"足球专家"
  2. user:提出第一个问题
  3. assistant:模型的回答(或预设的上下文)
  4. user:继续提问

实现多轮对话

核心思路

要让大模型记住历史问答,需要在每次请求中传递完整的对话上下文。实现方式是:

  • 初始化一个对话历史列表
  • 将每次的问题和回答追加到列表中
  • 在下次请求时将整个列表作为 messages 参数传递

Python 实现示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import openai

# 初始化对话历史
conversation_history = [
{
"role": "system",
"content": "你是一个智能助手,专注于提供技术支持。请记住用户的历史问题和你的回答,以便在后续对话中提供更好的帮助。"
}
]

def chat(user_input):
"""发送消息并获取回复"""
# 添加用户消息
conversation_history.append({
"role": "user",
"content": user_input
})

# 调用 API 生成响应
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=conversation_history
)

# 获取助手的回答
assistant_response = response['choices'][0]['message']['content']

# 保存助手回答到历史记录
conversation_history.append({
"role": "assistant",
"content": assistant_response
})

return assistant_response

# 第一轮对话
response1 = chat("我需要安装一个软件,你能告诉我怎么做吗?")
print(f"助手:{response1}")

# 第二轮对话(基于上下文)
response2 = chat("上次你提到如何安装软件,我想知道如何配置它。")
print(f"助手:{response2}")

Node.js 实现示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
const { Configuration, OpenAIApi } = require("openai");

const configuration = new Configuration({
apiKey: process.env.OPENAI_API_KEY,
});
const openai = new OpenAIApi(configuration);

// 初始化对话历史
const conversationHistory = [
{
role: "system",
content: "你是一个智能助手,专注于提供技术支持。"
}
];

async function chat(userInput) {
// 添加用户消息
conversationHistory.push({
role: "user",
content: userInput
});

// 调用 API
const response = await openai.createChatCompletion({
model: "gpt-3.5-turbo",
messages: conversationHistory
});

// 获取并保存助手回答
const assistantResponse = response.data.choices[0].message.content;
conversationHistory.push({
role: "assistant",
content: assistantResponse
});

return assistantResponse;
}

// 使用示例
(async () => {
const response1 = await chat("我需要安装一个软件,你能告诉我怎么做吗?");
console.log(`助手:${response1}`);

const response2 = await chat("上次你提到如何安装软件,我想知道如何配置它。");
console.log(`助手:${response2}`);
})();

历史对话管理

面临的问题

随着对话轮次增加,上下文会越来越长,可能导致:

  • 📈 Token 消耗增加,成本上升
  • ⏱️ 响应时间变慢
  • 🚫 超出模型的最大 token 限制

优化策略

策略一:对话摘要

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
def summarize_conversation(conversation_history):
"""对历史对话进行摘要"""
# 保留 system 消息
system_message = conversation_history[0]

# 对中间对话进行摘要
summary_prompt = "请简要总结以下对话的关键信息:\n"
for msg in conversation_history[1:-4]: # 保留最近4条消息
summary_prompt += f"{msg['role']}: {msg['content']}\n"

# 获取摘要
summary_response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[
{"role": "system", "content": "你是一个对话摘要助手。"},
{"role": "user", "content": summary_prompt}
]
)

summary = summary_response['choices'][0]['message']['content']

# 重构对话历史
new_history = [
system_message,
{"role": "assistant", "content": f"之前对话摘要:{summary}"},
*conversation_history[-4:] # 保留最近4条消息
]

return new_history

策略二:滑动窗口

1
2
3
4
5
6
7
8
MAX_HISTORY_LENGTH = 10  # 保留最近10条消息

def manage_conversation_history(conversation_history):
"""使用滑动窗口管理对话历史"""
if len(conversation_history) > MAX_HISTORY_LENGTH:
# 保留 system 消息和最近的消息
return [conversation_history[0]] + conversation_history[-(MAX_HISTORY_LENGTH-1):]
return conversation_history

策略三:外部存储

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import json
from datetime import datetime

class ConversationManager:
def __init__(self, user_id):
self.user_id = user_id
self.file_path = f"conversations/{user_id}.json"

def save_conversation(self, conversation_history):
"""保存对话到文件"""
data = {
"user_id": self.user_id,
"timestamp": datetime.now().isoformat(),
"conversation": conversation_history
}
with open(self.file_path, 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=2)

def load_conversation(self):
"""从文件加载对话"""
try:
with open(self.file_path, 'r', encoding='utf-8') as f:
data = json.load(f)
return data['conversation']
except FileNotFoundError:
return []

最佳实践

System 消息设计要点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# ✅ 好的 system 消息
good_system = {
"role": "system",
"content": """你是一位经验丰富的 Python 编程导师。

要求:
1. 用简单易懂的语言解释概念
2. 提供实际代码示例
3. 指出常见错误和最佳实践
4. 鼓励学习者提问

风格:友好、耐心、专业"""
}

# ❌ 不好的 system 消息
bad_system = {
"role": "system",
"content": "你是助手" # 太简单,缺乏具体指导
}

预设 Assistant 消息的技巧

1
2
3
4
5
6
7
8
9
10
# 为模型提供上下文或示例
conversation = [
{"role": "system", "content": "你是数学老师"},
{"role": "user", "content": "什么是勾股定理?"},
{
"role": "assistant",
"content": "勾股定理是直角三角形的基本定理,表述为:a² + b² = c²"
},
{"role": "user", "content": "能举个例子吗?"} # 模型会基于前面的回答继续
]

Token 使用优化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
def estimate_tokens(text):
"""粗略估算 token 数量(英文约 4 字符/token,中文约 1.5-2 字符/token)"""
return len(text) // 2

def optimize_conversation(conversation_history, max_tokens=3000):
"""控制对话历史的 token 数量"""
total_tokens = sum(estimate_tokens(msg['content']) for msg in conversation_history)

if total_tokens > max_tokens:
# 保留 system 和最近的消息
system_msg = conversation_history[0]
recent_msgs = []
current_tokens = estimate_tokens(system_msg['content'])

for msg in reversed(conversation_history[1:]):
msg_tokens = estimate_tokens(msg['content'])
if current_tokens + msg_tokens < max_tokens:
recent_msgs.insert(0, msg)
current_tokens += msg_tokens
else:
break

return [system_msg] + recent_msgs

return conversation_history

总结

角色使用要点

角色用途使用频率关键特点
system设定背景和规则对话开始时一次影响整体行为
user用户输入每次提问驱动对话
assistant模型回复每次回答存储历史

关键要点

  1. system 角色是设定模型行为的关键
  2. userassistant 交替出现构成对话
  3. 保留历史记录可实现多轮对话
  4. 需要合理管理历史记录以控制成本

参考资源


个人博客https://www.xiaowu95.wang/