鱼C论坛

 找回密码
 立即注册
查看: 16|回复: 1

[AI工作流] 29. LangChain——middleware中间件

[复制链接]
发表于 2 小时前 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
1. 中间件的作用?
中间件的作用是对智能体的每一步工作进行控制和自定义的执行。
下载 (51).png
LangChain中内置了一些基础的中间件:
https://docs.langchain.com/oss/python/langchain/middlewarre/built-in

2. 中间件可以嵌入在哪些节点中?
下载 (52).png


3.代码实战

  1. from typing import Dict, Any, List
  2. from uuid import UUID

  3. from langchain.agents import create_tool_calling_agent, AgentExecutor
  4. from langchain_openai import ChatOpenAI
  5. from langchain_core.tools import tool
  6. from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
  7. from langchain_core.callbacks import BaseCallbackHandler
  8. from langchain_core.outputs import LLMResult


  9. # ================= 2. 定义工具 =================
  10. @tool(description="查询天气,传入城市名称字符串,返回字符串天气信息")
  11. def get_weather(city: str) -> str:
  12.     return f"{city}天气:晴天"

  13. # ================= 3. 【核心修改】自定义回调处理器 (替代旧版 Middleware) =================
  14. class MyCustomHandler(BaseCallbackHandler):
  15.     """
  16.     自定义回调类,通过重写以下方法来实现 before/after 的逻辑
  17.     """
  18.    
  19.     # 对应: Agent 启动
  20.     def on_chain_start(self, serialized: Dict[str, Any], inputs: Dict[str, Any], **kwargs: Any) -> Any:
  21.         print(f"[before agent] agent启动,并附带消息")

  22.     # 对应: Agent 结束
  23.     def on_chain_end(self, outputs: Dict[str, Any], **kwargs: Any) -> Any:
  24.         print(f"[after agent] agent结束")

  25.     # 对应: Model 执行前
  26.     def on_llm_start(self, serialized: Dict[str, Any], prompts: List[str], **kwargs: Any) -> Any:
  27.         print(f"[before_model] 模型即将调用")
  28.         print("模型调用啦")

  29.     # 对应: Model 执行后
  30.     def on_llm_end(self, response: LLMResult, **kwargs: Any) -> Any:
  31.         print(f"[after_model] 模型调用结束")

  32.     # 对应: Tool 执行前
  33.     def on_tool_start(self, serialized: Dict[str, Any], input_str: str, **kwargs: Any) -> Any:
  34.         tool_name = kwargs.get('name', 'unknown_tool')
  35.         print(f"工具执行:{tool_name}")
  36.         print(f"工具执行传入参数:{input_str}")

  37. # ================= 4. 初始化模型和 Agent =================
  38. llm = ChatOpenAI(
  39.     model="qwen-max",
  40.     temperature=0,
  41.     openai_api_base="https://dashscope.aliyuncs.com/compatible-mode/v1",
  42. )

  43. prompt = ChatPromptTemplate.from_messages([
  44.     ("system", "你是一个天气助手。"),
  45.     ("human", "{input}"),
  46.     MessagesPlaceholder(variable_name="agent_scratchpad"),
  47. ])

  48. agent = create_tool_calling_agent(llm=llm, tools=[get_weather], prompt=prompt)
  49. agent_executor = AgentExecutor(agent=agent, tools=[get_weather], verbose=False)

  50. # ================= 5. 执行并传入回调 =================
  51. # 在这里把我们写好的 Handler 传进去
  52. my_handler = MyCustomHandler()

  53. print("--- 开始运行 ---")
  54. res = agent_executor.invoke(
  55.     {"input": "深圳今天的天气如何呀,如何穿衣"},
  56.     config={"callbacks": [my_handler]}
  57. )

  58. print("\n**********\n最终结果:", res["output"])
复制代码





本帖被以下淘专辑推荐:

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2 小时前 | 显示全部楼层
中间件的作用?
中间件的作用是对智能体的每一步工作进行控制和自定义的执行。


