junnhwan
全部文章

Weekly5 Part II:个人项目跟进 —— Agent 执行可视化与跨视频问答

记录 vid-lens 在上篇之后的改动,包括思考与执行过程可视化、Chat 与 Agent 模式收敛、跨视频问答、多轮上下文与偏好记忆,以及执行预算、断流恢复和反馈评测。

写在前面

上周我改善项目主要是把项目从普通的 AI 问答逐渐转向受控 Agent 自主搜集视频相关信息从而回答用户,但是还有几个我觉得要解决的问题。

一个是,上周改进之后,其实项目还是主要针对一个视频的 Agent 化检索,但是这样我说是视频知识库的话其实就不太妥当了,“知识库”起码也得是在有多个视频的集合里面去检索吧,也就是可以跨视频检索,相关的视频可以收到一个知识库中,针对知识库进行提问;

另一个是,上周那样改完之后,其实对于 Agent 的执行流程可能还是不太清晰的,也就是 Agent 执行过程的可视化不够完善,所以这周从 UI 和后台能力都完善了一下,把思考过程与决策链可视化算是做了一个最小实现了,另外上周其实有个流式输出的功能没做完善,最后还是在完整准备好回答一下子输出的,今天修了一下发现是前端的问题然后修好了。

最后,还有一点改动,就是上周做的分了很多个功能,这周收敛成了 Chat 和 Agent 两种模式,一种是单纯的 AI 问答,另一种就是给 AI 工具去从视频搜集信息回答用户,也就是“Agent”,还有把记忆的部分完善了一下,以及 Agent 输出的预算作为可配置项。具体的这周改动就见下面的说明吧。

对了,还把 README 精简完善了一下,放上了项目预览的截图,上周改完之后没空改 README,这周才改完。在这里求一下 star 🌟~

vid-lens 的 GitHub 项目仓库

项目地址:junnhwan/vid-lens。文中截图可以点击放大。

思考过程与决策链可视化

上篇写到,我给 vid-lens 加上了按需查看视频画面的能力。Agent 可以根据已有信息继续检索、补看画面,再组织回答。但一次提问经过的步骤多了之后,等待答案的这段时间,也需要让人知道它到底在做什么。

所以这次先完善了思考过程与决策链的可视化,把规划、工具执行、检索结果和回答生成接到同一条时间线上。除了看到“正在检索”,还可以看到这一步为什么需要检索、已有信息缺在哪里,以及后面准备补充什么。

比如一个假设的问题是“视频里这张图表说明了什么”,界面上可能呈现这样的过程:

检索相关转写,找到图表附近的时间
→ 已有文字缺少图表细节,准备查看对应画面
→ 读取已有视觉记录,必要时补充抽帧
→ 根据取得的证据生成回答

具体顺序取决于当次执行,界面跟着后端真实事件更新。每一步都有执行状态,结束后过程区域默认折叠,也可以重新展开。

README 中的跨视频 Agent 执行过程和视频库界面预览

README 中的界面预览:上方是跨视频 Agent,右侧可以查看执行步骤与决策说明;下方是视频库。

这里有两类内容。模型接口提供 reasoning 时,会单独展示这部分流式输出;每次规划完成后,则会保留一段简短的公开决策说明。接口没有提供 reasoning 时,仍然可以展示工具进度和决策说明。历史记录保存的是步骤与公开摘要,reasoning 只留在当前页面,不会全部塞进对话历史。

为了让这些内容及时出现,也修复了 Next.js 代理压缩缓冲 SSE 小块数据的问题。后端分段发送之后,还要确认数据经过代理到达浏览器时,依然是逐段显示的。

Chat 与 Agent 模式的收敛

上篇里我区分了普通 RAG、固定流程的流式 Agent,以及动态选择工具的 research 模式。这周又做了一次调整,把在线入口统一成了 Chat 和 Agent。

Chat 结合视频摘要、近期对话和一轮检索直接回答;Agent 则使用同一套有边界的“规划—执行—观察”循环。同步请求和流式请求都走这套循环,区别主要在结果怎样返回。这样选择 Agent 之后,执行方式就比较明确了,不用再区分几个名字相近、实际行为不同的模式。

同时,上篇提到的独立 Claim/Evidence 账本、强制反向检索和像素复核流程,这次也从在线链路中移除了。现在仍然保留来源引用、视觉调查和原视频回放,最终回答选择的引用也要回到服务端已经取得的证据中核对。

