许多任务在LLM工作流中需要动态决策,其中确切步骤通常事先未知,并取决于先前行动的结果。虽然某些LLM应用程序使用结构化的、预定的LLM或其他工具调用序列,但LangChain代理为这些更复杂的场景提供了所需的灵活性。代理不遵循链那样的固定路径,而是使用LLM作为其核心推理引擎。可以将LLM视为不仅仅是一个文本生成器,而是一个决策者。针对用户目标,代理利用LLM决定下一步采取什么行动、为此行动使用哪个工具以及向该工具提供什么输入。代理循环:思考、行动、观察代理运作的核心是一个迭代循环:思考: 基于初始目标和任何先前步骤,LLM对当前情况进行推理。它会考虑自己拥有哪些信息、还需要什么,以及采取何种行动最能接近目标。这种内部“独白”在正确提示时通常由LLM明确生成。行动: 基于其思考过程,LLM决定执行某个具体行动。一个行动通常涉及选择一个工具并指定该工具的输入。工具是允许代理与外部环境交互、执行计算、获取信息或运行代码的功能或服务。例子包括网络搜索、Python REPL、数据库查询界面或您定义的自定义函数。观察: 所选工具根据指定输入执行。此执行的结果被记录为观察结果。此观察可能来自网页的文本内容、计算结果、API调用数据,或者工具失败时的错误消息。重复: 观察结果连同原始目标和之前思考-行动-观察步骤的历史一起反馈给LLM。LLM随后开始下一个推理循环(思考),可能根据从观察中获得的新信息选择不同的行动。此循环持续进行,直到LLM确定原始目标已完全达成,或直到达到预设的停止条件(例如最大步骤数)。digraph G { rankdir=LR; node [shape=box, style=rounded, fontname="sans-serif", margin=0.2, color="#495057", fillcolor="#e9ecef", style="filled,rounded"]; edge [fontname="sans-serif", color="#495057"]; Input [label="用户目标"]; LLM [label="LLM\n(推理引擎)", shape=ellipse, fillcolor="#a5d8ff"]; Thought [label="思考\n(内部推理)", shape=note, fillcolor="#ffec99"]; Action [label="行动\n(工具 + 输入)", shape=cds, fillcolor="#ffd8a8"]; ToolExec [label="工具执行", shape=box, style="rounded,dashed", fillcolor="#d0bfff"]; Observation [label="观察\n(工具输出)", shape=document, fillcolor="#b2f2bb"]; Output [label="最终响应"]; Input -> LLM; LLM -> Thought [label="生成"]; Thought -> Action [label="决定"]; Action -> ToolExec [label="调用"]; ToolExec -> Observation [label="产生"]; Observation -> LLM [label="反馈"]; LLM -> Output [label="完成任务"]; }代理遵循的迭代过程,通过LLM根据工具执行的观察结果来决定行动。为什么使用代理?与简单的链相比,代理在处理复杂性和不确定性时提供了显著的优势:适应性: 它们能根据中间结果动态调整策略。如果某种方法失败或产生了意想不到的信息,代理可以对此进行推理并尝试不同的工具或行动。工具集成: 代理提供了一个自然的框架,用于赋予LLM访问外部能力,从而克服LLM的固有局限性(例如缺乏实时信息或无法进行精确计算)。复杂问题解决: 它们能将复杂的任务目标分解成一系列更小、可管理并通过工具执行的任务,这模仿了人类解决问题的方式。本质上,代理帮助LLM从简单的输入-输出转换转变为自主的问题解决者,能够与环境交互以达成目标。链擅长处理可预测的线性工作流,而代理在需要推理、规划和与外部资源交互的场景中表现出色。后续部分将详细介绍如何为代理配备工具并构建它们。