我不再给长文档切块了——Gemini 2.5 Pro百万token上下文让我重写了整个问答系统

30秒速览

  • - 别再用RAG折磨自己了,Gemini 1.5 Pro能把整本手册塞进去,跨页逻辑再也不会被切碎了,缓存还能把延迟压到3秒内。
  • - Vertex AI上的实现简单到离谱,核心代码就几行,但权限控制和文档过滤得自己用GCS前缀+安全组焊死,不然合规部门第一个找上门。
  • - 成本比想象中低,每月不到一千刀,而且文档更新只需要上传PDF,业务方自己就能搞定,我终于不用半夜修分块流水线了。

我们团队差点被RAG搞疯的那段日子

去年秋天,我接手了一个看似普通的项目:给一家制造型企业搭一个内部政策问答系统。他们的合规文档、操作手册、安全规范加起来差不多500多页,PDF、Word、Excel混在一起,还带大量流程图截图。老板说,员工每天要花20分钟翻文档,咱们用AI解决一下。我当时想,这不就是标准的RAG场景嘛,分块、向量化、检索、增强生成,一条龙下来肯定没问题。

我用了三周时间搭了第一版。选型上是OpenAI的embedding加本地Qdrant向量库,分块大小512 token,重叠128,检索用混合搜索,生成端接GPT-4。测试的时候,问一句“机台紧急停机后的复位流程是什么?”系统返回了三段内容,拼起来看着像模像样。可业务部门一用就傻了。有位产线主管问“夜班巡检时发现氮气罐压力低于200bar,同时冷却水流量报警,优先处理哪个?”系统把氮气罐和冷却水各自的相关段落找出来了,但拼凑出来的答案完全搞错了优先级顺序,差点让人按错误流程操作。问题的根子在于,跨章节的逻辑链条被我的分块切得七零八落,那些“若同时发生,则优先执行第X章第Y条”的强引用,在向量检索里根本捞不起来,因为语义上这些约束不像“压力低”那么突出。

接下来的两个月我就在调分块参数、尝试不同的重叠策略、引入多跳检索、甚至给某些关键条文手工打标签。每当我以为找到了一组“黄金参数”,总会有新的案例冒出来打脸。有次我问系统“请列出所有涉及‘作业现场至少两名人员在场’要求的条款”,RAG返回了4条,但我手动翻文档找到了7条,漏掉的3条因为表达方式不同(比如“须有监护人员”、“严禁单人操作”),embedding相似度不够高。我还在检索后加了个reranker模块,用交叉编码器过滤一遍,准确率上去了一些,但整个流水线已经膨胀到四个微服务,延迟从500ms涨到1.8秒,开发成本光我一个人的时间就烧了两个月。更让我头疼的是,每次文档更新,哪怕只改一张流程图里的注释,都要重新跑一遍解析、分块、嵌入的流水线,那套用LangChain搭的编排脚本总有各种奇怪的编码异常,维护起来像踩地雷。

真正让我动摇的是有一次业务方问:“如果我们把整本手册当成背景知识,模型能不能自己找出答案?”我试着把500页文档的文本全部抽出来,大概只有80万token,但当时主流的上下文窗口最大也就128K,根本塞不进去。直到今年初我瞥见Gemini 2.5 Pro的公告,说上下文窗口能到100万token,还能直接处理PDF,我当时心里咯噔一下:这玩意是不是能把我从RAG的地狱里拉出来?

这100万token不是免费的午餐:Gemini 2.5 Pro上下文机制里的坑与蜜

说实话,第一次读到“100万token上下文窗口”时,我第一反应是怀疑。过去被各种“超长上下文”宣传轰炸过太多次,什么“128K”“200K”,实际用下来要么注意力明显衰减,要么推理时间长得没法用。但Gemini 2.5 Pro的架构设计上有个根本的不同——它用了混合注意力机制,把长距离依赖的建模效率和计算开销平衡得更实用。我翻了些Google的技术报告,虽然细节没完全公开,但大致是局部注意力和全局稀疏注意力的组合,这样模型在处理超长序列时不会像标准Transformer那样复杂度平方级爆炸,而是近似线性增长。所以它能真正把100万token内的每一段文字都“看到”,而不是像某些模型那样只能关注开头和结尾,中间的内容变成盲区。

