智能体面试准备(五十三):多模态 Agent 工程实战------感知-决策闭环与 4MRAG 串联
引言:多模态 Agent 不是"LLM 加个看图接口"
B25 讲过多模态 Agent 的概念边界,B47 讲过 Agentic RAG 的自主知识工作流。但把多模态 Agent 真正工程化落地,最难的是"感知"和"决策"之间那道缝:模型看到的图像,怎么变成 Agent 可推理、可调用工具、可纠错的闭环?本篇是工程实战深化的第三讲,聚焦多模态 Agent 的感知-决策闭环,并把它和你的 4MRAG 项目(多模态检索增强生成)串起来讲------这既能体现技术深度,又能在面试里自然带出你的论文工作。
读完本篇,你应当能说清:视觉 grounding 怎么落进 Agent loop、Agent 怎么"主动决定看哪里"、多模态记忆怎么存、失败了怎么自我恢复。
文本 Agent 闭环
observe(text) -> think(LLM) -> act(tool_call) -> observe(result) -> ...
多模态 Agent 闭环(多一段感知)
perceive(image/video) -> ground(定位要素) -> think(LLM+多模态)
-> act(工具/导航/生成) -> perceive(新画面) -> 纠偏/续跑
关键差异:perceive 产出的是"带坐标/带置信度的结构化感知",而非裸图像
第一节 视觉 grounding:让 Agent "指得准"
1.1 grounding 的本质
LLM 输出的是 token,但 Agent 要操作的是"画面里第三排第二个按钮""图表左上角的标题"。把语言指代解析成空间坐标,就是视觉 grounding。常见两类:
- 检测式 grounding:给定文本 query,输出 bbox(边界框)。如 GLIP、Grounding DINO。
- 指代/点击式 grounding:给定图像和指令,输出点/框/掩码。如 Set-of-Mark(SoM,给每个可交互元素打标号,让 LLM 只输出编号)。
1.2 Set-of-Mark 的工程价值
SoM 的核心巧思:不要在像素层面让 LLM 直接回归坐标(又慢又不准),而是先对图像里的可交互元素做实例分割并打上可见编号(① ② ③...),再把"带编号的图"连同任务给 VLM。LLM 只需输出"点击 ③",定位由编号映射回原坐标完成。这把"视觉定位"转化成了"从离散编号里做选择",大幅降低出错率。
SoM 流程
原始图 -> 实例分割 -> 给每个元素画框+编号 -> 带编号图喂 VLM
VLM 输出: "点击 ③" -> 编号映射 -> 真实坐标 (x,y) -> 执行器点击
# Set-of-Mark 最简示意
def set_of_mark(image, detector):
masks = detector.segment(image) # 实例分割
annotated = image.copy()
mark_map = {}
for i, m in enumerate(masks, start=1):
annotated = draw_box(annotated, m, label=f"{i}")
mark_map[i] = m.centroid() # 编号 -> 真实坐标
return annotated, mark_map
def act_on_mark(vlm_decision: str, mark_map):
num = parse_number(vlm_decision) # "点击 ③" -> 3
return mark_map[num] # 真实 (x,y)
第二节 主动感知:Agent 该"看哪里、何时重看"
2.1 被动看 vs 主动看
朴素多模态 Agent 是"把当前画面一股脑塞给 VLM"。但长任务里画面会变、关键信息可能不在当前帧。主动感知要求 Agent 在 think 阶段显式决策:需要看哪块区域、需要重新截取哪个窗口、是否需要放大。
2.2 用工具调用表达"看"
把"看"也建模成 tool。Agent 的 action 空间里除了 click/type,还有 zoom(region)、crop(box)、reobserve()。这样"感知"和"决策"在同一套 ReAct 循环里统一表达,可追溯、可重放。
think -> [action: zoom(图表标题区)] -> perceive(放大图) -> think(读出数值)
-> [action: click(③)] -> perceive(新页面) -> think(校验) -> ...
2.3 与 4MRAG 的天然衔接
你的 4MRAG 是多模态检索增强生成:给定复杂多模态问题,先规划要检索哪些模态(文本/表格/图像/图表),再用对应检索器取回证据,最后生成答案。把它包成 Agent 的一个"知识工具",主动感知就变成了"主动决定检索哪个模态、检索哪段"------这正是 4MRAG 的规划器在做的事。面试里可以讲:我的 Agent 不只是看屏幕,它还会"主动决定去知识库里看哪张图、哪张表",感知从"看画面"扩展到"看多模态证据"。
| 感知模式 | 输入 | 决策主体 | 典型失败 | 缓解 |
|---|---|---|---|---|
| 被动全图 | 整帧 | 无(全喂) | 关键细节被淹没 | 区域裁剪 |
| SoM 编号 | 带编号图 | VLM 选编号 | 编号遗漏 | 重分割 |
| 主动 zoom/crop | 子区域 | Agent 规划 | 看错区域 | 校验+重看 |
| 4MRAG 检索 | 多模态证据 | 规划器 | 模态选错 | 按需组合检索器 |
第三节 多模态记忆:图像和视频怎么存、怎么取
3.1 为什么不能只存文本
文本 Agent 的记忆是"对话历史 + 摘要",天然可检索。但多模态 Agent 还要记住"之前看到的那张图里第三个柱子的数值""那段视频第 12 秒出现的车牌"。直接存原始像素既不经济也不可检索。
3.2 结构化多模态记忆
工程上常用三层:
-
原始层:图像/视频片段原文件,按 ID 存对象存储,只保留引用;
-
表征层:用 ViT/CLIP 编码成向量,支持"以图搜图""相似画面召回";
-
语义层:把画面里的关键实体、数值、文字(OCR)抽成结构化字段,支持关键词/SQL 检索。
多模态记忆架构
画面 -> OCR(文字) + 检测(实体/数值) + CLIP向量
-> 写入 [语义字段库] + [向量库] + [原图引用]
取用: 文本问题 -> 先语义/向量召回 -> 再用原图做精细 grounding多模态记忆写入示意
class MultiModalMemory:
def add(self, frame_id, image):
text = ocr(image) # 文字层
entities = detector.detect(image) # 实体/数值层
vec = clip.encode_image(image) # 向量层
self.kv.put(frame_id, {"text": text, "entities": entities})
self.vec_db.add(frame_id, vec)
self.store.put(frame_id, image) # 原图引用
def recall(self, query):
ids = self.vec_db.search(clip.encode_text(query), k=5)
return [self.kv.get(i) for i in ids]
第四节 失败恢复:检测到错了怎么兜回来
4.1 多模态特有的失败模式
- 看错:grounding 把"③"映射到错误元素,点了不该点的地方;
- 读错:OCR 把"1,234"读成"1234",或图表坐标轴误读;
- 看漏:关键信息在没截取到的区域,Agent 基于残缺信息决策。
4.2 恢复策略
策略一:状态校验。每个 action 执行后,重新 perceive 当前画面,用断言检查"预期状态是否达成"(如"应该进入结算页")。不达成则进入恢复分支。
策略二:回滚到检查点。长任务里周期性存"画面快照 + 决策点",失败时可回退到上一个稳定检查点重规划,而不是从零开始。
策略三:降级到人工/澄清。连续两次失败后,抛出 HITL 请求(B27),或反问用户"你指的是哪个元素?"。
失败恢复闭环
act -> perceive(校验) -> [断言通过] 续跑
-> [断言失败] -> 回滚检查点 / 反问澄清 / 换检索模态
第五节 一个可落地的多模态 Agent 工程骨架
把前面四节拼起来,就是一个最小可用的多模态 Agent 循环。下面给出骨架(伪代码),重点看"感知、决策、校验"三件事如何在同一循环里闭环。
class MultiModalAgent:
def __init__(self, vlm, tools, memory, four_mrag):
self.vlm = vlm; self.tools = tools
self.memory = memory; self.mrag = four_mrag
def step(self, obs):
# 1. 感知: 把画面转成可操作的结构化表示
annotated, mark_map = set_of_mark(obs.image, self.detector)
# 2. 决策: 把历史+当前感知+工具描述喂给 VLM
decision = self.vlm.decide(history=self.memory.recent(),
image=annotated, tools=self.tools.spec())
# 3. 执行: 若是"看知识库", 调 4MRAG; 若是"点", 映射坐标
if decision.tool == "four_mrag":
evidence = self.mrag.query(decision.arg) # 跨模态检索
self.memory.add_evidence(evidence)
elif decision.tool == "click":
coord = mark_map[decision.mark]
self.tools.click(coord)
# 4. 校验: 重新感知, 断言预期状态
new_obs = self.perceive()
if not self.assert_state(decision.expect, new_obs):
return self.recover(decision, new_obs) # 回滚/重规划
self.memory.append(obs, decision, new_obs)
return decision
def recover(self, decision, obs):
# 连续失败则升级为人工澄清
self.retry += 1
if self.retry >= 2:
return self.tools.ask_human("你指的是哪个元素?")
return self.step(self.rollback_checkpoint()) # 回退到检查点
这个骨架的工程要点有三个:第一,perceive 永远在决策之前,保证 Agent "看见的是最新的";第二,每个 action 后都有 assert_state 校验,而不是默认成功;第三,recover 把"失败"当成一等公民处理,长任务才扛得住。面试里能把这三点讲清楚,基本就超出大多数候选人的水平。
第六节 多模态 Agent 的七个工程坑
坑一:坐标漂移。屏幕分辨率、缩放比、滚动偏移都会让 grounding 坐标失效。必须对截图环境做标准化(固定分辨率/无滚动窗口),或每次感知都基于当前可见帧重算坐标。
坑二:OCR 幻觉。OCR 对模糊、倾斜、特殊字体极易读错,且 VLM 会"自信地"沿用错误数字。缓解:关键数值二次校验(如从表格结构里取而不是直接读图)、重要字段要求结构化抽取而非自由文本。
坑三:上下文膨胀。每帧画面编码成几百 token,多轮下来上下文被图像 token 撑爆。必须靠多模态记忆(第三节)把"看过的"沉淀成结构化字段,而不是把原始帧全塞进对话历史。
坑四:感知与决策不同步。Agent 基于"三秒前的画面"做了决策,但执行时画面已变。务必在执行前重新 perceive,或给 action 加"前置状态断言"。
坑五:4MRAG 返回证据过多。检索器返回一堆图文证据,直接全喂 VLM 同样撑爆上下文。需要重排(rerank)取 top-k,并把证据做成"可被引用"的结构(带出处),方便后续溯源。
坑六:恢复循环死锁。recover 里又失败又 recover,无限套娃。必须设最大重试和"升级人工"的硬出口,否则任务永远卡住。
坑七:不可重放难调试。多模态交互天然难复现(画面随时间变)。工程上要把每轮的"画面快照 + 决策 + 断言结果"落日志,出问题能回放定位,而不是靠猜。
第七节 与 4MRAG 的项目串联话术(面试可直接用)
把上面四节收进你的项目叙事,建议这样串:我的 4MRAG 解决"复杂多模态问题需要跨模态证据"的痛点,规划器决定检索哪些模态、用哪些检索器;而多模态 Agent 是这个能力的"执行外壳"------它既能感知屏幕(SoM grounding、主动 zoom),又能调用 4MRAG 作为知识工具去"看"知识库里的图与表,还能在取证后做失败恢复。二者结合,Agent 不是盲看屏幕,而是"带着检索增强的视野"去感知和决策。这段把论文工作和 Agent 工程自然打通,是面试里的差异化亮点。
面试速答(本篇可直接背的 3 句)
- 多模态 Agent 比文本 Agent 多一段"感知",关键不是喂图,而是把感知变成"带坐标/带置信度的结构化输出"(如 SoM 编号),才能被决策和工具调用消费。
- 主动感知把"看"建模成 tool(zoom/crop/reobserve/4MRAG 检索),让感知和决策在同一套 ReAct 循环里统一表达、可追溯可重放。
- 多模态记忆要分三层(原图引用 + CLIP 向量 + 语义字段),失败恢复靠"执行后校验 + 检查点回滚 + 必要时 HITL",而不是赌一次看对。
高频追问清单
- Set-of-Mark 和直接让 VLM 输出坐标相比,除了准确率还有什么工程好处?(提示:可重放、可审计)
- Agent 主动决定"看哪块区域",这个决策本身可能出错,怎么防?(提示:校验+回滚)
- 4MRAG 作为工具被 Agent 调用,返回的证据怎么和当前画面做对齐?
- 多模态记忆里 CLIP 向量和 OCR 文字,召回时怎么融合排序?
- 长视频 Agent 里,记忆窗口放不下全部帧,怎么做"关键帧摘要"?
- 失败恢复的检查点存在哪?状态快照包含哪些字段?怎么保证可重放?