LangChain Agent与工具:如何向工具传递input外的额外参数(如userId)
向LangChain工具传递userId这类额外参数的方案
针对你需要将userId传递给getPrice工具的需求,有两种实用的实现方式,结合你的代码示例具体说明:
方法一:通过偏函数绑定固定参数(适合单用户独立会话)
如果每个用户维护独立的Agent实例,可以用functools.partial把userId预先绑定到工具函数上,工具调用时会自动带上该参数。
修改后的代码:
from langchain import hub from langchain.agents import AgentExecutor, create_react_agent from langchain.tools import Tool from langchain_openai import ChatOpenAI from langchain.memory import ConversationBufferMemory import requests from functools import partial llm = ChatOpenAI() prompt = hub.pull("hwchase17/react-chat") def getPrice(input, extra): print("input +++", input, extra) url = f"https://api.coincap.io/v2/assets/{input.lower()}" response = requests.get(url) price = response.json()["data"]["priceUsd"] return price # 假设当前会话的userId为user_123 current_user_id = "user_123" # 用partial将userId绑定到getPrice的extra参数 bound_getPrice = partial(getPrice, extra=current_user_id) # 创建绑定后的工具 apicall = Tool( name="getCryptoPrice", func=bound_getPrice, description="use to get the price for any given crypto from user input" ) tools = [apicall] agent = create_react_agent(llm, tools, prompt) agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True) memory = ConversationBufferMemory( memory_key="chat_history", return_messages=True ) # 正常调用即可,无需在invoke中额外传userId agent_executor.invoke( { "input": "what is the price of cardano", "chat_history": "Human: Hi! My name is Bob\nAI: Hello Bob! Nice to meet you", } )
方法二:动态传递参数(适合多用户共享Agent实例)
如果需要在每次调用时动态传入userId,可以使用StructuredTool定义多参数工具,并修改Prompt让Agent识别并传递userId参数。
修改后的代码:
from langchain import hub from langchain.agents import AgentExecutor, create_react_agent from langchain.tools import StructuredTool from langchain_openai import ChatOpenAI from langchain.memory import ConversationBufferMemory from langchain_core.prompts import PromptTemplate import requests llm = ChatOpenAI() # 自定义Prompt,添加user_id变量供Agent使用 custom_prompt = PromptTemplate.from_template(""" Answer the following questions as best you can. You have access to the following tools: {tools} Use the following format: Question: the input question you must answer Thought: you should always think about what to do Action: the action to take, should be one of [{tool_names}] Action Input: a dictionary containing the required parameters for the tool Observation: the result of the action ... (this Thought/Action/Action Input/Observation can repeat N times) Thought: I now know the final answer Final Answer: the final answer to the original input question Begin! Question: {input} Chat History: {chat_history} User ID: {user_id} Thought:""") # 修改工具函数,明确接收crypto和user_id两个参数 def getPrice(crypto: str, user_id: str): print("crypto +++", crypto, "user_id +++", user_id) url = f"https://api.coincap.io/v2/assets/{crypto.lower()}" response = requests.get(url) price = response.json()["data"]["priceUsd"] return f"{crypto}的价格为{price}美元(查询用户:{user_id})" # 用StructuredTool定义多参数工具 apicall = StructuredTool.from_function( func=getPrice, name="getCryptoPrice", description="用于获取加密货币价格,需要传入两个参数:crypto(加密货币名称)和user_id(当前用户ID)" ) tools = [apicall] agent = create_react_agent(llm, tools, custom_prompt) agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True) memory = ConversationBufferMemory( memory_key="chat_history", return_messages=True ) # 在invoke中直接传入user_id agent_executor.invoke( { "input": "what is the price of cardano", "chat_history": "Human: Hi! My name is Bob\nAI: Hello Bob! Nice to meet you", "user_id": "user_123" } )
选择建议
- 若每个用户有独立的Agent实例,优先用方法一,实现简单且无需修改Prompt。
- 若多用户共享Agent实例,需要动态传递参数,用方法二,通过StructuredTool和自定义Prompt实现参数传递。
内容的提问来源于stack exchange,提问作者tejaswi avhad
相关产品推荐
相关产品推荐

