
说实话今年云栖我坐在场下看到“湖生万物助力 AI——面向 Agent 的全模态数据平台”这个主题时第一反应不是兴奋是松一口气。做了一年多的 Agent 应用我最大的体感是Agent 好不好用靠的不只是大模型的聪明程度而是它背后有没有一块能干、够宽、能及时把数据喂到嘴边的平台。这次的主题刚好把“AI 应用中数据到底该怎么组织”这件事提到了台面上。这篇内容我想从一个一线做数据平台和 Agent 应用的人的角度聊聊全模态数据平台到底在解决什么问题、为什么说“湖生万物”这个提法不是炒概念以及如果你也想搭一个面向 Agent 的数据底座有哪些核心设计、实操路径和坑是绕不开的。适合三类人看正在做 Agent 应用开发的人、负责数据平台建设的技术同学、以及想搞清楚“AI 落地数据层该长什么样”的产品负责人。1. 从云栖开头说起“湖生万物”到底在讲什么1.1 我看完这场主题后的整体感受先说结论这次提出来的“湖生万物”核心不是说数据湖本身有多厉害而是把数据湖从一个“被动存数据的地方”升级成一个“主动喂数据给 AI 的引擎”。这个转变对于做 Agent 的人来说非常重要。过去我们谈起数据湖下意识想到的是结构化和非结构化文件的离线归档、批处理作业、数仓建模这些偏传统的场景。但这次主题里的关键变量是“助力 AI”尤其是助力 Agent。Agent 和传统应用的区别在于它不是按固定规则调数据而是根据用户的一句话意图自己决定去读哪些资料、调哪些工具、组合哪些信息来完成任务。这意味着数据平台不能再等业务系统把数据整理好送上门它必须自己具备“数据可被 Agent 理解、可被检索、可被上下文化”的能力。“湖生万物”里面的“生”字我理解有两层意思。第一层是生成数据湖作为底座可以源源不断生成训练数据、评测数据、业务知识数据。第二层是生长数据平台像土壤一样让 Agent 应用这棵树上结出不同业务果实。所以它不只是一个存储概念而是一个以数据湖为核心、专门为 AI 场景重构过的数据基础设施。1.2 全模态数据平台这个概念怎么理解“全模态”这个词听起来有点绕但说白了就是把文本、表格、图片、音视频、代码、以及各类传感器和业务系统里的结构化数据全部放到同一套平台上来管理。结合 Agent 的实际使用场景其实很好理解。你让一个 Agent 帮你做行业调研它不仅要能读几十份 PDF 文档还要看得懂图表、听得了会议录音、查得动数据库里的事实数据。传统的数仓擅长结构化数据传统的非结构化存储擅长文件备份但两边是割裂的。结果就是 Agent 想要一次完整地组织一场跨模态的信息检索通常需要开发人员 manually 做大量数据搬运和格式转换工作。全模态数据平台的价值就是把这个割裂打破。它让各模态的数据在底层统一存储、统一元数据管理同时对外提供统一的访问和检索接口。这样 Agent 拿到的就不是一堆孤立的文件而是一张可以跨模态关联、可以按语义查询、可以随时被拉进上下文的“数据网”。这也是我读这场分享时觉得最值得记录的核心点。2. 全模态数据平台的架构设计思路2.1 传统数据方案的核心痛点数据是有的但不好“用”我在过往的项目里踩过不少传统架构的坑。典型的场景是这样的业务方要求做一个企业知识库 Agent能回答员工关于制度、报销、合同、培训材料等问题。我们当时的方案是把所有文档丢进一个对象存储然后用向量数据库做召回。刚上线的时候还行但用着用着问题就来了。第一个问题是模态割裂。员工的真实问题往往是复合的比如“上个月某项目的预算执行情况怎么样”这需要同时检索项目文档、结构化预算表、甚至会议纪要。但我们的设计里文档走向量库表格走 SQL 查询和 BI 报表语音纪要又在另一个系统里。结果就是 Agent 需要写一堆分支逻辑去判断该先查哪个系统再手工拼接结果开发效率极低效果还不稳定。第二个问题是数据缺乏语义级管理。对象存储里的文件只能通过文件名和路径定位一旦文件命名混乱或者时间久远Agent 根本不知道资料库里有什么更别提精准调用。传统元数据管理只管“文件大小、更新时间、作者”这类物理属性没有表达“这个文件的主题是什么、和哪个项目相关、可以回答什么问题”。全模态数据平台要做的第一步其实就是把这一层语义目录补上。2.2 平台的分层逻辑存储、处理、服务三层都要向 Agent 对齐结合这次云栖的内容和我自己实践下来比较顺手的架构可以把全模态数据平台拆成三层来看存储层负责把各模态数据统一收进来。底层是对象存储或云上的分布式存储数据格式上建议采用 Iceberg、Hudi、Delta 这类开放表格式。它们带来的好处是事务、快照和时间旅行能力这让 Agent 应用可以拿到某个历史时点的数据快照而不只是最新状态。另外图片、音视频等文件也需要保留原始字节流做后续重新处理和特征提取。处理层解决的是“让原始数据变成 Agent 能消费的资产”。这里包含几个关键工序数据解析与结构化。PDF、Word、网页、音视频转写等把非结构化内容抽成一段段可索引的文本块。实体与关系抽取。从文档中识别项目、人名、时间、金额等实体并构建图谱关系。这对 Agent 回答“谁负责什么”“哪个项目涉及哪些人”这类问题特别关键。向量化。把文本、图片、音视频片段各自映射为向量空间中的表示支持后续语义检索和跨模态理解。服务层直接面向 Agent 提供接口。一般会包括统一检索服务关键词检索向量检索图谱检索的混合查询、上下文组装服务把检索结果按相关度、时间、token 预算裁剪和组织、以及记忆服务记录 Agent 与用户的历史交互支持跨会话的个性化。这一层的目标是把底层复杂的存储和处理逻辑完全隐藏Agent 只需要用一套统一 API 就能拿到它想要的数据。我个人的经验是三层缺一不可但很多人一开始会忽略处理层。总觉得把文件丢进对象存储、装个向量库就万事大吉。实际上向量化前的文档解析和切分质量直接决定了后面检索的效果这个环节花多少心思都不过分。3. 面向 Agent 的四个关键能力与落地细节3.1 记忆数据平台要当 Agent 的“外接大脑”现在圈内讨论 Agent 记忆时经常区分为短期记忆、长期记忆、和工作记忆。我的理解更简单Agent 本身的大模型上下文窗口是“工作台”而数据平台是“书架”和“笔记本”。书架里放着可能需要的知识资料笔记本里记着用户说过的话、做过的选择、偏爱的方式。在做记忆设计时有两个地方你会发现特别依赖数据平台的支撑。一个是跨会话记忆。用户上周让 Agent 分析过某个行业这周再来问相关问题时Agent 需要知道“他上周已经对这些内容感兴趣了”。这不能靠大模型自己记住要把每次交互的核心内容沉淀成一个记忆对象存到平台里下次对话开始时按用户维度加载。另一个是记忆的时效管理。记忆不是越多越好过期的信息反而会造成误导。比如员工的职位变动、项目的状态更新、价格策略的调整Agent 必须能及时遗忘或覆盖旧记忆。数据平台需要支持记忆对象带生命周期、带版本、带生效时间这样 Agent 在读取时才不会拿着三个月前的信息说今天的话。这块在实操时经常被忽略我见过不少 Agent 产品因为记忆没有时效机制出现“把上一份合同金额报给下一个客户”的事故。3.2 多模态检索增强让 Agent 真正“看懂”资料RAG检索增强生成是现在 Agent 落地最主流的方案之一但大家平时做的多偏文本 RAG。全模态数据平台的差异点在于把图片、表格、音视频也纳入可检索的范围。举个例子一份带图表的行业分析报告传统 RAG 只会把 PDF 里的文字切块存向量库图表里的信息就丢了。但如果平台在预处理阶段就把图片抽取出来做图像理解或者OCR识别再把图片的描述文本与图像特征一起建立索引Agent 在回答“去年第四季度增长曲线是什么趋势”时就能准确检索到那张图表进而组织出有数据支撑的回答。这里有一个很关键的细节跨模态对齐。文本向量和图像向量如果不经过对齐模型检索时会出现“词不达意”的问题也就是查询“电池续航曲线”时系统无法召回相关的图表。实操中常用的做法是使用多模态 embedding 模型或训练一层跨模态映射把文本查询和图像、音频片段映射到同一个向量空间保证跨模态相似度计算有效。我建议第一次构建这类平台时直接选用已经发布的多模态向量模型不要自己造轮子先把链路跑通再说优化。3.3 工具调用与数据契约数据和 Agent 动作之间要有一层“契约”现在很多 Agent 应用都会用到 Function Calling / Tool Calling让模型自主决定调用哪个工具来完成某个子任务。但工具调用过程中最容易出问题的就是数据格式契约不稳定。我见过不少团队每个业务工具各自返回自己的 JSON 格式字段名称五花八门Agent 经常因为解析不了返回结果而中断执行。这个问题本质上也是数据平台职责的一部分。全模态数据平台在向 Agent 提供检索或其他数据服务时应当把每个服务抽象成带明确 Schema 的“数据工具”工具输入、输出、错误码都是可枚举、可测试的。比如“查询项目信息”这个工具输出必须固定为项目ID、项目名称、状态、负责人、预算、更新时间这些字段不能今天返回owner明天返回负责人姓名。在实施上我比较推荐的做法是在平台服务层用一个统一的工具网关来收敛所有数据接口每个接口向 Agent 暴露一份工具描述文档包括参数、返回格式、示例、权限范围。这样不只解决数据契约问题还方便做权限审计和安全管控。Agent 权限最小化是现在企业落地 AI 时非常敏感的事数据工具网关会让你在安全合规上省掉很多麻烦。3.4 上下文组装防止“检索了一大堆但 Agent 不会用”全模态数据平台如果只做检索任务其实只完成了一半。另一半是把检索出来的结果包装成 Agent 能高效使用的内容。这一步如果做不好会出现一个很玄幻的现象数据明明都查到了但 Agent 输出的答案还是和资料内容对不上。问题通常出在上下文组装时没有提供足够的“路标”。如果直接往上下文里塞十几段长文档模型很难知道哪段是当前问题最该依赖的证据。我建议在处理层就为每个数据块写好结构化的元信息比如来源文件与章节标题内容的时间戳与过期时间内容的相关度得分内容里涉及的关键实体列表。在组装上下文时先按相关度排序再按时间倒序把得分最高的3-5段作为核心证据直接放在上下文前部其余作为补充参考资料。同时要把检索到的关键数字、结论性句子单独摘出来作为“事实清单”让 Agent 先读事实清单再读原始段落。这套方法在我实测中能让 Agent 回答准确率明显提升因为模型更容易从事实清单里建立“答案锚点”。4. 最小可用原型从 0 搭一套全模态数据流水线4.1 环境准备与数据准备说再多架构不如直接动手搭一个最小原型。这里我们做一个简化版输入一份混合了文本、表格、图片的行业 PDF 报告输出一个能支持 Agent 查询的检索接口并且实现跨模态召回一个指定图表。建议环境一台 8C16G 的云服务器或本地机器即可安装 Python 3.10。依赖主要有PDF 解析库pdfplumber PyMuPDF、多模态向量模型可以用开源的bge-m3处理文本以及clip处理图像也可以直接用带多模态能力的 embedding API按自己资源情况来选、向量数据库Milvus 或者 Qdrant 都行单机模式足够跑通流程。数据准备方面我拿了一份带有 3 段文字和 2 张图表的行业报告 PDF 做测试。先把 PDF 放在项目的data/目录下然后写脚本解析。4.2 数据接入与归一化处理数据接入这一步最核心的是归一化。无论原始文件是 PDF、Word 还是网页都要先解析成“文本块 表格 图片”三种基本元素并各自附上来源信息。import pdfplumber import fitz # PyMuPDF def parse_pdf(path): text_blocks [] tables [] images [] with pdfplumber.open(path) as pdf: for page_num, page in enumerate(pdf.pages): # 提取文本块 words page.extract_words() lines {} for w in words: key (round(w[top], 0), round(w[x0], 0)) lines[key] w[text] # 简化处理按行聚合文本 page_text \n.join(str(v) for k, v in sorted(lines.items())) text_blocks.append({page: page_num, text: page_text, source: path}) # 提取表格 page_tables page.extract_tables() for t in page_tables: tables.append({page: page_num, table: t, source: path}) # 提取图片 doc fitz.open(path) for page_num, page in enumerate(doc): for img_index, img in enumerate(page.get_images(fullTrue)): xref img[0] base_image doc.extract_image(xref) images.append({ page: page_num, image_index: img_index, image_bytes: base_image[image], source: path }) return text_blocks, tables, images注意解析出来的图片最好在后续步骤用 OCR 或视觉模型生成一段“图片摘要”和图片的向量特征一起保存。这是实现跨模态检索的基础很多团队在这一步偷懒导致图表永远检索不到。4.3 向量化与索引构建文本块和图片摘要走文本向量模型图片原始内容走图像向量模型各得到一组向量后写入同一个 Collection但是用不同的modal_type字段区分。from qdrant_client import QdrantClient from qdrant_client.models import VectorParams, Distance from sentence_transformers import SentenceTransformer from PIL import Image import clip import torch client QdrantClient(hostlocalhost, port6333) client.recreate_collection( collection_namefull_modal_demo, vectors_config{ text: VectorParams(size1024, distanceDistance.COSINE), image: VectorParams(size512, distanceDistance.COSINE), } ) text_model SentenceTransformer(BAAI/bge-m3) clip_model, preprocess clip.load(ViT-B/32, devicecuda if torch.cuda.is_available() else cpu) # 写文本块 for block in text_blocks: vec text_model.encode(block[text]).tolist() client.upsert(full_modal_demo, [{ id: hash(block[text]), vector: {text: vec}, payload: {modal_type: text, content: block[text], page: block[page]} }]) # 写图片需要先生成图片摘要 for img in images: pil_img Image.open(io.BytesIO(img[image_bytes])) image_tensor preprocess(pil_img).unsqueeze(0).to(device) with torch.no_grad(): image_vec clip_model.encode_image(image_tensor)[0].tolist() summary summarize_via_vision_model(img[image_bytes]) # 用视觉模型生成一句话摘要 text_vec text_model.encode(summary).tolist() client.upsert(full_modal_demo, [{ id: hash(fimg-{img[page]}-{img[image_index]}), vector: {text: text_vec, image: image_vec}, payload: {modal_type: image, summary: summary, page: img[page]} }])这里有个设计细节值得多说一句我在 Collection 的向量配置里同时设置了text和image两种向量字段。图片既保存图像特征用于图搜图场景又保存其摘要的文本特征用于文搜图场景。这样查询时可以走全文案路径也可以走多模态混合路径灵活性高很多。4.4 与 Agent 对接的检索接口数据灌进去之后最后一步是把检索封装成 Agent 能直接调用的接口。真题接口要做两件事把用户问题向量化然后去库里做多路召回把文本和图片结果统一返回。def search_for_agent(query: str, top_k: int 5): query_vec text_model.encode(query).tolist() text_hits client.search( collection_namefull_modal_demo, query_vector(text, query_vec), query_filterNone, limittop_k, with_payloadTrue ) image_hits client.search( collection_namefull_modal_demo, query_vector(text, query_vec), # 图片的文本摘要字段也能命中 query_filterNone, limittop_k, with_payloadTrue ) # 合并结果按得分去重排序 results [] seen set() for hit in text_hits image_hits: if hit.id not in seen: seen.add(hit.id) results.append({ score: hit.score, modal_type: hit.payload[modal_type], content: hit.payload.get(content) or hit.payload.get(summary), page: hit.payload[page] }) results.sort(keylambda x: x[score], reverseTrue) return results[:top_k]实测下来这套简化流程已经能支撑一个基本的“跨模态问答 Demo”。把接口通过 FastAPI 暴露给 Agent 做工具调用即可。需要注意的是向量检索的top_k不要设太大否则后面的上下文组装和模型阅读的时间都会显著上升。我一般控制在 5 到 10 之间重点是把召回质量做精而不是做多。5. 真实踩过的坑与排查方法5.1 跨模态检索结果不相关如果你做了图像摘要和向量化但检索“电池容量变化”时仍然召不回图表优先检查是不是图片摘要写得过于笼统。我用一个通用视觉模型生成摘要时经常得到“图中展示了一些数据和曲线”这种句子完全没有信息量。解决思路是换更强的视觉理解模型或者用模板提示词让模型聚焦在“图表标题、坐标轴含义、趋势结论”上。摘要质量直接决定文搜图的命中率这个环节省不得。另外如果摘要质量短时间无法优化也可以在检索逻辑里加一个兜底把查询词和图片所在页的文本块做一个关键词重叠匹配命中后再把图片一起返回。5.2 数据新鲜度问题导致 Agent 回答过时Agent 用着用着开始一本正经地胡说八道不一定是模型出了问题很可能是数据底座没有及时刷新。我们之前做业务知识库 Agent 时合同文件每周更新但平台只是每天凌晨跑一次全量同步Agent 白天经常回答的是前一天甚至上一周的信息。后来改成双轨制表格类的高频数据走增量同步文档和图片走版本快照对比检测到文件变更就立刻触发重新解析和向量化。同时在上下文组装时把每条信息的updated_at字段传给模型并强制要求 Agent 回答时优先引用最近 7 天内的资料。这个改动看起来不起眼但对回答实时性的提升非常明显。5.3 成本与资源开销失控全模态数据平台的资源开销有三个重灾区向量化计算、向量库内存、存储。尤其是每天对全量文档做一次重新向量化非常浪费。我在项目上测试过1 万份文档全量向量化8 卡 GPU 机器要跑几个小时成本很高。优化手段是切分得更细只对变更的文件做增量向量化。向量库方面可以开启量化压缩比如把 1024 维 float 向量转成 int8准确率损失不大但内存占用降为原来的四分之一。存储方面原始文件建议用冷存储归档只保留一个精简版本用于在线检索能省不少钱。5.4 检索时延卡住 Agent 的思考节奏Agent 调用数据平台接口时如果等待时间超过 3 秒用户的体感会非常差而且模型容易出现中途放弃或重复调用工具的死循环。检索慢的常见原因有三个向量库查询没有走索引优化、大文档切块过多导致召回候选集太大、以及跨模态多路召回串行执行。我给一个有效的排查顺序先看向量库 QPS 和延迟监控确认单次查询耗时再检查召回候选数把limit调小最后把文本检索和图片检索改成并发执行而不是像我上面示例代码那样串行。实测把多路召回并发化之后接口 p95 时延从 2.8 秒降到了 0.9 秒效果非常明显。6. 最后再分享一点个人体会如果让我总结这次从云栖主题里学到的最重要的一件事我会说面向 Agent 的数据平台核心思维要从“存好数据”切换到“组织好让模型能用的知识”。传统数据平台追求的是数据完整、准确、可回溯这些当然重要但 Agent 场景还多了一层要求数据要能被人和模型通过自然语言直接理解要被组织成便于检索和推理的形式要能随着业务变化快速演进。我从零搭过不少平台最后发现真正决定 Agent 上限的往往不是模型选得多强而是数据底座打磨得多细。建议刚起步的朋友不要一上来就追求大而全可以先从你业务里最高频的一类数据开始比如企业文档问答把“解析 — 清洗 — 向量化 — 检索 — 上下文化”这条链路跑通再逐步加图片、加表格、加语音。每一步都把元数据做扎实把摘要质量做上去Agent 的效果自然会跟着提升。这条路没有太多捷径但走通之后你会发现所有的投入都值回票价。