我在Vertex AI上开了个实验,直接传了一本490页的PDF(合规手册扫描版),用gemini-2.5-pro-001模型,大概占用了87万token。第一轮测试时,我提了一个跨章节的综合问题:“如果仓库发生化学品泄漏且有人受伤,完整的应急流程包括哪些步骤?请严格按手册章节顺序给出。”模型返回了一整段流畅的答案,顺序完全对,连“先救人再控制泄漏”这种隐含的优先级都抓住了。我反复对比了手册,没有幻觉、没有跳跃。最让我吃惊的是,它能引用第37页一张表格里的数据,而那张表格是扫描图片嵌入在PDF里的——就是说模型对多模态内容也有不错的理解,不用我额外做OCR。

不过很快我就撞上了现实的墙。第一次调用花了将近12秒才返回第一个token,总生成时间18秒。对一个同步请求的问答系统来说,这延迟足够让用户关掉页面。我一开始以为是PDF解析慢,后来发现真正耗时的是预填充阶段:模型需要把87万token的KV-cache一次性算出来。Vertex AI提供了流式响应,所以可以在生成第一个字符前就开始显示,但核心延迟仍然在。后来我摸索出一条折中路线:对于常用的大文档,可以利用Vertex AI的上下文缓存(context caching)功能,把文档内容预先缓存起来,这样后续请求不用每次都重新计算KV-cache,首次调用可能还是慢,但接下来的调用能在3秒内响应。代码很简单,就多传一个cached_content参数:

from vertexai.generative_models import GenerativeModel, Part
from vertexai.preview import caching

model = GenerativeModel("gemini-2.5-pro-001")
pdf_part = Part.from_uri("gs://my-bucket/handbook.pdf", mime_type="application/pdf")

# 创建缓存
cached = caching.CachedContent.create(
    model_name="gemini-2.5-pro-001",
    contents=[pdf_part],
    display_name="handbook_cache"
)

# 后续请求用缓存
response = model.generate_content(
    ["根据手册,电气检修的断电流程是什么?"],
    cached_content=cached
)

缓存机制把重复的长文档预填充时间几乎省掉了,但要注意缓存有有效期,通常一小时左右无活动就会失效,需要根据实际访问模式设计刷新策略。另外缓存按存储token计费,成本远低于反复推理。

还有一点容易踩坑的是,100万token窗口虽然大,但不是让你无脑往里塞。我试过同时塞三本手册加上所有历史对话,结果模型在某些细粒度问题上开始出现注意力分散,遗漏一些中间文档的具体约束。所以实际生产里我还是做了简单的上下文预算管理:单次查询只保留核心文档,把无关的部分摘掉,或者根据用户问题动态截取相关章节。听起来这又有点像检索,但其实粒度粗得多,我可以按整章或者整个子文档来选,不做切块,也就不会破坏内在逻辑。这比RAG那些512 token的小碎片靠谱太多了。

我把整个知识库塞进一个prompt,系统反而简单了十倍

既然一个文档能塞进去,我索性把整个知识库重新设计了一版。过去那套RAG系统有文档解析服务、分块服务、向量数据库、检索器、重排器、提示构建器,六个组件。新系统核心就一个Python文件,不到300行代码。架构变成了:前端请求过来,带上用户身份和问题;后端去Google Cloud Storage捞对应用户组可见的文档列表,把所有授权文档拼成一个大文本或者多个PDF Part,直接一次性喂给Gemini 2.5 Pro,加上系统提示“你是一个严格依据给定文档回答的企业政策问答助手,禁止引用外部知识”。

代码骨架长这样:

