在人工智能飞速发展的今天,单纯的语言模型已经无法满足复杂任务的需求。就像一个聪明的大脑如果没有手脚,也难以完成实际工作。LangChain 1.0的智能体(Agent)正是为了解决这一问题,将语言模型与工具、中间件、记忆等组件深度融合,打造出能够自主推理、迭代求解的智能系统。本文将从核心组件、技术架构、实战应用三个维度,全面解析LangChain 1.0智能体的技术精髓,帮助开发者快速掌握智能体的构建与优化方法。

一、智能体的核心架构:五大组件协同工作
LangChain 1.0智能体的核心优势在于模块化设计,通过五大核心组件的灵活组合,实现从简单问答到复杂任务处理的全场景覆盖。这五大组件如同智能体的"大脑、手脚、语言、扩展能力和记忆系统",各司其职又协同工作。
(一)模型:智能体的推理大脑
模型是智能体的核心推理引擎,负责理解用户需求、规划任务流程、选择合适工具。LangChain 1.0支持静态与动态两种模型选择方式,满足不同场景的需求。
静态模型是最常用的配置方式,在创建智能体时一次性指定,整个执行过程中保持不变。例如使用阿里云通义千问模型构建的基础配置:
python
basic_model = ChatOpenAI(base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
model="qwen-plus",
api_key=os.getenv("DASHSCOPE_API_KEY"),
temperature=1.0,
timeout=60,
max_tokens=1024,
max_retries=2)
这种方式配置简单、性能稳定,适合需求明确的场景。
动态模型则更具灵活性,能够根据运行时的上下文信息动态选择合适的模型。比如根据用户的VIP等级选择基础模型或高级模型,实现成本与性能的平衡:
python
@wrap_model_call
def dynamic_select_model(request: ModelRequest, handle) -> ModelResponse:
if request.runtime.context["vip"] == 1:
print("使用基础模型")
model = basic_model
else:
print("使用高级模型")
model = advance_model
request.model = model
return handle(request)
动态模型选择在SaaS服务中尤为实用,既能满足普通用户的基础需求,又能为付费用户提供更优质的服务。
模型的关键调用方法包括invoke(同步调用)、stream(流式输出)和batch(批量处理)。流式输出在用户交互场景中非常重要,通过实时返回token,能够显著提升用户体验。例如查询天气时,流式输出可以逐步展示查询过程和结果,让用户感知系统的实时响应。
(二)工具:智能体的行动手脚
如果说模型是智能体的大脑,工具就是它的手脚,赋予智能体与外部系统交互的能力。LangChain 1.0的工具系统支持连续调用、并行调用、动态选择等高级功能,能够处理复杂的任务流程。
创建自定义工具非常简单,通过@tool装饰器即可快速定义。例如查询天气的工具:
python
@tool(name_or_callable="weather_search", description="查询天气")
def weather_search(location: str, units: str = "celsius", include_forecast: bool = False):
temp = 22 if units == "celsius" else 72
result = f"当前{location}天气:{temp}摄氏度"
if include_forecast:
result += "\n未来5天:晴"
return result
工具的参数验证可以通过Pydantic实现,确保输入参数的合法性,避免运行时错误。例如为天气查询工具添加参数校验:
python
class WeatherInput(BaseModel):
location: str = Field(description="城市名称或坐标")
units: Literal["celsius", "fahrenheit"] = Field(default="celsius", description="温度单位")
include_forecast: bool = Field(default=False, description="是否包含5天预报")
@tool(name_or_callable="weather_search", description="查询天气", args_schema=WeatherInput)
def weather_search(location: str, units: str = "celsius", include_forecast: bool = False):
# 实现逻辑不变
工具还可以通过ToolRuntime访问运行时上下文信息,包括状态数据、用户配置、存储信息等。这一特性使得工具能够根据上下文动态调整行为,例如在天气查询工具中记录用户的查询历史:
python
@tool(name_or_callable="weather_search", description="查询天气")
def weather_search(runtime: ToolRuntime, location: str = "北京", units: str = "celsius"):
# 获取用户ID
user_id = runtime.context.user_id
# 记录查询日志
stream_writer = runtime.stream_writer
stream_writer(f"用户{user_id}查询{location}天气")
# 执行查询逻辑
temp = 22 if units == "celsius" else 72
return f"当前{location}天气:{temp}摄氏度"
(三)消息:智能体的沟通语言
消息是智能体与用户、工具之间沟通的桥梁,LangChain 1.0定义了标准化的消息格式,支持文本、图像等多模态内容。消息包含角色(Role)、内容(Content)和元数据(Metadata)三个核心属性,角色分为系统消息、用户消息、AI消息和工具消息四种类型。
系统消息用于配置智能体的行为模式,例如定义天气查询助手的系统消息:
python
system_message = SystemMessage(
content="你是一个天气查询助手,需要根据用户输入的地点查询天气,回答简洁明了"
)
用户消息是用户的查询内容,AI消息是智能体的响应,工具消息则是工具调用的结果。这四种消息构成了智能体的对话上下文,支持复杂的多轮交互。
LangChain 1.0还引入了标准内容块(Content Blocks)特性,统一不同模型提供商的内容格式。例如使用DeepSeek模型的深度思考功能,会返回包含推理过程和最终结果的结构化内容块:
python
response = basic_model.invoke("深度思考下,如何才能实现AIGC?")
# 输出包含reasoning和text两种类型的内容块
这种结构化的消息格式使得智能体能够更好地理解和处理复杂响应,提升任务执行的准确性。
(四)中间件:智能体的扩展能力
中间件是LangChain 1.0最具创新性的特性之一,它允许开发者在不修改核心逻辑的情况下,对智能体的行为进行扩展和定制。中间件可以看作是智能体的"插件系统",支持在模型调用前后、工具执行前后插入自定义逻辑。
LangChain 1.0提供了丰富的内置中间件,覆盖常见的扩展场景:
- HumanInTheLoopMiddleware:人机交互中间件,在执行敏感工具前需要人工审批。例如在查询用户隐私数据时,需要管理员批准:
python
agent = create_agent(
model=base_model,
tools=[get_weather, get_user_info],
middleware=[
HumanInTheLoopMiddleware(
interrupt_on={
"get_user_info": {"allowed_decisions": ["approve", "edit", "reject"]},
"get_weather": False,
}
)
],
)
这种方式在企业级应用中非常重要,能够有效防范数据泄露风险。
- ModelCallLimitMiddleware:模型调用限制中间件,避免系统异常导致的无限调用。例如限制每个用户最多调用3次模型:
python
middleware=[ModelCallLimitMiddleware(
thread_limit=3,
run_limit=2,
exit_behavior="end"
)]
这一中间件能够有效控制API调用成本,防止恶意攻击。
- PIIMiddleware:敏感数据检测中间件,用于过滤用户输入和工具输出中的敏感信息。例如屏蔽密码、token等敏感数据:
python
sensitive_patterns = [
r'"[^"]*password[^"]*"\s*:\s*"[^"]*"',
r'"[^"]*token[^"]*"\s*:\s*"[^"]*"'
]
combined_pattern = '|'.join(sensitive_patterns)
middleware=[PIIMiddleware(
pii_type="personal",
strategy="mask",
detector=combined_pattern,
apply_to_input=True,
apply_to_output=True
)]
- LLMToolEmulator:工具模拟中间件,当工具尚未开发完成或测试成本较高时,可以使用LLM模拟工具行为。例如在开发旅行规划智能体时,模拟机票查询工具:
python
middleware=[LLMToolEmulator(
model=base_model,
tools=[get_plane_ticket, get_hotel_info]
)]
这种方式能够加速开发流程,降低测试成本。
除了内置中间件,LangChain 1.0还支持自定义中间件。开发者可以通过装饰器或子类继承的方式,实现个性化的扩展逻辑。例如通过装饰器定义日志记录中间件:
python
@before_model
def log_middleware(state: AgentState, runtime: Runtime) -> dict[str, Any] | None:
print(f"模型调用时间:{datetime.now()}")
print(f"当前消息数量:{len(state['messages'])}")
return None
中间件的执行流程遵循特定的顺序:before_*钩子按顺序执行,after_*钩子反向执行,wrap_*钩子嵌套执行。这种设计确保了中间件之间的兼容性,支持复杂的扩展场景。
(五)短期记忆:智能体的记忆系统
短期记忆使智能体能够记住对话过程中的关键信息,支持多轮交互和上下文感知。LangChain 1.0通过AgentState对象管理短期记忆,包含对话历史、运行时参数等信息。
自定义State可以扩展记忆的存储内容,例如记录用户的偏好设置:
python
class CustomState(AgentState):
user_preferences: dict # 存储用户偏好,如温度单位、语言等
记忆的保存方式分为内存存储(InMemorySaver)和数据库存储(PostgresSaver)。内存存储适用于开发测试场景,数据库存储则适用于生产环境,支持历史记录的持久化和多实例共享。
历史消息管理是短期记忆的核心功能,LangChain 1.0提供了消息裁剪(trim)、删除(delete)和摘要(summary)三种管理方式。消息裁剪用于控制上下文长度,避免超出模型的token限制:
python
@before_model
def customer_trim_messages(state: AgentState, runtime: Runtime) -> dict[str, Any] | None:
messages = state["messages"]
if len(messages) :
return None
# 保留最新5条消息
recent_messages = trim_messages(
messages,
strategy="last",
token_counter=len,
max_tokens=5,
)
first_msg = messages[0] # 保留系统消息
return {
"messages": [
RemoveMessage(id=REMOVE_ALL_MESSAGES),
first_msg,
*recent_messages
]
}
消息摘要则通过SummarizationMiddleware实现,当对话历史过长时,自动将历史消息汇总为摘要,节省上下文空间:
python
summary_prompt = """
您是一位对话摘要助手,需要总结人类与助手之间的对话。
按照"城市:天气"格式输出,不知道的天气信息不要输出。
"""
middleware=[SummarizationMiddleware(
model=base_model,
max_tokens_before_summary=100,
messages_to_keep=1,
summary_prompt=summary_prompt,
)]
这种方式既保证了上下文的完整性,又有效控制了token消耗。
二、核心组件的协同工作流程
理解了五大核心组件之后,我们来看它们如何协同工作完成一个完整的任务。以旅行规划智能体为例,其工作流程如下:
用户发起请求:用户输入"帮我制定一个去北京的旅行计划",系统将其封装为用户消息。
模型推理:智能体的模型解析用户需求,识别出需要查询天气、机票、酒店和景点信息,生成工具调用计划。
工具选择:通过LLMToolSelectorMiddleware筛选出相关工具,包括get_weather、get_plane_ticket、get_hotel_info和get_scenic。
工具执行:智能体依次调用或并行调用所选工具,获取北京的天气情况、酒店推荐、景点信息等数据。对于尚未开发完成的机票查询工具,通过LLMToolEmulator模拟返回结果。
结果处理:模型接收工具返回的结构化数据,进行整理和自然语言转换。
记忆更新:将用户请求、工具调用结果、最终响应等信息存入短期记忆,支持后续的多轮交互。
响应输出:通过流式输出将旅行计划逐步返回给用户,提升交互体验。
在整个流程中,中间件发挥着重要的支撑作用:HumanInTheLoopMiddleware确保敏感操作需要人工审批,PIIMiddleware过滤用户输入中的敏感信息,ModelCallLimitMiddleware控制模型调用次数,SummarizationMiddleware管理对话历史。
三、实战场景:构建企业级天气查询智能体
为了帮助开发者更好地理解和应用LangChain 1.0的核心组件,下面将通过一个企业级天气查询智能体的实战案例,展示组件的具体使用方法。
(一)需求分析
企业级天气查询智能体需要满足以下需求:
- 支持多城市天气查询,包括实时天气和5天预报。
- 支持用户偏好设置,如温度单位、语言等。
- 支持批量查询多个城市的天气。
- 具备敏感数据过滤功能,防止用户输入恶意内容。
- 具备模型调用限制,控制API成本。
- 支持对话历史记录和多轮交互。
(二)技术选型
模型:使用阿里云通义千问qwen-plus作为基础模型,高级用户自动切换到qwen-max。
工具:天气查询工具(集成第三方天气API)、用户偏好管理工具。
中间件:PIIMiddleware(敏感数据过滤)、ModelCallLimitMiddleware(调用限制)、SummarizationMiddleware(历史摘要)、HumanInTheLoopMiddleware(敏感操作审批)。
记忆存储:生产环境使用PostgresSaver,开发环境使用InMemorySaver。
(三)代码实现
- 模型配置
python
# 基础模型配置
basic_model = ChatOpenAI(
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
model="qwen-plus",
api_key=os.getenv("DASHSCOPE_API_KEY"),
temperature=0.3, # 降低随机性,保证结果准确性
timeout=60,
max_tokens=2048,
max_retries=3
)
# 高级模型配置
advance_model = ChatOpenAI(
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
model="qwen-max",
api_key=os.getenv("DASHSCOPE_API_KEY"),
temperature=0.3,
timeout=60,
max_tokens=4096,
max_retries=3
)
# 动态模型选择中间件
@wrap_model_call
def dynamic_select_model(request: ModelRequest, handle) -> ModelResponse:
# 根据用户VIP等级选择模型
vip_level = request.runtime.context.get("vip_level", 1)
if vip_level >= 2:
request.model = advance_model
print("使用高级模型qwen-max")
else:
request.model = basic_model
print("使用基础模型qwen-plus")
return handle(request)
- 工具定义
python
# 天气查询工具输入验证
class WeatherInput(BaseModel):
location: str = Field(description="城市名称,多个城市用逗号分隔")
units: Literal["celsius", "fahrenheit"] = Field(default="celsius", description="温度单位")
include_forecast: bool = Field(default=False, description="是否包含5天预报")
# 天气查询工具
@tool(name_or_callable="weather_search", description="查询天气,支持多城市批量查询", args_schema=WeatherInput)
def weather_search(runtime: ToolRuntime, location: str, units: str = "celsius", include_forecast: bool = False):
# 获取用户ID
user_id = runtime.context.get("user_id", "unknown")
# 记录查询日志
stream_writer = runtime.stream_writer
stream_writer(f"用户{user_id}正在查询以下城市天气:{location}")
# 分割多个城市
cities = [city.strip() for city in location.split(",")]
results = []
for city in cities:
# 调用第三方天气API(实际项目中替换为真实API调用)
# 此处使用模拟数据
temp = random.randint(15, 30) if units == "celsius" else random.randint(59, 86)
weather = "晴" if random.random() > 0.3 else "多云"
result = f"{city}:{weather},{temp}°{units[0].upper()}"
# 如果需要包含预报
if include_forecast:
forecast = "未来5天:晴、晴、多云、晴、阴"
result += f"\n{forecast}"
results.append(result)
# 写入查询历史到记忆
runtime.state["weather_history"] = runtime.state.get("weather_history", []) + cities
return "\n\n".join(results)
# 用户偏好设置工具
@tool(name_or_callable="set_preference", description="设置用户偏好,如温度单位")
def set_preference(runtime: ToolRuntime, units: str = "celsius", language: str = "zh"):
# 更新用户偏好
runtime.state["user_preferences"] = {
"units": units,
"language": language
}
return f"偏好设置成功:温度单位={units},语言={language}"
- 中间件配置
python
# 敏感数据检测中间件
sensitive_patterns = [
r'"[^"]*pwd[^"]*"\s*:\s*"[^"]*"',
r'"[^"]*password[^"]*"\s*:\s*"[^"]*"',
r'"[^"]*token[^"]*"\s*:\s*"[^"]*"',
r'"[^"]*apiKey[^"]*"\s*:\s*"[^"]*"'
]
combined_pattern = '|'.join(sensitive_patterns)
pii_middleware = PIIMiddleware(
pii_type="personal",
strategy="mask",
detector=combined_pattern,
apply_to_input=True,
apply_to_output=True,
apply_to_tool_results=True
)
# 模型调用限制中间件
call_limit_middleware = ModelCallLimitMiddleware(
thread_limit=10, # 每个用户最多10次调用
run_limit=3, # 每次运行最多3次调用
exit_behavior="end"
)
# 对话摘要中间件
summary_prompt = """
您是天气查询对话摘要助手,需要总结用户与助手的对话内容。
格式要求:
1. 记录用户查询的城市和对应的天气情况
2. 记录用户的偏好设置
3. 语言简洁,不超过30字
"""
summary_middleware = SummarizationMiddleware(
model=basic_model,
max_tokens_before_summary=200,
messages_to_keep=2,
summary_prompt=summary_prompt,
summary_prefix="对话摘要:"
)
# 人机交互中间件(批量查询需要审批)
hitl_middleware = HumanInTheLoopMiddleware(
interrupt_on={
"weather_search": lambda args: len(args.get("location", "").split(",")) > 3,
"set_preference": False
},
description_prefix="以下操作需要审批,请选择 approve/edit/reject"
)
- 智能体创建与运行
python
# 自定义State
class WeatherAgentState(AgentState):
user_preferences: dict = Field(default_factory=dict)
weather_history: list = Field(default_factory=list)
# 数据库存储配置(生产环境)
# db_uri = "postgresql://postgres:postgres@localhost:5432/weather_agent?sslmode=disable"
# checkpointer = PostgresSaver.from_conn_string(db_uri)
# checkpointer.setup()
# 内存存储配置(开发环境)
checkpointer = InMemorySaver()
# 创建智能体
agent = create_agent(
model=basic_model,
tools=[weather_search, set_preference],
state_schema=WeatherAgentState,
middleware=[
dynamic_select_model,
pii_middleware,
call_limit_middleware,
summary_middleware,
hitl_middleware
],
checkpointer=checkpointer,
system_prompt="你是一个专业的天气查询助手,能够查询多个城市的实时天气和5天预报,支持用户偏好设置。回答简洁明了,使用用户指定的语言和温度单位。"
)
# 运行智能体
def run_agent(user_query: str, user_context: dict):
config = {"configurable": {"thread_id": user_context.get("user_id", "default")}}
result = agent.invoke(
input={"messages": [{"role": "user", "content": user_query}]},
context=user_context,
config=config
)
return result
# 测试智能体
if __name__ == "__main__":
# 普通用户查询
user_context = {"user_id": "user_001", "vip_level": 1}
print("普通用户查询:")
result = run_agent("查询北京、上海、广州的天气,包含5天预报", user_context)
for msg in result["messages"]:
if msg.role == "assistant":
print(msg.content)
# VIP用户查询
print("\nVIP用户查询:")
vip_context = {"user_id": "user_002", "vip_level": 2}
result = run_agent("设置温度单位为fahrenheit,然后查询深圳、杭州、成都、重庆的天气", vip_context)
for msg in result["messages"]:
if msg.role == "assistant":
print(msg.content)
(四)功能测试与优化
- 多城市批量查询:支持同时查询多个城市的天气,超过3个城市时触发人工审批。
- 用户偏好记忆:用户设置温度单位后,后续查询自动使用该单位。
- 敏感数据过滤:如果用户输入包含密码、token等敏感信息,会自动屏蔽。
- 模型动态切换:VIP用户自动使用高级模型,支持更长的上下文和更精准的响应。
- 对话历史管理:长时间对话时自动生成摘要,节省token消耗。
通过这个实战案例,我们可以看到LangChain 1.0智能体的强大灵活性和扩展性。开发者可以根据实际需求,灵活组合五大核心组件,构建出满足不同场景的智能体应用。
四、总结与展望
LangChain 1.0通过模型、工具、消息、中间件、短期记忆五大核心组件的模块化设计,为智能体开发提供了灵活强大的框架。开发者可以像搭积木一样,根据实际需求组合不同的组件,快速构建出从简单问答到复杂任务处理的智能体应用。
中间件作为LangChain 1.0的核心创新,极大地扩展了智能体的能力边界,支持动态模型选择、敏感数据过滤、人机交互等高级功能。短期记忆系统则使智能体具备了上下文感知能力,支持复杂的多轮交互。