Appearance
0. 什么是ReAct框架?请描述其工作流程。
ReAct (Reasoning and Acting) 是一个用于构建AI Agent的框架,它通过将大型语言模型(LLM)的推理能力和与外部环境交互的行动能力相结合,来解决复杂的任务。
核心思想:
ReAct的核心思想是让LLM以一种交错的方式进行推理(Reasoning)和行动(Acting)。LLM不仅仅是生成最终答案,还会生成中间的思考过程和需要执行的动作,然后根据动作执行的结果(观察)来调整后续的思考和行动。
工作流程:
ReAct的工作流程通常遵循一个"思考-行动-观察"(Thought-Action-Observation)的循环:
初始输入(Input/Question):
Agent接收用户的请求或初始任务描述。
思考(Thought):
- LLM分析当前的任务状态、目标和已有的信息(包括之前的观察结果)。
- 进行推理,分解任务,制定下一步策略。
- 判断是否需要执行某个动作(如调用工具、查询信息)来获取更多信息或推进任务。
- LLM会显式地生成一个"Thought"文本,描述其思考过程。例如:“我需要查找X的信息才能回答这个问题。”
行动(Action):
- 基于"思考"的结果,LLM决定执行一个具体的动作。
- 动作通常是调用一个预定义的工具或API
- LLM会生成一个结构化的"Action"指令,通常包含动作类型(如Search, Lookup)和动作输入(如查询关键词)。例如:Action: Search[X]
执行与观察(Execution & Observation):
- Agent框架解析"Action"指令,并执行相应的工具调用。
- 工具执行后返回结果。
- 这个结果作为"观察(Observation)"被记录下来。例如:Observation: X是一个...
循环/迭代:
- 将"观察"结果添加到Agent的上下文中。
- Agent返回到第2步(“思考”),LLM基于新的信息(包含上一步的观察结果)进行下一轮的思考、行动和观察。
- 这个循环一直持续,直到LLM认为任务已经完成,或者达到了某个停止条件(如最大迭代次数)。
最终答案(Final Answer):
当LLM在"思考"步骤中判断任务已完成时,它会生成最终的答案或结果,而不是生成"Action"。
ReAct的优势:
- 可解释性:通过显式的"Thought"步骤,可以追踪Agent的推理过程。
- 动态适应:Agent可以根据"Observation"动态调整策略。
- 工具使用:能够有效地利用外部工具来弥补LLM知识的不足或执行特定操作。
- 错误处理:如果某个行动失败或结果不理想,Agent可以在下一轮思考中进行纠正。
- ReAct框架是许多现代Agent系统的基础,它提供了一种结构化的方式来引导LLM完成需要与外部世界交互的复杂任务。
ReAct 框架核心记忆点
| 模块 | 关键要点 | 示例 |
|---|---|---|
| Thought | 推理过程 | “我需要查一下‘巴黎的气温’,才能规划旅行。” |
| Action | 执行动作 | Action: Search[巴黎天气] |
| Observation | 动作反馈 | Observation: 巴黎当前气温是25℃ |
| Loop | 迭代调整 | LLM根据新观察重新思考:是否还需查湿度、机票等? |
| Final Answer | 终止输出 | “综合考虑气温和天气,推荐9月中旬前往巴黎旅游。” |
记忆技巧:关键词联想法(TAO循环)
你可以用“T-A-O 循环”快速记住:
T → Thought(思考)
A → Action(行动)
O → Observation(观察)
这个结构是 ReAct 的核心,帮助我们清晰地理解 Agent 是如何逐步构建答案的。
ReAct 框架的典型应用场景
| 应用任务 | ReAct作用 |
|---|---|
| 多轮问答系统 | 理解用户问题 → 搜索外部知识 → 迭代推理 → 回答 |
| 自动化数据分析 | 拆解任务 → 调用数据库/API → 分析数据 → 生成结论 |
| Agent工具链组合 | 判断哪个工具该用 → 执行 → 分析返回 → 决定下个工具或终止 |
如果准备面试时被问到 “为什么采用 ReAct 而不是直接生成答案?”,你可以回答:
“ReAct 能将推理与行动解耦,支持动态任务规划、透明可解释的思考路径,并可多次利用工具反馈优化回答,这在面对复杂、知识不足或实时需求的场景中尤其关键。”
1. LangChain中的记忆(Memory)组件的作用是什么?有哪些常见的类型?
LangChain中的记忆(Memory)组件的主要作用是在链(Chains)或Agent的多次交互之间保持状态。它使得LLM应用能够记住之前的对话内容或交互历史,从而进行更连贯、更有上下文感知的交互。
作用:
- 维持对话上下文:记住用户和AI之前的对话,使得后续的回答能够基于历史信息。
- 存储关键信息:从对话中提取并存储关键实体、用户偏好等信息。
- 支持长期交互:允许Agent或链在长时间运行中积累知识和经验。
- 改进用户体验:避免重复询问相同信息,提供更个性化的交互。
常见的记忆类型:
LangChain提供了多种记忆实现,以适应不同的需求和场景:
- 缓冲区记忆(Buffer Memory):
- ConversationBufferMemory:存储原始的对话消息列表。简单直接,但随着对话变长,会消耗大量Token。
- ConversationBufferWindowMemory:只存储最近的K条对话消息,控制Token消耗,但可能丢失早期重要信息。
- 摘要记忆(Summary Memory):
- ConversationSummaryMemory:使用LLM动态地对对话历史进行摘要总结。每次交互时,将新的对话内容添加到现有摘要中。
- ConversationSummaryBufferMemory:结合了缓冲区和摘要。存储最近的K条消息,并对更早的消息进行摘要。在Token效率和信息保真度之间取得平衡。
- 实体记忆(Entity Memory):
- ConversationEntityMemory:尝试从对话中识别并存储关于特定实体(如人、地点、组织)的关键信息。它会记住关于某个实体的细节,并在后续对话中需要时提取出来。
- 知识图谱记忆(Knowledge Graph Memory):
- ConversationKGMemory:将对话中识别出的实体及其关系存储在一个知识图谱中。允许更结构化的信息存储和查询。
- 基于向量存储的记忆(Vector Store-backed Memory):
- 将对话片段或摘要转换为向量,存储在向量数据库中。
- 在需要时,根据当前查询的语义相似度检索相关的历史记忆。
- 适合存储大量历史信息并进行相关性检索。
- 组合记忆(Combined Memory):
- 可以将多种记忆类型组合使用,例如同时使用ConversationBufferMemory存储近期对话和ConversationSummaryMemory存储长期摘要。
如何使用记忆:
- 在创建链或Agent时,将一个记忆对象实例传递给它。
- 链或Agent在执行过程中会自动读取和更新记忆内容。
- 记忆组件通常负责管理输入变量(如history)和输出变量,并将它们整合到传递给LLM的提示中。
选择哪种记忆类型取决于应用的具体需求,需要考虑Token限制、信息保真度、计算成本和所需记忆的复杂性。
强化记忆 & 举例联想
联想记忆法:
可以将 LangChain 中的 Memory 想象成一个「智能助理的备忘录系统」:
Buffer Memory:像对话记录器,一字不漏记录你说过的话,但可能太啰嗦。
Summary Memory:像速记员,听完之后会总结重点,不会忘,但细节可能少。
Entity Memory:像一个联系人记录本,会记住“张三是工程师”,“你女朋友喜欢猫”这类具体人/物信息。
Knowledge Graph Memory:像脑图工具,把“你是张三的同事”的信息建成结构化的图谱。
Vector Memory:像智能搜索工具,用语义去找出过去相似场景的内容,不是按时间找,而是按“意思”找。
Combined Memory:像一个混合记忆系统,短期记东西+长期归纳总结,既聪明又节省。
可能的面试提问角度与应答建议
提问角度 1:
“你在构建一个长期对话型AI助手时,会如何选择合适的记忆机制?”
建议答法:
我会结合
ConversationSummaryBufferMemory与EntityMemory:
前者在保持上下文连贯的同时降低 Token 压力;
后者确保我能记住用户的重要信息,例如姓名、喜好等;
同时我也可能用向量记忆作为历史补充,支持模糊检索。
提问角度 2:
“Buffer Memory 和 Summary Memory 的区别是什么?各自适用于什么场景?”
建议答法:
Buffer Memory 更适合短对话或调试时使用,因为它保留所有上下文;
Summary Memory 更适合长时间对话或需要控制Token成本的应用,因为它会将历史浓缩成摘要,有更高的Token效率。
提问角度 3:
“LangChain的记忆是如何与Chain或Agent整合的?”
建议答法:
在创建链或Agent时,我们可以将 Memory 实例作为参数传入。LangChain会自动管理输入变量(如
history),并将其注入到Prompt中。每次交互后,记忆内容也会自动更新。
2. LangChain Agent是如何工作的?ReAct是其中唯一的Agent类型吗?
LangChain Agent利用LLM作为推理引擎,使其能够动态地选择和使用工具来完成任务。Agent的核心是让LLM决定采取一系列行动,而不是像链那样遵循预定义的步骤。
工作流程:
- 接收输入:Agent接收用户的初始请求或任务。
- LLM决策:Agent执行器(Agent Executor)将输入、可用的工具描述以及可能的对话历史/记忆传递给LLM。
- 工具解析与执行:Agent执行器解析LLM输出的动作指令,找到对应的工具并执行它。
- 获取观察结果:工具执行后返回结果,这个结果被称为观察(Observation)。
- 迭代:Agent执行器将观察结果反馈给LLM,LLM基于新的信息进行下一轮的思考和行动规划。这个"思考-行动-观察"的循环会持续进行,直到LLM判断任务完成。
- 最终响应:当LLM认为任务完成时,它会生成最终的响应,Agent执行器将其返回给用户。
Agent类型:
ReAct (Reasoning and Acting) 是LangChain中最常用和基础的Agent类型之一,它明确地遵循"思考-行动-观察"的循环。但ReAct并不是LangChain中唯一的Agent类型。
LangChain支持多种Agent类型(或称为Agent执行器逻辑),它们在LLM如何决策以及如何与工具交互方面有所不同:
- Zero-shot ReAct:最基础的ReAct实现,只依赖于工具的描述来决定使用哪个工具。不需要示例,适用于通用任务。
- Structured Chat Zero-shot ReAct:专为聊天模型(Chat Models)设计。能够更好地处理多输入工具,并且通常在需要结构化输出时表现更好。
- OpenAI Functions Agent:利用OpenAI模型内置的函数调用(Function Calling)能力。LLM可以直接输出要调用的函数名和参数,而不是通过解析文本来确定动作。通常更可靠,更不容易出错。
- Self-Ask with Search:一种专门用于回答需要通过搜索获取中间事实的问题的Agent类型。LLM会生成后续问题,并调用搜索工具来回答这些问题,直到能够回答原始问题。
- Conversational Agent:专为对话场景设计,通常会结合记忆(Memory)组件来保持对话上下文。
- Plan and Execute Agent:首先让LLM制定一个详细的计划(步骤列表),然后按顺序执行计划中的每一步(可能涉及调用工具)。与ReAct的逐步决策不同,它先规划后执行。
开发者可以根据任务需求、所使用的LLM能力(如是否支持函数调用)以及对可靠性和灵活性的要求来选择合适的Agent类型。LangChain的框架也允许开发者创建自定义的Agent逻辑。
3. Agent开发中常见的框架有哪些?(例如LangChain, LlamaIndex, AutoGen等)
Agent开发框架旨在简化构建、部署和管理基于大型语言模型(LLM)的Agent的过程。以下是一些常见的Agent开发框架:
LangChain:
最早和最流行的LLM应用开发框架之一。 提供模块化组件,用于构建LLM驱动的应用,包括Agent。 支持多种LLM、记忆类型、工具、向量数据库和Agent执行器(如ReAct)。 拥有庞大的社区和丰富的集成。
优势:功能全面,生态成熟,文档丰富。
劣势:有时被认为过于抽象,学习曲线较陡,代码可能较复杂。
LlamaIndex:
最初专注于数据框架,用于连接LLM与外部数据(特别是RAG)。 后来扩展了Agent功能,强调数据Agent。 提供强大的数据索引、检索和查询能力,与Agent紧密结合。 支持构建能够查询和操作结构化、半结构化和非结构化数据的Agent。
优势:在数据处理和RAG方面非常强大,适合构建知识密集型Agent。
劣势:Agent功能相对LangChain可能稍晚推出,生态系统仍在发展中。
AutoGen (Microsoft):
专注于多Agent系统(MAS)的开发。 提供构建可对话、可协作的Agent框架。 支持定义不同角色和能力的Agent,并让它们通过对话交互来解决问题。 强调Agent之间的自动化协作流程。
优势:在构建多Agent协作系统方面有独特优势,易于实现复杂的Agent交互模式。
劣势:相对较新,生态系统和集成不如LangChain成熟。
Semantic Kernel (Microsoft):
由微软开发的开源SDK,旨在将LLM集成到传统应用程序中。 提供"Kernel"(内核)作为编排器,管理技能(Skills)、记忆(Memory)和连接器(Connectors)。 支持C#和Python。 强调与微软生态系统(如Azure OpenAI)的集成。
优势:设计清晰,与.NET生态结合紧密,适合企业级应用开发。
劣势:社区规模和第三方集成可能不如LangChain。
Haystack (deepset):
开源的LLM框架,最初专注于构建端到端的NLP应用,特别是搜索和问答系统。 提供了构建RAG和Agent的组件。 支持流水线(Pipelines)的概念来组织处理流程。
优势:在构建搜索和问答系统方面经验丰富,提供生产就绪的组件。
劣势:Agent功能可能不如专门的Agent框架全面。
CrewAI:
专注于构建协作式AI Agent的框架。 强调定义Agent角色、目标和工具,并让它们协同工作。 设计简洁,易于上手。
优势:专注于多Agent协作,API设计直观。
劣势:相对较新,生态系统较小。
选择框架的考虑因素:
- 项目需求:是构建单Agent还是多Agent系统?是否需要强大的RAG能力?
- 编程语言偏好:Python是主流,但Semantic Kernel也支持C#。
- 生态系统与集成:需要与哪些LLM、数据库或工具集成?
- 社区支持与文档:框架的活跃度、文档质量和社区帮助。
- 易用性与学习曲线:框架的抽象程度和上手难度。
- 生产环境需求:框架是否提供生产部署所需的可观测性、鲁棒性等特性。
这些框架都在快速发展中,功能和侧重点可能会变化。开发者通常需要根据具体项目需求和团队熟悉度来选择最合适的框架。
4. LangChain 中 ReAct Agent 的工作原理
ReAct(Reasoning + Acting)是一种结合推理(Thought)与行动(Action)的智能体(Agent)框架。LangChain 对 ReAct 模式进行了封装,使其能够通过大语言模型(LLM)调用外部工具,实现多轮交互式问题求解。
一、Prompt 模板设计
LangChain 内置了符合 ReAct 范式的提示模板,通常包含以下四个核心部分:
角色描述
- 明确告知模型:你是一个具备多轮推理能力和工具调用能力的智能体。
输出格式规范
- 模型必须严格按照以下格式输出:
Thought:表示当前推理步骤;Action:表示要调用的工具及其参数(如SearchTool[query]);Observation:表示工具执行后的结果反馈;Final Answer:表示最终答案,结束流程。
- 模型必须严格按照以下格式输出:
可用工具列表
- 列出所有可调用工具的名称、功能描述及调用格式,帮助模型理解何时使用哪个工具。
终止条件说明
- 指导模型在获得足够信息后输出
Final Answer,避免无限循环。
- 指导模型在获得足够信息后输出
二、工具(Tool)定义
每个工具在 LangChain 中是一个封装好的可调用单元,包含:
- 工具名称(name):用于在 Prompt 和模型输出中识别;
- 工具描述(description):供模型理解其用途和适用场景;
- 调用格式(schema):模型需按指定格式(如
ToolName[参数])生成 Action; - 实际实现(function):后端 Python 函数,执行具体逻辑并返回结果。
三、Agent 执行循环(Agent Loop)
当用户输入问题后,LangChain 启动 ReAct Agent 的执行循环,流程如下:
构建 Prompt
将用户问题 + 历史对话(Thought/Action/Observation 序列)填入预设模板,生成当前轮次的完整提示。调用大模型
将 Prompt 输入 LLM,模型根据 ReAct 格式输出下一步(Thought + Action 或 Final Answer)。解析与执行
- 若输出包含
Action,LangChain 解析出工具名和参数; - 调用对应工具函数,获取结果;
- 将结果包装为
Observation,与之前的Thought一起追加到对话历史。
- 若输出包含
迭代或终止
- 将新的
Observation加入下一轮 Prompt,重复步骤 1–3; - 当模型输出
Final Answer或达到最大迭代次数时,循环结束,返回最终答案。
- 将新的
