跳转到主要内容

别急着买一个 RAG:在 AWS 上自建 Agent 知识库的第一步

14 分钟
RAGAI AgentAWS架构自建方案

先别急着买一个 RAG

最近聊企业 AI,很难绕开两个词:RAG 和 Agent。

这两个词现在被用得很宽。很多企业项目其实只是把一堆 PDF、Word、飞书文档塞进某个聊天框里,能问几句,能吐出一段像样的话,于是大家就说自己有了 RAG,有了 Agent。

先说一个更现实的数字。以研报图书馆现在的量级粗算,每天约一千份 PDF,一个月三万份上下。我自己踩过一次很直接的坑:当时只是把向量库放在 serverless 托管上,一周就花了 6000 美元。这还只是向量检索这一层,不包括解析、embedding、模型调用、席位和其它服务。换句话说,如果全部走企业 SaaS 或高度托管的云服务,每月进入 数万美元并不奇怪;如果自己控制文件流水线,只把 S3、Lambda、数据库、向量库和必要的模型调用拆开用,稳定运行成本大概可以压在 300 到 1500 美元/月 这个区间。这个数字不是报价单,页数、图片比例、查询量和模型选择都会影响结果,但量级差异是真实存在的。

这当然不是完全没用。钉钉、ima、飞书、Bedrock Knowledge Base 这类方案,最大的优点就是快。账号开好,文档传上去,第二天就能给老板演示。但快并不等于适合长期使用。等到你真的想把它放进业务里,让它处理客户资料、研报、合同、产品文档、内部知识库,一些麻烦就会慢慢冒出来。

比如数据能不能出域,权限到底怎么跟你原来的系统对齐,PDF 里那些表格和脚注到底有没有被正确解析,同一家公司不同年份的报告会不会混在一起,召回错了你有没有地方调,模型费用涨起来之后还能不能睡得着。演示阶段很少问这些问题,生产环境会一个个找上门。

我不反对买现成方案。很多时候,先买一个反而是最合理的选择,至少能验证这件事是不是真的有人用。但如果你已经撞到上面这些墙,或者一开始就知道数据和流程很难交给外部 SaaS,那就需要想一想:如果要高自由度自建,一个 RAG Agent 到底要长成什么样?

这篇先不写代码,也不讲 prompt。我们先把系统拆开。拿我自己的「研报图书馆」做例子:它每天处理大约一千份 PDF,来源有投行研报,也有各种结构并不太友好的文件;解析、打标、向量化、查询、权限和 iframe 嵌入都要跑起来。这个系统当然不完美,甚至有些地方还很土,但它足够真实。真实系统最重要的一点是:它会告诉你哪些东西不能省。


一个 RAG Agent,先看它吃什么

先把 Agent 这个词放一放。真正的第一步不是“让模型会思考”,而是“让系统知道自己到底吃了什么”。文件从哪里来,是什么版本,属于哪个客户,解析成了什么,失败了几次,哪些内容进了向量库,哪些只是存档。这些事情听起来不性感,但它们决定了后面所有问答的上限。

把 RAG Agent 拍扁,大概就是下面这条流水线:

这张图很简单,简单到看起来像废话。但生产里出问题,十次有八次不是模型突然变笨,而是这五步中某一步偷懒了。

最常见的是跳过打标。很多人相信 embedding 能解决一切,好像把文本丢进向量库之后,语义关系就会自然浮现。实际情况是,同一家公司的 2022 年报告和 2024 年报告可能都叫一个差不多的名字,页眉页脚还一模一样;如果没有年份、来源、行业、公司实体、权限和状态这些 metadata,召回结果会混在一起,看起来都相关,真正用的时候却很难稳定命中。

另一个问题是把 embedding 当成一次性任务。今天你换了解析器,明天你发现 chunk 切得不对,后天你要给老文件补一个字段。如果没有版本、增量和重算策略,最后就只剩两个选择:要么不敢改,要么全量重跑。前者会让系统越来越难维护,后者会直接反映在成本上。

所以,与其一上来讨论 Agent 多聪明,不如先问:文件有没有被可靠地搬进来?解析失败有没有日志?打标结果能不能回看?向量库里的每一块文本还能不能追溯回原始 PDF?这些问题答不上来,前端对话做得再好看也很难进入生产。


