0 前言
ChatGPT 之所以好用,核心在于:
- 个性化的系统提示词
- 多轮对话记忆
本文基于 LangChain,用不到 30 行代码复刻这两个能力,构建一个可自定义人格的对话 AI。
1 技术栈
| 组件 | 说明 |
|---|---|
LLMChain |
LangChain 的核心链,将 LLM、Prompt、Memory 串联起来 |
PromptTemplate |
结构化提示词模板,支持变量注入 |
ConversationBufferWindowMemory |
滑动窗口记忆,保留最近 k 轮对话 |
ChatOpenAI / Qwen |
底层大模型(本文使用 Qwen) |
2 核心思路
flowchart LR
A[用户输入] --> B["PromptTemplate
注入 history + human_input"] B --> C[LLM] C --> D[输出] E[ConversationBufferWindowMemory] --> B C -. 自动保存对话历史 .-> E classDef input fill:#E3F2FD,stroke:#1E88E5,stroke-width:2px,color:#0D47A1; classDef process fill:#E8F5E9,stroke:#43A047,stroke-width:2px,color:#1B5E20; classDef memory fill:#FFF3E0,stroke:#FB8C00,stroke-width:2px,color:#E65100; classDef output fill:#FCE4EC,stroke:#D81B60,stroke-width:2px,color:#880E4F; class A input; class B,C process; class E memory; class D output;
注入 history + human_input"] B --> C[LLM] C --> D[输出] E[ConversationBufferWindowMemory] --> B C -. 自动保存对话历史 .-> E classDef input fill:#E3F2FD,stroke:#1E88E5,stroke-width:2px,color:#0D47A1; classDef process fill:#E8F5E9,stroke:#43A047,stroke-width:2px,color:#1B5E20; classDef memory fill:#FFF3E0,stroke:#FB8C00,stroke-width:2px,color:#E65100; classDef output fill:#FCE4EC,stroke:#D81B60,stroke-width:2px,color:#880E4F; class A input; class B,C process; class E memory; class D output;
每次调用时,Memory 自动将历史对话注入到 {history} 变量,使 LLM 具备"记忆"能力。
3 完整代码
3.1 设计 Prompt 模板
Prompt 是塑造 AI 个性的关键。注意两个必要的占位变量:
{history}:由 Memory 自动填充,无需手动传入{human_input}:用户每次的输入
python
template = """AI助手是由OpenAI训练的大型语言模型。
AI助手旨在能够处理各种任务,从回答简单问题到提供广泛话题的深入解释和讨论。
作为一个语言模型,AI助手能够根据接收到的输入生成类似人类的文本,使其能够进行
自然的对话并提供与当前话题相关且连贯的回答。
{history}
Human: {human_input}
AI助手:"""
prompt = PromptTemplate(
input_variables=["history", "human_input"],
template=template
)
关键设计点:
- 系统描述放在最前面,定义 AI 的能力边界和人格
{history}和{human_input}之间保持清晰分隔- 末尾的
AI助手:作为续写触发词,引导模型以 AI 身份回复
3.2 组装 LLMChain
python
chatgpt_chain = LLMChain(
llm=llm,
prompt=prompt,
memory=ConversationBufferWindowMemory(k=2), # 保留最近 2 轮对话
)
ConversationBufferWindowMemory(k=2) 只保留最近 2 轮对话,避免 Token 超限,适合生产环境。
3.4 运行对话
python
output = chatgpt_chain.predict(human_input="你好,介绍一下你自己")
print(output)
4 进阶玩法:角色扮演 Linux 终端
修改 Prompt,让 AI 扮演一个 Linux 终端,只返回命令执行结果:
python
output = chatgpt_chain.predict(
human_input="我要求你扮演Linux终端。我会输入命令,你将回复终端应显示的内容。"
"我希望你只在一个唯一的代码块内回复终端输出,不添加其他内容。"
"我的第一个命令是 pwd"
)
print(output)
之后可以像操作真实终端一样连续交互:
python
# 由于有 Memory,模型知道"当前目录"的上下文
output = chatgpt_chain.predict(human_input="ls ~")
output = chatgpt_chain.predict(human_input="cd ~")
# 创建文件(模拟)
output = chatgpt_chain.predict(
human_input="{创建一个名为crypto.txt的文件,并在其中放入主流的加密货币代码}"
)
# 执行 Python 脚本(模拟)
output = chatgpt_chain.predict(
human_input='echo -e "x=lambda y:y*5+3;print(x(6))" > run.py && python3 run.py'
)
这展示了 Memory 的核心价值:多轮对话之间的状态共享。
5 Memory 类型对比
| Memory 类型 | 特点 | 适用场景 |
|---|---|---|
ConversationBufferMemory |
保存全部历史 | 短对话、调试 |
ConversationBufferWindowMemory |
保留最近 k 轮 | 长对话、生产环境 |
ConversationSummaryMemory |
用 LLM 压缩历史为摘要 | 超长对话 |
ConversationTokenBufferMemory |
按 Token 数量限制历史 | Token 精确控制 |
6 总结
| 步骤 | 代码量 | 核心组件 |
|---|---|---|
| 定义模板 | ~5 行 | PromptTemplate |
| 配置记忆 | ~1 行 | ConversationBufferWindowMemory |
| 组装链 | ~5 行 | LLMChain |
| 运行对话 | ~1 行 | .predict() |
LLMChain = LLM + Prompt + Memory 的优雅封装 ,通过替换 Prompt 模板即可快速构建不同人格的 AI 助手,这正是 LangChain 的设计哲学:组合而非重写。