最近在探索LangChain框架时,我实现了一个有趣的猫咪角色聊天机器人。这个项目不仅能够模拟猫咪的语气进行对话,还能记住上下文内容,实现连贯的多轮对话体验。作为LangChain的初学者,我发现这个框架确实为构建基于大语言模型的应用提供了极大便利。
核心功能是通过DeepSeek模型(一个兼容OpenAI API的国产大模型)实现的,整个项目代码不到50行,却包含了角色设定、上下文记忆等关键特性。下面我将详细拆解这个项目的实现过程和技术要点,特别适合想要入门LangChain的开发者参考。
首先需要安装必要的Python包。建议使用虚拟环境来管理依赖:
bash复制pip install langchain-openai langchain-core python-dotenv
项目使用了.env文件来管理敏感信息,这是开发中的最佳实践。创建.env文件并添加以下内容:
code复制DEEPSEEK_API_KEY=你的API密钥
DEEP_URL=https://api.deepseek.com/v1
注意:API密钥是敏感信息,千万不要直接硬编码在代码中或上传到公开仓库。
.env文件应该加入.gitignore
模型初始化是项目的核心之一,这里使用了ChatOpenAI类来对接DeepSeek的API:
python复制llm = ChatOpenAI(
api_key=os.getenv("DEEPSEEK_API_KEY"),
base_url=os.getenv("DEEP_URL"),
model="deepseek-v3:671b",
temperature=0.7,
max_tokens=1024
)
关键参数说明:
temperature:控制生成文本的随机性(0-1)。0.7是一个适中的值,既不会太死板也不会太跳脱max_tokens:限制单次响应的最大长度。1024对于聊天场景足够model:指定使用的模型版本。DeepSeek提供了多个版本,可以根据需求选择实操心得:temperature参数对角色扮演类应用特别重要。经过多次测试,0.7能让猫咪角色既有一定个性,又不会过于离谱。如果设为1,猫咪可能会说一些很奇怪的话;如果设为0.2,又会显得太机械。
角色设定是通过系统消息(SystemMessage)实现的,这是影响聊天机器人性格的关键:
python复制chat_template = ChatPromptTemplate.from_messages([
("system", """你是一只很粘人的小猫,你叫{name}。我是你的主人...""")
])
完整的角色设定包含以下要素:
提示工程技巧:角色设定越具体,生成效果越稳定。我特别加入了"从迎接下班开始"这样的具体场景指示,这比泛泛的"表现得像只猫"效果要好得多。
LangChain使用三种标准消息类型:
SystemMessage:系统指令,设定角色和规则HumanMessage:用户输入AIMessage:AI的回复这种结构化设计是支持上下文记忆的基础。在初始化时,我们先创建包含系统消息和第一条用户消息的列表:
python复制messages = chat_template.format_messages(name="咪咪", user_input="想我了吗?")
初始对话很简单:
python复制response = llm.invoke(messages)
print(response.content)
但真正的价值在于如何让机器人记住之前的对话。这是通过维护消息列表实现的:
python复制# 将AI回复加入历史
messages.append(AIMessage(content=response.content))
# 添加新用户消息
messages.append(HumanMessage(content="今天遇到了1个小偷"))
# 再次调用模型
response = llm.invoke(messages)
每次调用模型时,我们都传入完整的消息历史。大模型会根据全部上下文生成回复,这就实现了记忆功能。关键在于:
常见问题:如果发现模型"忘记"了之前的对话,首先检查消息列表的顺序和类型是否正确。另一个常见原因是上下文太长导致模型"注意力分散",这时可以考虑摘要或截断早期对话。
temperature参数对角色扮演影响很大:
建议根据角色特点调整。对于猫咪角色,0.7是个不错的起点。
随着对话轮次增加,消息列表会越来越长。这可能导致:
解决方案:
实际应用中需要考虑:
一个简单的重试机制示例:
python复制from tenacity import retry, stop_after_attempt
@retry(stop=stop_after_attempt(3))
def safe_invoke(messages):
try:
return llm.invoke(messages)
except Exception as e:
print(f"调用失败: {e}")
raise
这个基础项目可以进一步扩展:
以情绪系统为例,可以在系统消息中加入状态变量:
python复制system_message = f"""你是一只{current_mood}的小猫..."""
然后根据对话内容动态更新current_mood状态。
在实际开发中,我遇到了几个典型问题:
问题:模型不按角色设定回答
问题:上下文似乎没起作用
问题:响应速度慢
问题:生成内容不符合预期
以下是整合了所有最佳实践的完整代码:
python复制from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.messages import SystemMessage, HumanMessage, AIMessage
import os
from dotenv import load_dotenv
from tenacity import retry, stop_after_attempt
load_dotenv()
# 初始化模型
llm = ChatOpenAI(
api_key=os.getenv("DEEPSEEK_API_KEY"),
base_url=os.getenv("DEEP_URL"),
model="deepseek-v3:671b",
temperature=0.7,
max_tokens=1024,
request_timeout=30
)
# 定义角色模板
chat_template = ChatPromptTemplate.from_messages([
("system", """你是一只很粘人的小猫,你叫{name}..."""),
("human", "{user_input}"),
])
# 带重试的调用封装
@retry(stop=stop_after_attempt(3))
def chat_with_cat(messages):
return llm.invoke(messages)
# 初始化对话
messages = chat_template.format_messages(name="咪咪", user_input="想我了吗?")
response = chat_with_cat(messages)
print(f"猫咪: {response.content}")
# 继续对话
messages.append(AIMessage(content=response.content))
messages.append(HumanMessage(content="今天遇到了1个小偷"))
response = chat_with_cat(messages)
print(f"猫咪: {response.content}")
这个项目虽然不大,但涵盖了LangChain的核心概念:模型封装、提示模板、消息历史和对话链。通过这个实践,我对如何构建基于大语言模型的应用有了更深入的理解。特别是上下文记忆的实现方式,这种设计模式可以应用到各种对话系统中。