Agent-study项目教程(01):命令行智能聊天机器人
·
一、理论部分
1. 多轮对话的本质:模型无状态,历史由客户端维护
大语言模型在一次请求结束后不会“自动记住”上一轮对话内容。我们看到的“连续对话”能力,本质上来自客户端在每次请求时携带完整的历史消息列表(通常命名为 messages)。模型并不是在记忆,而是在“阅读你传入的历史”。
常见的消息结构包含三类角色:
system:系统指令(定义助手身份、输出风格与约束)user:用户输入assistant:模型输出
只要历史消息按顺序被发送,模型就能在当前轮生成时参考上下文,从而表现为“记得之前聊过什么”。
2. Context Window(上下文窗口):能力边界与工程约束
messages 会随着轮次增加而变长,而模型对单次输入的最大容量是有限的(上下文窗口,通常以 token 计)。当对话持续增长时,会出现三类典型问题:
- 输入接近/超过上限,导致报错或被截断
- 请求变慢、成本上升
- 关键信息被长历史稀释,回答质量下降
本项目采用最简单的“把所有历史都带上”的方式,目的是让你先把多轮对话跑通;后续阶段再系统引入滑动窗口、摘要记忆与检索增强等策略。
3. Streaming(流式输出):提升交互体验的关键机制
非流式模式下,模型需要生成完整文本后一次性返回,用户会感受到明显的等待。开启流式输出后,服务端会以 chunk(增量片段)的方式持续返回内容,客户端可以边接收边展示,实现类似“打字机”的效果。
流式输出的工程要点:
- 开启
stream=True - 循环消费 chunk 的增量内容
- 既实时输出,也要拼接成完整回复写回历史,保证下一轮的上下文完整
二、实战部分
1. 项目目标
实现一个命令行聊天机器人,具备:
- 多轮对话:能在一定范围内记住前文
- 流式输出:回答内容逐步输出
- 基础可用性:支持退出指令与异常处理
2. 运行准备
请确保本地已安装依赖,并配置好环境变量。
依赖安装(示例):
pip install -r requirements.txt
环境变量(示例):
DEEPSEEK_API_KEY:你的 API KeyDEEPSEEK_BASE_URL:兼容 OpenAI 协议的服务地址
你可以使用 .env 文件配合 python-dotenv 加载(项目代码已包含加载逻辑)。
3. 主要代码(核心实现)
import os
from openai import OpenAI
from dotenv import load_dotenv
load_dotenv()
client = OpenAI(
api_key=os.getenv("DEEPSEEK_API_KEY"),
base_url=os.getenv("DEEPSEEK_BASE_URL"),
)
def chat_loop():
print("AI 聊天助手已启动(输入 'exit' 或 'quit' 退出)")
print("-" * 50)
messages = [
{"role": "system", "content": "你是一个乐于助人的 AI 助手,请用简洁的中文回答用户的问题。"}
]
while True:
try:
user_input = input("\n你: ").strip()
if user_input.lower() in ["exit", "quit"]:
print("\n再见。")
break
if not user_input:
continue
messages.append({"role": "user", "content": user_input})
print("AI: ", end="", flush=True)
stream = client.chat.completions.create(
model="deepseek-chat",
messages=messages,
stream=True,
temperature=0.7,
)
full_response = ""
for chunk in stream:
delta = chunk.choices[0].delta
if delta and delta.content:
print(delta.content, end="", flush=True)
full_response += delta.content
print()
messages.append({"role": "assistant", "content": full_response})
except KeyboardInterrupt:
print("\n程序已中断。")
break
except Exception as e:
print(f"\n发生错误:{e}")
if __name__ == "__main__":
chat_loop()
这段代码对应三件关键事:
messages作为对话历史容器,实现多轮上下文stream=True+ 循环 chunk,实现流式输出full_response拼接完整回答并写回messages,形成“记忆闭环”
4. 如何运行
在项目根目录执行:
python stage_01_llm_basics/project_01_chatbot/chatbot.py
5. 运行结果示例
下面是一段典型的交互示例(为了展示多轮效果,连续问了两轮):
AI 聊天助手已启动(输入 'exit' 或 'quit' 退出)
--------------------------------------------------
你: 我叫小林,今天心情一般
AI: 好的,小林。我在这里,你可以和我说说发生了什么,或者我可以帮你做一个简单的情绪梳理。
你: 你还记得我叫什么吗?
AI: 你叫小林。
你: exit
再见。
6. 项目总结
- 多轮对话并不神秘:关键在于客户端维护并回传历史
messages - 流式输出显著提升体验:通过持续消费 chunk 实现“边生成边展示”
- 该项目是后续 Agent 能力的基础:工具调用、RAG、工作流、多智能体协作,本质上都建立在“对话状态管理 + 可控输出/输入”的工程结构之上
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐

所有评论(0)