前提条件与环境配置在我们开始之前,请确保您的环境已准备好。我们将使用 Tavily Search API 作为我们的网络搜索工具,因为它与 LangChain 集成得很好,并且专注于提供清晰、适合 AI 处理的搜索结果。首先,安装所需的 Python 包。我们包含 langgraph,因为它是 LangChain 生态系统中构建代理工作流的现代标准。pip install langchain langchain-openai tavily-python langgraph接下来,您需要为 OpenAI(用于 LLM)和 Tavily(用于搜索工具)配置 API 密钥。您可以从他们的网站获取 Tavily API 密钥。将这些设置为环境变量,以实现安全访问。export OPENAI_API_KEY="your-openai-api-key" export TAVILY_API_KEY="your-tavily-api-key"环境准备就绪后,我们就可以开始组合代理的组件了。1. 定义工具代理的能力由它可用的工具来决定。为了我们的目的,一个工具就足够了:一个网络搜索器。LangChain 为 Tavily Search API 提供了便捷的集成。让我们导入并初始化这个工具。我们将搜索结果数量限制为三个,以保持提供给 LLM 的上下文简洁。from langchain_community.tools.tavily_search import TavilySearchResults # 初始化工具。我们可以配置它返回结果的数量。 # 更少的结果速度更快,并且使用的 token 也更少。 tools = [TavilySearchResults(max_results=3)]这个 tools 列表将提供给我们的代理,使 TavilySearchResults 函数可供其调用。2. 初始化 LLM代理的核心是一个能够判断使用哪个工具的 LLM。对于需要遵循指令和使用函数定义的任务,更先进的模型表现更好。我们将使用 OpenAI 的 gpt-4o 模型。from langchain_openai import ChatOpenAI # 初始化 LLM。温度设置为 0 会促使输出更具确定性和事实性。 llm = ChatOpenAI(model="gpt-4o", temperature=0)在下一步中,我们将把这个 LLM 实例直接传递给代理的构造函数。3. 创建代理为了构建代理,我们将使用 langgraph,它使我们能够创建稳定、有状态的代理工作流。create_react_agent 函数构建了一个图,该图作为我们代理的运行时。它管理着调用 LLM、解释决策(思考)、执行所选工具(行动)并将输出反馈给模型(观察)的循环。下面的图表说明了这个执行循环。digraph G { rankdir=TB; splines=true; node [shape=box, style="rounded,filled", fillcolor="#e9ecef", fontname="Arial"]; edge [fontname="Arial"]; UserInput [label="用户输入", fillcolor="#a5d8ff"]; AgentLLM [label="代理 (LLM)"]; Action [label="行动:调用工具", fillcolor="#ffd8a8"]; Tool [label="工具 (例如,搜索)", fillcolor="#ffc9c9"]; Observation [label="观察", fillcolor="#b2f2bb"]; FinalAnswer [label="最终答案", fillcolor="#96f2d7"]; UserInput -> AgentLLM [label="查询"]; AgentLLM -> Action [label="思考与决策"]; Action -> Tool [label="执行"]; Tool -> Observation [label="返回结果"]; Observation -> AgentLLM [label="反馈给推理过程"]; AgentLLM -> FinalAnswer [label="合成与响应"]; }代理图管理着 LLM 推理、使用工具采取行动、观察结果并将其反馈到推理过程中的循环。现在,让我们用代码创建代理。from langgraph.prebuilt import create_react_agent # create_react_agent 函数将 LLM 绑定到工具,并设置 # 管理交互循环的执行图。 agent_executor = create_react_agent(llm, tools)4. 运行代理所有组件组装完毕后,我们的代理就可以使用了。让我们问一个问题,这个问题需要从两个不同方面:技术和金融,搜索信息。代理期望接收一个包含消息列表的字典作为输入。我们将问题格式化为用户消息。question = "What was the stock price of NVIDIA (NVDA) at the time of the announcement of the Blackwell GPU architecture?" # 用用户输入调用代理 response = agent_executor.invoke({"messages": [("user", question)]}) print("\nFinal Answer:") # 最终答案包含在返回历史的最后一条消息中 print(response["messages"][-1].content)当代理运行时,它会在内部执行必要的步骤。其推理过程的追踪如下所示:思考:用户询问 NVIDIA (NVDA) 在 Blackwell GPU 架构发布时的股价。我需要找到两部分信息: 1. Blackwell GPU 架构的发布日期。 2. NVDA 在该日期的股价。 我将首先搜索发布日期。 行动: { "tool": "tavily_search_results", "tool_input": "NVIDIA Blackwell GPU architecture announcement date" } 观察:NVIDIA 在 2024 年 3 月 18 日的 GTC 2024 主题演讲中正式发布了 Blackwell 架构。 思考:我已找到发布日期:2024 年 3 月 18 日。现在我需要找到 NVDA 在该日期或前后时间的股价。我可以再次搜索此信息。 行动: { "tool": "tavily_search_results", "tool_input": "NVDA stock price on March 18, 2024" } 观察:2024 年 3 月 18 日,NVIDIA 公司 (NVDA) 股票收盘价为 884.55 美元。 思考:我已找到两部分信息。 1. Blackwell GPU 架构于 2024 年 3 月 18 日发布。 2. 当天 NVDA 的收盘价为 884.55 美元。 现在我可以向用户提供最终答案了。 最终答案:NVIDIA 于 2024 年 3 月 18 日发布了 Blackwell GPU 架构。当天,NVDA 的收盘价为 884.55 美元。这个序列展示了代理的能力。它正确地将复杂的查询分解为子问题,按顺序执行其搜索工具以收集必要的事实,然后将这些事实综合成一个完整准确的答案。您现在构建了一个简单但有效的自主系统,能够与外部环境交互以实现一个目标。这种基本模式是构建更复杂代理的依据,这些代理可以与数据库、API 和其他软件系统交互。