LangChain 本地部署与 Agent 智能体助手搭建实战
文档概述
课程会带给你
如何本地部署 LangChain 框架及生态工具
LangChain 核心组件与 Agent 智能体工作原理
搭建 Agent 智能体助手的完整流程(工具集成、记忆管理、交互设计)
Agent 调试、优化与生产级部署技巧
基于 LangChain 构建实用型智能助手案例
学习目标
理解 LangChain 框架核心价值与生态体系
掌握 LangChain 本地部署的环境配置与依赖安装
精通 Agent 智能体的核心组件(LLM、工具、记忆、提示模板)
能够独立搭建具备工具调用能力的 Agent 智能助手
学会 Agent 调试、性能优化与生产部署最佳实践
理解 LangChain 与向量数据库、外部工具的集成逻辑
一、LangChain 技术概述
1.1 什么是 LangChain?
LangChain 是一个用于构建基于大语言模型(LLM)的应用程序与智能体(Agent)的开源框架。它通过标准化接口整合了模型、嵌入、向量存储、工具等组件,提供模块化的架构设计,帮助开发者快速构建具备复杂逻辑、实时数据交互和工具调用能力的 AI 应用。
核心定位:连接 LLM 与外部资源的“桥梁”,解决纯 LLM 存在的知识时效性差、缺乏工具调用能力、无长期记忆等问题。
1.2 纯 LLM 的局限性(LangChain 解决的核心痛点)
知识时效性:模型训练数据存在时间截止点,无法获取实时信息
工具调用缺失:无法直接操作外部系统(搜索、数据库、API 等)
长期记忆不足:对话上下文管理能力有限,难以处理长程交互
任务拆解薄弱:无法将复杂任务分解为可执行的子步骤
集成成本高:与外部数据源、业务系统的对接需要大量定制化开发
1.3 LangChain 核心优势
| 优势维度 | 具体说明 |
|---|
| 生态丰富 | 支持 100+ 种集成(模型、向量库、工具、API 等) |
| 模块化设计 | 组件可自由组合,支持从快速原型到生产级应用的全流程 |
| Agent 原生支持 | 内置 Agent 框架,简化智能体的规划、工具调用、记忆管理逻辑 |
| 生产级特性 | 集成 LangSmith 调试、监控、评估工具,支持规模化部署 |
| 社区活跃 | 开源社区持续贡献组件、模板和最佳实践 |
1.4 Agent 智能体工作原理
Agent 是 LangChain 的核心应用场景,指具备自主决策、工具调用、任务规划能力的智能体。其工作流程如下:
接收用户指令(Query)
基于上下文和记忆,分析任务目标
规划执行步骤(复杂任务拆解为子任务)
选择合适的工具并调用(如搜索、数据库查询、本地文档检索)
解析工具返回结果
生成最终回复(或继续迭代任务步骤)
核心组件:
LLM:Agent 的“大脑”,负责决策、规划和语言生成
Tools:Agent 可调用的外部工具(如搜索引擎、文件读取、API 调用)
Memory:存储对话历史或任务状态,支持长程交互
Prompt Template:定义 Agent 的行为准则、输出格式和决策逻辑
LangGraph:用于构建复杂 Agent 工作流(支持循环、分支、人类介入)
二、LangChain 本地部署流程
2.1 部署环境要求
2.2 环境配置步骤
2.2.1 使用 Conda 创建独立环境
# 创建 LangChain 专属环境(指定 Python 版本)
conda create -n langchain-agent python=3.10
# 激活环境
conda activate langchain-agent
2.2.2 安装核心依赖库
# 安装 LangChain 核心框架(最新稳定版)
pip install langchain==0.2.14
# 安装 LLM 相关依赖(支持本地模型调用)
pip install langchain-llms-huggingface==0.1.7
pip install langchain-embeddings-huggingface==0.1.2
# 安装向量数据库(以 Chroma 为例,轻量且适合本地部署)
pip install chromadb==0.5.17
pip install llama-index-vector-stores-chroma==0.1.4
# 安装 PyTorch(GPU 版本,需匹配 CUDA 版本)
pip install torch==2.5.1 torchvision==0.20.1 torchaudio==2.5.1 --index-url https://download.pytorch.org/whl/cu118
# 安装工具集成依赖(搜索、文件处理等)
pip install requests==2.32.3 # 网络请求工具
pip install python-dotenv==1.0.1 # 环境变量管理
pip install pdfplumber==0.11.4 # PDF 文档读取
pip install python-magic==0.4.27 # 文件类型识别
2.2.3 拉取 LangChain 源码(可选)
# 克隆 LangChain 官方仓库(获取最新示例和源码)
git clone https://github.com/langchain-ai/langchain.git
cd langchain
# 安装开发依赖(如需修改源码或运行示例)
pip install -e .[all]
2.2.4 部署验证
运行以下代码验证环境是否配置成功:
# 导入 LangChain 核心模块
from langchain import LangChain
from langchain.llms import HuggingFaceLLM
from langchain.embeddings import HuggingFaceEmbeddings
# 验证模块导入
print("LangChain 版本:", LangChain.__version__)
print("HuggingFaceLLM 导入成功")
print("HuggingFaceEmbeddings 导入成功")
# 简单测试:创建 Embedding 模型实例
embedding = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
test_embedding = embedding.embed_query("LangChain 部署测试")
print(f"Embedding 向量维度:{len(test_embedding)}")
print("LangChain 本地部署成功!")
三、模型下载(Agent 核心依赖)
Agent 智能体需要依赖 LLM(决策核心)和 Embedding 模型(文本向量化),以下为本地部署推荐的开源模型及下载流程。
3.1 工具准备
使用 ModelScope 或 Hugging Face Hub 下载模型,这里以 ModelScope 为例(国内访问速度更快):
# 安装 ModelScope SDK
pip install modelscope==1.14.0
3.2 下载 Embedding 模型
推荐使用中文优化模型 BAAI/bge-base-zh-v1.5(兼顾效果与速度):
from modelscope import snapshot_download
# 下载 Embedding 模型到本地目录
embedding_model_dir = snapshot_download(
model_id="BAAI/bge-base-zh-v1.5",
cache_dir="D:/AIProject/modelscope/embedding" # 本地存储路径
)
print(f"Embedding 模型下载完成,路径:{embedding_model_dir}")
3.3 下载 LLM 大模型
推荐使用阿里通义千问(中文支持好、性能稳定):
from modelscope import snapshot_download
# 下载 7B 量级模型(平衡性能与硬件需求)
llm_model_dir = snapshot_download(
model_id="Qwen/Qwen2.5-7B-Instruct",
cache_dir="D:/AIProject/modelscope/llm" # 本地存储路径
)
print(f"LLM 模型下载完成,路径:{llm_model_dir}")
3.4 模型选择说明
| 模型类型 | 推荐模型 | 硬件要求 | 适用场景 |
|---|
| Embedding | BAAI/bge-base-zh-v1.5 | CPU 8GB+ 或 GPU | 中文文本向量化、检索 |
| LLM | Qwen2.5-7B-Instruct | GPU 12GB+ | 中小规模 Agent 决策、对话 |
| LLM(轻量) | Qwen2.5-1.8B-Instruct | GPU 6GB+ 或 CPU 16GB+ | 轻量化部署、快速测试 |
| LLM(高性能) | Qwen2.5-14B-Instruct | GPU 24GB+ | 复杂任务规划、高精度回复 |
四、Agent 智能体助手搭建实战
以“通用智能助手”为例,具备以下能力:1. 本地文档问答;2. 实时搜索查询;3. 对话记忆管理。
4.1 核心组件设计
| 组件 | 选型 | 作用 |
|---|
| LLM | Qwen2.5-7B-Instruct | 决策核心:解析用户需求、选择工具、生成回复 |
| Embedding | BAAI/bge-base-zh-v1.5 | 文本向量化:支持本地文档检索 |
| 向量数据库 | Chroma | 存储文档 Embedding 向量,提供相似性检索 |
| 工具 | 本地文档检索工具 + 网络搜索工具 | 扩展 Agent 能力边界 |
| 记忆 | ConversationBufferMemory | 存储对话历史,支持上下文关联 |
| 提示模板 | 自定义中文 Prompt | 规范 Agent 行为与输出格式 |
4.2 代码实现步骤
4.2.1 项目文件树形结构(含文件作用说明)
langchain-agent-project/
│
├── .env
│
│
│
├── requirements.txt
│
│
│
├── README.md
│
│
│
├── LICENSE.md
│
│
│
├── config.py
│
│
│
├── main.py
│
│
│
├── api.py
│
│
│
├── agent_core/
│ ├── __init__.py
│ │
│ │
│ ├── llm_setup.py
│ │
│ │
│ │
│ ├── embedding_setup.py
│ │
│ │
│ │
│ ├── vector_db.py
│ │
│ │
│ │
│ ├── tools_setup.py
│ │
│ │
│ │
│ ├── memory_setup.py
│ │
│ │
│ │
│ └── agent_builder.py
│
│
│
├── agent_documents/
│ │
│ │
│ ├── sample1.txt
│ ├── sample2.pdf
│ └── sample3.docx
│
├── agent_chroma_db/
│ │
│ │
│ ├── chroma.sqlite3
│ └── uuid_to_path.json
│
├── model_links/
│ │
│ ├── llm -> D:/AIProject/modelscope/llm/Qwen/Qwen2.5-7B-Instruct/
│ │
│ └── embedding -> D:/AIProject/modelscope/embedding/BAAI/bge-base-zh-v1.5/
│
│
└── logs/
│
│
└── agent_run.log
4.2.2 requirements.txt依赖库文件
执行 pip install -r requirements.txt 即可一键安装所有依赖:
langchain==0.2.14
langchain-llms-huggingface==0.1.7
langchain-embeddings-huggingface==0.1.2
chromadb==0.5.17
llama-index-vector-stores-chroma==0.1.4
torch==2.5.1
torchvision==0.20.1
torchaudio==2.5.1
requests==2.32.3
python-dotenv==1.0.1
pdfplumber==0.11.4
python-magic==0.4.27
modelscope==1.14.0
langsmith==0.1.125
fastapi==0.111.0
uvicorn==0.30.1
pydantic==2.7.4
python-multipart==0.0.7
cors==0.1.10
redis==5.0.1
4.2.3导入依赖库
import logging
import sys
import torch
from dotenv import load_dotenv
from langchain import PromptTemplate, LLMChain
from langchain.agents import AgentType, initialize_agent, load_tools
from langchain.memory import ConversationBufferMemory
from langchain.llms import HuggingFaceLLM
from langchain.embeddings import HuggingFaceEmbeddings
from langchain.vectorstores import Chroma
from langchain.document_loaders import SimpleDirectoryReader
from langchain.text_splitter import SentenceSplitter
# 加载环境变量(存储 API 密钥等敏感信息)
load_dotenv()
# 日志配置
logging.basicConfig(stream=sys.stdout, level=logging.INFO)
logging.getLogger().addHandler(logging.StreamHandler(stream=sys.stdout))
4.2.4 初始化核心组件
(1) 创建 config.py`(项目配置文件)
集中管理所有配置参数,修改时无需改动核心逻辑代码:
import os
from langchain.agents import AgentType
PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__))
DOCUMENTS_DIR = os.path.join(PROJECT_ROOT, "agent_documents")
CHROMA_DB_DIR = os.path.join(PROJECT_ROOT, "agent_chroma_db")
MODEL_LINKS_DIR = os.path.join(PROJECT_ROOT, "model_links")
LOGS_DIR = os.path.join(PROJECT_ROOT, "logs")
for dir_path in [DOCUMENTS_DIR, CHROMA_DB_DIR, MODEL_LINKS_DIR, LOGS_DIR]:
if not os.path.exists(dir_path):
os.makedirs(dir_path)
LLM_PATH = os.path.join(MODEL_LINKS_DIR, "llm")
EMBEDDING_MODEL_PATH = os.path.join(MODEL_LINKS_DIR, "embedding")
CONTEXT_WINDOW = 4096
MAX_NEW_TOKENS = 2048
TEMPERATURE = 0.1
CHUNK_SIZE = 512
CHUNK_OVERLAP = 50
RETRIEVE_TOP_K = 3
AGENT_TYPE = AgentType.CHAT_CONVERSATIONAL_REACT_DESCRIPTION
MAX_ITERATIONS = 5
PARSING_ERROR_MSG = "请重试:无法解析工具调用结果,请重新选择工具"
SYSTEM_PROMPT = """你是一个通用智能助手,具备以下能力:
1. 可以回答用户的各类问题,优先使用本地文档知识和实时搜索结果
2. 当需要获取实时信息(如天气、新闻、股票)时,调用搜索工具
3. 当用户询问本地文档相关内容时,调用文档检索工具
4. 回答需简洁、准确,基于工具返回结果,不编造信息
5. 记住用户之前的对话内容,提供连贯的交互体验"""
REDIS_HOST = "localhost"
REDIS_PORT = 6379
REDIS_DB = 0
REDIS_PASSWORD = ""
(2)创建 agent_core/llm_setup.py(LLM 配置)
from langchain import PromptTemplate
from langchain.llms import HuggingFaceLLM
import torch
from config import (
LLM_PATH, CONTEXT_WINDOW, MAX_NEW_TOKENS,
TEMPERATURE, SYSTEM_PROMPT
)
def setup_llm():
"""封装 LLM 初始化逻辑"""
# 构建 Prompt 模板
query_wrapper_prompt = PromptTemplate(
template="[INST]<>\n{system_prompt}\n<>\n\n{query_str}[/INST] ",
input_variables=["system_prompt", "query_str"]
)
# 初始化本地 LLM
llm = HuggingFaceLLM(
context_window=CONTEXT_WINDOW,
max_new_tokens=MAX_NEW_TOKENS,
generate_kwargs={
"temperature": TEMPERATURE,
"do_sample": True
},
query_wrapper_prompt=query_wrapper_prompt,
tokenizer_name=LLM_PATH,
model_name=LLM_PATH,
device_map="auto",
model_kwargs={"torch_dtype": torch.float16}
)
return llm
(3)配置 Embedding 与向量数据库(本地文档检索)
from langchain.embeddings import HuggingFaceEmbeddings
from config import EMBEDDING_MODEL_PATH
def setup_embedding():
"""封装 Embedding 模型初始化逻辑"""
embedding_model = HuggingFaceEmbeddings(
model_name=EMBEDDING_MODEL_PATH
)
return embedding_model
(4)创建 agent_core/vector_db.py(向量数据库配置)
from langchain.document_loaders import SimpleDirectoryReader
from langchain.text_splitter import SentenceSplitter
from langchain.vectorstores import Chroma
from config import DOCUMENTS_DIR, CHROMA_DB_DIR, CHUNK_SIZE, CHUNK_OVERLAP, RETRIEVE_TOP_K
def build_vector_db(embedding_model):
"""加载本地文档,构建 Chroma 向量数据库"""
# 加载文档
documents = SimpleDirectoryReader(
DOCUMENTS_DIR,
required_exts=[".txt", ".pdf", ".docx"]
).load_data()
# 文档切分
text_splitter = SentenceSplitter(
chunk_size=CHUNK_SIZE,
chunk_overlap=CHUNK_OVERLAP
)
split_docs = text_splitter.split_documents(documents)
# 构建向量库
vector_db = Chroma.from_documents(
documents=split_docs,
embedding=embedding_model,
persist_directory=CHROMA_DB_DIR
)
vector_db.persist()
# 构建检索器
doc_retriever = vector_db.as_retriever(
search_kwargs={"k": RETRIEVE_TOP_K}
)
return doc_retriever
(5)创建 agent_core/tools_setup.py(工具集配置)
from langchain.agents import load_tools
from langchain.tools import RetrievalQAWithSourcesTool
from config import RETRIEVE_TOP_K
def setup_tools(llm, doc_retriever):
"""加载内置工具 + 集成本地文档检索工具"""
# 加载内置工具(serpapi:搜索,llm-math:数学计算)
tools = load_tools(
["serpapi", "llm-math"],
llm=llm
)
# 封装本地文档检索工具
doc_tool = RetrievalQAWithSourcesTool.from_chain_type(
llm=llm,
chain_type="stuff",
retriever=doc_retriever,
name="document_retrieval",
description="用于回答本地文档相关的问题,当用户询问文档内容时调用"
)
# 合并工具集
tools.append(doc_tool)
return tools
(6)创建 agent_core/memory_setup.py(记忆配置)
from langchain.memory import ConversationBufferMemory
def setup_memory():
"""封装对话记忆初始化逻辑"""
memory = ConversationBufferMemory(
memory_key="chat_history",
return_messages=True,
output_key="output"
)
return memory
(7)创建 agent_core/agent_builder.py(Agent 构建)
from langchain.memory import ConversationBufferMemory, RedisChatMessageHistory
from config import REDIS_HOST, REDIS_PORT, REDIS_DB, REDIS_PASSWORD
def setup_memory(session_id: str = "default", use_redis: bool = False):
"""
封装对话记忆初始化逻辑,支持本地内存和 Redis 存储(多用户场景推荐 Redis)
:param session_id: 会话 ID(区分不同用户)
:param use_redis: 是否使用 Redis 存储记忆
:return: 配置好的 ConversationBufferMemory 实例
"""
if use_redis:
message_history = RedisChatMessageHistory(
session_id=session_id,
host=REDIS_HOST,
port=REDIS_PORT,
db=REDIS_DB,
password=REDIS_PASSWORD
)
memory = ConversationBufferMemory(
memory_key="chat_history",
return_messages=True,
output_key="output",
chat_memory=message_history
)
else:
memory = ConversationBufferMemory(
memory_key="chat_history",
return_messages=True,
output_key="output"
)
return memory
(8)api.py(后端 API 服务文件)
from fastapi import FastAPI, Request, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
from typing import Optional
import logging
import os
from config import LOGS_DIR, REDIS_HOST, REDIS_PORT
from agent_core.llm_setup import setup_llm
from agent_core.embedding_setup import setup_embedding
from agent_core.vector_db import build_vector_db
from agent_core.tools_setup import setup_tools
from agent_core.memory_setup import setup_memory
from agent_core.agent_builder import build_agent
app = FastAPI(title="LangChain Agent 智能助手 API", version="1.0")
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
log_file = os.path.join(LOGS_DIR, "api_run.log")
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s - %(levelname)s - %(message)s",
handlers=[
logging.FileHandler(log_file, encoding="utf-8"),
logging.StreamHandler()
]
)
logging.info("API 服务启动,开始初始化 Agent 核心组件...")
try:
llm = setup_llm()
embedding_model = setup_embedding()
doc_retriever = build_vector_db(embedding_model)
tools = setup_tools(llm, doc_retriever)
logging.info("核心组件初始化完成,API 服务就绪!")
except Exception as e:
logging.error(f"核心组件初始化失败:{str(e)}", exc_info=True)
raise
class ChatRequest(BaseModel):
user_input: str
session_id: Optional[str] = "default"
use_redis: Optional[bool] = False
class ChatResponse(BaseModel):
code: int = 200
message: str = "success"
data: dict = {}
@app.get("/health")
async def health_check():
return {
"code": 200,
"message": "Agent API 服务运行正常",
"data": {
"redis": f"连接成功" if check_redis() else "未启用或连接失败",
"llm": "加载成功",
"vector_db": "构建成功"
}
}
@app.post("/chat", response_model=ChatResponse)
async def chat(request: ChatRequest):
try:
user_input = request.user_input.strip()
session_id = request.session_id
use_redis = request.use_redis
if not user_input:
raise HTTPException(status_code=400, detail="用户输入不能为空")
memory = setup_memory(session_id=session_id, use_redis=use_redis)
agent = build_agent(tools=tools, llm=llm, memory=memory)
logging.info(f"会话 [{session_id}] - 用户输入:{user_input}")
response = agent.run(user_input)
logging.info(f"会话 [{session_id}] - Agent 回复:{response}")
return ChatResponse(
data={
"response": response,
"session_id": session_id,
"use_redis": use_redis
}
)
except HTTPException as e:
logging.error(f"会话 [{request.session_id}] - 客户端错误:{e.detail}")
return ChatResponse(
code=e.status_code,
message=f"客户端错误:{e.detail}",
data={"session_id": request.session_id}
)
except Exception as e:
logging.error(f"会话 [{request.session_id}] - 服务端错误:{str(e)}", exc_info=True)
return ChatResponse(
code=500,
message=f"服务端错误:{str(e)}",
data={"session_id": request.session_id}
)
def check_redis() -> bool:
try:
import redis
r = redis.Redis(
host=REDIS_HOST,
port=REDIS_PORT,
db=0,
password=REDIS_PASSWORD,
socket_timeout=2
)
return r.ping()
except Exception:
return False
if __name__ == "__main__":
import uvicorn
uvicorn.run(
app="api:app",
host="0.0.0.0",
port=8000,
reload=True,
workers=1
)
(9)创建 main.py(项目主程序)
import logging
import os
from config import LOGS_DIR
from agent_core.llm_setup import setup_llm
from agent_core.embedding_setup import setup_embedding
from agent_core.vector_db import build_vector_db
from agent_core.tools_setup import setup_tools
from agent_core.memory_setup import setup_memory
from agent_core.agent_builder import build_agent
def setup_logging():
log_file = os.path.join(LOGS_DIR, "agent_run.log")
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s - %(levelname)s - %(message)s",
handlers=[
logging.FileHandler(log_file, encoding="utf-8"),
logging.StreamHandler()
]
)
logging.info("日志配置完成,开始初始化 Agent...")
def init_agent():
try:
logging.info("加载 LLM 模型...")
llm = setup_llm()
logging.info("加载 Embedding 模型...")
embedding_model = setup_embedding()
logging.info("构建本地文档向量库...")
doc_retriever = build_vector_db(embedding_model)
logging.info("加载工具集...")
tools = setup_tools(llm, doc_retriever)
logging.info("初始化对话记忆...")
memory = setup_memory()
logging.info("构建 Agent 智能体...")
agent = build_agent(tools, llm, memory)
logging.info("Agent 初始化完成!")
return agent
except Exception as e:
logging.error(f"Agent 初始化失败:{str(e)}", exc_info=True)
raise
def agent_chat(agent):
print("=== 通用智能助手(输入 'quit' 退出)===")
while True:
try:
user_input = input("\n用户:")
if user_input.lower() == "quit":
print("助手:再见!")
logging.info("用户退出交互")
break
logging.info(f"用户输入:{user_input}")
response = agent.run(user_input)
print(f"助手:{response}")
logging.info(f"助手回复:{response}")
except Exception as e:
error_msg = f"交互出错:{str(e)}"
print(f"助手:{error_msg}")
logging.error(error_msg, exc_info=True)
if __name__ == "__main__":
setup_logging()
agent = init_agent()
agent_chat(agent)
4.2.5 初始化 Agent
# 构建 Agent
agent = initialize_agent(
tools=tools,
llm=llm,
agent=AgentType.CHAT_CONVERSATIONAL_REACT_DESCRIPTION, # 对话型 Agent
memory=memory,
verbose=True, # 打印详细日志(便于调试)
max_iterations=5, # 最大迭代次数(避免无限循环)
handle_parsing_errors="请重试:无法解析工具调用结果,请重新选择工具",
system_message=SYSTEM_PROMPT
)
4.2.6 测试 Agent 交互
# 交互函数
def agent_chat():
print("=== 通用智能助手(输入 'quit' 退出)===")
while True:
user_input = input("\n用户:")
if user_input.lower() == "quit":
print("助手:再见!")
break
# 调用 Agent 生成回复
response = agent.run(user_input)
print(f"助手:{response}")
# 启动交互
if __name__ == "__main__":
agent_chat()
4.3 关键配置说明
(1)Agent 类型选择
| Agent 类型 | 适用场景 | 特点 |
|---|
| CHAT_CONVERSATIONAL_REACT_DESCRIPTION | 对话型智能助手 | 支持记忆管理,适合多轮交互 |
| ZERO_SHOT_REACT_DESCRIPTION | 单轮任务处理 | 无需记忆,快速执行单一任务 |
| STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION | 结构化输出任务 | 支持 JSON 等格式输出,适合数据处理 |
(2)温度参数(temperature)调整
temperature=0.0:输出完全确定,无随机性(适合需要精准答案的场景)
temperature=0.1-0.3:平衡准确性与灵活性(通用场景推荐)
temperature=0.5-0.8:输出更具创造性(适合生成类任务)
(3)工具调用优化
工具描述需清晰:让 LLM 准确理解工具的用途(如“document_retrieval 用于回答本地文档相关问题”)
限制工具数量:初期避免过多工具,减少 LLM 决策负担
增加工具优先级:通过 Prompt 引导 LLM 优先使用合适的工具
五、Agent 调试与优化
5.1 调试工具:LangSmith
LangSmith 是 LangChain 官方推出的一站式调试、监控与评估平台,能全程追踪 Agent 从 “接收请求→决策→工具调用→生成回复” 的完整链路,精准定位每一步的问题。以下是从环境配置→代码集成→测试运行→控制台分析→问题修复的全流程详细说明,含可直接复用的代码片段。
5.1.1 配置 LangSmith
# 安装 LangSmith
pip install langsmith==0.1.125
(1) 获取 LangSmith API Key
- 访问 LangSmith 官网(https://smith.langchain.com),使用 GitHub/Google 账号注册并登录。
- 登录后,点击右上角头像 → Settings → API Keys → 点击 Create API Key,输入密钥名称(如 “agent-debug”),点击创建。
- 复制生成的 API Key(格式类似
ls__xxxxxx),后续配置会用到(密钥仅显示一次,需妥善保存)。
(2) 配置环境变量
在 .env 文件中配置 API 密钥(需在 LangSmith 官网注册获取):
LANGCHAIN_TRACING_V2=true
LANGCHAIN_ENDPOINT=https://api.smith.langchain.com
LANGCHAIN_API_KEY=your_api_key
LANGCHAIN_PROJECT=agent-debug
5.1.2 调试流程
需要在 Agent 初始化时添加 LangSmith 回调,实现 “每一步操作都被记录”。以下是 命令行交互(main.py) 和 API 服务(api.py) 的完整集成代码。
(1)命令行交互(main.py)集成示例
在 main.py 中导入 LangSmith 回调相关模块,修改 init_agent 函数,添加 CallbackManager 配置:
import logging
import os
from dotenv import load_dotenv
from config import LOGS_DIR
from langchain.callbacks import LangChainTracer, CallbackManager
from agent_core.llm_setup import setup_llm
from agent_core.embedding_setup import setup_embedding
from agent_core.vector_db import build_vector_db
from agent_core.tools_setup import setup_tools
from agent_core.memory_setup import setup_memory
from agent_core.agent_builder import build_agent
load_dotenv()
def setup_logging():
log_file = os.path.join(LOGS_DIR, "agent_run.log")
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s - %(levelname)s - %(message)s",
handlers=[
logging.FileHandler(log_file, encoding="utf-8"),
logging.StreamHandler()
]
)
logging.info("日志配置完成,开始初始化 Agent...")
def init_agent():
try:
tracer = LangChainTracer()
callback_manager = CallbackManager([tracer, logging.StreamHandler()])
logging.info("加载 LLM 模型...")
llm = setup_llm(callback_manager=callback_manager)
logging.info("加载 Embedding 模型...")
embedding_model = setup_embedding()
logging.info("构建本地文档向量库...")
doc_retriever = build_vector_db(embedding_model)
logging.info("加载工具集...")
tools = setup_tools(llm, doc_retriever)
logging.info("初始化对话记忆...")
memory = setup_memory()
logging.info("构建 Agent 智能体...")
agent = build_agent(
tools=tools,
llm=llm,
memory=memory,
callback_manager=callback_manager
)
logging.info("Agent 初始化完成!(已启用 LangSmith 调试追踪)")
return agent
except Exception as e:
logging.error(f"Agent 初始化失败:{str(e)}", exc_info=True)
raise
def agent_chat(agent):
print("=" * 50)
print("=== 通用智能助手(支持本地文档问答、实时搜索、多轮对话)===")
print("=== 输入 'quit' 或 '退出' 即可结束交互 ===")
print("=== 所有操作已同步至 LangSmith 控制台,可前往查看轨迹 ===")
print("=" * 50)
while True:
try:
user_input = input("\n用户:")
if user_input.lower() in ["quit", "退出"]:
print("助手:感谢使用,再见!")
logging.info("用户主动退出交互,程序结束。")
break
logging.info(f"用户输入:{user_input}")
response = agent.run(user_input)
print(f"助手:{response}")
logging.info(f"Agent 回复:{response}")
except Exception as e:
error_msg = f"交互过程中出现错误:{str(e)}"
print(f"助手:{error_msg}")
logging.error(error_msg, exc_info=True)
if __name__ == "__main__":
setup_logging()
agent = init_agent()
agent_chat(agent)
(2)同步修改 agent_core/llm_setup.py(接收回调参数)
由于 main.py 中初始化 LLM 时传入了 callback_manager,需要修改 llm_setup.py 的 setup_llm 函数,支持接收该参数:
from langchain import PromptTemplate
from langchain.llms import HuggingFaceLLM
import torch
from config import (
LLM_PATH, CONTEXT_WINDOW, MAX_NEW_TOKENS,
TEMPERATURE, SYSTEM_PROMPT
)
def setup_llm(callback_manager=None):
"""封装 LLM 初始化逻辑"""
query_wrapper_prompt = PromptTemplate(
template="[INST]<<SYS>>\n{system_prompt}\n<</SYS>>\n\n{query_str}[/INST] ",
input_variables=["system_prompt", "query_str"]
)
llm = HuggingFaceLLM(
context_window=CONTEXT_WINDOW,
max_new_tokens=MAX_NEW_TOKENS,
generate_kwargs={
"temperature": TEMPERATURE,
"do_sample": True
},
query_wrapper_prompt=query_wrapper_prompt,
tokenizer_name=LLM_PATH,
model_name=LLM_PATH,
device_map="auto",
model_kwargs={"torch_dtype": torch.float16},
callback_manager=callback_manager
)
return llm
(3)同步修改 agent_core/agent_builder.py(接收回调参数)
修改 build_agent 函数,支持传入 callback_manager 并传递给 Agent:
from langchain.agents import initialize_agent
from config import AGENT_TYPE, MAX_ITERATIONS, PARSING_ERROR_MSG, SYSTEM_PROMPT
def build_agent(tools, llm, memory, callback_manager=None):
"""整合所有组件,构建 Agent"""
agent = initialize_agent(
tools=tools,
llm=llm,
agent=AGENT_TYPE,
memory=memory,
verbose=True,
max_iterations=MAX_ITERATIONS,
handle_parsing_errors=PARSING_ERROR_MSG,
system_message=SYSTEM_PROMPT,
callback_manager=callback_manager
)
return agent
(4)API 服务(api.py)集成示例(可选)
如果需要调试 API 接口调用场景,在 api.py 中添加 LangSmith 回调配置:
from fastapi import FastAPI, Request, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
from typing import Optional
import logging
import os
from dotenv import load_dotenv
from langchain.callbacks import LangChainTracer, CallbackManager
from config import LOGS_DIR, REDIS_HOST, REDIS_PORT
from agent_core.llm_setup import setup_llm
from agent_core.embedding_setup import setup_embedding
from agent_core.vector_db import build_vector_db
from agent_core.tools_setup import setup_tools
from agent_core.memory_setup import setup_memory
from agent_core.agent_builder import build_agent
load_dotenv()
app = FastAPI(title="LangChain Agent 智能助手 API", version="1.0")
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
tracer = LangChainTracer()
callback_manager = CallbackManager([tracer, logging.StreamHandler()])
log_file = os.path.join(LOGS_DIR, "api_run.log")
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s - %(levelname)s - %(message)s",
handlers=[
logging.FileHandler(log_file, encoding="utf-8"),
logging.StreamHandler()
]
)
logging.info("API 服务启动,开始初始化 Agent 核心组件...")
try:
llm = setup_llm(callback_manager=callback_manager)
embedding_model = setup_embedding()
doc_retriever = build_vector_db(embedding_model)
tools = setup_tools(llm, doc_retriever)
logging.info("核心组件初始化完成,API 服务就绪!(已启用 LangSmith 调试)")
except Exception as e:
logging.error(f"核心组件初始化失败:{str(e)}", exc_info=True)
raise
agent = build_agent(tools=tools, llm=llm, memory=memory, callback_manager=callback_manager)
集成完成后,运行项目并执行测试用例,LangSmith 会自动记录每一步操作。以下是 3 个典型测试场景(覆盖 Agent 核心能力):
测试用例 1:本地文档问答(验证检索工具调用)
运行
python main.py
在终端输入:
用户:sample1.txt 里记录了什么内容?
- 预期行为:Agent 调用
document_retrieval 工具,检索本地文档并返回结果。 - LangSmith 会记录:文档检索的输入(查询词)、输出(检索到的文档片段)、工具调用决策过程。
测试用例 2:实时搜索查询(验证外部工具调用)
终端输入:
用户:2026年1月北京的平均气温是多少?
- 预期行为:Agent 调用
serpapi 工具,获取实时搜索结果并整理回复。 - LangSmith 会记录:搜索工具的请求参数(查询词、时间范围)、返回结果、Agent 对结果的解析过程。
测试用例 3:多轮对话记忆(验证记忆组件)
终端输入:
用户:我刚才问的是什么问题?
- 预期行为:Agent 从
ConversationBufferMemory 中读取历史对话,回复上一轮问题。 - LangSmith 会记录:记忆存储的内容、Agent 读取记忆的过程、上下文关联逻辑。
测试用例 4:故意触发错误(验证异常追踪)
终端输入:
用户:计算 123456789 × 987654321(故意输入复杂计算,触发工具调用异常)
- 预期行为:Agent 调用
llm-math 工具,但可能因计算复杂度或参数问题报错。 - LangSmith 会记录:错误类型、异常堆栈、工具调用失败的详细原因。
5.1.3 LangSmith 控制台分析:精准定位问题
运行测试用例后,访问 LangSmith 控制台(https://smith.langchain.com),按以下步骤分析轨迹:
(1) 进入项目和轨迹列表
- 登录后,在左侧导航栏点击 Projects,找到你配置的项目名(如 “agent-debug-project”)。
- 进入项目后,会看到所有测试用例的轨迹列表,每条轨迹包含:
- 运行时间、状态(成功 / 失败)、耗时、关联的 LLM / 工具。
- 点击轨迹名称(如 “AgentRun: 2026 年 1 月北京的平均气温是多少?”),进入详细分析页。
(2)轨迹详细分析(核心功能)
轨迹详细页按 “时间线” 展示 Agent 从接收请求到生成回复的全流程,每个步骤都可展开查看细节:
1.查看 Agent 决策过程(最关键)
- 找到 AgentExecutor 步骤,点击展开 → 查看 Action 字段:
action:Agent 选择的工具(如 “serpapi”“document_retrieval”)。action_input:工具的输入参数(如搜索词 “2026 年 1 月北京平均气温”)。observation:工具的返回结果(如搜索到的气温数据、文档片段)。thought:Agent 的思考过程(如 “用户需要实时气温数据,需调用搜索工具”)。
- 示例:若 Agent 错误地选择了
document_retrieval 工具处理实时天气查询,可在此处发现 “决策逻辑错误”,问题根源可能是 Prompt 中工具用途描述不清晰。
2.查看 Prompt 实际传入内容
3.查看记忆存储与读取
找到
ConversationBufferMemory
步骤,点击展开 → 查看
Memory
字段:
chat_history:存储的对话历史(用户输入 + Agent 回复)。- 示例:若多轮对话中 Agent 忘记上一轮问题,可在此处检查
chat_history 是否为空或未正确传递,问题可能是记忆组件未被正确初始化或回调未关联。
4.查看工具调用详情
5.查看 LLM 生成过程
找到
LLM
步骤的
Outputs
字段:
- 查看 LLM 生成的原始回复(包括工具调用指令、最终回复内容)。
- 示例:若 LLM 生成的工具调用指令格式错误(如未按要求输出 JSON),可确定是 Prompt 中工具调用格式说明不清晰,需优化 Prompt 模板。
5.1.4 典型问题定位与修复示例(结合 LangSmith 轨迹)
以下是 3 个 Agent 常见问题的 “LangSmith 定位 + 代码修复” 完整流程:
问题 1:Agent 不调用工具,直接编造答案(如本地文档查询)
定位过程:
- 进入 LangSmith 轨迹详情页,找到 AgentExecutor 步骤。
- 查看
thought 字段:发现 Agent 思考 “用户查询本地文档,但未找到相关工具,直接回答”。 - 查看 Tools 列表:确认
document_retrieval 工具已被加载,但 description 字段过于简略(如 “用于回答本地文档问题”)。 - 查看 LLM 的
formatted_prompt:发现 System Prompt 中未明确 “本地文档查询必须调用 document_retrieval 工具”。
修复方案:
优化 tools_setup.py 中工具的 description,明确适用场景:
运行
doc_tool = RetrievalQAWithSourcesTool.from_chain_type(
llm=llm,
chain_type="stuff",
retriever=doc_retriever,
name="document_retrieval",
description="专门用于回答本地文档(包括 sample1.txt、sample2.pdf、sample3.docx 等)相关的问题,只要用户询问的内容来自这些文档,必须调用该工具"
)
同时优化 config.py 中的 SYSTEM_PROMPT:
运行
SYSTEM_PROMPT = """你是一个高效、精准的通用智能助手,严格遵循以下规则:
1. 若用户查询本地文档内容(如 sample1.txt、sample2.pdf、sample3.docx),必须调用 document_retrieval 工具,禁止直接编造答案;
2. 若用户查询实时信息(如天气、新闻、气温),必须调用 serpapi 工具;
3. 若用户查询数学计算,必须调用 llm-math 工具;
4. 回答需基于工具返回结果,不编造信息。"""
问题 2:多轮对话中,Agent 忘记上一轮问题(记忆丢失)
定位过程:
- 进入 LangSmith 轨迹详情页,找到 ConversationBufferMemory 步骤。
- 查看
chat_history 字段:发现仅存储了当前轮对话,上一轮对话未被保留。 - 查看 AgentExecutor 步骤的
inputs 字段:发现 chat_history 参数未被传递给 Agent。 - 检查代码:发现
agent_builder.py 中 build_agent 函数未正确关联记忆组件。
修复方案:
确认 agent_builder.py 中 memory 参数已正确传入,且 ConversationBufferMemory 的 return_messages=True:
运行
def setup_memory(session_id: str = "default", use_redis: bool = False):
if use_redis:
message_history = RedisChatMessageHistory(
session_id=session_id,
host=REDIS_HOST,
port=REDIS_PORT,
db=REDIS_DB,
password=REDIS_PASSWORD
)
memory = ConversationBufferMemory(
memory_key="chat_history",
return_messages=True,
output_key="output",
chat_memory=message_history
)
else:
memory = ConversationBufferMemory(
memory_key="chat_history",
return_messages=True,
output_key="output"
)
return memory
同时在 main.py 中确认记忆组件已传入 build_agent:
运行
memory = setup_memory()
agent = build_agent(tools=tools, llm=llm, memory=memory, callback_manager=callback_manager)
问题 3:工具调用失败(如 serpapi 搜索无返回)
定位过程:
- 进入 LangSmith 轨迹详情页,找到 Tool: serpapi 步骤。
- 查看
Error 字段:显示 “API Key invalid”(API 密钥无效)。 - 查看
Input 字段:确认 api_key 参数未被正确传递(为空)。 - 检查
.env 文件:发现 SERPER_API_KEY 拼写错误(如 SERPER_APIKEY)。
修复方案:
修正 .env 文件中的密钥名称:
正确:SERPER_API_KEY=your_key
同时在 tools_setup.py 中确认工具加载时已读取环境变量:
运行
tools = load_tools(
["serpapi", "llm-math"],
llm=llm
)
5.2 优化方向
(1)检索效果优化
(2)Agent 决策优化
(3)记忆管理优化
六、生产级部署最佳实践
6.1 容器化部署(Docker)
6.1.1 编写 Dockerfile
# 基础镜像
FROM python:3.10-slim
# 设置工作目录
WORKDIR /app
# 安装系统依赖
RUN apt-get update && apt-get install -y --no-install-recommends \
gcc \
git \
&& rm -rf /var/lib/apt/lists/*
# 复制依赖文件
COPY requirements.txt .
# 安装 Python 依赖
RUN pip install --no-cache-dir -r requirements.txt
# 复制项目文件
COPY . .
# 复制模型文件(或通过挂载目录方式挂载)
COPY ./modelscope /app/modelscope
# 暴露端口
EXPOSE 8000
# 启动命令(使用 FastAPI 封装 Agent 为 API 服务)
CMD ["uvicorn", "agent_api:app", "--host", "0.0.0.0", "--port", "8000"]
6.1.2 构建与运行容器
# 构建镜像
docker build -t langchain-agent .
# 运行容器(挂载模型目录和向量库)
docker run -d \
-p 8000:8000 \
-v D:/AIProject/modelscope:/app/modelscope \
-v ./agent_chroma_db:/app/agent_chroma_db \
--name langchain-agent-container \
langchain-agent
6.2 服务化封装(FastAPI)
将 Agent 封装为 HTTP API 服务,支持跨平台调用:
# agent_api.py
from fastapi import FastAPI, Request
from pydantic import BaseModel
from agent_core import agent # 导入之前构建的 Agent
app = FastAPI(title="LangChain Agent API")
# 请求模型
class ChatRequest(BaseModel):
user_input: str
session_id: str = "default"
# 响应模型
class ChatResponse(BaseModel):
response: str
session_id: str
# 聊天接口
@app.post("/chat", response_model=ChatResponse)
async def chat(request: ChatRequest):
try:
# 调用 Agent 生成回复
response = agent.run(request.user_input)
return ChatResponse(
response=response,
session_id=request.session_id
)
except Exception as e:
return ChatResponse(
response=f"出错了:{str(e)}",
session_id=request.session_id
)
# 健康检查接口
@app.get("/health")
async def health_check():
return {"status": "healthy"}
6.3 监控与评估
监控指标:Agent 响应时间、工具调用成功率、错误率、用户满意度
评估工具:LangSmith 提供的 Agent 评估模块,支持自定义评估指标
持续优化:定期分析错误案例,优化 Prompt、工具配置和模型选择
七、常见问题解决
7.1 模型加载失败
7.2 Agent 工具调用错误
7.3 检索结果不准确
7.4 对话记忆丢失
问题原因:记忆类型选择不当、上下文窗口过小
解决方案:
使用 ConversationBufferMemory 或 ConversationSummaryMemory
增大 LLM 的 context_window 参数
定期清理无关记忆内容
八、扩展与进阶
8.1 工具扩展
集成业务系统:如数据库查询工具(SQLDatabaseToolkit)、API 调用工具(RequestsToolkit)
自定义工具:根据业务需求开发专属工具(如订单查询、数据统计工具)
工具链组合:将多个工具组合为工具链,实现复杂任务自动化(如“数据查询 → 分析 → 报告生成”)
8.2 LangChain 生态工具集成
LangGraph:构建更复杂的 Agent 工作流(支持循环、分支、人类介入)
LangServe:快速部署 LangChain 应用为服务
LangChain Hub:共享和复用 Prompt、链、Agent 配置
Deep Agents:构建具备规划能力、子Agent 协作的高级智能体
8.3 高级应用场景
智能客服:集成知识库、工单系统,提供自动化客户支持
数据分析助手:连接数据库,自动生成 SQL、分析数据并生成报告
研发助手:集成代码仓库、文档系统,辅助代码编写、文档生成
个人助理:管理日程、发送邮件、查询信息,提供个性化服务
总结
本文档详细介绍了 LangChain 框架的本地部署流程、Agent 智能体的核心原理与搭建步骤,并提供了完整的代码示例和优化方案。通过 LangChain 的模块化设计,开发者可以快速构建具备工具调用、记忆管理、任务规划能力的智能助手,并基于实际需求进行扩展与优化。
随着 AI 技术的发展,LangChain 生态将持续完善,Agent 智能体的应用场景也将不断扩展。建议开发者在实践中结合 LangSmith 等工具进行调试与评估,持续优化产品体验,逐步实现从原型到生产级应用的落地。