AI agent 开发千万别越努力,越心酸!【AI agent 搭建实操指南 第二弹】
By 数字黑魔法
Summary
## Key takeaways - **外部输入需加审阅流程**: agent流程正确但结果错,往往因工具返回错误信息,如搜索flux2时排名第一是导流网站而非官网,因此必须引入审阅流程,不能假设工具信息一定正确。 [01:09], [01:42] - **记忆系统存中间状态bug**: 后端只存用户输入和agent输出,未存工具调用中间状态,导致不刷新界面第二轮带旧状态,刷新后丢失,输入不一致输出不同,违反行为一致原则。 [03:04], [03:49] - **顶层规划者上下文动态瘦身**: 顶层规划者上下文难瘦身,因需全局分配任务但信息庞大,策略是先让其判断用户任务类型,再动态检索相关规则和工具,如用RAG或code as tool,而非直接用大模型判断否则无节省。 [07:07], [08:34] - **对话agent不擅长深度长链**: 对话式agent工具松散,擅长串联几工具但不擅需严密逻辑的长链任务,因缺乏稳定编排,每轮即兴发挥,无法稳定输出。 [09:38], [10:00] - **引入skill提供稳定方法论**: skill是一套固定执行模板,如做PPT的步骤流程,提供给agent后可将松散工具映射到稳定结构,解决深度拓展,让通用agent有稳定编排而非每次重想。 [10:56], [11:17]
Topics Covered
- 工具输出必须审阅
- 内存策略决定信息可见
- 顶层规划动态瘦身上下文
- Skill补齐深度稳定编排
Full Transcript
Hello大家好,上期视频收到了 很多积极的 反馈,非常感谢大家的支持。
这次其实我想接着上一期的 视频继续往下讲,随着AIAgent开发的 深入,还有哪些坑是你可能遇到的。
我们依旧从真实的 工程实践出发,拆解这些坑是 怎么一步一步走到大家现在 在论文或者技术博客里看到的 那些成熟方案的。
欢迎大家收看我们今天新一期的视频。
在上一期的 视频里面,我们其实提到了 三件事情。
首先我们要做上下文的 隔离,其次我们会有一个记忆系统 ,最后我们需要有一个log的 系统,能够看到你agent 每一步是怎么运行的。
那到这个地方,我们就已经有了 一个能跑的agent了 ,我们可以去做一些实际的操作。
那当然,agent不是 所有时候都能给我们很好的 结果,当我们去查看那些坏的 结果,你会发现一些情况, 就是它很有可能流程是对的 ,但是结果是错的。
你会发现有些东西好像不是 这个agent自己能控制的 ,尤其是外部输入。
举一个实际的 例子,我们做的 这个AI视频剪辑agent, 我曾经想做一个flux2相关的 视频,然后这个AIagent 会去搜索关于flux2相关的 资料。
结果在搜索的 时候,排名第一的 这个搜索内容并不是flux2的 官方网站,而是一个买下了 flux2这个域名用来做导流的 网站。
这个时候你并不能说agent的 流程是错的 ,它的确做了正确的 选择,只不过工具返回的 输入本身就是错的 ,你拿这个错误的 信息放到后面的 流程里,你结果肯定是错的。
这里就引出了 在很多文章里面都会提到的 概念,review,一个审阅的 流程,道理也很简单,就是你通过工具拿到的 信息,我们不能假设这个信息一定是对的。
所以在我们去制作这个agent工具的 时候,我们需要思考,这个东西 它到底是不是一个光秃秃的 APIcall,它是否需要在后面 引入一个这种review的 一个流程。
第一步抓取这个信息,第二步就审阅 这个信息,我们还要去考虑是否需要 重视,或者说直接给一个带有总结的 错误提示。
至于你是在后面新加一个APIcall 去做审阅,还是用本身的 agent的 能力去做审阅,其实都不太重要,重要的 是你必须要有这样一个审阅的 流程。
所以我们会看到在一些文章 里面会提到review的 这个过程它不是一个可选项而是 agent开发里面必须要考虑到的 机制然后在上一期视频里我们其实就简单的 把记忆系统分成了 内存和外存在实际的 开发过程这个记忆系统可能还是比较复杂的 这里拿我自己用AISDK遇到的 一个bug给大家我用的 是Versailles 官方一个chatbot的
开源项目场景是这个就是用户 首先在前端发一个消息给到后 端后端agent收到了 之后,我们就开始进行一个执行。
中间会有一些执行的 状态,比如说调用了 什么工具,工具的 输入输出是什么,然后agent 是怎么进行一个思考。
这些信息都会返回给前端用来更新 UI,让用户看到agent执行的 过程。
但是在存储的 时候,后端只把用户的 输入和agent最终的 输出结果存到了 数据库里面。
中间工具的调用并没有存。
在单轮对话里面其实没有什么太大的 影响,但是问题出现在第二轮对话,如果 用户他不刷新这个界面,前端还保留着 上一轮的这些工具调用的 中间状态,第二轮请求发送到后端的时候呢 ,会把这些中间状态一起发送给 后端,但是如果用户刷新了 这个界面,这些中间状态并没有 存到数据库里面,所以第二轮的
请求就只剩下了第一轮的 用户输入,第一轮的 agent的 输出和第二轮的 用户输入同样的 任务刷新和不刷新agent得到的 输入不一样它的 输出也有可能会不一这显然 是一个bug我们最基本的 原则就是不管你刷新前还是刷新后其实它的 行为都应该是一致的但是 这方面题就来了中间的 这些工具调用的
状态到底应不应该在第二轮这种传回 给agent你会发现其实网上的 说法是矛盾的有的 文章说这应该传因为这是一系列的 对话,你第二轮的 对话需要有第一轮所有的 场景,更好的 判断,也有人说不应该传 ,因为你需要做上下文的 隔离,举个例子,你如果这个地方有个
subagent,那在第二轮对话的 时候,你这个顶层的 规划者,应该看到上一轮对话里面具体的 执行者是怎么样进行操作的 ,他应该把这些工具的 调用给屏蔽掉,他应该只看最后的 结果,所以这个地方真正的 信息不是说内存或者说外存这么简单, 而是我们在返回信息给到agent的
时候,我们应该有一个策略来 决定什么信息应该被看到。
那我解决这个问题的 策略其实非常的 简单,我首先做的 一件事情就是我把所有的 中间状态都不传回去,也就是不管 刷新还是不刷新,我就只传用户的 输入和agent的输出。
如果在这种情况下,agent 不能够继续去完成任务了 ,那就说明有些重要的 信息丢失了。
你接下来要做的 事情并不是说把所有的 这个中间状态全部都存回去,而是你去 看这个信息丢失到底是在哪一步发生的 ,那这一步关键的 信息需要被保留下来。
所以这个时候你就可以决定, 那哪些信息是一定要存在内存的 ,哪些信息是一定要存在外存的。
这个也是我们上一期视频里面强调的 为什么log系统非常重要 你只有有一个很强大的 log系你才能够清楚的 看到agent每一步的 信息是怎么样走才能够去判断 哪些信息是关键哪些信息是噪声 当我们继续做agent开发的 时候我们会在上下文隔离这个碰到一个新的 问题当我们说上下文隔离的
时候我们会发现subagent 就是这些执行者他们其实已经隔离的 很好了它们收到都是有效的 信息,但是对于顶层的 规划者,它的 上下文好像很难瘦身,因为 顶层规划者要先拿到用户的 输入,其次他要冲观全局去分配谁做什么, 谁负责哪一步,然后再把这些必要的 信息传给不同的执行者。
在这一套系统里面,似乎顶层的 规划者必须看到几乎所有的 外部信息,但问题是,这个外部信息 可能非常大,或者说可能持续性的 增大。
就比如说我们的 这个视频AIAgent, 我们最开始只让它解决一个小的 问题,比如说剪视频的 这种能力。
那这个问题完成的 不错之后呢 ,我就希望,你能不能再给我剪另外 一种风格,你能不能再做个拼接的 任务,你能不能再做一个生成的 任务,你能不能再做一个规划的 任务。
于是我就不得不去准备更多的 规则,更多的工具。
每一套规则和工具其实背后对应的 就是更长的上下文。
agent解决的 问题越多,它的 上下文就肯定会越长。
那应该怎么样对这样一个上下文 进行瘦身?其实用户每一次来的
进行瘦身?其实用户每一次来的 任务,他可能并不需要用到所有的 工具。
他的这个任务很有可能是一个单一类型。
比如说用户想要做一个剪辑的 工作,这个时候上下文它不仅仅读了 剪辑的工具和剪辑的 流程,它还读了 其他工具和其他的流程。
所以瘦身的 核心策略就是,不要先把所有的 上下文都塞给这个顶层的 规划者,先让他判断用户 想要干嘛,再通过用户的 判断去动态的 拿这类任务可能需要用到哪些规则, 这类任务可能需要用到哪些工具。
这里主流就是两种方法,第一种 方法是RAG,就是我拿到用户的 输入,先判断它大概是个什么任务, 然后它大概有哪些关键词,通过这样的 关键词去检索上下文里面可能相关的 那部分信息,拿出来。
第二种方法叫做codeastool ,就是通过写代码的 方式,在这个上下文本里面把相关的 内容找出来。
比如说用户想要剪辑, 那我这方就写一个简单的 graph,Ninux的这样的 一个命令,然后把跟剪辑相关的 东西给它给搜出来,或者说写一个更复杂的 Python文本,一个更精准的 筛选。
这两种方法的核心解决的都是同一个问题。
在不直接看到全部上下文的 情况下,怎么样把用户想要做的 事情和agent需要的 上下文给联合起来。
这个地方做一个小测验。
我如果不用上面那两种方式, 我在这方直接用一个代言模型的 工具,把用户的 输入接进来,让这个代言模型 去判断,它应该去找哪部分的 上下文,这件事情可不可以。
这个地方是不行的 ,因为大约模型想去找相对应的 上下文,它必须得 读全部的上下文。
你在这方引入一个大约模型,你根本 就没有去节省上下文长度这件事情。
在上面所有的 问题解决之后呢 ,AI在广度的 问题上其实已经解决的 差不多了。
如果你有用户在用这个agent ,它一定会有要求能不能让 这个AIagent解决一些深度的 问题。
我们在上期视频里面其实提到过 ,这个对话式agent有一个天然的 特性。
它不是一个确定性的 长链流程,即使是一个看起来很长的 任务,它本质上也是把它拆成了 一小步一小步来执行的。
举个例子,我希望我的 AIAgent能够帮我生成一个视频 元素,那我这个AIAgent第一步是 去搜集素材,然后搜集素材之后需要我的 反馈,然后搜集完素材以后 进行设计,进行设计的 时候也需要我的 反馈,然后最终进行一个执行,执行的 时候也需要我的反馈。
它其实是把这样一个场内任务拆成了 可执行的 小步,每一步可用调用一个或者几个 工具,每一步之间会有用户参与, 帮助agent决定下一步往哪走。
随着agent能力越来越强,用户的 期待也会发生变化,能不能中间少参加 一点,能不能一次性把这件事情做完。
这里就会出现一个问题,我们构建的 这种对话式的 agent,它的 工具本身是松散的 ,把一两个或者三四个工具串起来,可能做的 还不错,但是一旦涉及到需要 非常强方法论,非常严密逻辑的 这种长练任务的 时候,他就不是那么擅长,因为 他不够确定,这个不是模型 不够聪明,说agent的 组织架构决定了
,他就是自己去编排流程,没有办法稳定的 得到一套统一的 流程,当用户希望他做的更深的 时候,其实这个深代表的 是按照一套固定的 方法论来执行,在期待的 是一种稳定的 编排,而不是每一次都让 agent去即兴发挥。
那这种稳定的 编排就跟这个N8N或者Diffie 这种workflow非常的 相似,一条很长的 链,它可以跑得 很深很稳定。
那问题来了 ,怎么能够让agent从这种松散的 工具调用,拓展 到workflow这种级别的 执行?这里其实就对应到一个新的
执行?这里其实就对应到一个新的 概念,也是之前大家在评论区里面讨论过的 概念,agentskill,Skill 你可以把它理解成为解决一类问题的 方法论或者说一套固定的 执行模板比如说做一个PPT 第一步第二步第三步第四步 这个流程可能会很复杂但是你按照 这个流程做它就能得到最终的
PP当你把这样一条类似于长链的 方法论提供给AIAgent的 时候Agent就可以把原来相对松散的 工具映射到这套固定的 结构可以得到一个相对稳定的 输出所以skill补齐的 其实不是subagent这种上下文隔离的 也不是这种tool的 调用它其实解决的
是让agent有一套稳定的 编排不需要每一次都自己重新去想一次了解了 这个之后我们就能很好的 判什么时候会需要agent的 skill如果一个任务用n8n 这种workflow做得 很好然后你希望把这种workflow的 能力引入到你的 AIagent里面那你就 需要用到skill的 这种形式。
如果你本身就在做一个非常垂直的 agent,这个领域里面你已经做了 非常成熟的 方法论和编排,那你不一定需要再额外的 引入skill这种概念了。
所以skill更多的 解决的是通用的 这个agent,怎么样能够 在深度上去进行一个拓展。
虽然我们上面说了 这么多,但是AIagent开发的 核心概念并没有发生变化。
当我们想要给AIAgent 去加一套比较复杂的 架构的时候呢 ,我们一定要去判断, 那这个AIAgent它是否真正的 遇到了这样的 一个问题,它的 开发流程永远都是先发现 问题,再解决问题啊。
那以上就是这期视频的 全部内容,如果你觉得我们的 视频做的 还不错的话欢迎点赞收藏转发订阅评论我们的 频道,对我们来说非常的 重要,感谢你的收看,祝
Loading video analysis...