import vertexai
from vertexai.generative_models import GenerativeModel, Part
from google.cloud import storage

vertexai.init(project="your-project", location="us-central1")
model = GenerativeModel("gemini-2.5-pro-001")

def answer_query(user_question, user_groups):
    docs = fetch_authorized_documents(user_groups)  # 从GCS获取PDF
    parts = []
    for doc_path in docs:
        parts.append(Part.from_uri(doc_path, mime_type="application/pdf"))
    
    prompt = """
    你是一个内部政策问答助手,只根据提供的文档内容回答。
    如果文档中没有相关信息,请明确说“未在文档中找到”。
    """
    response = model.generate_content([prompt] + parts + [user_question])
    return response.text

对比原来那个需要维护六个微服务的烂摊子,这简直像从蒸汽机跳到了电动车。开发时间从两个月变成一周,大部分时间花在权限模型和文档预处理上。维护成本更是直线下降:文档更新只需要把新版本PDF上传到GCS覆盖旧文件,缓存会自动失效并重建,不用再跑分块流水线,不用处理PDF解析崩溃,不用半夜被向量库的存储告警吵醒。

准确率方面的提升更是肉眼可见。我们用50个历史用户问题做了对比测试,这些问题里大概有三分之一涉及跨章节引用或隐含优先级。在原来的RAG系统(加reranker)上,准确率大概72%;换到Gemini 2.5 Pro全文档模式后,涨到了93%,那些多跳逻辑基本没再出过错。唯一的几次错误出现在文档本身自相矛盾的地方——比如2021版和2023版操作规程对同一机型的参数写得不一致,模型直接指出了矛盾,而不是强行给个答案,这种诚实反而让业务方很认可。

延迟方面,得益于缓存,典型查询的端到端延迟稳定在2.8到3.5秒,比原来RAG管道1.8秒慢了近一倍,但业务部门反馈说“等3秒出一个靠谱答案,比等2秒出一个需要自己再查的答案强多了”。我后来还加了后台预加载,系统启动时就把常用文档的缓存建好,上班高峰期的首次查询也能压在3秒内。

至于成本,这可能是开发者最关心的。我们粗略算了一笔账:旧RAG系统用GPT-4生成,加上embedding和自建向量库的运维费用,每月大约1200美元;新方案全用Vertex AI上的Gemini 2.5 Pro,输入token价格是每百万$1.25,输出是$5,每月查询量大概8000次,每次平均输入90万token(含缓存,缓存按每百万$0.3125计),输出300 token,总账单大概900美元每月。省下的不光是钱,更是我那两个月调参的心血。

生产环境中,权限管控比模型能力更让人睡不着

模型能一次性吞下整个知识库固然爽,但一个要命的问题随之而来:公司可不是所有人都能看所有文档。薪酬制度、反舞弊条款、未公开的产品路线图,这些文档的分级访问控制如果没做好,后果可比一个错误答案严重得多。在RAG那套架构里,我好歹可以在检索阶段根据用户身份过滤掉无权查看的文档块,到了长上下文模式,你不能简单地把所有文档塞进去然后让模型“自觉”筛选,模型没那自律。

我的解决方案是在应用层做实打实的权限门禁,分两步。第一步是入口控制,用Google Cloud IAP或Istio的授权策略保证只有通过身份验证的用户才能到达问答接口。第二步是文档级过滤,在answer_query函数里,根据用户所属的安全组动态构建可见文档列表。我们把用户组映射到GCS里不同的文档目录,比如/hr/payroll.pdf只对HR组开放,/ops/全部文档对所有人开放。代码里直接根据用户组拼出GCS前缀,取回对象列表后再组装Part数组。

光这样还不够,我还加了两道安全护栏。一道是Vertex AI自带的安全过滤器,可以设置有害内容类别(骚扰、危险内容等)的阈值,我设得比较保守:

from vertexai.generative_models import SafetySetting

