自定义LangChain工具无法完成Agent流水线,Discord功能异常求助
问题:自定义Discord工具无法被LangChain Agent识别有效响应
开发Discord消息AI助手时,自定义Discord工具函数返回的成功提示(如Successfully sent Can you grab some apples on your way home? to John)未被CHAT_CONVERSATIONAL_REACT_DESCRIPTION类型的Agent识别为有效工具响应,导致Agent错误输出"There was no tool response"。
核心原因
- 内部LLM的JSON格式要求错误:原Prompt要求输出的JSON缺少外层大括号,虽然本次运行侥幸解析成功,但存在格式合法性隐患,易导致
json.loads失败。 - 纯自然语言响应干扰Agent解析:该类型Agent对工具响应格式敏感,无标识的纯自然语言字符串可能被误判为对话内容,而非工具执行结果。
- 返回字符串末尾存在多余空格:可能干扰Agent对响应边界的识别。
解决方案
1. 修复内部LLM的JSON输出格式
修改Discord工具内部的PromptTemplate,确保生成合法的JSON对象(用双大括号{{}}转义避免模板解析冲突):
prompt = PromptTemplate( template=""" You are a message interpreter for Discord messages. Extract the recipient and core message content from: {message}. Output ONLY a valid JSON object with no extra text, following this structure: {{ "recipient": "name_of_recipient", "message": "core_message_text" }} """, input_variables=["message"], )
2. 给工具响应添加明确标识
返回带特殊标记的字符串,帮助Agent快速识别工具执行结果:
def discord(message): # ... 保留其他代码 ... try: jsonResp = json.loads(response) # 增加明确标识,避免与普通对话混淆 return f"[Discord Tool Success] Sent '{jsonResp['message']}' to {jsonResp['recipient']}" except json.JSONDecodeError: return "[Discord Tool Error] Failed to parse message content"
3. 简化工具定义
去掉不必要的lambda包装,直接引用函数:
tools = [ # Fibonacci工具不变 Tool( name="Discord", func=discord, # 直接使用函数,无需lambda description="Use when you need to send a message via Discord. Input should include recipient and message content in natural language." ), ]
4. 可选:使用StructuredTool明确输入输出结构
通过StructuredTool定义工具的输入输出规范,帮助Agent更清晰理解工具用法:
from langchain.tools import StructuredTool from pydantic import BaseModel, Field class DiscordInput(BaseModel): message: str = Field(description="Natural language instruction containing recipient and message content for Discord") discord_tool = StructuredTool.from_function( func=discord, name="Discord", description="Use when you need to send a message via Discord. Input should include recipient and message content in natural language.", args_schema=DiscordInput, ) tools = [fib_tool, discord_tool]
修改后的完整代码示例
import json from dotenv import load_dotenv from langchain.chains import LLMChain from langchain.chat_models import ChatOpenAI from langchain.agents import Tool, initialize_agent, AgentType from langchain.prompts import PromptTemplate from langchain.llms import OpenAI from langchain.memory import ConversationBufferMemory load_dotenv() def fib(n): if n <= 1: return n else: return (fib(n-1) + fib(n-2)) def discord(message): prompt = PromptTemplate( template=""" You are a message interpreter for Discord messages. Extract the recipient and core message content from: {message}. Output ONLY a valid JSON object with no extra text, following this structure: {{ "recipient": "name_of_recipient", "message": "core_message_text" }} """, input_variables=["message"], ) llm = OpenAI(temperature=0) chain = LLMChain(llm=llm, prompt=prompt, verbose=True) response = chain.run(message) # 增加异常处理,避免JSON解析失败中断流程 try: jsonResp = json.loads(response) return f"[Discord Tool Success] Sent '{jsonResp['message']}' to {jsonResp['recipient']}" except json.JSONDecodeError: return "[Discord Tool Error] Failed to parse message content" tools = [ Tool( name="Fibonacci", func=lambda n: str(fib(int(n))), description="Use when you want to calculate the nth fibonacci number" ), Tool( name="Discord", func=discord, description="Use when you need to send a message via Discord. Input should include recipient and message content in natural language." ), ] memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True) llm=ChatOpenAI(temperature=0, verbose=True) agent_chain = initialize_agent( tools, llm, agent=AgentType.CHAT_CONVERSATIONAL_REACT_DESCRIPTION, memory=memory, verbose=True ) response = agent_chain.run(input="Ask John on discord to grab some apple before coming home ") print(f"response : {response}")
效果验证
修改后,Agent能正确识别工具的成功响应,最终会返回类似"Successfully sent the message to John via Discord."的正常结果,不再出现错误提示。
内容的提问来源于stack exchange,提问作者Dylan Grum's
相关产品推荐
相关产品推荐