这部分核对能约束引用的来源,防止模型随意填写未读取的证据。但它不再额外判断每个事实是否成立,也不能保证模型一定读对画面。这是当前版本和上篇相比需要讲清楚的变化。

工具调用本身也补了一些细节:给规划模型提供完整的参数结构,修复检索参数名和返回数量没有正确生效的问题。参数在工具执行前校验失败时,可以把错误交回模型纠正一次;这次失败仍然计入预算,权限和证据来源错误则不能靠重试绕过去。

vid-lens 当前系统架构,包含 Next.js 工作台、Go API、异步视频处理、Chat 与 Agent 及存储服务

当前系统架构:视频处理负责准备可检索的内容,Chat 与 Agent 在这些内容上完成问答与调查。

从单视频扩展到跨视频问答

之前的自主 Agent 主要在一个视频内工作。这次把同一套执行循环接到了知识库,模型可以在一组已授权的视频里检索,也可以指定其中一个视频继续调查。

例如,把两段讲同一主题的视频放进知识库,再问“它们的方案有什么区别”。这时需要分别找到两边的相关内容,组织回答时也要保留每个结论属于哪个视频。如果只找到了其中一边,就应该说明另一边还缺少依据。

检索这边也补上了集合范围的 BM25。原来的跨视频路径主要依赖向量召回,现在关键词检索可以在当前知识库的视频集合上计算,再与向量结果融合。像术语、参数名这类问题,也就有了关键词这一条召回路径。

多视频放在一起之后,来源关系会更重要。同样是“两分钟附近”,在不同视频中完全不是同一个位置,所以查看转写窗口、读取画面或补充抽帧时,都需要带上具体的视频标识。回答里的证据按视频分组,查看引用时也能跳回对应原视频。

范围也不能只在提问开始时检查一次。一次运行会保存当时的知识库成员集合,在后续规划、工具执行和保存答案时继续复查。如果中途移除了视频,旧运行就不能继续使用已经失效的范围。

另外,这次还补了两个和内容定位有关的地方。

一个是读取转写上下文时,把相邻片段的来源也一起加入当前证据集合。前面已经读到的补充内容,后面生成答案时才能继续引用。另一个是给模型提供有长度限制的视频地图,利用已有摘要和时间线,抽取分布在全片不同位置的定位信息,避免上下文里只剩开头一小段。

这个地图主要帮助决定去哪里找。需要回答具体问题时,仍然要检索或查看对应内容,不能把抽样摘要当作已经完整检查了整个视频。

多轮对话与长期偏好的完善

跨视频问答接起来之后,追问也需要继续处理。比如先比较两个方案,再问“那第二个方案有什么限制”,后一次请求需要知道“第二个”指什么,同时重新找到支持回答的证据。

这次把有长度和条数限制的近期对话接入了 Agent 的规划与最终生成,Chat 和 Agent 切换后也能利用当前会话的上下文。历史主要帮助理解指代和讨论对象,之前的助手回答仍然需要由当前视频证据核对。

知识库历史还多了一层来源检查。只有来源记录完整、并且相关视频仍在当前知识库里的问答对,才会进入后续上下文。如果某段回答使用过后来被移除的视频,就连同对应问题一起过滤,避免只删掉引用,正文里的旧信息却继续流入模型。

长期记忆上周已经有基础,仍然按用户和会话的设置启用。这周主要完善的是回答偏好和写入过程。

目前自动提取的范围比较明确,主要是语言、详略程度和回答格式。例如“以后默认用中文,回答简洁一点”,可以分别保存语言和详略偏好;“这次简短一点”这样的临时要求则留在当前对话。提取使用的是保守规则,对否定、引用和转述也做了过滤,复杂表达仍然可能识别不到。

同一个维度出现新的明确偏好时,会替换旧值,并保留来源和版本。后台迟到的旧任务不能覆盖更新的选择,也不能让已经撤回的记录重新生效。

写入侧改用了 PostgreSQL 中的持久任务,和成功保存的消息在同一个事务里提交,再由后台处理。这样服务重启后,尚未完成的任务仍然可以被找到和重试;真正写入前,还会再次检查用户授权和来源消息。

对我来说,这部分需要区分的状态很具体:任务已经排队、偏好已经保存、用户后来又关闭或撤回了记忆,分别对应不同的处理。偏好最后也只是影响回答方式,不能替代视频本身的内容。

执行预算与最终回答的预留

前面这些能力都需要调用模型和工具。如果只设置“最多执行几步”,还有可能出现一种情况:检索做了不少,到了最后组织回答的时候,时间或者 Token 已经用完了。