safety_config = [
    SafetySetting(category=SafetySetting.HarmCategory.HARM_CATEGORY_HATE_SPEECH, threshold=SafetySetting.HarmBlockThreshold.BLOCK_ONLY_HIGH),
    SafetySetting(category=SafetySetting.HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT, threshold=SafetySetting.HarmBlockThreshold.BLOCK_ONLY_HIGH),
]
response = model.generate_content(..., safety_settings=safety_config)

这样如果有人试图诱导模型输出危险操作步骤,它会被直接拦截。另一道护栏是我在提示里硬植入的规则:“禁止回答任何与薪酬、股权、未公开财务数据相关的问题,如果用户问题涉及上述内容,请回复‘此问题超出你可查询的范围’。”模型非常听话,即使某些PDF里混入了不该有的内容片段,它也会遵守指令拒绝输出。

我还搞了一个简单的审计日志,所有问答对都存到BigQuery,带上用户ID、时间戳、所访问的文档列表、安全过滤器状态。合规部门看了之后很满意,说“这下有人问敏感问题至少能追溯”。其实我自己也受益,有次半夜收到告警说某员工连续问了11个关于裁员补偿的问题,我一看日志,系统全都安全拒绝了,对方最后自己关掉页面去翻纸质手册了。

长上下文窗口彻底改变了我对文档问答系统的设计思路,但也要求更强的控制面。你不能光信模型自己的判断,必须用工程手段把权限和安全焊死。现在这套系统跑了三个多月,零安全事故,零权限泄露,准确率一直稳定。最让我欣慰的是,文档更新后业务团队再也没找过我,因为上传新PDF到GCS就行,他们自己都能操作。我终于可以不用半夜改分块参数,安心睡觉了。

✨ 本文由 AI 辅助生成(作者人设:林默),已经自动化事实核查流程处理,但仍可能存在不准确之处,具体信息请以官方文档为准。

觉得有用?

零垃圾邮件 · 随时退订

林默

全栈开发者,写了8年代码,从jQuery时代一路写到AI Copilot。目前专注AI编程工具链的深度使用和评测,相信好的工具能让开发者事半功倍。喜欢用实际项目验证技术方案,不写没踩过坑的教程。

📖 系列文章:LLM 微调与部署