在LangChain中,中间件(现在通常通过回调处理器实现)允许我们在智能体执行的各个阶段插入自定义逻辑,比如日志记录、监控、修改输入输出等。

中间件可以嵌入在哪些节点中?


通过自定义回调处理器,我们可以嵌入以下节点(事件):
  • 链(Chain)开始和结束
  • 大型语言模型(LLM)调用开始和结束
  • 工具(Tool)调用开始和结束
  • 其他如检索、提示等事件


代码实战


以下是修复后的完整代码示例:

  1. from typing import Dict, Any, List
  2. from uuid import UUID

  3. from langchain.agents import create_tool_calling_agent, AgentExecutor
  4. from langchain_openai import ChatOpenAI
  5. from langchain_core.tools import tool
  6. from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
  7. from langchain_core.callbacks import BaseCallbackHandler
  8. from langchain_core.outputs import LLMResult


  9. # ================= 1. 定义工具 =================
  10. @tool(description="查询天气,传入城市名称字符串,返回字符串天气信息")
  11. def get_weather(city: str) -> str:
  12.     return f"{city}天气:晴天"

  13. # ================= 2. 自定义回调处理器 =================
  14. class MyCustomHandler(BaseCallbackHandler):
  15.     """
  16.     自定义回调类,通过重写方法实现中间件逻辑
  17.     """
  18.    
  19.     def on_chain_start(self, serialized: Dict, inputs: Dict, **kwargs: Any) -> Any:
  20.         print(f" agent启动,并附带消息")

  21.     def on_chain_end(self, outputs: Dict, **kwargs: Any) -> Any:
  22.         print(f" agent结束")

  23.     def on_llm_start(self, serialized: Dict, prompts: List, **kwargs: Any) -> Any:
  24.         print(f" 模型即将调用")
  25.         print("模型调用啦")

  26.     def on_llm_end(self, response: LLMResult, **kwargs: Any) -> Any:
  27.         print(f" 模型调用结束")

  28.     def on_tool_start(self, serialized: Dict, input_str: str, **kwargs: Any) -> Any:
  29.         tool_name = kwargs.get('name', 'unknown_tool')
  30.         print(f"工具执行:{tool_name}")
  31.         print(f"工具执行传入参数:{input_str}")

  32. # ================= 3. 初始化模型和Agent =================
  33. llm = ChatOpenAI(
  34.     model="qwen-max",
  35.     temperature=0,
  36.     openai_api_base="[url=https://dashscope.aliyuncs.com/compatible-mode/v1",]https://dashscope.aliyuncs.com/compatible-mode/v1",[/url]
  37. )

  38. # 构建提示模板
  39. prompt = ChatPromptTemplate.from_messages([
  40.     ("system", "You are a helpful assistant."),
  41.     ("human", "{input}"),
  42.     MessagesPlaceholder(variable_name="agent_scratchpad"),
  43. ])

  44. # 工具列表
  45. tools = [get_weather]

  46. agent = create_tool_calling_agent(llm=llm, tools=tools, prompt=prompt)
  47. agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=False)

  48. # ================= 4. 执行并传入回调处理器 =================
  49. my_handler = MyCustomHandler()

  50. print("--- 开始运行 ---")
  51. res = agent_executor.invoke(
  52.     {"input": "深圳今天的天气如何呀,如何穿衣"},
  53.     config={"callbacks": [my_handler]}
  54. )

  55. print("\n**********\n最终结果:", res)
复制代码


关键点说明:
  • 我们创建了一个自定义回调处理器 MyCustomHandler,通过重写特定方法(如 on_chain_starton_tool_start 等)来在智能体执行的不同阶段添加自定义操作。
  • 在初始化智能体执行器后,通过 config={"callbacks": [my_handler]} 将回调处理器传入,从而实现对执行过程的监控和控制。


运行此代码,你将看到在智能体执行过程中,各个节点(如链启动、模型调用、工具执行等)都会触发我们定义的回调方法,打印相应的信息。这就是LangChain中利用回调处理器实现中间件功能的方式。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2026-3-9 15:06

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表