所以这次把 Agent 预算接到了用户的 AI Profile,可以配置工具调用次数、总执行时间、输入输出 Token 和视觉帧数。运行开始时会保存本轮使用的预算,后面修改配置,也不会悄悄改变已经开始的任务。

其中比较重要的一点,是提前给最终回答预留额度。每次继续规划前,都要考虑已有消耗、下一次调用的预计消耗,以及最后整理答案需要的资源。接近限制时,就停止继续扩展调查,转而根据已有证据回答,并说明还没有确认的部分。

时间预留也落实到了规划请求自身的截止时间里。否则只在两次调用之间检查,一次很慢的规划请求就可能把最后的时间全部占完。

如果规划输出因为长度限制被截断,也不会拿着半段参数继续调用工具,而是丢弃未完成决策,保留这次消耗,再尝试受限收尾。已经没有模型额度时,则保存已有证据摘录和缺口说明,界面显示有限结果。

这里的预留仍然算在总预算内,也不能保证一定得到完整答案。用量展示还区分了接口实际返回的数据和估算值,方便后面判断一次提问的成本主要花在哪里。

断流后的状态与结果恢复

另一个需要补齐的问题,是浏览器连接中断之后应该怎么办。

流式回答里,看到部分文字不代表答案已经保存;连接结束,也可能只是网络断开。如果前端直接认为失败,再重新发起一轮 Agent,就可能重复调用模型和工具。

所以现在前端会明确等待完成或错误事件。没有收到终态就断流时,会根据已经取得的运行标识查询后端状态和消息记录:如果答案已经保存,就取回保存的版本;如果仍在执行或已经失败,就展示对应状态。

这一步只查询已有结果,不会自动重新发起执行。刷新之后也可以查看持久化的步骤和运行状态;没有保存的部分正文与 reasoning,不能靠刷新恢复。

后端则继续按同一次运行去重保存问答,保存成功之后才发送完成事件。前端以这个事件里的最终文本为准,覆盖此前的流式内容,避免重复追加,也避免把还没有保存成功的文字当作完成结果。

上周已经做了执行记录和恢复的基础,这次主要是把它接到用户实际遇到的断流、刷新和历史消息显示上。

从检索诊断到反馈评测

功能多了以后,如果一次回答不理想,还需要知道问题出在哪一段。

这次加了一个独立的检索测试台,可以用同一个问题查看向量、关键词和混合检索的结果,以及融合、最终排序和耗时。它直接调用实际检索链路,省去最终答案生成,方便先检查相关内容有没有被找到。

答案侧则增加了反馈入口。对于已经保存的回答,可以标记有帮助,或者记录内容、引用、遗漏和速度方面的问题。反馈会关联到具体消息与运行,后续再看时,可以找回当时的回答、来源和预算信息。

这些问题还能导出为回归候选。不过一条负反馈本身不能直接说明正确答案是什么,需要有人回看来源,补充必须回答的要点和对应证据,再把它整理成可重复执行的用例。

产品评测入口也开始覆盖真实的 Chat 和 Agent 请求,并按顺序执行多轮问题,记录保存结果、引用、停止原因、耗时和用量。如果前一轮失败,就停止依赖它的后续追问,并保留这组用例的失败状态。

目前这些工作更多是在补齐诊断和回归的基础。一次请求成功结束、有引用、消息保存正常,都还不足以说明答案在语义上完整正确。后续需要持续拿具体视频和问题检查,尤其是跨视频比较里有没有遗漏一方,以及补看画面究竟提供了哪些有效信息。

上篇发出后还补了一些使用细节,包括知识库成员管理页面、历史会话切换和删除,以及视频标题编辑。ASR 生成的标题不合适时,可以直接修正,不需要为了改标题重新处理视频或重建索引。README 也更新了中英文说明、架构图和界面截图,方便从当前版本了解项目。

更新后的 vid-lens README,展示项目介绍和核心能力

更新后的 README,把当前项目介绍和核心能力集中整理了一遍。

写在最后

大概就是这些了,接下来的计划就是准备梳理一下项目,看怎么写简历吧,后面简历上应该就是放这一个 Agent 项目加上开源经历加上实习经历了,马上又要为找下一段实习准备了啊,真想找个 Agent / AI 应用开发的实习啊,希望能找到那种小而美的 Agent 初创收留我 😭

最后如果项目有什么想法的或者有什么问题的欢迎提 issue 和 pr 交流啊,最后再求求看到这里的友友给个 star 🌟,对我很有帮助 😭