1. LangChain基础入门与核心概念解析
LangChain是一个强大的框架,专门用于构建基于大语言模型(LLM)的应用程序。它提供了一套标准化的接口和组件,让开发者能够轻松地将LLM与各种工具、数据源和外部服务连接起来。对于刚接触LangChain的开发者来说,理解其核心概念至关重要。
LangChain的核心思想是将复杂的LLM应用拆解为可组合的"链"(Chain)。每个链由多个组件构成,比如模型、提示模板、记忆存储等。这种模块化设计让开发者能够灵活地构建各种应用场景,从简单的问答系统到复杂的多步骤推理任务。
1.1 环境准备与API配置
在开始使用LangChain之前,我们需要先配置开发环境。以下是一个典型的设置过程:
python复制import os
from langchain_community.llms import Tongyi # 导入通义千问模型
import dashscope
# 从环境变量获取API Key
api_key = os.getenv('DASHSCOPE_API_KEY')
dashscope.api_key = api_key
# 加载Tongyi模型
llm = Tongyi(model_name="qwen-turbo", dashscope_api_key=api_key)
注意:在实际项目中,建议将API密钥存储在环境变量中,而不是直接硬编码在代码里。这可以避免敏感信息泄露的风险。
1.2 第一个LangChain应用:公司命名服务
让我们从一个简单的例子开始 - 创建一个为公司命名的服务。这个例子展示了LangChain最基本的PromptTemplate和LLMChain的使用:
python复制from langchain_core.prompts import PromptTemplate
# 创建Prompt模板
prompt = PromptTemplate(
input_variables=["product"],
template="What is a good name for a company that makes {product}?",
)
# 将prompt和llm组合成chain
chain = prompt | llm
# 使用chain生成公司名称
result = chain.invoke({"product": "colorful socks"})
print(result) # 输出可能是:"Rainbow Toes"或"Vibrant Sock Co."
这个简单的例子展示了LangChain的几个关键特点:
- Prompt模板化:使用{变量}语法动态生成提示
- 链式组合:通过|操作符将组件连接起来
- 统一接口:使用invoke方法执行链
2. 构建功能型Agent
LangChain的真正强大之处在于它能创建具有特定功能的Agent。Agent可以理解用户意图,选择适当的工具,并执行复杂任务。
2.1 基础Agent搭建
下面是一个使用搜索引擎工具(serpapi)的Agent示例:
python复制from langchain_community.agent_toolkits.load_tools import load_tools
from langchain_community.chat_models import ChatTongyi
from langchain.agents import create_agent
# 加载模型和工具
llm = ChatTongyi(model_name="qwen-turbo", dashscope_api_key=api_key)
tools = load_tools(["serpapi"])
# 创建Agent
agent = create_agent(llm, tools)
# 运行Agent查询
result = agent.invoke({"messages": [("user", "今天是几月几号?历史上的今天有哪些名人出生")]})
print(result["messages"][-1].content)
这个Agent能够:
- 理解用户关于日期和历史名人的查询
- 自动调用serpapi工具获取最新信息
- 整理并返回格式化的答案
2.2 自定义工具开发
当内置工具不能满足需求时,我们可以创建自定义工具。下面是一个数学计算工具的示例:
python复制from langchain_core.tools import tool
@tool
def calculator(expression: str) -> str:
"""计算数学表达式。只接受数字和运算符,例如: 2+2, 100/4, 32*1.8+32"""
import re
if not re.match(r'^[\d\s\+\-\*\/\.\(\)]+$', expression):
return f"错误: 表达式 '{expression}' 包含无效字符"
return str(eval(expression))
# 将自定义工具与serpapi结合使用
serpapi_tools = load_tools(["serpapi"])
tools = serpapi_tools + [calculator]
# 创建增强版Agent
agent = create_agent(llm, tools)
# 查询天气并计算
result = agent.invoke({"messages": [("user", "当前北京的温度是多少华氏度?这个温度的1/4是多少")]})
print(result["messages"][-1].content)
提示:自定义工具时,务必添加清晰的文档字符串(docstring),这能帮助LLM理解何时以及如何使用该工具。
3. 构建对话系统
LangChain提供了强大的对话记忆功能,可以创建具有上下文感知能力的聊天机器人。
3.1 基础对话链
python复制from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.chat_history import InMemoryChatMessageHistory
from langchain_core.runnables.history import RunnableWithMessageHistory
# 创建带历史记录的prompt
prompt = ChatPromptTemplate.from_messages([
("system", "You are a helpful assistant."),
MessagesPlaceholder(variable_name="history"),
("human", "{input}")
])
# 构建基础链
chain = prompt | llm
# 存储会话历史
store = {}
def get_session_history(session_id: str):
if session_id not in store:
store[session_id] = InMemoryChatMessageHistory()
return store[session_id]
# 创建带记忆的对话链
conversation = RunnableWithMessageHistory(
chain,
get_session_history,
input_messages_key="input",
history_messages_key="history"
)
# 配置会话ID
config = {"configurable": {"session_id": "default"}}
# 进行多轮对话
output = conversation.invoke({"input": "Hi there!"}, config=config)
print(output.content)
output = conversation.invoke({"input": "What was my first message?"}, config=config)
print(output.content) # 能记住之前的对话
3.2 高级对话功能
我们可以扩展基础对话系统,添加更多实用功能:
python复制import textwrap
import time
def output_response(response: str) -> None:
"""带动态效果的输出函数"""
if not response:
return
for line in textwrap.wrap(response, width=60):
for word in line.split():
for char in word:
print(char, end="", flush=True)
time.sleep(0.05)
print(" ", end="", flush=True)
print()
print("-"*60)
# 使用动态输出
output = conversation.invoke({"input": "Tell me a story about AI"}, config=config)
output_response(output.content)
这种动态输出效果可以显著提升用户体验,特别是在演示或教育场景中。
4. 实战案例:产品信息查询系统
让我们构建一个更复杂的实战案例 - 一个汽车产品信息查询系统。
4.1 系统设计
python复制# 产品描述工具
@tool
def find_product_description(product_name: str) -> str:
"""通过产品名称找到产品描述。输入产品名称如 Model 3, Model Y"""
product_info = {
"Model 3": "具有简洁、动感的外观设计,流线型车身和现代化前脸。定价23.19-33.19万",
"Model Y": "更高的车身和更大的后备箱空间。定价26.39-36.39万",
"Model X": "独特的翅子门设计。定价89.89-105.89万",
}
return product_info.get(product_name, "没有找到这个产品")
# 公司信息工具
@tool
def find_company_info(query: str) -> str:
"""回答关于公司的问题"""
context = """
特斯拉最知名的产品是电动汽车,包括Model S、3、X和Y等多款车型。
公司以技术创新、高性能和领先的自动驾驶技术而闻名。
"""
prompt = f"根据以下信息回答问题:\n{context}\n\n问题:{query}"
response = llm.invoke(prompt)
return response.content
# 创建产品查询Agent
tools = [find_product_description, find_company_info]
agent = create_agent(llm, tools)
4.2 交互式查询界面
python复制if __name__ == "__main__":
while True:
try:
user_input = input("请输入您的问题:")
result = agent.invoke({"messages": [("user", user_input)]})
response = result["messages"][-1].content
output_response(response)
except KeyboardInterrupt:
print("\n再见!")
break
这个系统可以处理如下的查询:
- "Model Y的价格是多少?"
- "特斯拉最著名的技术是什么?"
- "比较Model 3和Model X的特点"
5. 性能优化与最佳实践
在实际使用LangChain时,有几个关键点需要注意:
5.1 模型选择策略
不同的任务适合不同的模型:
- 简单问答:qwen-turbo (快速响应)
- 复杂推理:deepseek-v3 (更强推理能力)
- 长文本处理:qwen-max (更大上下文窗口)
python复制# 根据任务动态选择模型
def get_llm_for_task(task_type):
if task_type == "simple":
return ChatTongyi(model_name="qwen-turbo")
elif task_type == "complex":
return ChatTongyi(model_name="deepseek-v3")
else:
return ChatTongyi(model_name="qwen-max")
5.2 错误处理与重试机制
python复制from tenacity import retry, stop_after_attempt, wait_exponential
@retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=4, max=10))
def safe_invoke(chain, input_data):
try:
return chain.invoke(input_data)
except Exception as e:
print(f"调用失败: {str(e)}")
raise
5.3 提示工程技巧
有效的提示设计可以显著提升模型表现:
- 明确指令:清晰说明你希望模型做什么
- 提供示例:few-shot prompting通常效果更好
- 结构化输出:指定返回格式(JSON/XML等)
python复制good_prompt = """
你是一个专业的产品顾问。请根据以下规则回答问题:
1. 对于产品查询,提供完整规格和价格
2. 对于比较请求,列出关键差异
3. 对于技术问题,用非专业术语解释
当前产品线:{products}
问题:{query}
"""
6. 常见问题排查
在实际开发中,你可能会遇到以下问题:
6.1 Agent不调用工具
症状:Agent直接回答问题而不使用可用工具
解决方案:
- 检查工具的描述是否清晰
- 确保模型支持tool calling功能
- 尝试更明确的用户指令
6.2 记忆丢失
症状:对话不记得之前的交流
解决方案:
- 确认正确配置了message history
- 检查session_id是否一致
- 验证历史存储是否正常工作
6.3 性能问题
症状:响应速度慢
优化建议:
- 使用更轻量级的模型
- 实现缓存机制
- 限制工具调用的次数
我在实际项目中发现,合理设置超时和重试策略可以显著提升系统稳定性。例如,为工具调用添加5秒超时,并在失败时自动重试2次,能够有效处理临时性的网络问题。