LLM框架通常使用“链式调用”来执行预设的LLM调用序列及其他操作。然而,许多任务需要比这些固定序列更具动态性的行为。设想一个场景,应用需要回答一个问题,例如“伦敦昨天的天气如何,以及上个月那里报告的下雨天数的平方根是多少?”一个直接的链式调用可能难以处理,因为具体步骤依赖于中间结果(例如,查询天气报告,提取下雨天数,然后进行计算)。对于这类情况,智能体非常有效。智能体究竟是什么?在LangChain这类LLM框架中,一个智能体不只是使用大型语言模型生成文本,更是将其作为推理引擎,来决定要执行的一系列动作。与其说它像遵循食谱(链式调用),不如说它更像一个能够利用一系列可用工具来找出如何完成目标的助手。其核心思想是智能体:接收一个输入或目标。利用LLM“思考”下一步该怎么做。这步可能涉及使用特定工具(如网页搜索、计算器或访问你数据库的自定义函数),或者判断自己已有足够信息来给出最终回复。如果使用了工具,智能体将执行它并观察结果。结果(或“观察”)会反馈给LLM,以便进行下一轮“思考”。这个循环会一直重复,直到达成目标。智能体循环这种决策过程在一个循环中运行,这个循环通常被称为“智能体执行器”或“运行时”。在每一步中,LLM不仅会收到原始目标,还会收到迄今为止已执行动作的历史记录和收到的观察结果,以及它可以使用的工具的描述。以下是智能体执行流程的简化视图:digraph G { rankdir=LR; node [shape=box, style="rounded,filled", fontname="Arial", fontsize=10, margin=0.2, fillcolor="#e9ecef"]; edge [fontname="Arial", fontsize=9, color="#495057"]; UserInput [label="用户输入/目标", fillcolor="#a5d8ff"]; LLM [label="LLM推理\n(思考过程)", fillcolor="#ffec99"]; ActionDecision [label="行动决策\n(使用工具或回复?)", shape=diamond, style="rounded,filled", fillcolor="#ffd8a8"]; ToolExecution [label="执行工具", fillcolor="#bac8ff"]; ToolOutput [label="工具输出\n(观察)", fillcolor="#e9ecef"]; FinalResponse [label="最终回复", fillcolor="#b2f2bb"]; UserInput -> LLM [color="#1c7ed6"]; LLM -> ActionDecision [color="#f59f00"]; ActionDecision -> ToolExecution [label=" 选择工具", color="#fd7e14"]; ToolExecution -> ToolOutput [color="#4263eb"]; ToolOutput -> LLM [label=" 反馈观察结果", color="#495057"]; ActionDecision -> FinalResponse [label=" 生成回复", color="#fd7e14"]; }一张图表,说明了智能体执行循环,其中LLM根据输入和之前的步骤决定是使用工具还是生成最终回复。用于引导LLM推理的提示语非常重要。它通常会指导LLM如何一步步思考,列出可用工具及其功能和预期输入,并指定LLM应使用的格式来指示其选择的动作及其输入。ReAct(思考+行动)等技术常作为这些提示语的基础,鼓励LLM在选择动作前明确说明其推理过程。为什么要使用智能体?智能体在处理某些类型的问题时,比简单的链式调用具有显著优势:灵活性: 它们可以根据中间结果调整方法,按需选择不同的工具或动作序列。复杂问题解决: 它们能将复杂目标分解为更小、更易于管理的小步,并在此过程中使用工具收集信息或执行计算。交互性: 它们使LLM能够以结构化的方式与外部系统(数据库、API、文件系统)交互,运用其预训练知识来发挥作用。然而,这种动态特性也意味着智能体可能不如链式调用那样可预测。它们的行为很大程度上取决于LLM的质量、提示语的清晰度以及工具的可靠性。调试有时需要追溯智能体在多个步骤中的思考过程。此外,如果推理引导不当或工具产生意外错误,智能体也有可能陷入循环或未能完成任务。另外,由于智能体在其执行循环中经常对LLM进行多次调用,因此与单次链式调用相比,它们可能产生更高的运营成本。在下一节中,我们将详细了解如何定义和整合这些赋予智能体行动能力的“工具”。