1. 为什么“七要素”和“七个决策点”才是 Agent 工程的分水岭
很多人第一次接触 AI Agent,脑子里浮现的画面是“一个会自己思考、自己调工具、自己完成任务的智能体”。但真到动手写代码的时候,问题立刻变得非常具体:LLM 怎么知道该调用哪个工具?调用完工具之后结果怎么塞回去?循环什么时候停?记忆存哪里?权限怎么控?这些问题不解决,Agent 就只是一个“会聊天的 API 包装器”,根本跑不起来一个完整任务。
我过去一年里陆续用 LangChain、Dify、CrewAI 以及自己手写的轻量 Agent 框架做过十几个项目,从自动发消息、自动整理文档,到代码生成、数据抓取、多步推理任务编排,踩过的坑基本都集中在同一批问题上。后来我把这些经验收敛成两个视角:七要素回答“一个 Agent 由哪些零件组成”,七个决策点回答“这些零件在运行时如何协同”。把这两层想清楚,Agent 的工程实现就不再是玄学,而是一套可以拆解、可以调试、可以复现的系统。
这篇文章适合三类人:第一类是想从零搭建 Agent 但不知道从哪里下手的开发者;第二类是已经用过现成框架、但遇到“循环停不下来”“工具乱调”“上下文爆炸”等问题的工程师;第三类是想理解 Agent 底层机制、为面试或技术选型做准备的人。我会尽量用从业者之间的语言,把每个决策点背后的“为什么”讲透,并给出可以直接抄作业的参数、代码结构和排查方法。
核心关键词会贯穿全文:AI Agent、Agent、LLM、工具调用、循环机制。你不需要先精通大模型原理,只要写过基本的 API 调用,就能跟着往下走。
2. 七要素拆解:一个能跑的 Agent 到底由什么组成
2.1 要素一:LLM 作为推理内核,不是“大脑”而是“决策器”
很多人把 LLM 比作 Agent 的大脑,这个比喻容易误导。更准确的说法是:LLM 是一个概率决策器,它根据当前上下文输出“下一步该做什么”的文本。它不负责执行,不负责记忆,也不负责状态管理。真正让 Agent 动起来的,是外围的工程代码。
选 LLM 的时候,我一般看三个维度:指令遵循能力、工具调用格式稳定性、上下文窗口。指令遵循决定它会不会跑偏;工具调用格式稳定性决定它输出的 JSON 能不能被解析;上下文窗口决定它能记住多少轮历史。实测下来,做 Agent 时模型“听话”比“聪明”更重要,一个指令遵循强的小模型,往往比一个聪明但爱自由发挥的大模型更适合做工具调用。
注意:不要用同一个模型同时做“规划”和“执行”。规划需要强推理,执行需要强格式遵循,混在一起容易两头不讨好。常见做法是规划用强模型,执行用快模型。
2.2 要素二:工具集是 Agent 的手脚,接口设计决定成败
工具(Tool)就是 Agent 能调用的外部函数。它可以是查数据库、发请求、读文件、算数学、调另一个模型。工具集的设计质量,直接决定 Agent 能不能完成任务。
我见过最常见的错误是:把工具描述写得像函数文档,比如“query_user(id): 查询用户”。LLM 看到这种描述根本不知道什么时候该用。正确的做法是把工具描述写成使用场景说明,比如“当用户询问某个账号的基本信息时,调用此工具,参数 id 为账号唯一标识”。描述里要包含:什么时候用、参数含义、返回什么、有什么限制。
工具数量也要控制。我实测下来,单次暴露给 LLM 的工具最好不超过 10 个,超过之后选择准确率明显下降。如果业务需要几十个工具,就先做一层“工具路由”,让 LLM 先选类别,再选具体工具。
2.3 要素三:记忆系统分短期和长期,别混在一起
记忆分两种:短期记忆是当前任务的对话历史,长期记忆是跨任务沉淀的知识。短期记忆通常直接放在上下文里,长期记忆需要外部存储(向量库、KV 库、文件)。
短期记忆的核心问题是上下文膨胀。一个多步任务跑十几轮之后,历史可能几千 token,既贵又慢,还容易让模型迷失。我的做法是:保留最近 N 轮原文,更早的历史做摘要压缩。N 一般取 5 到 8,摘要用便宜的小模型生成。
长期记忆的核心问题是写入时机。不是每句话都值得记。我一般只在任务结束时,把“结论性信息”写入长期记忆,比如用户偏好、任务结果、关键实体。写入前做一次去重和冲突检查,避免记忆库越来越脏。
2.4 要素四:规划模块决定 Agent 是“走一步看一步”还是“先想后做”
规划(Planning)有两种模式:ReAct 式的边想边做,和Plan-and-Execute 式的先出计划再执行。前者灵活,适合探索性任务;后者稳定,适合步骤明确的任务。
ReAct 的循环是:思考 → 行动 → 观察 → 再思考。它的优点是能根据工具返回结果动态调整,缺点是容易陷入循环、跑偏。Plan-and-Execute 是先让 LLM 输出一个步骤列表,然后逐步执行,每步执行完可以重新规划。它的优点是可控,缺点是不够灵活。
我的经验是:任务步骤少于 5 步、路径不确定的,用 ReAct;步骤多于 5 步、流程相对固定的,用 Plan-and-Execute。两者也可以混合,先规划再在每步内用 ReAct。
2.5 要素五:执行器负责“真正干活”,要隔离要限流
执行器(Executor)是真正调用工具、处理返回、捕获异常的模块。它和 LLM 是分离的,LLM 只输出“我要调用哪个工具、参数是什么”,执行器负责实际调用。
执行器必须做三件事:超时控制、异常捕获、结果裁剪。超时控制防止某个工具卡死整个 Agent;异常捕获保证工具报错不会让 Agent 崩溃,而是把错误信息返回给 LLM 让它重试或换路;结果裁剪是因为工具返回可能很长,直接塞回上下文会爆,需要截断或摘要。
提示:工具返回结果建议统一裁剪到 500 到 1000 字符以内,超出部分做摘要。这个阈值是我多次实测后比较稳的区间。
2.6 要素六:循环控制是 Agent 的“心跳”,也是最容易失控的地方
循环机制是 Agent 区别于普通 LLM 调用的核心。它让 Agent 能多步执行,但也是 bug 重灾区。常见失控场景:LLM 反复调用同一个工具、循环不终止、每轮都在重复思考。
控制循环的关键参数有三个:最大轮数、终止条件、重复检测。最大轮数一般设 10 到 15,超过就强制结束并返回当前结果;终止条件包括 LLM 输出“完成”标记、或达到目标状态;重复检测是记录最近几轮的工具调用,如果发现完全相同的调用重复出现,就打断并提示 LLM 换策略。
2.7 要素七:安全与权限是底线,不能事后补
Agent 能调工具,就意味着它能产生真实副作用:发消息、改数据、花钱。安全设计必须在架构阶段就考虑,而不是上线前补。
我一般做三层防护:工具白名单(只暴露必要工具)、参数校验(危险操作二次确认)、操作审计(记录每次工具调用的输入输出)。对于涉及资金、删除、对外发送的操作,强制走人工确认或 dry-run 模式。
3. 七个决策点:Agent 运行时到底在“决策”什么
3.1 决策点一:这一轮要不要调用工具
不是每一轮都需要调工具。LLM 可能只需要回答、需要澄清、或者已经可以给出结论。这个决策由 LLM 根据当前上下文判断,但工程上要给它明确的“不调用工具”的出口,否则它会为了调用而调用。
我的做法是在系统提示里明确写:如果已有信息足够回答,直接输出最终答案,不要调用工具。同时给一个finish工具或标记,让 LLM 有明确的结束动作。
3.2 决策点二:调用哪个工具
这是工具选择问题。工具多的时候,靠 LLM 直接选容易错。我的优化手段是:工具描述里写清楚适用场景,工具名用动词开头(如search_docs、send_message),并在系统提示里给出选择优先级。
如果工具超过 10 个,加一层路由:先让 LLM 选类别(查询类、操作类、计算类),再在类别内选具体工具。实测这个两层结构能把选择准确率提升不少。
3.3 决策点三:参数怎么填
参数填充是最容易出错的地方。LLM 可能填错类型、漏参数、编造不存在的值。工程上要做参数 schema 校验,用 JSON Schema 定义每个工具的参数类型、必填项、取值范围,LLM 输出后先校验再执行,校验失败就把错误返回给 LLM 让它重填。
注意:不要让 LLM 自由生成参数后直接执行。一定要有校验层。我踩过的坑就是 LLM 编了一个不存在的用户 ID,工具直接报错,整个流程中断。
3.4 决策点四:工具返回结果怎么处理
工具返回可能是长文本、结构化数据、错误信息。处理策略有三种:直接透传(短结果)、截断(长结果)、摘要(超长结果)。选择依据是结果长度和后续是否需要细节。
我的默认策略是:小于 500 字符直接透传,500 到 2000 字符截断加提示,超过 2000 字符用模型摘要。摘要会损失细节,所以对于需要精确引用的结果,宁可截断也不要摘要。
3.5 决策点五:这一轮之后是继续还是结束
每轮结束都要判断:任务完成了吗?还需要更多信息吗?出错了吗?这个判断可以交给 LLM(输出 finish 标记),也可以由工程代码根据状态判断(比如达到目标、超过最大轮数、连续出错)。
我倾向于两者结合:LLM 可以主动声明完成,工程代码做兜底(最大轮数、错误次数)。这样既灵活又不会失控。
3.6 决策点六:记忆怎么更新
每轮结束后,要不要把这一轮的信息写入记忆?短期记忆一般直接追加,长期记忆要谨慎。我的规则是:短期记忆每轮追加,长期记忆只在任务结束时写入结论。中间过程不写长期记忆,避免污染。
如果任务很长,短期记忆也要做压缩。压缩时机一般是超过上下文窗口的 60% 时触发,把最早的历史摘要成一段话。
3.7 决策点七:出错之后怎么恢复
Agent 出错是常态:工具超时、参数错误、LLM 输出格式不对、循环卡死。恢复策略分三级:重试(临时错误,重试 1 到 2 次)、换路(当前工具不行,让 LLM 换一个)、终止(无法恢复,返回当前结果并说明)。
重试要加退避,避免雪崩;换路要把错误信息返回给 LLM,让它重新决策;终止要保证有意义的输出,而不是空手而归。
4. 从零搭一个最小可用 Agent:完整实操流程
4.1 环境准备与依赖选择
我用 Python 做示例,因为生态最成熟。核心依赖只有两个:一个 LLM SDK,一个 HTTP 库。不需要一上来就上 LangChain,手写一遍更能理解机制。
pip install openai requests如果你用其他模型,把 SDK 换掉即可,逻辑一样。我建议第一版不要用框架,手写循环,跑通之后再考虑用框架提效。
4.2 定义工具与 schema
先定义两个工具:一个查天气,一个算数学。工具用字典描述,包含名称、描述、参数 schema。
tools = [ { "name": "get_weather", "description": "当用户询问某个城市的天气时调用,参数 city 为城市名", "parameters": { "type": "object", "properties": { "city": {"type": "string", "description": "城市名称"} }, "required": ["city"] } }, { "name": "calculate", "description": "当需要做数学计算时调用,参数 expression 为算式", "parameters": { "type": "object", "properties": { "expression": {"type": "string"} }, "required": ["expression"] } } ]注意描述里写的是“什么时候调用”,不是“这个函数做什么”。这是给 LLM 看的,不是给人看的。
4.3 实现执行器与参数校验
执行器负责真正调用工具,并做参数校验和异常处理。
import json def validate_params(params, schema): required = schema.get("required", []) for key in required: if key not in params: return False, f"缺少必填参数: {key}" return True, "" def execute_tool(name, params): if name == "get_weather": ok, msg = validate_params(params, tools[0]["parameters"]) if not ok: return {"error": msg} return {"weather": f"{params['city']} 晴,25 度"} if name == "calculate": ok, msg = validate_params(params, tools[1]["parameters"]) if not ok: return {"error": msg} try: return {"result": eval(params["expression"], {"__builtins__": {}})} except Exception as e: return {"error": str(e)} return {"error": f"未知工具: {name}"}eval这里只做演示,生产环境绝对不要直接用,要换成安全的表达式解析库。
4.4 主循环实现与终止条件
主循环是 Agent 的心脏。核心逻辑:调用 LLM → 解析输出 → 如果有工具调用就执行 → 把结果塞回上下文 → 再调用 LLM,直到 LLM 输出最终答案或达到最大轮数。
MAX_TURNS = 10 def run_agent(user_input): messages = [ {"role": "system", "content": "你是一个助手,需要时调用工具,信息足够时直接回答。"}, {"role": "user", "content": user_input} ] for turn in range(MAX_TURNS): response = call_llm(messages, tools) if response.get("finish"): return response["content"] tool_call = response.get("tool_call") if tool_call: result = execute_tool(tool_call["name"], tool_call["params"]) messages.append({"role": "assistant", "content": json.dumps(tool_call)}) messages.append({"role": "tool", "content": json.dumps(result)}) else: return response["content"] return "达到最大轮数,任务未完成"call_llm是封装好的模型调用,负责把工具 schema 传进去、解析模型输出。不同模型的输出格式不同,需要按实际调整。
4.5 循环控制与重复检测
上面的循环还缺重复检测。加一个记录最近工具调用的列表,发现重复就打断。
recent_calls = [] # 在每次工具调用后 signature = f"{tool_call['name']}:{json.dumps(tool_call['params'], sort_keys=True)}" if signature in recent_calls[-3:]: messages.append({"role": "system", "content": "检测到重复调用,请换一种方式或直接回答。"}) recent_calls.append(signature)这个简单的重复检测能解决大部分“循环卡死”问题。实测下来,加上之后 Agent 的完成率明显提升。
4.6 记忆压缩与上下文管理
当消息历史超过一定长度,做一次压缩。把最早的非系统消息摘要成一段。
def compress_if_needed(messages, threshold=3000): total = sum(len(m["content"]) for m in messages) if total < threshold: return messages system = messages[0] recent = messages[-6:] old = messages[1:-6] summary = summarize(old) return [system, {"role": "system", "content": f"历史摘要: {summary}"}] + recentsummarize用便宜的小模型做。阈值 3000 字符是我常用的起点,具体按模型窗口调整。
5. 常见问题与排查技巧实录
5.1 Agent 反复调用同一个工具怎么办
这是最高频的问题。原因通常是:工具返回结果没有让 LLM 满意,或者 LLM 没理解结果已经够了。排查步骤:先看工具返回是不是错误信息,如果是,修工具;如果返回正常但 LLM 还在调,检查系统提示有没有明确“信息足够就回答”;最后加重复检测兜底。
我的经验是,80% 的重复调用是工具返回格式问题。比如工具返回了空结果,LLM 以为没查到,就一直重试。所以工具返回一定要有明确的“成功/失败/空”状态。
5.2 上下文爆炸怎么处理
上下文爆炸表现为:请求越来越慢、越来越贵、模型开始胡言乱语。根因是历史消息无限增长。解决手段就是前面说的压缩:保留最近 N 轮,更早的摘要。另外工具返回结果一定要裁剪,这是最容易被忽略的膨胀源。
提示:我一般会在每轮结束后打印当前消息总长度,超过阈值就告警。这个简单的监控能提前发现大部分上下文问题。
5.3 工具调用参数错误怎么排查
参数错误分两类:格式错误(类型不对、缺字段)和语义错误(值不存在、越界)。格式错误靠 schema 校验拦截;语义错误靠工具内部校验拦截。两者都要把错误信息返回给 LLM,让它重填。
排查时先看 LLM 原始输出,再看校验日志。如果 LLM 经常填错,说明工具描述不够清楚,或者参数名太抽象。把参数名改得更直白,往往能立竿见影。
5.4 Agent 跑偏、不按预期执行怎么办
跑偏通常是系统提示不够明确,或者任务本身太模糊。解决手段:把系统提示写得更具体,明确角色、目标、限制、输出格式;把大任务拆成小任务,每个任务单独跑;给 LLM 少量示例(few-shot),展示期望的行为。
我踩过的坑是:系统提示写得太“客气”,LLM 就自由发挥。后来改成命令式、带明确约束的提示,稳定性提升很多。
5.5 常见问题速查表
| 问题 | 常见原因 | 排查方向 | 解决手段 |
|---|---|---|---|
| 反复调用同一工具 | 工具返回不明确 | 看工具返回状态 | 明确成功/失败/空状态 |
| 上下文爆炸 | 历史无限增长 | 打印消息长度 | 压缩历史、裁剪工具结果 |
| 参数错误 | 描述不清或校验缺失 | 看 LLM 原始输出 | 加 schema 校验、改参数名 |
| 跑偏 | 系统提示模糊 | 检查提示词 | 明确角色目标限制 |
| 循环不终止 | 缺终止条件 | 看轮数和重复调用 | 最大轮数加重复检测 |
| 工具报错中断 | 无异常捕获 | 看执行器日志 | 捕获异常返回给 LLM |
5.6 几个我踩过的坑
第一个坑是工具描述写得太技术化。我一开始把工具描述写成函数签名,结果 LLM 完全不知道什么时候用。改成场景描述后,选择准确率大幅提升。
第二个坑是没有最大轮数。早期版本没设上限,遇到一个查不到的数据,Agent 循环了几十轮,烧了不少 token。后来强制设 10 轮,超了就返回当前结果。
第三个坑是长期记忆写入太随意。什么都往向量库塞,结果检索出来的都是噪音。后来改成只写结论,并且写入前做去重,记忆质量才上来。
第四个坑是忽略工具返回的裁剪。有个工具返回了几万字的文档,直接塞回上下文,下一轮请求直接超限。后来统一裁剪到 1000 字符以内,问题解决。
6. 工具选型与框架对比:什么时候该自己写,什么时候该用现成的
6.1 手写 vs 框架的取舍
手写 Agent 的优势是可控、可调试、无黑盒。你能看到每一轮的消息、每一次的工具调用、每一个决策点。缺点是重复造轮子,多 Agent 协作、复杂记忆、可视化这些要自己实现。
框架的优势是开箱即用、生态丰富。LangChain 工具多、Dify 可视化好、CrewAI 多 Agent 协作方便。缺点是抽象层多,出问题不好排查,版本更新快,容易踩兼容性坑。
我的建议是:第一版手写,跑通核心循环;第二版按需引入框架。手写一遍能让你真正理解 Agent 的机制,之后用框架也知道它在背后做了什么。
6.2 主流框架的适用场景
| 框架 | 适合场景 | 优势 | 注意点 |
|---|---|---|---|
| LangChain | 通用 Agent、工具生态丰富 | 工具多、文档全 | 抽象层多,调试成本高 |
| Dify | 快速搭建、可视化编排 | 上手快、界面友好 | 深度定制受限 |
| CrewAI | 多 Agent 协作 | 角色分工清晰 | 单 Agent 场景偏重 |
| 自研 | 深度定制、性能敏感 | 完全可控 | 工作量大 |
选型时先问自己:任务复杂度多高?需要多 Agent 吗?团队对框架熟悉吗?上线时间紧不紧?答案清楚了,选型自然清楚。
6.3 模型选型的实操建议
做 Agent 时,模型选型比框架选型更重要。我的实操建议是:规划用强模型,执行用快模型,摘要用便宜模型。三者可以不同。规划模型负责理解任务、拆解步骤;执行模型负责工具调用、格式输出;摘要模型负责压缩历史。
如果预算有限,至少保证执行模型指令遵循强。工具调用格式不稳定,整个 Agent 就废了。实测下来,指令遵循比参数规模更影响 Agent 稳定性。
7. 安全与权限:Agent 能干活,也能闯祸
7.1 三层防护的具体落地
第一层工具白名单:只暴露当前任务需要的工具,不要把所有工具都挂上去。任务结束就收回权限。
第二层参数校验:所有工具参数走 schema 校验,危险操作(删除、发送、支付)加二次确认或 dry-run。
第三层操作审计:每次工具调用记录时间、工具名、参数、结果、调用者。出问题能追溯。
这三层不是可选项,是底线。我见过太多 Agent 因为没做权限控制,误删数据、误发消息的案例。
7.2 危险操作的确认机制
对于有副作用的操作,我一般做两种确认:人工确认(弹窗让用户点确认)和dry-run(先模拟执行,返回将要做什么,用户确认后再真执行)。
dry-run 特别适合批量操作。比如批量发消息,先让 Agent 列出要发给谁、发什么,用户确认后再发。这样既保留了自动化效率,又避免了误操作。
7.3 审计日志的设计要点
审计日志要包含:时间戳、会话 ID、轮次、工具名、参数、结果状态、耗时。日志要结构化存储,方便查询和告警。
我一般还会加一个异常告警:连续多次工具失败、单次任务轮数超限、危险操作触发,都发告警。这样能在问题扩大前介入。
8. 从单 Agent 到多 Agent:什么时候该扩展
8.1 多 Agent 的适用场景
单 Agent 能搞定大部分任务。多 Agent 适合:任务需要不同专业角色(研究员、写手、审核)、任务可以并行、任务需要对抗性检查(一个生成一个审核)。
不要为了多 Agent 而多 Agent。多 Agent 的通信成本、协调成本、调试成本都比单 Agent 高。我一般先用单 Agent 跑,跑不动了再拆。
8.2 多 Agent 的协作模式
常见模式有三种:流水线(A 输出给 B,B 输出给 C)、辩论(多个 Agent 给方案,互相评审)、主管-工人(一个主管 Agent 分派任务给工人 Agent)。
流水线适合流程固定的任务;辩论适合需要高质量决策的任务;主管-工人适合任务可拆分的场景。选哪种取决于任务结构。
8.3 多 Agent 的通信与状态管理
多 Agent 最大的坑是状态不一致。A 改了数据,B 不知道,结果冲突。解决手段是共享状态存储加版本控制,或者用消息队列串行化关键操作。
我的经验是:多 Agent 之间尽量通过结构化消息通信,不要传自然语言。自然语言容易歧义,结构化消息(JSON)明确、可校验。
9. 性能优化:让 Agent 跑得更快更省
9.1 token 成本控制
Agent 的 token 消耗主要在三个地方:系统提示、历史消息、工具返回。系统提示尽量精简,能一句话说清就不要三句;历史消息做压缩;工具返回做裁剪。这三项做好,成本能降一半以上。
另外,缓存也很重要。相同的工具调用结果可以缓存,避免重复请求。规划结果也可以缓存,相似任务直接复用。
9.2 延迟优化
延迟主要来自 LLM 调用和工具调用。优化手段:并行调用无依赖的工具、用流式输出减少等待感、用快模型做简单决策。
我一般会把“规划”和“执行”分开,规划一次,执行多次。这样规划的高延迟只付一次,执行的快模型延迟低。
9.3 并发与限流
多个任务并发时,要控制对 LLM 和工具的并发数,避免被限流。用信号量或队列控制并发,加退避重试。
提示:工具调用一定要设超时,我一般设 10 到 30 秒,具体看工具类型。超时后返回错误给 LLM,让它决定重试还是换路。
10. 面试与学习路线:Agent 工程师该会什么
10.1 高频面试题方向
Agent 相关面试常问:ReAct 和 Plan-and-Execute 的区别、工具调用怎么实现、循环怎么控制、记忆怎么设计、多 Agent 怎么协作、怎么保证安全。回答时不要只背概念,要结合具体项目讲你踩过的坑和解决方案。
我面试别人时,最看重的是有没有真正跑过一个 Agent 项目。跑过的人能说出具体的参数、具体的错误、具体的优化,没跑过的人只能背概念。
10.2 学习路线建议
第一步,手写一个最小 Agent,跑通工具调用和循环。第二步,加记忆、加规划、加安全。第三步,用框架重构,对比差异。第四步,做多 Agent 和性能优化。第五步,读优秀开源项目的源码,理解工程细节。
这个路线我走过,每一步都有明确的产出。不要跳步,跳步会在后面某个环节卡住。
10.3 值得读的开源项目
LangChain、Dify、CrewAI 都值得读,但不要一上来就读源码,先跑通再用,用出问题再读对应模块。另外,一些轻量 Agent 实现(几百行的项目)更适合入门,能快速理解核心机制。
读源码时重点关注:循环怎么写的、工具怎么注册的、记忆怎么存的、错误怎么处理的。这四个点理解了,Agent 工程就通了。
11. 我个人的一些实操体会
做 Agent 这一年多,最大的体会是:Agent 的难点不在 LLM,在工程。LLM 负责决策,但决策的质量取决于你给它的上下文、工具描述、系统提示。这些全是工程问题。
第二个体会是:简单优先。能用单 Agent 就别用多 Agent,能用规则就别用 LLM,能裁剪就别透传。每加一层复杂度,调试成本就翻倍。
第三个体会是:监控和日志是生命线。Agent 是黑盒,没有日志你根本不知道它为什么这么决策。我每个项目都会加详细的调用日志和轮次日志,出问题第一时间能定位。
最后一个体会是:安全不能省。Agent 能干活,也能闯祸。工具白名单、参数校验、操作审计,这三样一个都不能少。省了这三样,早晚出事。
如果你正准备搭自己的第一个 Agent,我的建议是:先手写一个 100 行的最小版本,跑通“提问 → 调工具 → 回答”的闭环,然后再逐步加记忆、加规划、加安全。不要一上来就上框架,也不要一上来就追求多 Agent。把七要素和七个决策点想清楚,剩下的就是写代码和调参数的事了。