ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

全栈AI修图Agent实战:从意图识别到工具调用的完整链路拆解

全栈AI修图Agent实战:从意图识别到工具调用的完整链路拆解 这篇迟来的复盘文章其实已经在我草稿箱里“压”了快两周。原因很简单项目做完的那天晚上我盯着屏幕上跑通的演示视频居然有种“不知道该从哪儿讲起”的恍惚感。不是因为代码量有多惊人而是因为这个“全栈 AI 修图 Agent”项目真正让我第一次完整地走通了一条从 Model、Agent 到前后端全链路的研发闭环——以前总觉得这些概念是散的这次它们终于在同一个项目里拧成了一股绳。写这篇长文不是想晒什么“新项目完结”的仪式感而是想把我踩过的坑、反复推翻过的架构决策、还有那种“原来 Agent 工程化和写 Demo 完全是两码事”的顿悟一次性讲清楚。如果你也正打算从纯前端或者纯后端往全栈 AI 应用方向转或者在 Agent 开发的“工具调用”和“意图识别”里绕不出来这篇文章应该能帮你省下不少自己摸索的时间。1. 项目缘起为什么“又”做了一个修图 Agent而不是传统修图网站先说个现象。这两年 AI 修图工具并不稀缺从在线抠图到一键变清晰市面上能叫得上名的产品少说也有几十款。但如果你真正以“创作者”的身份去用很快就会发现一个尴尬的事实市面上的修图工具大多是“单点功能”——这个工具只能抠图那个工具只能调色想完成“帮我抠出人物、换一个背景、再把整体色调调成日系清新风”这条完整链路你得手动切换三四个网站还要反复上传下载同一个文件。这个痛点我感受很深。之前我做后期时经常要在不同工具之间来回倒腾效率低不说最烦人的是风格参数每次都要重新调。所以这个项目立项的时候我就给自己定了一个跟以往不太一样的目标我不做“又一款修图网站”而是做一个“能听懂人话、能自己规划修图步骤、能调用不同图像工具”的 Agent。1.1 从“按钮式修图”到“对话式修图”的思维转变传统修图应用的核心交互是“功能按钮”。用户看到“抠图”“增强”“滤镜”这些按钮然后点击再调参数。这个模式对工具类产品来说非常成熟但它有一个隐藏门槛用户得知道“自己需要什么功能”。而对话式修图 Agent 的产品逻辑完全不同。用户只需要说“把这个背景换掉”或者“让照片更有质感”Agent 要自己判断出这背后对应的是语义分割、图像合成、色彩分级这些技术操作然后编排好调用顺序去执行。换句话说传统 App 是“把工具放到用户面前”Agent 是“把用户的意图翻译成工具链”。1.2 这个 Agent 到底能修哪些图这里我先明确一下项目边界。由于是个人项目我不太可能从零训练一个图像生成模型所以我的策略是“管线编排 能力串联”——底层调用现成的图像处理能力比如抠图模型、超分模型、图像描述模型上层用 Agent 做意图解析和步骤规划。目前实际跑通的能力包括背景替换准确识别主体轮廓替换成用户描述的新场景批量调色一次性处理多张图片统一色调风格智能裁剪根据主体位置自动构图裁剪图像增强模糊图片变清晰、低分辨率放大从实际使用效果来看单一能力跑通并不难难点全在“Agent 怎么知道该用哪个能力、按照什么顺序组合”上。这也就是整篇文章想跟你重点聊的核心。2. 技术选型全景全栈项目不该只有“前端 后端 模型”三层很多全栈初学者对“全栈 AI 应用”的理解就是 React 写页面、Python 写后端接口、再挂一个模型 API。这个理解没错但放到 Agent 场景里是远远不够的。真正的全栈 AI 应用中间必须多出一个“Agent 编排层”而这一层才是整个项目技术架构的灵魂。2.1 前端技术栈为什么选了 React TypeScript 而不是 Vue前端选型上我几乎没有犹豫就决定了 React TypeScript。原因有以下几点第一Agent 应用的交互状态非常复杂。用户对话消息、Agent 执行的每个步骤、工具调用的中间产物、最终图像结果这些状态如果不用强类型约束光是维护 props 就能把人逼疯。TypeScript 的接口定义在这种场景下价值极高——我可以提前定义好“工具执行结果”的数据结构后端返回什么、前端展示什么一目了然。第二React 的生态更适合做 AI 应用原型。流式输出、消息列表、画布预览这些组件在 React 生态里能找到非常成熟的方案。特别是react-markdown配合remark-gfm处理 Agent 返回的结构化文本非常顺手。2.2 后端技术栈Node.js 不只是“能跑”而已后端我选择的是 Node.js 技术栈NestJS 框架。可能有人会问AI 应用的后端不是用 Python 更合适吗我的答案是要看“AI 应用”这四个字的重心在哪。如果你做的是模型训练、模型微调那 Python 是唯一解但如果你做的是“ AI 应用”核心是业务逻辑编排、API 网关、任务队列、数据持久化Node.js 的优势反而更突出——它和前端语言统一类型可以共享异步 I/O 处理并发请求非常高效而且说实话如果只是调 API 拼逻辑Python 和 Node.js 在开发效率上并不存在代差。在这类项目中语言差异不是瓶颈架构和组织代码的能力才是关键。2.3 Agent 编排层被很多人忽略的“全栈”新维度如果这个项目只做前端 后端 调模型接口那它跟我之前写过的技术 Demo 没有本质区别。真正让它升格为“Agent 项目”的是中间新增的Agent 编排层。这一层要做的事包括接收用户输入的自然语言指令解析背后的真实意图根据意图编排工具调用序列决定先调什么、后调什么解析工具返回值判断是否需要再次调用模型还是直接产出最终结果把整个执行过程以结构化的方式推送给前端让用户能看到“Agent 正在做什么”这个编排层我最早是用纯if-else写的后来发现可维护性太差于是重构成了“策略模式 有限状态机”的结合体。关于这一块的踩坑过程后面有专门的章节展开讲。2.4 图像能力接入我的工具调用设计图像能力的接入我采取的是“工具化”思路。每一个图像处理能力——分割、放大、调色——都被封装成一个独立的工具函数定义好输入输出格式然后交给 Agent 调用。这样设计的好处非常直接Agent 不用关心某个工具内部是怎么实现的它只需要知道“这个工具能干什么、需要什么参数、返回什么结果”。借助本项目我实际试过几个不同的图像处理服务商最大的教训是做个本地 mock 服务做基于 OpenCV 的调色和格式转换能帮你省下一大笔在线 API 调试时间。我在项目初期就是在真实 API 上调工具协议结果经常因为网络超时排查半天后来全部改成本地 mock 服务开发效率至少提升了一半而且本地实现可以做很多工具的底层兜底不会因为某个服务商的限流卡住整个链路。3. Agent 核心机制拆解意图解析、任务规划与工具调用这一章是全文的“硬核区”我尽量用最容易理解的方式讲透 Agent 工作流的三个核心环节。如果你对 Agent 的印象还停留在“聊天机器人”那看完这一章你应该能理解Agent 和 Chatbot 最大的区别是 Agent 能“动手干活”而不仅仅是“动嘴说话”。3.1 第一步意图解析——怎么让模型明白用户要“干什么”这里我先用生活化的比喻解释一下。如果把 Agent 比作一个餐厅经理用户的话就是顾客下的订单。订单上写的是“来点爽口的”经理就得自己翻译成“拍黄瓜加冰镇酸梅汤”订单上写“老样子”经理还得结合历史订单来判断“老样子”到底是什么。技术实现上我使用的方案是“LLM 函数调用Function Calling 结构化输出约束”。我会在系统提示词里明确告诉模型用户需求可能对应图片编辑、图像生成、信息查询、简单对话四类行为如果是编辑请求必须提炼出操作类型、目标区域、风格参数如果信息不足不能瞎猜必须列出需要追问用户的问题清单这个约束非常关键。没有结构化约束的模型输出就像你让一个实习生去干活但没说清楚交付格式他可能给你一段流畅的小作文但你就是没法把它变成程序能识别的指令。3.2 第二步任务规划——把“大目标”拆解成“工具链”意图解析之后Agent 面临的核心挑战是得到一个意图不等于知道怎么执行。比如用户说“把这个人的背景换成海边日落”这里至少涉及两个图像操作——前景分割识别人的轮廓和背景合成把新背景填进去。任务规划这个环节本质上是一个决策问题当前请求应该拆成哪些子任务子任务之间是串行还是并行我采取的方案是“方案 子步骤”两段式结构第一段Agent 根据工具清单描述将要采用的图像处理方案这个方案会推送给前端展示让用户了解 Agent 的计划第二段Agent 输出一个结构化的子步骤数组每个子步骤包含工具名称、工具参数、步骤描述这个设计的妙处在于既保留了模型的“智能规划”能力又把执行路径变得可预测、可调试。如果某个步骤失败了我可以精确定位到是哪个工具、什么参数导致的而不是面对一大段模型输出一头雾水。3.3 第三步工具注册与调用——怎么让 Agent 能“驾驭”外部能力在工具调用环节我参考了业界常见的“工具注册表”模式。项目里有一个tools/index.ts每个图像工具都遵循如下格式interface ToolDefinition { name: string; // 工具唯一标识 description: string; // 给 LLM 看的工具能力描述 parameters: JSONSchema; // 参数格式约束 executor: (params: any) PromiseToolResult; }这里最难的部分不是写 executor而是给每个工具写 description。因为 LLM 是凭借 description 来决定“什么时候用哪个工具”的描述得太笼统模型会乱选描述得太长又会浪费 token。我自己的经验是要用“触发场景 能力边界 参数说明”三段式来写。例如抠图工具的 description当用户需要将图像中的人物、物体或主体与背景分离时使用。支持输入图像 URL 或 base64 字符串返回透明背景的主体抠图结果。本工具处理的是语义分割任务不是单纯的边缘检测在调用前请确保已经从用户输入中提取了图像地址。这样写完后模型“用错工具”的概率明显下降。这也是一个通用经验Agent 的质量一半靠模型能力另一半靠工具描述的工程化水平。3.4 状态管理Agent 的“有限状态机”设计Agent 的一次完整任务不是“一次请求 一次响应”这么简单。它更像是用户发指令 → Agent 回方案 → 用户确认 → Agent 开始执行 → 工具返回中间结果 → Agent 判断是否继续 → 直到完成。在这个过程中任务状态不断变化。最开始我用一堆布尔值isThinking、isDone、isError来标记状态结果代码越写越乱。后来重构为标准的有限状态机FSMIDLE → PLANNING → CONFIRMING → EXECUTING → FINISHED ↘ ERROR → RETRY → EXECUTING这个状态的转换逻辑被统一封装在一个TaskStateMachine类里前端收到状态变更就展示对应的 UI后端收到状态事件就触发对应的动作。状态机带来的最大好处是任何时刻系统都处于一个合法状态不会出现“既是执行中又是已完成”这种边界混乱。3.5 与“无限制 AI”等热搜词的思考为什么我没有追求“全功能”在搜索项目相关资料的过程中我注意到“无限制 AI”“无审核生成式 AI”这类关键词的热度很高。这里我想聊两句我的真实想法技术能力应该有边界感。“无限制”听起来美好但如果你做的是面向公众的图像工具一旦被恶意利用后果是不可逆的。所以这个项目里我对图像输入做了基础的内容合规校验对生成类工具做了输出内容过滤用户上传的图像也会被临时存储且定时清理。我认为真正的技术能力不只是“能不能实现”更包括“敢不敢为后果负责”。这一点在任何内容生成型产品里都值得优先考虑。4. 全栈链路实战从 Agent 规划到图像处理落地的完整流程理论说了很多这一章我完整带你走一遍代码链路。我会以“给我这张图换个赛博朋克风格的背景”这个最经典的案例为线索说明这条指令从用户输入到最终成图中间到底发生了什么。4.1 前端交互层消息流与工具执行轨迹展示前端的核心页面其实只有两个视图左半部分是对话列表和状态流右半部分是图像预览画布。先说对话列表。用户的指令消息、Agent 的规划文案、工具执行状态卡片全都以“流式消息”的形式平铺在时间线上。为了实现流畅的流式体验我用的是 SSEServer-Sent Events——后端把 Agent 执行过程中的事件逐步推送到前端前端按事件类型渲染不同的组件。工具执行状态卡片是 UI 层最有“Agent 感”的地方。它会展示当前正在执行的工具图标和名称执行的进度状态等待中 / 执行中 / 完成 / 失败工具返回的中间产物预览这里有个产品细节想跟你分享千万不要把工具执行过程完全隐藏。用户看到 Agent 在“先抠图再合成再调色”会建立强烈的信任感这种信任感是黑盒式处理给不了的。这也是 Agent 产品区别于传统 API 封装类产品的重要体验差异。SSE 的核心订阅逻辑可以精简成这样const eventSource new EventSource(/api/tasks/${taskId}/events); eventSource.addEventListener(agent.status, (event) { const data JSON.parse(event.data); updateTaskState(data.taskState); // 更新任务状态机 }); eventSource.addEventListener(tool.executed, (event) { const tool JSON.parse(event.data); pushToolCard(tool); // 新增工具执行卡片 refreshPreview(tool.resultUrl); // 刷新画布预览 });4.2 后端 API 设计任务驱动而不是请求驱动传统 REST API 的设计是“一个请求对应一个响应”但在 Agent 场景里一次用户指令的执行时间可能长达几十秒甚至几分钟这时候如果还用同步请求会非常难受。我的设计是“任务驱动”前端发起POST /api/tasks创建图像编辑任务拿到taskId后端将这个任务丢进队列开始异步执行 Agent 流水线前端通过GET /api/tasks/{taskId}/events建立 SSE 长连接全部工具执行完成后后端推送task.completed事件包含最终图像 URL这个模式的本质是把“执行过程”和“结果交付”解耦也是全栈 AI 应用后端的通用标配。4.3 工具层实战以“背景替换”为例的完整调用链背景替换这条链路在项目里算典型的三步串联我在这里完整贴一下精简版的流程代码去掉具体 API 密钥等敏感信息。第一步调用分割工具获取主体掩码const segResult await imageTools.segment({ imageUrl: userUploadedImageUrl, target: person }); // segResult.maskUrl 是主体区域的透明底 PNG // segResult.bounds 是主体在原图中的包围盒坐标第二步生成新背景图const bgResult await imageTools.generateBackground({ prompt: cyberpunk city street at night, neon lights, rain reflections, aspectRatio: 16:9 }); // bgResult.imageUrl 是生成的赛博朋克风格背景图第三步图像合成const finalResult await imageTools.composite({ foregroundUrl: segResult.maskUrl, backgroundUrl: bgResult.imageUrl, position: { x: 0, y: 0 }, scale: 1.0, blendMode: normal }); // finalResult.imageUrl 就是最终成图这三个工具依次执行完毕后后端把最终图片地址包装成任务结果推给前端。可以看到的是工具层完全不关心“为什么要做这三步”它只提供原子能力而 Agent 层完全不需要知道“合成算法是怎么实现的”它只负责任务编排。这就是分层架构的意义——各司其职互不干扰。4.4 前端图像预览从“上传原图”到“分阶段效果展示”图像预览区的设计比看起来要复杂一些核心难点在于“怎么展示中间状态”。我实现了一个三栏对比组件最左侧始终显示原始上传图中间栏展示“最近一次工具执行后的中间产物”最右侧展示“Agent 全部执行完的最终结果”这个设计的用户体验非常好。用户能直观地看到“每一步操作带来了什么变化”而不是从头到尾只有一个“转圈”然后突然出图。中间产物的加载我是用“对象临时存储 过期清理”策略实现的——每个中间图片保存 24 小时然后自动删除防止存储空间被撑爆。4.5 一个隐藏的难点上下文保持与“多轮修改”修图场景和对话场景还有一个显著区别用户经常会基于上一轮的编辑结果继续提要求。比如第一轮“把背景换成海边日落”第二轮“嗯…这背景有点太亮了暗一点”这就意味着 Agent 不能把每一次对话当成完全独立的请求。我的做法是每一轮任务结束时把最终结果的图片 URL 和简短的编辑操作摘要存回对话上下文下一轮任务启动时这些信息会自动作为系统上下文的一部分传给 Agent。这个设计让多轮修改成为可能但也带来一个问题上下文越来越长Token 消耗不断增加。我的折中方案是只保留最近 5 轮的摘要更早的历史记录只保留图片 URL 不保留操作细节。这个“摘要遗忘”策略让成本控制在一个合理范围内。5. 避坑实录全栈 Agent 项目里最容易踩的 7 个深坑这个项目的开发周期大概是六周。说实话前两周半的进度比我想象的顺利得多但后面三周多几乎每天都在跟各种奇怪的问题搏斗。这一章我系统地复盘一下最典型的 7 个深坑希望你能避开。5.1 工具参数里的“图像格式”不一致导致黑图现象分割工具返回的是 PNG 透明底但合成工具默认只接受 JPG结果合成工具读图时出现黑色底块。根因不同图像服务返回的图片格式不统一而且很多工具对中国区访问的存储域名有自己的处理逻辑。我在系统提示词里没有把“统一输出为 PNG”作为公共约定各个工具各自为政格式混乱。解法所有图像工具的输出在返回 Agent 之前统一经过一层“标准格式转换中间件”强制转成 PNG 并提供可访问的 URL。这一步看似多此一举实际上省掉了大量后续兼容性排查的时间。5.2 LLM 把 image_url 参数填成了辅助文本现象用户上传了一张图Agent 在规划时却把图片地址写成了“用户上传的图片在附件里”这段自然语言文本。根因我对工具参数的描述不够强硬模型以为图片可以在消息上下文里传递就偷懒没填参数。解法在系统上下文里加了一条硬性规则所有图像编辑类请求必须先从用户消息中提取或确认 image_url 参数该参数不得为空如果未能提取到必须追问用户提供图片链接。同时在工具参数的 JSON Schema 里把imageUrl标记为required并且加上pattern校验必须是http(s)://开头。5.3 SSE 连接频繁断开任务执行到一半就断了现象Agent 执行长任务时SSE 连接经常在 1 分钟左右断开前端拿到的事件不完整。根因我一开始用默认的 HTTP 服务器配置没有设置心跳保活也没有处理代理服务器的空闲超时。很多云厂商的接入层对长连接的空闲时间有硬性限制静默时间一长就会主动断开。解法实现了两个机制一是 SSE 服务端每隔 15 秒发送一次注释心跳包data: ping\n\n二是前端在断开时自动重连并根据Last-Event-ID事件游标补齐缺失的事件区间。这个“断线续传”机制很关键否则用户在弱网环境下根本没法完成多步骤修图任务。5.4 Agent 规划出“不可能执行”的流程现象用户说“把这张图放大两倍再添加文字”Agent 规划出来的步骤居然是“先生成文字再放大”。这个顺序导致文字被放大后清晰度下降效果很差。根因模型对图像处理工具的依赖关系缺乏理解规划时只是把工具按“提到顺序”排列没有思考工具之间的顺序约束。解法我在每个工具的 description 里增加了“前置依赖建议”字段。比如“添加文字”工具的描述里明确写建议在本工具之前完成所有几何变换缩放、裁剪、旋转类操作否则文字会被拉伸变形。同时在 Agent 规划结果的后置校验环节增加了一个简单的规则引擎检测是否存在明显顺序冲突如果发现就强制调整执行顺序。5.5 前端大量图片加载导致内存溢出现象任务执行到第 8、9 步时浏览器开始明显变卡最后直接崩溃。根因每次工具执行都会返回一个新的中间结果图前端为了对比方便把所有图片都缓存在内存里没有释放几百张 Base64 图片数据直接把标签页拖垮。解法改用临时对象存储 URL 方式引用中间结果前端只保留当前步骤和前一步骤两张图片的内存引用同时加了一个纯前端的 LRU 缓存超出限制就自动把最旧的图片从createObjectURL释放掉。5.6 多轮对话中的上下文污染现象用户第一轮说“换背景”第二轮说“顺便把亮度调一下”。Agent 在第二轮居然把背景又换了一次然后才调亮度。根因对话历史里的工具结果和当前请求混在一起模型无法区分“哪些是已经完成的历史操作”“哪些是当前请求新增的操作”。解法在维护上下文时把“历史任务摘要”和“当前请求目标”分开存放。系统提示词里明确告知模型当前轮只处理本轮提出的新增需求历史已完成的编辑结果作为上下文参考除非用户明确要求推翻重做否则不要重复执行。这个约束加上之后多轮指令的准确率提升非常明显。5.7 真实 API 的限流与故障必须有降级方案现象某图像服务商的免费额度用完导致 Agent 流程中某一步直接 429 报错整个任务中断。根因我的编排层没有考虑“工具调用失败后的降级方案”只要一个工具挂了整个任务链就断了。解法为关键工具增加了“降级策略”配置。比如分割服务失败自动降级为“传统图像处理库的轮廓检测”兜底背景生成失败自动降级为“纯色渐变背景”。同时增加了“能力健康检测”模块启动时探活所有工具端点不健康的服务会自动从工具清单里摘除这样 Agent 就不会规划出无法执行的流程。6. 项目可观测性Agent 应用调试不能只靠 console.log传统全栈项目调试靠console.log和断点基本能应付。但 Agent 应用不一样——它的很多决策是模型自主做出的日志里不打出来你根本不知道模型为什么选了这个工具而不是另一个。这个项目做到中期我开始认真给 Agent 执行链路加可观测性。具体做了三件事6.1 记录“模型原始输出”和“结构化输出”的对照每次调用 LLM我都会同时保存两份日志一份是模型返回的原始 JSON/文本另一份是经过 schema 校验和纠错后的结构化指令。很多诡异的行为一对比这两份日志就能看出来是“模型输出本身就错了”还是“我的解析层把正确的输出搞坏了”。6.2 任务执行轨迹的可视化我把一次完整任务的所有事件意图解析、任务规划、工具开始、工具结束、中间产物、失败重试按时间线串起来渲染成一个“任务执行轨迹图”。排查问题的时候直接看轨迹图就能快速定位到“哪一步耗时异常”“哪一步输入输出不匹配”。这个功能也是我自己最满意的一个部分做 Agent 产品给自己的 Agent 做一套“行车记录仪”绝对是值得的投资。6.3 工具调用的成本审计每次 LLM 调用和图像 API 调用都会记录 token 数、耗时和费用。项目后期优化成本时这张表帮了大忙——我能一眼看出哪些环节过度消耗 token然后针对性地压缩上下文和优化提示词。做 AI 应用成本意识要前置不然上线后用户一多账单会让你怀疑人生。7. 项目复盘与进阶路线从“修图 Agent”到“通用任务型 Agent”项目完结后我花了几天时间做了一次比较彻底的复盘。这里想把最后沉淀下来的思考和下一步计划也一并写出来。7.1 这个项目验证了什么首先它验证了“LLM 工具调用 状态机”这个组合在图像处理领域是实际可行的。Agent 完全能够通过策略性调用不同的图像工具完成复杂的修图任务而且用户体验比传统“按钮式修图”要自然得多。其次它也验证了一个全栈 AI 工程师的核心能力不是“会调 API”而是“能把模型能力和工程架构丝滑地结合起来”——这包括工具描述工程、状态流转设计、降级容灾策略这些能力在传统全栈开发里是学不到的。7.2 这个项目暴露了什么短板目前的 Agent 其实还比较“脆”。第一个短板是对边缘案例的处理能力不足如果用户上传的图片质量极低、主体不清晰分割工具和后续步骤的质量都会明显下降Agent 自己也很难察觉并主动提示用户。第二个短板是不支持自定义工具扩展目前工具清单是写死的后续如果想让第三方开发者也能上传自己的图像处理能力还需要改造工具注册表并增加更多安全校验。第三个短板是缺少更细粒度的用户反馈收集Agent 执行完成后只能靠最终成图效果来判断结果好坏缺少对中间步骤的满意度反馈采集这会影响后续优化方向的判断。7.3 下一步的可行性计划基于复盘的结论我规划了几个明确的优化方向引入“质量评估器”增加一个独立的评价模型在最终结果交付给用户之前对成图质量做一个自动打分和基础检查低分结果自动触发重新规划或提示用户补充描述。开放工具注册机制把工具定义从硬编码改为可配置的 JSON 描述 可插拔的执行函数这样不修改核心代码也能新增工具能力。更精细的 Agent 记忆管理引入向量数据库保存历史编辑偏好例如用户长期偏好高饱和度风格、暖色调等新任务启动时可以自动把这些偏好加入上下文。移动端适配目前前端布局以桌面为主但实际使用场景里“手机上传照片”的需求占比很高移动端的交互重构会是下一个短期目标。8. 最后分享一个我反复用到的“Agent 系统提示词”模板文章的最后我直接把我在项目里反复打磨过的一份“Agent 图像编辑系统提示词模板”分享出来。它没有绑定某个具体模型直接把规则抽象成了四层。几乎任何修图类 Agent 场景都能套用你在设计自己的 Agent 系统时也可以直接修改使用。8.1 第一层角色设定与能力边界你是一名专业且经验丰富的图像编辑 Agent。你的目标是理解用户的图像处理需求 通过规划和调用图像编辑工具来完成用户的指令。 你有能力执行以下类型的图像操作主体分割、背景生成、图像合成、色彩调整、 智能裁剪、图像增强、文字添加、尺寸调整。 你不需要向用户解释工具内部的工作原理。你只需要根据用户指令规划并执行正确的工具链。 当用户的需求在你的能力范围之外或者信息不足以执行时请明确告知用户。8.2 第二层工作流程约束你处理每一次图像编辑请求都将严格按照以下流程进行 1. 分析用户的请求提取关键信息输入图像地址、编辑目标、风格参数 2. 检查信息完整性如果缺少必要信息列出需要追问的问题不要猜测 3. 规划工具调用链输出执行方案等待用户确认后执行 4. 执行过程中实时汇报当前正在执行的工具与进度 5. 全部工具执行完成后汇总最终结果简要说明完成情况 如果用户是基于历史结果的二次修改只处理本轮新提出的需求 除非用户明确要求推翻重做否则不要重复执行历史步骤。8.3 第三层工具使用选择策略当你有多个工具可选择时按以下原则决策 - 如果用户指令是单一操作直接使用对应工具 - 如果用户指令包含多个操作先做几何变换缩放、裁剪再做像素级变换调色、增强最后做合成类操作 - 当“达到相同效果有多条路径”时选择步骤最少、成本最低的路径 - 如果某一步失败优先考虑降级方案是否需要调整后续步骤或者重新规划8.4 第四层输出格式要求你的所有结构化输出必须遵循 JSON 格式包含字段 - action: 本次操作的类型标识 - plan: 自然语言描述的步骤计划需向用户展示 - steps: 结构化工具调用链数组每个元素包含工具名、参数、说明 - needMoreInfo: 如果需要向用户提问此处必须是 true否则 false - questions: needMoreInfo 为 true 时此处列出需要追问的问题列表 JSON 之外的任何额外文字仅用于对话说明不作为程序执行指令。这份模板的设计意图很清晰它既约束了模型的行为边界又给了足够的自由度去处理多种多样的用户指令。我在不同的模型上试过效果都比我预想的要好也大大减少了“模型乱来”的概率。我给这个模板命名为“四层约束法”如果你正在设计自己的 Agent 系统不妨按这个思路试一下。其实写到这里这个项目的意义已经超出了“完成了多少个功能”的范畴。它真正让我体会到了全栈 AI 应用开发的独特节奏一边要理解模型能力的边界一边要像传统工程一样保证系统的稳定性和可维护性中间还要兼顾用户体验的细腻感。这三条线交织在一起就是 Agent 应用和传统应用最大的不同也是最迷人的地方。希望这篇长文能给你带来一些实际的启发。如果在做的过程中有任何问题欢迎在评论区聊聊你的方案和踩坑经历。
返回列表