最近每隔几天就会有人甩一串词给我:大模型、提示词、RAG、Function Calling、ReAct、Multi-Agent、记忆机制、工作流编排……然后问一句:这些到底啥关系?我太熟悉这种感觉了,AI Agent相关的概念这两年像爆米花一样往外蹦,每篇教程都在讲一个单独的点,真到上手时却发现脑子里全是碎片。这篇就想来一次“概念串烧”,把这些高频词串到同一根线上,说说它们各自卡在什么位置,顺便把我实际搭Agent时踩过的坑也一并抖出来。适合那种已经听说过Agent、但还串不成体系的人,读完之后再去看具体框架文档,思路会顺很多。
1. 为什么需要一场概念串烧:先定准Agent在技术版图里的坐标
1.1 AI Agent到底是什么:一家“自动完成任务的微型公司”
用大白话说,AI Agent是一个“能感知环境、自主决策、采取行动、并对结果负责”的程序实体。它不是单纯聊天的大模型,也不是写死流程的脚本,而是把大模型当成“大脑”,把外部工具当成“手”,把各类存储当成“档案柜”,在一个目标驱动下持续运转的系统。
我习惯用一个类比来理解:你开了一家微型公司,员工是多个大模型角色,老板下发一个目标,员工自己拆解步骤、查阅资料、调用工具、检查结果,最后交差。传统程序是“记好了每一步的流水线”,Agent则是“只拿到KPI,过程自己看着办”。这个区别是串烧里所有概念的地基——后面提到的记忆、规划、工具调用、多智能体协作,本质都是在回答“这家公司怎么运转”。
1.2 大模型、普通程序与Agent的根本差异
大多数人混淆的根源,是把Agent和大模型划等号。大模型是一个概率推理引擎,给它一段文本它续写一段文本;Agent则是在这个引擎外面套了一层“感知—决策—行动—反馈”的闭环。
| 维度 | 普通程序 | 纯大模型应用 | AI Agent |
|---|---|---|---|
| 控制逻辑 | 开发人员写死if-else | 模型根据上下文生成回复 | 模型参与生成策略,系统负责执行 |
| 外部交互 | 直接调用API和数据库 | 几乎没有,只有对话 | 通过工具调用、检索、执行代码等 |
| 错误处理 | 异常捕获,确定性兜底 | 答错就是答错 | 可观察中间步骤,支持重试与纠错 |
| 适用场景 | 流程固定、要求稳定 | 内容生成、问答 | 目标开放、需要多步操作 |
这个表格很重要,它解释了你为什么需要引入一连串辅助概念:因为一旦把“决策权”交给模型,怎么让它看得全、想得透、做得准,就成了核心问题。RAG解决“看得全”,ReAct解决“想得透”,Function Calling解决“做得准”,工作流和多智能体解决“复杂任务怎么组织”。所有概念其实都是在这个闭环的不同位置上补缺口,这就是串烧的主线。
2. 串烧第一盘:Agent五大核心模块逐个拆解
2.1 记忆模块:上下文、工作记忆与长期记忆的配合
Agent没有记忆就没法干活。但它不是真的“记住”东西,而是把信息放到上下文窗口里,再通过策略让窗口保持精炼。
我的经验是把记忆拆成两层来看:
- 短期记忆:当前任务对话的上下文,通常就是发给模型的messages列表。它决定了Agent“现在知道什么”。
- 长期记忆:跨会话持久化的知识,一般存在向量数据库里,按语义检索后注入上下文。它决定了Agent“曾经知道什么”。
- 工作记忆:中间计算过程、步骤记录、工具返回结果,相当于草稿纸。
实操中最常见的坑是“无脑塞记忆”。有人把整个历史聊天记录全塞给模型,上下文窗口很快被撑爆,费用飙升,响应变慢,还让模型被无关信息干扰。我通常会做三件事:设一个滑动窗口,只保留最近N轮关键对话;对过长的历史做摘要压缩;核心数据继续放在结构化存储里,需要时再检索,而不是一股脑全带上。
记忆不是越全越好,而是“够用、及时、可回溯”。平时排障时,能回溯Agent每一步看到了什么,比记忆容量大更重要。
2.2 规划模块:ReAct、Plan-and-Execute与反思机制
规划是Agent“想”的部分,目前主流有三种范式,每种都是我实际调过之后才体会到它边界在哪。
第一种是ReAct,即推理与行动交替进行。模型输出一段思考(Thought),决定调用什么工具(Action),工具返回结果(Observation),再基于结果继续思考,如此循环。它的特点是灵活、反应快,适合任务路径不明确的场景,缺点是容易绕圈,没有全局权衡。
第二种是Plan-and-Execute,先让模型把任务拆成一份计划,再逐步执行。它的稳定性和可控性更强,适合步骤明确的流程型任务,比如“调研竞品、生成报告、发送邮件”这种。缺点是计划一旦出错,后面全跟着偏,所以我一般会让执行完每步后就回来修正计划。
第三种是反思与自我纠错。让模型扮演执行者和批判者两个角色,或者让一个模型先生成,再让另一个模型挑毛病,循环迭代改进。这个机制在代码生成、文案打磨上效果明显,但成本翻倍。我的建议是:简单任务别滥用反思,容易把原本不错的输出改坏,只有在容错率低的场景才启用。
2.3 行动模块:工具调用与Function Calling选型
Agent光想不做没意义,行动模块就是它跟外部世界交互的出口。目前最主流的方案是Function Calling,模型不是直接执行函数,而是根据对话内容输出一个结构化的“调用意图”,系统去真正调用函数,再把结果塞回给模型。
我用一个例子说明它的工作过程。假设我给Agent注册了一个“查询天气”的功能,函数定义大致长这样:
tools = [ { "type": "function", "function": { "name": "get_weather", "description": "查询指定城市当前天气", "parameters": { "type": "object", "properties": { "city": {"type": "string", "description": "城市名"} }, "required": ["city"] } } } ]当用户说“北京今天适合出门吗”,模型不会直接回答,而是输出类似{"name": "get_weather", "arguments": {"city": "北京"}}的结构,系统拿到这个结构去查API,再把“北京气温、风速、是否有雨”作为工具结果返回给模型,模型依据真实数据生成最终回复。
实操中我会注意三点:第一,函数描述要写清楚“什么时候用、参数怎么填”,模型对描述的理解直接决定调用准确率;第二,工具结果要附带上获取时间或来源说明,免得模型把过期数据当新鲜;第三,一定要处理调用失败的情况,比如API挂了就给模型返回一个明确错误信息,让它换条路走,而不是静默失败。
3. 串烧第二盘:RAG、Prompt、Workflow、Multi-Agent一次分清
3.1 RAG不是Agent,但它是Agent最常用的记忆外挂
检索增强生成(RAG)乍看跟Agent很像,都是“先拿资料再回答”,但两者的目标完全不同。RAG解决的是“让模型知道训练数据之外的信息”,核心动作是检索和注入;Agent解决的是“让模型完成一个多步骤任务”,核心动作是规划与执行。
在实际系统中,RAG经常作为Agent的记忆组件存在:Agent需要某个领域的知识时,先去向量库检索,把相关片段拼进上下文,再决定下一步行动。反过来,Agent也可以调用“搜索并总结”作为一个工具,这时候RAG就变成Agent的一只手。
我遇到过不少方案把RAG和Agent混为一谈,最后做成了“检索式聊天机器人”,还宣城是Agent。我的判断标准很简单:看系统有没有“自主决策的多步闭环”。有自主决策的是Agent,只有查资料回答问题的是RAG。两者可以嵌套,但概念不要混。
3.2 提示词工程、工作流与Agent:稳定和灵活的取舍
提示词工程是“在单次或少数几次模型调用中,通过措辞和示例引导输出”;工作流是“用代码或工具把多个模型调用和逻辑节点固定成一张流程图”;Agent则是“把流程节点的选择权部分交给模型”。三者的核心变量是“谁来决定路径”。
一个稳定型任务,比如“每天定时抓数据、清洗、生成报表”,我坚定不移地写成工作流,固定节点、固定输出,出错了也容易定位。一个探索型任务,比如“帮我分析这份PDF里的风险点,并根据分析结果起草一份报告”,路径不太固定,这时候用Agent更合适,它可以自己决定先看哪页、查哪个术语、草案改成几个版本。
3.3 多智能体协作的甜点与毒药
多智能体系统(Multi-Agent)是最容易被过度吹捧的概念。它的本质是把一个复杂任务拆给多个各司其职的Agent,让它们互相配合甚至互相争论。常见模式有:一个“领导者”负责拆任务、多个“执行者”干活;或者多个Agent平级协作,自由讨论。
理想很美好,现实很骨感。我的经验是,多Agent首要收益是“每个Agent的提示词可以更聚焦”,比如一个Agent只读书,一个Agent只写代码,上下文干净,指令清晰,效果往往比一个全能干将更强。但代价也很明显:各Agent之间要传递信息,上下文被重复复制,成本成倍上涨;某个Agent出错,错误还会带着“看起来合理”的包装传给下一个环节,形成错误滚雪球。
所以我给团队定了一条原则:能用单Agent加工具解决,就不要上多Agent;非得上,也要保持每个Agent职责边界清晰,并在关键交接点加校验环节,不能放任自流。
4. 从串烧到实操:最小Agent闭环的构建过程
4.1 设计一个最小闭环:选型与循环逻辑
概念讲多了容易飘,真正上手才能把“串烧”变成肌肉记忆。我做过的第一个最小Agent是一个极简的ReAct循环,不用任何重量级框架,就是手写循环加两个工具。我认为这是一个锻炼理解的最佳方式:先跑通骨架,再考虑引入框架。
最小闭环的逻辑就四步:
- 系统把用户任务和可用工具描述拼进提示词。
- 模型输出文本,包含思考过程和下一步动作指令。
- 代码解析动作,如果是调用函数就执行,获得结果。
- 结果拼回对话历史,重复,直到模型输出明确的“最终答案”。
我选用的是一个兼容主流接口的模型API,工具就两个:一个处理数学计算,一个做关键词搜索。工具越多,模型选择的压力越大,所以先从两个开始。
4.2 核心代码逐段解读:一个手写ReAct循环骨架
下面这个骨架我保留了大量注释,方便直接复现。
import json import re SYSTEM_PROMPT = """ 你是一个能调用工具的助手。可用工具有: - calculate: 计算数学表达式,参数是表达式字符串 - search: 搜索关键词,参数是查询词 请严格按照格式输出: Thought: 你的思考 Action: 工具名称 ActionInput: 工具参数 或者当你有结论时输出: FinalAnswer: 最终答案 """ def call_llm(messages): # 这里接入任意兼容接口,返回模型文本 # 例如用某主流大模型SDK,传入model、messages,拿到result pass def run_agent(task, max_steps=6): messages = [ {"role": "system", "content": SYSTEM_PROMPT}, {"role": "user", "content": task} ] for step in range(max_steps): text = call_llm(messages) print(f"--- 第{step + 1}步输出 ---") print(text) final_match = re.search(r"FinalAnswer:\s*(.*)", text, re.S) if final_match: return final_match.group(1).strip() action_match = re.search(r"Action:\s*(\w+)", text) input_match = re.search(r"ActionInput:\s*(.+)", text) if action_match and input_match: action = action_match.group(1) action_input = input_match.group(1).strip() if action == "calculate": # 用eval只做演示,实际生产请用安全表达式解析库 result = str(eval(action_input)) elif action == "search": # 这里接真实搜索API,返回结果摘要 result = f"关于{action_input}的搜索结果摘要" else: result = "未知工具" messages.append({"role": "assistant", "content": text}) messages.append({"role": "system", "content": f"工具结果:{result}"}) else: # 输出格式不对,让模型重新来 messages.append({"role": "assistant", "content": text}) messages.append({"role": "system", "content": "格式错误,请严格按格式输出"}) return "达到最大步数,强制结束" print(run_agent("帮我计算(12+34)*2的结果"))这段代码的关键在“把每一步输出都回填到messages里”。模型看到工具结果后,才能进入下一轮思考。我建议你第一次跑的时候把每步输出打出来,仔细观察它是怎么从“角度思考”走向“调用工具”,又是怎么根据工具结果收敛到FinalAnswer的,这个过程比任何概念讲解都有用。
4.3 一个“串烧实验”:让Agent现场生成概念讲解
我在自己电脑上做过一个应景的实验:把RAG、ReAct、Multi-Agent、Function Calling四个词写进任务,让Agent串成一个60秒的讲解稿。第一步它先拆解了任务,第二步调用了搜索确认几个术语的定义,第三步开始起草,第四步自我检查了一遍逻辑是否递进。
最终它生成的初稿虽然不算惊艳,但结构是对的:先解释单一Agent闭环,再讲RAG补知识、工具补行动,最后说多Agent解决复杂协作。这个演示给我的启发是:Agent的价值不是一次性输出正确答案,而是当任务需要“检索—组织—成型—校验”多环节时,它能自己调度全套动作。你做类似实验时,可以故意不给它工具,只给它一个聊聊定义的任务,再去对比一下输出质量,立刻就能看出工具调用对Agent能力的杠杆作用。
5. 概念易混点与实战排坑手册
5.1 五个经典认知误区
概念串烧时,总有几个误区反复出现,我先替读者踩一遍。
第一,Agent等于大模型。大模型只是推理核心,Agent还包含记忆、工具、控制循环和校验机制,没有这些它只是个聊天窗口。
第二,提示词越长越好。过长且信息密度低的提示词会稀释关键指令,反而降低模型表现。我的习惯是保持“角色、目标、限制、格式”四要素,辅助示例只放最能代表边界的。
第三,多Agent一定比单Agent聪明。多数场景单Agent加优质工具就已经够用,多Agent带来的通信成本和组织成本经常超过它带来的精度提升。
第四,RAG一定消除幻觉。RAG只能降低幻觉概率,如果检索到的内容本身就是错的,或者模型在拼接时跑偏,幻觉照样发生,所以还要有事实核查和引用来源。
第五,Workflow不如Agent先进。这种想法害人不浅。固定流程用工作流才更可靠、更快、更好维护,硬套Agent只会让简单问题复杂化。
5.2 真实翻车现场与排查清单
我搭Agent时踩过的坑,按出现频率排一下,你大概率也会遇到。
首先是“死循环”,Agent在同一个工具调用上反复绕圈,越滚越长,消耗惊人。对策很简单:设最大步数上限,到时候强制终止输出当前结论;同时在提示词里写入“如果某条路尝试了两次还没进展,请换策略”。
然后是“工具参数乱填”。模型有时会把中文地名写成拼音,或者漏掉必填参数。我的办法是:函数定义里把参数示例写清楚,系统层增加参数校验,不合法就返回具体错误提示,让模型自行修正。
再一个是“上下文爆炸”。多步循环后历史消息越来越长,成本飙升。我一般做两步处理:较早的工具结果只保留摘要;相同类型的动作结果合并记录。说白了就是对上下文做“断舍离”。
最后是“模型幻觉式调工具”,明明不需要调用工具,却偏要调用。我通常会在工具描述里写明“仅在用户主动要求或结果需要外部数据时使用”,并在系统提示词里加一句“默认依靠自身知识回答,拿不准才调用工具”。这个改动往往能明显降低无效调用。
5.3 我个人沉淀Agent概念体系的笨办法
串烧文看再多,不如自己动手烧一次。我学习这些概念时用了很笨但有效的方法:每学一个概念,就去改一遍那个最小Agent骨架。学RAG时,我就给工具列表加一个检索函数;学记忆时,我就给Agent加一个向量存储;学Multi-Agent时,我用两个最小Agent拼一个“检索员加写作员”的组合。每次改动都不大,但概念和代码之间建立了强映射。
顺序建议是:先跑通ReAct循环,理解规划与行动;接着接入工具,理解Function Calling;然后加长期记忆,理解向量检索;最后再尝试多Agent协作。按这条线走,你会发现那些流行术语其实都只是“给同一个骨架加零件”。
我在实际操作中的体会是:概念的价值不在于叫得多响亮,而在于到底解决哪个环节的问题。当你遇到“上下文不够用”“行动不够准”“任务分不好”时,自然知道该掏出哪个概念去补。这场串烧的意义,就是让你手里先有一张完整的地图,以后每个新名词出现时,都能快速找到它该被安放的位置。