在人工智能飞速发展的今天,单纯的语言模型已经无法满足复杂任务的需求。就像一个聪明的大脑如果没有手脚,也难以完成实际工作。LangChain 1.0的智能体(Agent)正是为了解决这一问题,将语言模型与工具、中间件、记忆等组件深度融合,打造出能够自主推理、迭代求解的智能系统。本文将从核心组件、技术架构、实战应用三个维度,全面解析LangChain 1.0智能体的技术精髓,帮助开发者快速掌握智能体的构建与优化方法。
一、智能体的核心架构:五大组件协同工作
LangChain 1.0智能体的核心优势在于模块化设计,通过五大核心组件的灵活组合,实现从简单问答到复杂任务处理的全场景覆盖。这五大组件如同智能体的"大脑、手脚、语言、扩展能力和记忆系统",各司其职又协同工作。
(一)模型:智能体的推理大脑
模型是智能体的核心推理引擎,负责理解用户需求、规划任务流程、选择合适工具。LangChain 1.0支持静态与动态两种模型选择方式,满足不同场景的需求。
静态模型是最常用的配置方式,在创建智能体时一次性指定,整个执行过程中保持不变。例如使用阿里云通义千问模型构建的基础配置:
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等级选择基础模型或高级模型,实现成本与性能的平衡:
@wrap_model_calldefdynamic_select_model(request:ModelRequest,handle)->ModelResponse:ifrequest.runtime.context["vip"]==1:print("使用基础模型")model=basic_modelelse:print("使用高级模型")model=advance_model request.model=modelreturnhandle(request)动态模型选择在SaaS服务中尤为实用,既能满足普通用户的基础需求,又能为付费用户提供更优质的服务。
模型的关键调用方法包括invoke(同步调用)、stream(流式输出)和batch(批量处理)。流式输出在用户交互场景中非常重要,通过实时返回token,能够显著提升用户体验。例如查询天气时,流式输出可以逐步展示查询过程和结果,让用户感知系统的实时响应。
(二)工具:智能体的行动手脚
如果说模型是智能体的大脑,工具就是它的手脚,赋予智能体与外部系统交互的能力。LangChain 1.0的工具系统支持连续调用、并行调用、动态选择等高级功能,能够处理复杂的任务流程。
创建自定义工具非常简单,通过@tool装饰器即可快速定义。例如查询天气的工具:
@tool(name_or_callable="weather_search",description="查询天气")defweather_search(location:str,units:str="celsius",include_forecast:bool=False):temp=22ifunits=="celsius"else72result=f"当前{location}天气:{temp}摄氏度"ifinclude_forecast:result+="\n未来5天:晴"returnresult工具的参数验证可以通过Pydantic实现,确保输入参数的合法性,避免运行时错误。例如为天气查询工具添加参数校验:
classWeatherInput(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)defweather_search(location:str,units:str="celsius",include_forecast:bool=False):# 实现逻辑不变工具还可以通过ToolRuntime访问运行时上下文信息,包括状态数据、用户配置、存储信息等。这一特性使得工具能够根据上下文动态调整行为,例如在天气查询工具中记录用户的查询历史:
@tool(name_or_callable="weather_search",description="查询天气")defweather_search(runtime:ToolRuntime,location:str="北京",units:str="celsius"):# 获取用户IDuser_id=runtime.context.user_id# 记录查询日志stream_writer=runtime.stream_writer stream_writer(f"用户{user_id}查询{location}天气")# 执行查询逻辑temp=22ifunits=="celsius"else72returnf"当前{location}天气:{temp}摄氏度"(三)消息:智能体的沟通语言
消息是智能体与用户、工具之间沟通的桥梁,LangChain 1.0定义了标准化的消息格式,支持文本、图像等多模态内容。消息包含角色(Role)、内容(Content)和元数据(Metadata)三个核心属性,角色分为系统消息、用户消息、AI消息和工具消息四种类型。
系统消息用于配置智能体的行为模式,例如定义天气查询助手的系统消息:
system_message=SystemMessage(content="你是一个天气查询助手,需要根据用户输入的地点查询天气,回答简洁明了")用户消息是用户的查询内容,AI消息是智能体的响应,工具消息则是工具调用的结果。这四种消息构成了智能体的对话上下文,支持复杂的多轮交互。
LangChain 1.0还引入了标准内容块(Content Blocks)特性,统一不同模型提供商的内容格式。例如使用DeepSeek模型的深度思考功能,会返回包含推理过程和最终结果的结构化内容块:
response=basic_model.invoke("深度思考下,如何才能实现AIGC?")# 输出包含reasoning和text两种类型的内容块这种结构化的消息格式使得智能体能够更好地理解和处理复杂响应,提升任务执行的准确性。
(四)中间件:智能体的扩展能力
中间件是LangChain 1.0最具创新性的特性之一,它允许开发者在不修改核心逻辑的情况下,对智能体的行为进行扩展和定制。中间件可以看作是智能体的"插件系统",支持在模型调用前后、工具执行前后插入自定义逻辑。
LangChain 1.0提供了丰富的内置中间件,覆盖常见的扩展场景:
- HumanInTheLoopMiddleware:人机交互中间件,在执行敏感工具前需要人工审批。例如在查询用户隐私数据时,需要管理员批准:
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次模型:
middleware=[ModelCallLimitMiddleware(thread_limit=3,run_limit=2,exit_behavior="end")]这一中间件能够有效控制API调用成本,防止恶意攻击。
- PIIMiddleware:敏感数据检测中间件,用于过滤用户输入和工具输出中的敏感信息。例如屏蔽密码、token等敏感数据:
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模拟工具行为。例如在开发旅行规划智能体时,模拟机票查询工具:
middleware=[LLMToolEmulator(model=base_model,tools=[get_plane_ticket,get_hotel_info])]这种方式能够加速开发流程,降低测试成本。
除了内置中间件,LangChain 1.0还支持自定义中间件。开发者可以通过装饰器或子类继承的方式,实现个性化的扩展逻辑。例如通过装饰器定义日志记录中间件:
@before_modeldeflog_middleware(state:AgentState,runtime:Runtime)->dict[str,Any]|None:print(f"模型调用时间:{datetime.now()}")print(f"当前消息数量:{len(state['messages'])}")returnNone中间件的执行流程遵循特定的顺序:before_*钩子按顺序执行,after_*钩子反向执行,wrap_*钩子嵌套执行。这种设计确保了中间件之间的兼容性,支持复杂的扩展场景。
(五)短期记忆:智能体的记忆系统
短期记忆使智能体能够记住对话过程中的关键信息,支持多轮交互和上下文感知。LangChain 1.0通过AgentState对象管理短期记忆,包含对话历史、运行时参数等信息。
自定义State可以扩展记忆的存储内容,例如记录用户的偏好设置:
classCustomState(AgentState):user_preferences:dict# 存储用户偏好,如温度单位、语言等记忆的保存方式分为内存存储(InMemorySaver)和数据库存储(PostgresSaver)。内存存储适用于开发测试场景,数据库存储则适用于生产环境,支持历史记录的持久化和多实例共享。
历史消息管理是短期记忆的核心功能,LangChain 1.0提供了消息裁剪(trim)、删除(delete)和摘要(summary)三种管理方式。消息裁剪用于控制上下文长度,避免超出模型的token限制:
@before_modeldefcustomer_trim_messages(state:AgentState,runtime:Runtime)->dict[str,Any]|None:messages=state["messages"]iflen(messages):returnNone# 保留最新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实现,当对话历史过长时,自动将历史消息汇总为摘要,节省上下文空间:
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。
(三)代码实现
- 模型配置
# 基础模型配置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_calldefdynamic_select_model(request:ModelRequest,handle)->ModelResponse:# 根据用户VIP等级选择模型vip_level=request.runtime.context.get("vip_level",1)ifvip_level>=2:request.model=advance_modelprint("使用高级模型qwen-max")else:request.model=basic_modelprint("使用基础模型qwen-plus")returnhandle(request)- 工具定义
# 天气查询工具输入验证classWeatherInput(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)defweather_search(runtime:ToolRuntime,location:str,units:str="celsius",include_forecast:bool=False):# 获取用户IDuser_id=runtime.context.get("user_id","unknown")# 记录查询日志stream_writer=runtime.stream_writer stream_writer(f"用户{user_id}正在查询以下城市天气:{location}")# 分割多个城市cities=[city.strip()forcityinlocation.split(",")]results=[]forcityincities:# 调用第三方天气API(实际项目中替换为真实API调用)# 此处使用模拟数据temp=random.randint(15,30)ifunits=="celsius"elserandom.randint(59,86)weather="晴"ifrandom.random()>0.3else"多云"result=f"{city}:{weather},{temp}°{units[0].upper()}"# 如果需要包含预报ifinclude_forecast:forecast="未来5天:晴、晴、多云、晴、阴"result+=f"\n{forecast}"results.append(result)# 写入查询历史到记忆runtime.state["weather_history"]=runtime.state.get("weather_history",[])+citiesreturn"\n\n".join(results)# 用户偏好设置工具@tool(name_or_callable="set_preference",description="设置用户偏好,如温度单位")defset_preference(runtime:ToolRuntime,units:str="celsius",language:str="zh"):# 更新用户偏好runtime.state["user_preferences"]={"units":units,"language":language}returnf"偏好设置成功:温度单位={units},语言={language}"- 中间件配置
# 敏感数据检测中间件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":lambdaargs:len(args.get("location","").split(","))>3,"set_preference":False},description_prefix="以下操作需要审批,请选择 approve/edit/reject")- 智能体创建与运行
# 自定义StateclassWeatherAgentState(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天预报,支持用户偏好设置。回答简洁明了,使用用户指定的语言和温度单位。")# 运行智能体defrun_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)returnresult# 测试智能体if__name__=="__main__":# 普通用户查询user_context={"user_id":"user_001","vip_level":1}print("普通用户查询:")result=run_agent("查询北京、上海、广州的天气,包含5天预报",user_context)formsginresult["messages"]:ifmsg.role=="assistant":print(msg.content)# VIP用户查询print("\nVIP用户查询:")vip_context={"user_id":"user_002","vip_level":2}result=run_agent("设置温度单位为fahrenheit,然后查询深圳、杭州、成都、重庆的天气",vip_context)formsginresult["messages"]:ifmsg.role=="assistant":print(msg.content)(四)功能测试与优化
- 多城市批量查询:支持同时查询多个城市的天气,超过3个城市时触发人工审批。
- 用户偏好记忆:用户设置温度单位后,后续查询自动使用该单位。
- 敏感数据过滤:如果用户输入包含密码、token等敏感信息,会自动屏蔽。
- 模型动态切换:VIP用户自动使用高级模型,支持更长的上下文和更精准的响应。
- 对话历史管理:长时间对话时自动生成摘要,节省token消耗。
通过这个实战案例,我们可以看到LangChain 1.0智能体的强大灵活性和扩展性。开发者可以根据实际需求,灵活组合五大核心组件,构建出满足不同场景的智能体应用。
四、总结与展望
LangChain 1.0通过模型、工具、消息、中间件、短期记忆五大核心组件的模块化设计,为智能体开发提供了灵活强大的框架。开发者可以像搭积木一样,根据实际需求组合不同的组件,快速构建出从简单问答到复杂任务处理的智能体应用。
中间件作为LangChain 1.0的核心创新,极大地扩展了智能体的能力边界,支持动态模型选择、敏感数据过滤、人机交互等高级功能。短期记忆系统则使智能体具备了上下文感知能力,支持复杂的多轮交互。