如何让LangChain Agent按正确顺序选择对应工具?
问题修复方案
核心问题分析
原代码的三个工具都绑定了同一个qa.run(内部检索链),完全不符合功能需求;同时工具描述模糊,Agent无法准确判断触发时机,导致工具选择逻辑失效。
具体调整步骤
1. 拆分工具执行逻辑
- 内部知识库工具:保留原RetrievalQA检索链,新增检索结果有效性判断
- 外部知识库工具:直接调用大模型原生能力,无需访问内部库
- 日常对话工具:调用大模型并注入友好角色设定,生成自然回应
2. 优化工具描述
给每个工具明确触发条件与优先级,帮助Agent精准判断调用时机
3. 调整RetrievalQA配置
开启return_source_documents=True,让Agent能识别内部库是否检索到有效内容
4. 优化对话记忆
调高k值保留对话上下文,让日常对话更连贯自然
完整修正代码
from langchain.agents import Tool from langchain.chat_models import ChatOpenAI from langchain.chains.conversation.memory import ConversationBufferWindowMemory from langchain.chains import RetrievalQA from langchain.agents import initialize_agent from chroma_database import ChromaDatabase from langchain.embeddings import OpenAIEmbeddings from parameters import EMBEDDING_MODEL, BUCKET_NAME, COLLECTION_NAME embeddings = OpenAIEmbeddings(model=EMBEDDING_MODEL) chroma = ChromaDatabase(embedding_function=embeddings, persist_directory='database/vectors/', bucket_name=BUCKET_NAME, collection_name=COLLECTION_NAME) # 基础大模型实例 llm = ChatOpenAI( model_name='gpt-3.5-turbo', temperature=0.0 ) # 对话记忆:保留最近2轮对话,维持上下文连贯性 conversational_memory = ConversationBufferWindowMemory( memory_key='chat_history', k=2, return_messages=True ) # 内部知识库检索链:开启源文档返回,用于判断检索有效性 qa_internal = RetrievalQA.from_chain_type( llm=llm, chain_type="stuff", retriever=chroma.db.as_retriever(), return_source_documents=True # 关键配置:返回检索到的原始文档 ) # 封装内部知识库工具逻辑:判断检索结果并返回对应内容 def run_internal_knowledge(query): result = qa_internal({"query": query}) # 无有效检索结果时,返回明确提示引导Agent切换工具 if not result['source_documents']: return "No relevant information found in internal knowledge base. Please use external knowledge base." return result['result'] # 外部知识库工具逻辑:直接调用大模型原生能力 def run_external_knowledge(query): return llm.predict(query) # 日常对话工具逻辑:注入友好角色设定 def run_natural_conversation(query): prompt = f"Act as a friendly chat partner, respond naturally to: {query}" return llm.predict(prompt) # 定义工具列表,每个工具的描述明确触发规则与优先级 tools = [ Tool( name='Knowledge Internal Base', func=run_internal_knowledge, description=( 'Always use this tool FIRST when answering questions related to internal stored knowledge (e.g., Pepito-related content). ' 'If it returns "No relevant information found", switch to the external knowledge tool.' ) ), Tool( name='Knowledge External Base', func=run_external_knowledge, description=( 'Use this tool ONLY when the internal knowledge base returns no relevant information. ' 'For public information not stored internally (e.g., Tom Cruise movie details).' ) ), Tool( name='Natural Conversation', func=run_natural_conversation, description=( 'Use this tool ONLY for casual daily conversations (e.g., greetings, "how are you?", small talk). ' 'Respond in a warm, human-like tone.' ) ) ] # 初始化Agent:适配对话场景的agent类型 agent = initialize_agent( agent='chat-conversational-react-description', tools=tools, llm=llm, verbose=True, max_iterations=3, early_stopping_method='generate', memory=conversational_memory ) # 测试用例 agent.run("What Pepito said?") agent.run("What Tom Cruise said in the movie Impossible Mission 1?") agent.run("Hello, how are you?")
关键调整说明
- 工具逻辑解耦:每个工具绑定独立的执行函数,彻底解决原代码中工具功能混淆的问题
- 检索结果判断:通过源文档返回状态,让Agent能明确感知内部库是否有答案,实现工具切换逻辑
- 工具描述强化:明确了调用优先级与触发边界,比如内部工具必须优先使用,日常对话工具仅用于闲聊场景
- 对话记忆优化:将
k值从0调整为2,保留对话上下文,让日常对话更符合自然交流逻辑
内容的提问来源于stack exchange,提问作者Eric Bellet
相关产品推荐
相关产品推荐

