第03章:多轮对话与上下文管理——让AI记住你说过的每句话
第03章:多轮对话与上下文管理——让AI记住你说过的每句话
3.1 单轮 vs 多轮:一个问题的两种命中的差距
单轮对话(每次都是新的上下文):
你:帮我分析这份数据
AI:[分析]
你:按月份拆开看
AI:[不知道你在说哪份数据]
多轮对话(有上下文记忆):
你:帮我分析这份销售数据
AI:[分析完成]
你:按月份拆开看
AI:[基于之前的数据,按月份分析] ✅
你:哪个月表现最差,分析原因
AI:[结合前两轮的数据,给出分析] ✅✅
多轮对话的核心价值:让AI的每次回复都基于之前所有对话的积累。
3.2 对话上下文管理的基本原理
AI的"记忆"来自两部分:
1. System Prompt(系统提示词):开场设定,只读一次
2. Conversation History(对话历史):每次对话都带上
AI并不是真的"记住"了——而是每次请求都会把历史对话一起发过去。
所以优化的关键是:管理对话历史的长度、结构和质量。
3.3 策略一:自动摘要压缩
对话超过一定轮数后,把历史对话压缩成摘要,保留关键信息:
import anthropic
client = anthropic.Anthropic()
MAX_TOKENS_PER_TURN = 4000 # 保守限制
def compress_conversation(conversation_history):
"""
当对话历史超过阈值时,压缩为摘要
"""
total_tokens = sum(len(msg["content"]) // 4 for msg in conversation_history)
if total_tokens < MAX_TOKENS_PER_TURN:
return conversation_history # 不需要压缩
# 调用AI压缩历史
compression_prompt = f"""
以下是一段AI对话历史,请压缩为一段不超过300字的摘要,
保留所有关键信息、决定、用户偏好和待处理事项。
对话历史:
{chr(10).join([f"用户:{m['user']}\nAI:{m['assistant']}" for m in conversation_history])}
摘要格式:
关键背景:[...]
用户偏好:[...]
已完成事项:[...]
待处理事项:[...]
"""
response = client.messages.create(
model="claude-opus-4-5",
max_tokens=500,
messages=[{"role": "user", "content": compression_prompt}]
)
compressed = [{
"role": "user",
"content": "[以上对话已压缩为摘要]",
"summary": response.content[0].text
}, {
"role": "assistant",
"content": "[对话已压缩,保留关键信息以便继续]"
}]
return compressed
3.4 策略二:长期记忆注入
除了对话历史,还有一个更持久的记忆层:长期记忆。
# 长期记忆存储(PostgreSQL / Redis / 文件都可以)
def save_long_term_memory(user_id, key, value):
conn = get_db_conn()
conn.execute("""
INSERT INTO user_memory (user_id, memory_key, memory_value, updated_at)
VALUES (%s, %s, %s, NOW())
ON CONFLICT (user_id, memory_key)
DO UPDATE SET memory_value = %s, updated_at = NOW()
""", (user_id, key, value, value))
conn.commit()
def load_long_term_memory(user_id):
conn = get_db_conn()
rows = conn.execute("""
SELECT memory_key, memory_value FROM user_memory
WHERE user_id = %s
""", (user_id,)).fetchall()
return {row["memory_key"]: row["memory_value"] for row in rows}
# 在每次对话开始时,把长期记忆注入上下文
def build_system_prompt_with_memory(user_id):
memory = load_long_term_memory(user_id)
memory_section = ""
if memory:
memory_section = "\n\n## 关于用户的长期记忆(请在回复时参考):\n"
for key, value in memory.items():
memory_section += f"- {key}:{value}\n"
return f"""
你是一名专业的AI助手,名字叫小明。
你的特点是:
- 专业、简洁、有耐心
- 回答问题时直接给结论,再解释原因
- 遇到不确定的事情,明确告知用户而不是胡乱猜测
{user_id}
你与用户有过一段合作历史,以下是相关信息:
{memory_section}
"""
3.5 策略三:Session 分层设计
不同类型的对话,适合放在不同的Session里:
Session A(日常助理)
→ 帮我查天气、设提醒、发消息
Session B(专业工作)
→ 数据分析、报告撰写、代码审查
Session C(长期项目)
→ 产品规划、战略讨论、创意发散
同一Session内的事项才有上下文继承。 日常闲聊不要和专业工作混在一起,否则AI既记不住你喜欢的风格,也没法专注专业判断。
3.6 实战:用 OpenClaw 实现多轮记忆
# 在 OpenClaw 的 skill 配置里启用对话记忆
SKILL_MEMORY_CONFIG = {
"memory_enabled": True,
"memory_backend": "postgresql", # 或 redis / file
"memory_table": "conversation_memory",
"auto_compress_after_turns": 10,
"compress_threshold_tokens": 6000,
"long_term_memory_keys": [
"user_preferences",
"onboarding_completed",
"active_projects",
"important_context"
]
}
CREATE TABLE conversation_memory (
id SERIAL PRIMARY KEY,
user_id VARCHAR(100),
session_id VARCHAR(100),
turn_number INTEGER,
user_message TEXT,
ai_response TEXT,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE TABLE user_long_term_memory (
id SERIAL PRIMARY KEY,
user_id VARCHAR(100),
memory_key VARCHAR(100),
memory_value TEXT,
confidence FLOAT DEFAULT 1.0,
updated_at TIMESTAMP DEFAULT NOW(),
UNIQUE(user_id, memory_key)
);
3.7 常见问题
Q:AI忘记了之前说过的事情怎么办? A:主动在对话开头提醒它,比如"继续上次我们讨论的XX项目"。
Q:对话太长了,速度变慢怎么办? A:用自动摘要压缩策略(本章3.3节),把超过10轮的历史压缩成摘要。
Q:不同设备/平台之间记忆能同步吗? A:把记忆存储在后端数据库(PostgreSQL/Redis),而不是前端Session。
落地动作
- 检查你当前使用的AI工具,支持多少轮上下文,接近上限时如何处理
- 设计你的Session分层结构(日常/专业/项目分离)
- 在数据库里建立 user_long_term_memory 表,存3个你最常用的用户偏好
- 写一个对话摘要函数,在超过10轮时自动触发压缩
- 测试"跨Session连续性":在上一个Session里告诉AI一个偏好,在新的Session里验证它是否记住了