最小可用系统,不是一个向量库

如果只是做 demo,一个脚本、一个向量库、一个聊天页面就够了。文件不多,错了也没人追责,系统重启一下又是好汉。

生产不是这样。生产系统有一个很朴素的要求:它要在你不盯着的时候继续工作,并且在坏掉的时候留下足够多的证据。按这个标准看,一个 RAG Agent 至少需要下面这些东西。

#子系统作用自建关键点
1采集器(Ingest / Crawler)把分散在邮箱、共享盘、SaaS、爬虫源的文件搬到自家域内速率限制、断点续传、来源标签
2对象存储(两层)原文件桶 + 解析产物桶分离生命周期、版本、跨账号读取策略
3解析流水线(Parsing)PDF / Word / PPT / 网页 → 结构化文本 + 块 + 图异步、可重试、限速、失败可观测
4元数据库(Meta DB)任务状态机 + 业务字段 + 多租户一定要做 status / version / tenant
5LLM WorkflowMeta 抽取、摘要、打分、翻译模型可替换、可降级、有预算控制
6切片 + Embedding 服务按业务策略切块、生成向量、写入向量库增量 / 重算 / 版本回滚
7向量库 + 关键词索引向量召回 + BM25 / 全文索引混合至少两路召回 + 一路 rerank
8Agent / Workflow 编排把工具、记忆、检索串成多轮对话可观测的 trace、可灰度的 prompt
9API Gateway + Auth多租户 / iframe 嵌入 / 速率限制对接 SaaS 的最常见痛点
10调度器(Cron / EventBus)把上述子系统按节奏拼起来隔离 cron、限速、补偿任务

这里面最容易被低估的是第四项:元数据库。

很多第一版系统会把状态藏在文件名里,或者藏在队列消息里,甚至靠 S3 里有没有某个输出文件来判断“任务完成”。这在几十个文件的时候还凑合,到了几万份文件就会变得很可怕。你不知道哪个任务失败了,为什么失败,重试了几次,是否已经入库,是否需要重算。最后所有问题都会变成一句话:要不我们全量再跑一遍?

我不喜欢这句话。它通常意味着前面缺少状态设计,后面只能用算力和时间补。

在研报图书馆里,状态表是整个系统的核心。PDF 是否抓取、是否预处理、是否解析、是否抽取 metadata、是否 embedding、是否可查询,都要落在表里。你可以不用 Supabase,可以用 RDS、DynamoDB,甚至一开始用 SQLite,但你不能没有它。


研报图书馆:一个不太优雅但能跑的参考实现

下面这张图,是我从现有研报图书馆架构里抽出来的简化版。

真实图比这张更乱一些。真实系统跑过一段时间以后,总会多出一些临时补丁、兼容路径和历史原因。只要主干还清楚,这不是坏事。

这个系统的目标很具体:每天抓取大约 1000 份投行研报,解析 PDF,提取结构化信息,生成向量索引,给前端和 iframe 嵌入提供查询能力。它不是“通用知识库平台”,也不打算假装自己什么都能做。边界越清楚,系统越容易活下来。

这张图里有几个地方值得多看一眼。

第一,S3 分了 raw 和 parsed 两层。 原始 PDF 永远保留,解析产物单独放。这样做的好处很实际:解析器换了、chunk 策略改了、图片抽取出问题了,都可以从 raw 重新加工,而不用回头再抓一次来源文件。对于外部数据源来说,能不能再抓到、抓到的版本是不是一样,很多时候都不是你能决定的。

第二,minerU 解析是一个独立的重计算环节。 SVG 里写得很朴素:1min/pdf1000pdf/day4 thread async。这些数字不大,却足够暴露问题。PDF 解析不是轻任务,尤其是研报这种图表、页眉、脚注、目录都很多的文件。如果把它塞进一个同步 API 里,用户会等到怀疑人生,API Gateway 也会先一步失去耐心。

第三,Supabase 在这里不是“顺便存点数据”,而是任务中枢。 哪些 PDF 已经解析,哪些失败,哪些需要重试,哪些进入了 embedding 批次,都要靠它协调。EventBridge 和 Lambda 只是负责按节奏推动任务,真正让系统不乱的,是状态表。