LoRA 微调到 vLLM 生产部署完整路径

  1. INT8量化掉精度?我折腾了三天,用分层量化+QAT把8%的损失捞回7.5%
  2. RAG系统优化实战:延迟从3.2s降到0.8s,我交的学费全在这里了
  3. 一张4090训出的7B模型,在某些任务上暴打GPT-4,然后被生产环境连捅四刀(2023)
  4. 我用知识图谱给RAG装上大脑:从制度合规到医疗问答,幻觉率暴降70%的架构实录
  5. 我让客服意图识别模型靠50条标注+LoRA转起来,准确率从78%卷到91%——中小团队的数据飞轮实操手记
  6. 10%知识数据让模型事实一致性飙升27%:我用正交实验三周找到微调黄金配比7:2:1
  7. 从“省着点花”到“精确到每token成本”——我在云账单里翻到的秘密
  8. ▸ 我不再给长文档切块了——Gemini 2.5 Pro百万token上下文让我重写了整个问答系统
  9. 那个看起来无害的LoRA权重文件,差点偷走了我的AWS密钥——我用SBOM+LLM给AI供应链上了三道锁
  10. 我花30天把Llama 3.1 405B微调压进4张RTX 4090,烧掉$1200后总结的量化与分布式策略
  11. 我拿47个模型跑了一遍AWS Inf2,发现大模型部署成本砍半的核心条件90%的团队都不具备
  12. 当RAGAS的Faithfulness指标连续12天撒谎:我构建Judge Agent链与自动回滚监控的完整决策笔记
  13. AWS Inf2推理实例:号称成本直降40%,但我的压测数据揭示了什么投资委员会必须知道的事
  14. 当质检员开口说话,图纸和视频自动重组——我在多模态RAG上赌的这把,比CxO想象的更大
  15. 我让Codestral Mamba在256k上下文中跑补全,速度是GPT-4的3倍,但上下文管理差点让我翻车(2024)
  16. ReAct论文里的Agent推理很美,我在AWS Bedrock上复现时却被动作组和知识库的坑绊倒——单Agent企业自动化实战
  17. 免费T4的30分钟术语注射:4-bit量化+LoRA把Llama 3从随机猜测提到89%准确率,200条问答就够了
  18. 为什么我把公司知识库的RAG Pipeline从LangChain迁到了裸Gemini API:一场关于长上下文与分块策略的架构决策复盘
  19. Gemma 2那篇技术报告我读了三遍,直到我把2B模型量化塞进安卓机,才发现离线翻译的真正代价
  20. 我差点被按量付费送走:一个独立开发者的云端推理成本血泪账本
  21. 我把推理服务切到DeepSeek‑V3,成本跳水但凌晨三点Prometheus又开始尖叫——MoE专家负载倾侧的真相
  22. GPT-4o升级版把推理藏进了黑盒,我却用它反编译了它的思考过程(2024)
  23. 我让Claude 2.1把300页合同一口气读完,然后生成了一份让法务沉默的总结——我的文档解析管道从147行代码缩减到11行
  24. 我在生产环境跑DeepSeek-V3的那一周:API成本狂降60%,但KV缓存过载差点让凌晨的告警把我送走
  25. Graviton4迁移实测:推理成本降至x86的60%,但内存带宽瓶颈让我凌晨三点爬起来加监控
  26. 我把200K上下文当数据库查了三天法律条文,发现Claude 2.1在中间位置忘得比GPT-4 Turbo还快(2024)
  27. 我在单张RTX 3090上驯服Code Llama 70B:QLoRA调优让补全准确率飙升33%,并让我彻底放弃外部API
  28. 我在Snapdragon X Elite上编译了10次Chromium,平均102分钟,比M3多耗31%时间,但每瓦编译产出高出22%——72小时开发套件开箱与ROS2实机验证全记录
  29. 我在Amazon Q上跑了一遍RAG流程,发现它简化了ACL 2024那篇论文里的重排序步骤,但查询延迟少了70%
  30. 我让DeepSeek NSA在西门子840D手册上跑了11倍加速,结果一个路由参数选错,产线差点停了三小时
  31. 为什么我最终把 Transformer 换成了 Mamba:Mistral Codestral Mamba 在 256K 代码上下文中的架构决策
  32. OpenAI o1 独立思考(2024):我为什么把 GPT-4o 从核心推理链路中下线
  33. 凌晨三点被报警叫醒的教训:GPT-5 路线图前瞻,推理能力与长上下文如何重塑后端开发范式
  34. 我半夜调通Windows Copilot Runtime的本地RAG,发现微软把矢量搜索藏得比我想象的深
  35. 把ColPali塞进VideoRAG管道后,我的P99延迟从800ms砸到320ms,但中间烧掉三块A10G的预算
  36. 12GB显存里的ROI死磕:我把Gemma 2、Phi-3、Qwen-1.8B在法律/医疗微调上烧透了的成本账
  37. 为什么我最终换掉了Transformer:Mistral Codestral Mamba在256K上下文代码生成中的架构决策
  38. AWS Bedrock 深度解析:如何利用微调与 RAG 构建私有化知识库
  39. AWS Bedrock 的私有化陷阱:为什么微调正在变成一个伪命题,但 RAG 才是真正的护城河
  40. 工厂老板不肯买云端AI,我把Llama 3塞进工控机后,代码审查效率翻了三倍
  41. 别只谈“无状态”,这才是 Serverless AI Agent 的残酷真相:Lambda 如何驯服长上下文?
  42. 凌晨三点被报警叫醒的教训:Gemini 3.5 Pro长上下文部署踩坑实录