1. 从单模态到多模态:Agent 感知能力的质变
1.1 为什么纯文本 Agent 越来越不够用
过去两年我一直在做 Agent 相关的开发,最开始接触的都是纯文本场景——用户输入一段话,模型理解意图,调用工具,返回结果。这套链路跑通之后确实能解决不少问题,比如自动整理会议纪要、根据需求生成代码片段、帮用户做信息检索和摘要。但做着做着就发现,真实业务场景里纯文本的局限性太大了。
举个很典型的例子。用户发来一张产品包装的照片,问“这个配料表里有没有反式脂肪”。纯文本 Agent 拿到的是图片的 URL 或者文件路径,它没法直接“看”到图片内容,只能依赖 OCR 先做文字提取,然后再把提取结果喂给语言模型去判断。这个链路的问题在于:OCR 可能识别错,配料表的排版可能是多栏的,OCR 出来的文字顺序会乱,模型拿到乱序的文字就可能判断失误。更麻烦的是,用户可能拍的是货架上一排产品,问“哪个含糖量最低”,这时候需要的不只是文字识别,还要理解空间位置关系、对比不同产品的标签信息。
多模态能力解决的就是这类问题。模型可以直接处理图像、音频、视频等多种输入形式,不再需要“先转文字再理解”这种间接路径。对于 Agent 来说,这意味着它能感知的信息维度从一维变成了多维,能处理的任务类型也一下子拓宽了。
1.2 多模态在 Agent 架构中的实际位置
我在实际项目中把多模态能力放在 Agent 的“感知层”。整个 Agent 架构大致可以分成四层:感知层负责接收和理解多模态输入,决策层负责推理和规划,执行层负责调用工具和 API,记忆层负责存储和检索历史信息。多模态主要影响的是感知层和决策层的交互方式。
传统的做法是感知层把图像转成文字描述,再交给决策层。但这样做有个信息损耗的问题——图像里的颜色、布局、表情、手势这些非文字信息在转成文字描述时会大量丢失。多模态模型可以直接把原始图像特征和文本特征在同一个语义空间里做对齐,决策层拿到的是更完整的信息。
我实测下来,在商品识别、文档理解、界面操作这几个场景里,直接使用多模态输入比“先转文字”的方案准确率能高出不少。当然代价是推理成本更高,响应速度也会慢一些,这个后面会详细说。
1.3 多模态 Agent 的典型应用场景拆解
从我这边的项目经验来看,多模态 Agent 目前落地比较多的场景有这么几类:
第一类是文档智能处理。比如合同审核、发票识别、报表分析。这类场景的特点是文档结构复杂,有表格、有印章、有手写签名,纯文本方案很难处理。多模态模型可以同时理解文字内容和版面结构,把表格的行列关系、印章的位置和类型都纳入判断。
第二类是界面自动化操作。比如让 Agent 帮用户在 App 里完成一系列操作。传统方案是靠无障碍服务的控件树来定位元素,但很多 App 的控件树信息不全或者层级混乱。多模态方案可以直接“看”屏幕截图,理解按钮、输入框、列表的位置和功能,然后模拟点击和输入。这个方向目前还比较早期,但潜力很大。
第三类是内容审核与理解。比如电商平台的商品图片审核、社交媒体的视频内容理解。这类场景需要同时处理图像、文字、音频等多种模态,判断是否存在违规内容。多模态 Agent 可以把不同模态的信息综合起来做判断,比单模态方案更准确。
第四类是教育和辅助场景。比如拍照搜题、作业批改、实验操作指导。学生拍一张题目照片,Agent 需要理解题目中的文字、公式、图形,然后给出解题步骤。这里面公式和图形的理解是纯文本方案做不到的。
2. Harness 工程:让 Agent 稳定跑起来的关键
2.1 Harness 到底是什么,为什么需要它
Harness 这个词在 Agent 开发圈里最近被提得很多,但很多人对它的理解还比较模糊。我自己的理解是:Harness 是包裹在模型外面的一层工程框架,负责管理模型的输入输出、工具调用、状态维护、错误处理、安全约束等一系列“模型本身不管但实际运行必须要有”的事情。
打个比方,模型就像一台发动机,Harness 就是底盘、传动系统、仪表盘和刹车。发动机再好,没有这些东西也跑不起来,更别说稳定运行了。我在早期做 Agent 的时候,很多逻辑是散落在业务代码里的——工具调用的重试逻辑写一遍,超时处理写一遍,输出格式校验写一遍,结果就是代码越来越乱,改一个地方容易影响到另一个地方。后来把这些通用逻辑抽出来做成 Harness 层,整个架构就清晰多了。
Harness 要解决的核心问题包括:模型输出的解析和校验、工具调用的编排和重试、多轮对话的状态管理、异常情况的降级处理、以及安全边界的控制。这些东西看起来都是“脏活累活”,但少了它们,Agent 在生产环境里根本跑不稳。
2.2 Harness 的核心模块拆解
我目前用的 Harness 框架大致包含这几个模块:
输入预处理模块。负责把用户的原始输入转换成模型能理解的格式。如果是多模态输入,这里要做图像压缩、音频转码、视频抽帧等处理。如果是文本输入,要做敏感词过滤、长度截断、格式规范化。这个模块的要点是“无损转换”——尽量保留原始信息,不要在这一步丢太多东西。
提示词组装模块。负责根据当前任务类型、历史对话、可用工具列表,动态组装系统提示词和用户提示词。这个模块的设计直接影响到模型的输出质量。我的经验是把提示词拆成几个部分:角色定义、任务描述、工具说明、输出格式要求、约束条件。每个部分单独维护,组装时按需拼接。
输出解析模块。负责把模型的原始输出解析成结构化数据。如果模型输出的是 JSON,要处理 JSON 解析失败的情况;如果模型输出的是工具调用指令,要提取工具名和参数;如果模型输出的是自然语言,要判断是否需要进一步处理。这个模块的鲁棒性很关键,因为模型输出格式不稳定是常态。
工具调用编排模块。负责管理工具调用的整个生命周期:参数校验、调用执行、超时控制、结果处理、失败重试。这里有个容易踩的坑是工具调用的并发控制——有些工具不能并发调用,有些工具需要串行执行,有些工具可以并行但需要限制并发数。这些策略都要在 Harness 层配置好。
状态管理模块。负责维护对话历史、工具调用记录、中间结果等状态信息。这个模块的设计要考虑上下文窗口的限制,不能把所有历史都塞给模型。我的做法是分层存储:最近几轮对话保留完整内容,较早的对话做摘要压缩,工具调用结果只保留关键信息。
安全与合规模块。负责检查输入输出是否符合安全规范,拦截敏感内容,记录审计日志。这个模块在生产环境里是必须的,尤其是面向 C 端用户的产品。
2.3 Harness 设计中的几个关键取舍
做 Harness 设计的时候,有几个取舍点我反复纠结过,这里分享一下我的思考过程。
第一个取舍是“重 Harness 还是轻 Harness”。重 Harness 意味着把更多逻辑放在框架层,业务代码只负责定义任务和工具;轻 Harness 意味着框架只做最基础的封装,更多逻辑留给业务代码自己处理。我一开始倾向于轻 Harness,觉得灵活度高。但项目多了之后发现,每个项目都在重复实现类似的逻辑,而且实现质量参差不齐。后来转向重 Harness,把通用逻辑都收拢到框架层,业务代码变得很薄,维护成本反而降低了。
第二个取舍是“同步还是异步”。同步模式下,Agent 处理完一个请求才处理下一个,实现简单但吞吐量低。异步模式下,多个请求可以并发处理,但状态管理和错误处理会复杂很多。我的选择是核心链路用异步,但对外暴露同步接口。这样内部可以充分利用并发能力,外部调用方不用关心异步细节。
第三个取舍是“集中式还是分布式”。集中式 Harness 把所有模块跑在一个进程里,部署简单但扩展性差。分布式 Harness 把不同模块拆成独立服务,扩展性好但运维复杂。我目前用的是“逻辑集中、物理分布”的方案——代码层面是一个整体,但部署时可以按模块拆分。这样小规模场景下可以单机部署,大规模场景下可以水平扩展。
3. MCP 协议:Agent 工具调用的标准化尝试
3.1 MCP 要解决的核心问题
MCP 全称是 Model Context Protocol,是一个面向 Agent 工具调用的标准化协议。它要解决的核心问题是:不同的 Agent 框架、不同的模型、不同的工具之间,缺乏统一的交互标准,导致每接一个新工具就要写一套适配代码,每换一个模型就要改一遍工具调用逻辑。
这个问题我在实际项目中感受很深。早期做 Agent 的时候,每接一个外部 API 就要写一个专门的工具描述文件,定义工具名、参数格式、返回值格式、错误码。不同项目的工具描述格式还不一样,有的用 JSON Schema,有的用自定义的 YAML,有的直接写在提示词里。结果就是工具复用率很低,换个项目就要重新写一遍。
MCP 的思路是把工具的定义、调用、结果返回都标准化。工具提供方按照 MCP 规范暴露自己的能力,Agent 框架按照 MCP 规范发现和调用工具。这样工具和 Agent 之间就解耦了,一个工具可以被多个 Agent 使用,一个 Agent 也可以接入多个工具源。
3.2 MCP 的核心概念与工作流程
MCP 的核心概念包括几个部分:
Server 和 Client。MCP Server 是工具提供方,负责暴露工具能力;MCP Client 是工具使用方,通常是 Agent 框架。两者之间通过标准协议通信。
Resources 和 Tools。Resources 是 Server 暴露的数据资源,比如文件、数据库记录、API 返回的数据;Tools 是 Server 暴露的可执行操作,比如发送邮件、创建任务、查询信息。Agent 可以读取 Resources 来获取上下文,也可以调用 Tools 来执行操作。
Prompts。Server 可以预定义一些提示词模板,Client 可以直接使用这些模板来引导模型输出。这个设计的好处是把领域知识封装在 Server 侧,Client 不需要了解具体业务的提示词怎么写。
工作流程大致是这样的:Agent 启动时连接到 MCP Server,获取可用的 Resources 和 Tools 列表;用户发起请求后,Agent 根据请求内容决定需要哪些上下文和工具;Agent 从 Server 读取 Resources,组装提示词,调用模型;模型返回工具调用指令后,Agent 通过 MCP 协议调用对应的 Tool;Server 执行工具并返回结果,Agent 把结果喂回模型继续推理。
3.3 MCP 在实际项目中的落地经验
我在一个内部知识助手项目里试过 MCP 方案,整体感受是“方向对,但生态还在早期”。
好处很明显:工具接入变得标准化了,以前接一个内部 API 要写半天的适配代码,现在按照 MCP 规范暴露一下就行。工具复用也方便了,同一个数据库查询工具可以在多个 Agent 项目里直接使用,不用重复开发。
但问题也有不少。首先是 MCP Server 的部署和运维需要额外的工作量,每个工具源都要跑一个 Server 进程,进程管理、健康检查、日志收集这些都要做。其次是协议本身的成熟度还不够,有些边界情况没有明确定义,不同实现之间会有兼容性问题。还有就是性能开销,多了一层协议通信,延迟会比直接调用高一些。
我的建议是:如果你的 Agent 项目需要接入大量外部工具,而且这些工具需要在多个项目间复用,那 MCP 值得投入。如果只是接几个内部 API,直接用函数调用或者 HTTP 请求可能更简单。
4. 多模态、Harness、MCP 三者的协同关系
4.1 三者在 Agent 架构中的分工
把这三个东西放在一起看,它们各自解决的是 Agent 开发中不同层面的问题。
多模态解决的是“感知”问题——让 Agent 能看懂图片、听懂音频、理解视频。这是输入侧的扩展。
Harness 解决的是“运行”问题——让 Agent 的推理、工具调用、状态管理、错误处理能稳定运行。这是控制侧的工程。
MCP 解决的是“连接”问题——让 Agent 和外部工具之间的交互有标准可循。这是输出侧的规范。
三者之间的关系是:多模态输入经过 Harness 的处理和编排,通过 MCP 协议调用外部工具,工具返回的结果再经过 Harness 处理,最终输出给用户。Harness 是中枢,多模态是输入增强,MCP 是输出扩展。
4.2 实际项目中的协同案例
我拿一个具体的项目场景来说明三者的协同。假设我们要做一个“智能客服 Agent”,用户可以通过文字、图片、语音多种方式描述问题。
用户发来一张产品故障的照片,配了一段语音说明。多模态能力负责把图片和语音都转成模型能理解的输入。Harness 负责管理整个处理流程:先做输入预处理,把图片压缩到合适尺寸,把语音转成文字;然后组装提示词,把图片特征和文字描述一起喂给模型;模型判断需要查询产品信息和故障知识库,Harness 通过 MCP 协议调用对应的工具;工具返回结果后,Harness 把结果和原始输入一起喂回模型,生成最终回复。
这个流程里,多模态让 Agent 能理解图片和语音,Harness 让整个流程可控可观测,MCP 让工具调用标准化。三者缺一不可。
4.3 协同中的性能与成本考量
三者协同带来的一个直接问题是性能和成本。多模态推理比纯文本推理贵很多,Harness 的编排逻辑会增加延迟,MCP 的协议通信也有开销。这些加起来,端到端的响应时间可能会比简单方案慢好几倍。
我的优化策略是分层处理:对于简单请求,走轻量链路,不做多模态处理,不经过复杂的 Harness 编排,直接调用模型和工具;对于复杂请求,才走完整链路。判断逻辑放在 Harness 的入口处,根据请求的复杂度动态选择处理路径。
成本控制方面,多模态输入要做压缩和采样,不要把所有原始数据都传给模型。Harness 要记录每个环节的耗时和成本,方便定位优化点。MCP 工具调用要做缓存,相同参数的调用可以直接返回缓存结果。
5. 实操中的常见问题与排查技巧
5.1 多模态输入处理的典型坑
图片尺寸和格式问题。不同模型对输入图片的尺寸和格式要求不一样,有的要求长边不超过 1024 像素,有的要求必须是 JPEG 格式。如果直接传原始图片,可能会被模型拒绝或者效果很差。我的做法是在 Harness 的输入预处理模块里统一做图片规范化:统一转成 JPEG,长边压缩到模型支持的最大尺寸,同时保留原始图片的备份以便排查问题。
多图输入的顺序问题。当用户上传多张图片时,图片的顺序会影响模型的判断。比如用户上传了三张图,分别是产品正面、背面、侧面,如果顺序乱了,模型可能会混淆。我的做法是在提示词里明确标注每张图片的编号和描述,让模型知道每张图对应什么。
音频转文字的准确率问题。语音输入转文字这一步,如果准确率不高,后面的推理都会受影响。我的经验是不要完全依赖自动转写,对于关键信息(比如数字、专有名词)要在提示词里提醒模型注意核对。另外,音频的质量也很重要,背景噪音大的音频转写准确率会明显下降。
5.2 Harness 运行中的常见故障
工具调用超时。这是最常见的故障之一。外部 API 响应慢或者不可用,导致整个 Agent 卡住。我的处理策略是设置分级超时:单个工具调用超时时间短一些(比如 10 秒),整个请求的超时时间长一些(比如 60 秒)。单个工具超时后可以重试或者降级,整个请求超时后返回兜底回复。
模型输出格式错误。模型有时候不按要求的格式输出,比如要求输出 JSON 但输出了带 markdown 标记的 JSON,或者 JSON 里少了某个字段。Harness 的输出解析模块要能处理这些情况:先尝试直接解析,失败后尝试提取 JSON 片段,再失败后尝试用模型重新生成。同时要记录这些异常情况,方便后续优化提示词。
上下文窗口溢出。多轮对话加上工具调用结果,很容易超出模型的上下文窗口限制。我的做法是在 Harness 的状态管理模块里做上下文压缩:保留最近 N 轮完整对话,更早的对话做摘要,工具调用结果只保留关键字段。压缩策略要根据任务类型调整,不能一刀切。
5.3 MCP 接入的排查清单
| 问题现象 | 可能原因 | 排查方法 |
|---|---|---|
| 连接 MCP Server 失败 | Server 未启动或地址配置错误 | 检查 Server 进程状态和网络连通性 |
| 工具列表为空 | Server 未正确注册工具 | 查看 Server 日志,确认工具注册逻辑 |
| 工具调用返回错误 | 参数格式不匹配 | 对比工具定义的参数 schema 和实际传参 |
| 调用延迟高 | 网络问题或 Server 负载高 | 检查网络延迟和 Server 资源使用情况 |
| 结果解析失败 | 返回格式与预期不符 | 查看原始返回内容,确认协议版本兼容性 |
5.4 我的避坑经验总结
做了这么多 Agent 项目,踩过的坑确实不少,这里挑几个最有代表性的分享一下。
不要过早引入复杂框架。我一开始做 Agent 的时候,上来就想搭一套完整的 Harness 框架,结果花了很多时间在设计上,实际功能没做多少。后来调整策略,先用最简单的方案把核心链路跑通,遇到问题再逐步抽象和封装。这样迭代速度反而更快。
多模态不是万能的。有些场景用纯文本方案加 OCR 就够了,没必要上多模态。多模态的成本和延迟都更高,只有在纯文本方案确实解决不了的时候才值得用。判断标准很简单:如果 OCR 加文本理解的准确率能满足业务要求,就不要用多模态。
MCP 的生态还在早期。目前 MCP 的规范和工具链还不够成熟,接入过程中可能会遇到各种兼容性问题。如果项目时间紧,建议先用传统的函数调用方案,等 MCP 生态更完善了再迁移。
日志和监控要提前做。Agent 的运行过程比传统程序复杂很多,没有完善的日志和监控,出了问题很难排查。我的做法是在 Harness 的每个关键节点都打日志,记录输入输出、耗时、错误信息。同时做监控看板,实时展示请求量、成功率、平均延迟等指标。
测试用例要覆盖边界情况。Agent 的输入空间很大,正常情况的测试很容易过,但边界情况往往出问题。我的测试用例里会专门覆盖:空输入、超长输入、格式错误的输入、包含特殊字符的输入、多模态混合输入等。这些用例能提前发现很多潜在问题。
6. 从项目实践看技术选型与演进方向
6.1 当前阶段的技术选型建议
如果你现在要开始做一个 Agent 项目,我的选型建议是这样的:
模型层面,优先选择支持多模态的模型,即使当前只需要文本能力,后续扩展也方便。如果成本敏感,可以用“文本模型为主、多模态模型为辅”的混合方案,只在需要处理图像音频时才调用多模态模型。
Harness 层面,如果团队规模小、项目少,可以先用轻量封装,把最核心的输出解析和工具调用逻辑抽出来就行。如果团队规模大、项目多,建议投入做一套完整的 Harness 框架,长期来看能省很多重复工作。
工具接入层面,如果工具数量少且固定,直接用函数调用最简单。如果工具数量多、需要跨项目复用,可以尝试 MCP 方案,但要预留足够的调试和适配时间。
6.2 我观察到的几个演进方向
从我这边的项目经验和技术社区的趋势来看,Agent 开发有几个方向值得关注。
多模态能力的进一步融合。目前多模态主要还是“理解”层面,即看懂图片和音频。下一步可能会向“生成”层面扩展,Agent 不仅能理解多模态输入,还能生成多模态输出,比如直接生成图表、示意图、语音回复等。
Harness 的标准化和产品化。目前 Harness 还是各团队自己搭,未来可能会出现标准化的 Harness 产品或者开源框架,把通用能力封装好,开发者只需要关注业务逻辑。
MCP 生态的完善。如果 MCP 能形成类似 HTTP 那样的生态,各种工具和服务都按照 MCP 规范暴露能力,Agent 开发的门槛会大幅降低。但这需要时间,也需要更多厂商和开发者的参与。
Agent 的可观测性增强。目前 Agent 的运行过程还是比较黑盒,出了问题不好排查。未来可能会有更完善的可观测性工具,能追踪每个决策步骤、每个工具调用的输入输出、每个环节的耗时和成本。
6.3 给刚入门的开发者的建议
如果你是刚接触 Agent 开发,我的建议是从小场景入手,不要一上来就做通用 Agent。选一个具体的、边界清晰的任务,比如“根据用户描述查询订单状态”,把这条链路跑通,理解 Agent 的基本工作原理。然后再逐步扩展能力,加入多模态、加入更多工具、加入更复杂的 Harness 逻辑。
另外,多看看开源项目和社区讨论,但不要盲目跟风。新技术出来的时候,先想清楚它解决的是什么问题,你的项目是否真的需要。很多时候,简单的方案反而更可靠。
我在实际项目中的体会是,Agent 开发最难的不是模型调用,而是工程化——怎么让整个系统稳定、可观测、可维护、可扩展。多模态、Harness、MCP 这些都是手段,最终目标都是让 Agent 能真正解决实际问题。技术选型的时候,始终要回到这个目标上来判断。