第四,Dify Workflow 被我用在两个位置。 一处是前处理阶段,用来做 metadata 抽取、打分、摘要;另一处是在查询阶段做 Agent 编排。它们看起来都叫 LLM Workflow,但预算、延迟和容错要求完全不同。前处理可以慢一点、便宜一点、失败重试;查询阶段则要响应快、trace 清楚、必要时能降级。

至于 Qdrant 和 Bedrock KB 的并存,倒不是因为我喜欢复杂。向量库这件事变化很快,供应商也多,迁移成本不能太高。把系统写死在某一个托管知识库里,短期省心,长期会限制后续调优和迁移。


AWS 负责地基,自研负责不通用的地方

如果用 AWS 做主干,我的原则很简单:能用托管服务解决的东西,不要为了显得“技术含量高”而自研。 你真正需要花精力的,是解析适配、业务 metadata、权限、多租户、召回策略和 Agent 工具。这些地方才决定一个系统是不是你的系统。

下面这张表不是标准答案,只是一个比较稳的起步方式。

#子系统主推 AWS 托管何时考虑自研 / 第三方
1采集器EventBridge + Lambda复杂爬虫 → ECS Fargate / 第三方爬虫 SaaS
2对象存储S3(双桶)+ Lifecycle跨云需求 → R2 / 阿里 OSS
3解析流水线Lambda(轻)/ Batch(重)minerU / unstructured.io / Tika 做适配层
4元数据库RDS Postgres / DynamoDBSupabase(一并拿到 Auth + Realtime)
5LLM WorkflowBedrock + Step FunctionsDify / LangGraph / Flowise 做可视化编排
6Embedding 服务Bedrock Embeddings + Lambda自托管 bge / m3e(需要 GPU)
7向量库OpenSearch Serverless / Aurora pgvectorQdrant / Weaviate(功能更丰富)
8Agent 编排Bedrock AgentsDify / LangGraph(自由度高)
9API Gateway + AuthAPI Gateway + CognitoSupabase Auth + Cloudflare Worker
10调度器EventBridge Scheduler—(强烈建议托管)

这里有两个选择需要特别谨慎。

一个是解析层。PDF 解析没有银弹,尤其是中文、扫描件、复杂表格、投研报告这种格式。你可以用 minerU,可以用 unstructured,也可以用 Tika 或自研 OCR 流水线,但一定要把解析层做成可替换的适配层,不要让后面的 chunk 和 embedding 直接依赖某个工具的临时输出格式。

另一个是 Agent 编排层。Bedrock Agents、Dify、LangGraph 都能做,区别不只是“哪个更强”,而是你的团队更需要什么:可视化、可控代码、托管运维,还是更自由的 trace 和版本管理。这个选择不急着一步到位,先把接口边界留好。


先把主干搭起来

如果只记住一件事,我希望是这句:RAG Agent 不是一个向量库加一个聊天框,而是一套文件处理和检索系统。

聊天框只是入口,真正麻烦的是文件怎么进来、怎么被拆开、怎么打标、怎么入库、怎么重算、怎么查、怎么知道自己查错了。你当然可以先买一个 SaaS 试试水,但如果最后决定自建,第一版不要从“Agent 多聪明”开始,而要从这几块开始:

  • 双层 S3:原文件和解析产物分开;
  • 解析流水线:异步、可重试、失败有日志;
  • 元数据库:任务状态、业务字段、租户和版本;
  • Embedding 批处理:能增量,能重算,能回滚;
  • 向量库:不要只考虑 demo 召回,要考虑过滤、迁移和成本;
  • 调度器:让系统按节奏自己往前走,不靠人肉点按钮。

这些东西搭起来之后,Agent 才有资格上场。否则它能回答几句,但很难稳定承担业务任务。

下一章先不急着写采集器,而是讲一个更容易被低估的问题:可拆卸的处理节点,以及 RAG 最麻烦的重跑。解析器、打标 prompt、chunk 策略、embedding 模型都会变,如果第一版没有把节点和版本拆清楚,后面每一次优化都会变成高成本重跑。

如果你正在做类似的东西,也欢迎在 联系我 里聊聊你卡在哪一步。真实问题通常比架构图更有信息量。