《实用笔记》:为1亿份文档设计RAG系统
《实用笔记》操作指南:为1亿份文档设计RAG系统——适用于采用该模式的团队的合同、校验项及可直接使用的代码模块。
可将此内容视为《为亿级文档设计RAG》中理念面向操作人员的重构版本:清晰的阶段划分、有序的代码模块,以及能在交接过程中保留的恢复说明。 将“概览”阶段视为可量化的界面使用效果最佳。在扩大范围之前,需记录一份最优处理方案、一个故障案例以及回滚说明。 在功能结果旁同时记录耗时以及令牌或查询成本。提前了解成本情况,可避免在从演示环境过渡到共享环境时出现意外账单。
具体要求如下:
在“需求说明”阶段,应在修改代码之前明确输入参数、该步骤的负责人以及结束标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 配置信息应置于应用程序代码之外。环境文件、密钥存储以及功能开关应集中存放于一个位置,以便操作人员无需查看整个系统结构即可进行审核。 需引用实际作为答案依据的段落。如果没有引用,操作人员就无法区分是虚假信息还是索引缺失导致的错误。
从数学模型开始
在“从数学开始”阶段,应在修改代码之前明确输入参数、该步骤的负责人以及终止标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 需同时记录正常流程和异常恢复流程。重试机制、人工审核环节以及错误处理都是产品本身的组成部分,而非后续需要完善的内容。 必须引用实际作为答案依据的段落。如果没有引用,操作人员就无法区分是幻觉内容还是索引缺失导致的错误。
Documents = 100,000,000
Average chunks/document = 30
Embedding dimensions = 768
Storage/dimension = 4 bytes (float32)
100,000,000 × 30
= 3,000,000,000 vectors
3B × 768 × 4 bytes
≈ 9.2 TB
ANN index structures
chunk text
document metadata
ACL metadata
IDs
lexical indexes
replicas
snapshots
WALs
temporary indexes
operational headroom
100M documents × 50 chunks
= 5 billion vectors
你将构建的架构
对于要构建的架构,在修改代码之前需明确输入参数、该步骤的负责人以及终止标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 优先选择小型、可测试的单元,而非冗长的脚本。当某个步骤失败时,故障应指向单一责任点,而非复杂的流程链。 需引用实际作为答案依据的段落。没有引用的话,操作人员就无法区分是幻觉内容还是索引缺失导致的错误。 对于要构建的架构,在修改代码之前需明确输入参数、该步骤的负责人以及终止标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 除了功能结果外,还需记录执行时间以及令牌或查询成本。提前了解成本情况,可避免在流程从演示环境转为共享环境时出现意外费用。
……
真相的来源并非你的向量数据库
在处理“真相的来源”这一阶段时,首先需写下相关规范:所需的输入参数、成功标志,以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改保持一致性。 应将配置信息置于应用程序代码之外。环境文件、密钥存储以及功能开关应集中存放于一个位置,这样操作人员无需查看整个系统结构即可进行审计。 在调整提示词之前,需先使用固定的问题集来衡量检索的召回率。仅仅更换提示词往往无法解决检索效果不佳的问题。
数据摄入必须为异步方式
在处理“数据摄入必须为异步”这一阶段时,首先需明确相关规范:所需的输入参数、成功信号以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改不会偏离原有设计。
POST /documents
│
▼
Store document
│
▼
Create ingestion event
│
▼
Return 202 Accepted
每个数据摄入步骤都应具备幂等性
在处理“每个数据摄入步骤都应满足的条件”这一阶段时,首先需明确相关规范:所需的输入参数、成功标志,以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改始终符合预期。 相比冗长的脚本,更应采用小型且可测试的单元。当某个步骤出现故障时,故障原因应能指向单一责任模块,而非复杂的流程链。 在调整提示词之前,先使用固定的问题集来测试召回率。仅仅更换提示词往往无法解决检索效果不佳的问题。 在处理“每个数据摄入步骤都应满足的条件”这一阶段时,首先需明确相关规范:所需的输入参数、成功标志,以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改始终符合预期。 在功能结果之外,还需记录处理时间以及Token或查询成本。提前了解成本情况,可避免在从演示环境过渡到共享环境时出现意外费用。
document_id
document_version
chunk_index
embedding_model_version
hash(
tenant_id +
document_id +
document_version +
chunk_index
)
upsert(chunk_id, ...)
分块策略成为基础设施层面的决策
将“分块策略成为基础设施”这一阶段视为可度量的对象来处理效果最佳。在扩大范围之前,先记录一份优秀的示例文本、一个故障案例以及回滚说明。 配置应与应用程序代码分开存放。环境文件、密钥存储和功能开关应集中于一个位置,以便操作人员无需查看整个系统结构即可进行审计。 分块策略与检索策略应相互独立。当质量指标发生变化时,修改其中一项不应迫使重新编写另一项。
embedding compute
vector storage
indexing work
retrieval fan-out
reindexing time
replication traffic
{
"chunk_id": "c_982...",
"document_id": "doc_51...",
"document_version": 8,
"tenant_id": "tenant_17",
"page": 43,
"section": "Risk Factors",
"language": "en",
"created_at": "...",
"acl_groups": ["finance", "executives"],
"embedding_version": "embed_v4"
}
除非确实有必要,否则不要搜索整个语料库
将“禁止搜索”阶段视为可度量的界面时,其效果最佳。在扩大范围之前,先记录一个成功的案例、一个失败案例以及回滚说明。同时记录正常流程和恢复流程。重试机制、人工审核环节以及死信处理都是产品本身的一部分,而非后续需要补充的内容。应将分块策略与检索策略分开,当质量指标发生变化时,修改其中一项不应迫使重新编写另一项。
organization = current tenant
region = Europe
topic = refund policy
time = current quarter
permissions = documents user may access
分片是向量层实现分布式的方式
将该阶段视为可度量的对象时,分片机制是使其最佳运行的方式。在扩大范围之前,先记录一份理想的运行示例、一个故障案例以及回滚说明。 优先选择小型且可测试的单元,而非庞大的脚本。当某个步骤出现故障时,故障应指向单一责任模块,而非复杂的流程链。 将分块策略与检索策略分开。当质量指标发生变化时,修改其中一项不应迫使重新编写另一项。 将该阶段视为可度量的对象时,分片机制是使其最佳运行的方式。在扩大范围之前,先记录一份理想的运行示例、一个故障案例以及回滚说明。 除了功能结果外,还需记录执行时间以及令牌或查询成本。提前了解成本情况,可避免在从演示环境过渡到共享环境时出现意外费用。
tenant_id
region
document namespace
language
time partition
Query
↓
128 shards
tenant_id = 429
↓
Shard group 18
↓
4 shards
复制机制解决的是不同问题
在“复制机制解决的是不同问题”这一阶段,应在修改代码之前明确输入参数、该步骤的负责人以及结束标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 配置信息应置于应用程序代码之外。环境文件、密钥存储以及功能标志应集中存放于一个位置,这样操作人员无需查看整个系统结构即可进行审核。 需引用实际作为答案依据的段落。如果没有引用,操作人员就无法区分是虚假信息还是索引缺失导致的错误。
Shard A → Node 1
Shard B → Node 2
Shard C → Node 3
Shard A → Node 1 + Node 4
Shard B → Node 2 + Node 5
Shard C → Node 3 + Node 6
仅靠向量搜索是不够的
在“仅向量搜索”阶段,应在修改代码之前明确输入参数、该步骤的负责人以及终止标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 需同时记录正常流程和异常恢复流程。重试机制、人工审核环节以及错误处理都是产品本身的组成部分,而非后续需要补充的功能。 必须引用那些真正作为答案依据的段落。如果没有引用,操作人员就无法区分是幻觉内容还是索引缺失导致的错误。
RRF(d) = Σ 1 / (k + rank_i(d))
谨慎使用顺序预过滤
在“谨慎处理顺序执行”阶段,修改代码之前需明确输入参数、该步骤的负责人以及终止标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 优先选择小型、可测试的单元,而非冗长的脚本。当某个步骤失败时,故障应指向单一责任点,而非复杂的流程链。 需引用实际作为答案依据的段落。没有引用的话,操作人员就无法区分是幻觉内容还是索引缺失导致的错误。 在“谨慎处理顺序执行”阶段,修改代码之前需明确输入参数、该步骤的负责人以及终止标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 除了功能结果外,还需记录执行时间以及令牌或查询成本。提前了解成本情况,可避免在从演示环境过渡到共享环境时出现意外费用。
……
3B documents
↓
BM25 returns 10,000
↓
vector search only those
tenant
permissions
document status
在证据传递给大语言模型之前必须完成授权
在处理“必须先完成授权”这一阶段时,首先写下相关合同条款:所需的输入参数、成功信号以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改保持一致性。 应将配置信息置于应用程序代码之外。环境文件、密钥存储以及功能开关应集中存放于一个位置,这样操作人员无需查看整个系统结构即可进行审计。 缓存稳定的系统指令和工具架构。重复发送相同的开头信息是导致资源浪费的常见原因。
Engineering documents
HR documents
Board documents
Legal documents
Executive compensation
Customer contracts
Vector Search
↓
Retrieve confidential chunk
↓
Send chunk to LLM
↓
Check permission
User
↓
Identity
↓
Groups / roles / ACL
↓
Authorized search space
↓
Retrieval
检索应返回候选项而非上下文
在处理“检索应生成候选项”这一阶段时,首先需明确相关约定:所需的输入参数、成功标志以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改不会偏离原有设计。
Vector candidates: 200
Lexical candidates: 200
│
▼
Fusion
│
▼
~250 unique chunks
│
▼
Reranker
│
▼
top 20–40
然后去除冗余内容
在处理“去除冗余”阶段时,首先需明确相关规范:所需输入、成功标志以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改保持一致性。 优先选择小型、可测试的单元,而非庞大的脚本。当某个步骤失败时,故障应指向单一责任点,而非复杂的流程链。 在调整提示词之前,先使用固定的问题集测试召回率。仅仅更换提示词很难改善较差的检索效果。 在处理“去除冗余”阶段时,首先需明确相关规范:所需输入、成功标志以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改保持一致性。 在功能结果旁记录执行时间以及token或查询成本。提前了解成本情况,可避免从演示环境过渡到共享环境时出现意外费用。
Chunk 1 → page 14
Chunk 2 → page 14
Chunk 3 → page 15
Chunk 4 → page 14
Chunk 5 → page 15
deduplication
document diversity
section diversity
near-duplicate detection
adjacent-chunk merging
token budgeting
chunk 46
chunk 47
chunk 48
上下文构建属于独立层次
将上下文构建视为可测量的层面时,其相关流程能发挥最佳效果。在扩大范围之前,先记录一份优秀的处理案例、一个失败案例以及回滚说明。 配置应置于应用程序代码之外。环境文件、密钥存储和功能开关应集中存放,以便操作人员无需查看整个系统结构即可进行审计。 将分块策略与检索策略分开。当质量指标发生变化时,修改其中一项不应迫使重新编写另一项。
context = "\n\n".join(retrieved_chunks)
Retrieved Evidence
↓
Deduplicate
↓
Merge related chunks
↓
Enforce token budget
↓
Preserve source IDs
↓
Order evidence
↓
Generate context
SOURCE S1
Document: Employee Handbook
Page: 42
Version: 18
Text: ...
SOURCE S2
Document: European Leave Addendum
Page: 7
Version: 4
Text: ...
QUESTION
...
查询理解应当成本低廉
将查询理解视为可度量的指标时,其在“阶段化处理”模式下的效果最佳。在扩大范围之前,先记录一个成功的查询案例、一个失败案例以及回滚说明。 同时记录正常处理流程和故障恢复流程。重试机制、人工审核环节以及死信处理都是产品本身的一部分,而非后续需要补充的功能。 应将分块策略与检索策略分开。当质量指标发生变化时,调整其中一个不应强制要求重新编写另一个。
metric = revenue
region = Europe
year = 2025
intent = financial comparison
How much did revenue grow in Asia in 2025?
small model
↓
classification
small model
↓
query rewriting
embedding model
↓
retrieval
reranker
↓
relevance
large model
↓
final reasoning
largest model everywhere
查询分解有助于处理多跳查询
将“查询分解辅助阶段处理”视为可度量的对象时,其效果最佳。在扩大范围之前,先记录一份理想的处理结果、一个故障案例以及回滚说明。 相较于庞大的脚本,应优先选择小型且可测试的单元。当某一步骤出现故障时,故障原因应能明确指向某个特定责任方,而非复杂的流程链。 应将分块策略与检索策略分开。当质量指标发生变化时,调整其中一个不应迫使重新编写另一个。 将“查询分解辅助阶段处理”视为可度量的对象时,其效果最佳。在扩大范围之前,先记录一份理想的处理结果、一个故障案例以及回滚说明。 除了功能结果外,还需记录处理时间以及令牌或查询成本。提前了解成本情况,可避免在从演示环境过渡到共享环境时出现意外费用。
Question 1:
Which European product had the largest decline?
Question 2:
What explanation did management provide for that product?
Complex Query
│
▼
Query Decomposer
/ \
/ \
▼ ▼
Subquery A Subquery B
│ │
▼ ▼
Retrieval Retrieval
\ /
\ /
▼ ▼
Evidence Join
│
▼
LLM
新鲜度会改变索引策略
在“新鲜度改变索引”阶段,应在修改代码之前明确输入参数、该步骤的负责人以及终止标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 配置信息应置于应用程序代码之外。环境文件、密钥存储以及功能标志应集中存放于一个位置,以便操作人员无需查看整个系统结构即可进行审核。 需引用实际作为答案依据的段落。如果没有引用,操作人员就无法区分是幻觉内容还是索引缺失导致的错误。
Document updated
│
▼
new document version
│
▼
parse changed document
│
▼
generate new chunks
│
▼
embed
│
▼
write new index entries
│
▼
mark previous version inactive
document_id = D17
version 41 → status=inactive
version 42 → status=active
status = active
模型版本控制同样重要
在“模型版本控制也很重要”阶段,应在修改代码之前明确输入参数、该步骤的负责人以及终止标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 需同时记录正常流程和异常恢复流程。重试机制、人工审核环节以及错误处理都是产品本身的组成部分,而非后续需要补充的内容。 当下一步操作是代码编写或工具调用时,应优先使用具有结构化格式且经过模式验证的输出,而非自由形式的文本。
embedding_model
embedding_version
embedding_dimensions
chunking_version
parser_version
Documents
│
┌─────────┴─────────┐
▼ ▼
embedding model V3 embedding model V4
│ │
▼ ▼
Index V3 Index V4
│
▼
shadow traffic
│
▼
evaluate
│
▼
switch alias
缓存应存在于多个层级
在“缓存应当存在”阶段,修改代码之前需明确输入参数、该步骤的负责人以及终止标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 优先选择小型、可测试的单元,而非冗长的脚本。当某个步骤失败时,故障应指向单一责任点,而非复杂的流程链。 需引用实际作为答案依据的段落。没有引用的话,操作人员就无法区分是幻觉内容还是索引缺失导致的错误。 在“缓存应当存在”阶段,修改代码之前需明确输入参数、该步骤的负责人以及终止标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 除了功能结果外,还需记录执行时间以及令牌或查询成本。提前了解成本情况,可避免在从演示环境过渡到共享环境时出现意外费用。
ts。
embedding
→ distributed retrieval
→ reranking
→ large LLM
User Query
│
▼
Exact Response Cache
│ miss
▼
Semantic Cache
│ miss
▼
Retrieval Cache
│ miss
▼
Search
hash(normalized_query)
↓
query embedding
Policy version 17
Policy version 18
错误处理比正常路径的延迟更为重要
在处理“错误处理更为重要”这一阶段时,首先需明确相关规范:所需的输入参数、成功信号,以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改保持一致性。 应将配置信息与应用程序代码分开存放。环境文件、密钥存储以及功能开关应集中管理,以便操作人员无需查看整个系统结构即可进行审计。 在调整提示词之前,需先使用固定的问题集来测试系统的召回率。仅仅更换提示词往往无法解决检索效果不佳的问题。
embedding provider unavailable
one vector shard unavailable
search cluster degraded
reranker timeout
LLM rate limited
LLM provider outage
queue backlog growing
parser crashing on malformed PDF
OCR worker running out of memory
Vector search fails
↓
Can lexical search answer?
↓
yes
↓
return degraded retrieval mode
Primary LLM unavailable
↓
Fallback model
↓
Lower quality but service continues
Document parser fails 5 times
↓
Dead-letter queue
↓
record failure reason
↓
operator / automated remediation
背压机制不可或缺
在处理“背压机制至关重要”这一阶段时,首先需明确相关约定:所需的输入参数、成功信号以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改保持一致性。 同时记录正常流程与故障恢复流程。重试机制、人工审核环节以及死信处理都是产品功能的一部分,而非后续的优化工作。 在调整提示词之前,需先用固定的问题集来衡量检索效果。仅仅更换提示词很难解决检索能力薄弱的问题。
20M chunks/hour
25M chunks/hour
200M chunks/hour
embedding service overloaded
↓
timeouts
↓
retries
↓
more load
↓
more failures
↓
retry storm
incoming workload
↓
durable queue
↓
workers consume at safe rate
↓
backlog temporarily grows
可观测性必须能够衡量检索质量
在处理“可观测性必须能够量化”这一阶段时,首先需明确相关规范:所需的输入参数、成功标志,以及部分失败时的处理方式。这样的清单能确保后续的代码修改保持一致性。 相较于庞大的脚本,应优先选择小型且可测试的单元。当某个步骤出现故障时,故障点应指向单一责任模块,而非复杂的流程链。 在调整提示词之前,先针对固定的问题集测试召回率。仅仅更换提示词很难解决检索效果不佳的问题。 在处理“可观测性必须能够量化”这一阶段时,首先需明确相关规范:所需的输入参数、成功标志,以及部分失败时的处理方式。这样的清单能确保后续的代码修改保持一致性。 除了功能结果外,还需记录执行时间以及Token或查询成本。提前了解成本情况,可避免在从演示环境过渡到共享环境时出现意外费用。
HTTP 200 rate
CPU
memory
disk
p95 latency
error rate
requests/second
request_id: rq_912
query rewrite:
"parental policy?" → "parental leave policy"
vector retrieval:
200 candidates
145 ms
lexical retrieval:
200 candidates
91 ms
fusion:
278 unique candidates
reranking:
278 → 20
212 ms
context:
13 chunks
8,420 tokens
LLM:
input 9,104 tokens
output 681 tokens
1.8 sec
citations:
3 documents
total:
2.4 sec
将检索流程与LLM分开评估
将“评估检索流程”这一环节视为可测量的对象来处理效果最佳。在扩大范围之前,先记录一份理想的处理结果、一个失败案例以及回滚说明。 配置应置于应用程序代码之外。环境文件、密钥存储和功能开关应集中存放,以便操作人员无需查看整个系统结构即可进行审计。 为每轮对话和每次会话设定token预算。智能工具往往会大量消耗上下文信息,设置上限可避免演示过程突然产生额外费用。
检索失败
将检索失败阶段视为可度量的指标时,其效果最佳。在扩大范围之前,先记录一个成功的处理案例、一个失败案例以及回滚说明。 同时记录正常流程和恢复流程。重试机制、人工审核环节以及死信处理都是产品本身的组成部分,而非后续需要补充的功能。 应将分块策略与检索策略分开。当质量指标发生变化时,修改其中一项不应迫使重新编写另一项。
Correct document exists
↓
retriever misses it
↓
LLM never sees it
↓
wrong answer
生成失败
将生成失败阶段视为可度量的对象来处理效果最佳。在扩大范围之前,先记录一份理想的输出样本、一个失败案例以及回滚说明。 优先选择小型且可测试的单元,而非庞大的脚本。当某个步骤出现故障时,故障应指向单一责任模块,而非复杂的流程链。 将分块策略与检索策略分开。当质量指标发生变化时,修改其中一项不应迫使重新编写另一项。 将生成失败阶段视为可度量的对象来处理效果最佳。在扩大范围之前,先记录一份理想的输出样本、一个失败案例以及回滚说明。 除了功能结果外,还需记录处理时间以及令牌或查询成本。提前了解成本情况,可避免在从演示环境过渡到共享环境时出现意外费用。
correct evidence
↓
context
↓
LLM
↓
incorrect interpretation
延迟应设有预算限制
在修改代码之前,针对延迟问题应先明确相关阶段、输入参数、该步骤的负责人以及结束标准。操作人员应当能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 配置应置于应用程序代码之外。环境文件、密钥存储以及功能标志应集中存放于一个位置,这样操作人员无需查看整个系统结构即可进行审核。 需引用实际作为答案依据的段落。如果没有引用,操作人员就无法区分是虚假信息还是索引缺失导致的问题。
API + auth 50 ms
query understanding 100 ms
retrieval 300 ms
fusion 20 ms
reranking 250 ms
context construction 30 ms
LLM time-to-first-token 1,200 ms
network / safety margin 550 ms
-----------------------------------
target ~2,500 ms
成本问题也需要同样处理
对于同一阶段的成本需求,应在修改代码之前明确输入参数、该步骤的负责人以及结束标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 需同时记录正常流程和异常恢复流程。重试机制、人工审核环节以及错误处理都是产品本身的组成部分,而非后续需要补充的内容。 必须引用实际作为答案依据的段落。如果没有引用,操作人员就无法区分是虚假信息还是索引缺失导致的错误。
object storage
document parsing
OCR
embedding generation
vector storage
vector replicas
lexical search
metadata database
network transfer
reranking
LLM input tokens
LLM output tokens
observability
backups
cost / 1,000 indexed documents
cost / million chunks
cost / query
cost / successful answer
cost / tenant
Tenant A
5% of revenue
42% of LLM spend
不要将所有数据都存放在昂贵的存储中
在“不要把所有内容都放在一起”阶段,修改代码之前需明确输入参数、该步骤的负责人以及结束标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 相较于冗长的脚本,更应选择小型且可测试的单元。当某个步骤失败时,故障原因应能指向单一责任点,而非复杂的流程链。 需引用实际作为答案依据的段落。没有引用的话,操作人员就无法区分是虚假信息还是索引缺失导致的错误。 在“不要把所有内容都放在一起”阶段,修改代码之前需明确输入参数、该步骤的负责人以及结束标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 除了功能结果外,还需记录执行时间以及令牌或查询成本。提前了解成本情况,可避免在流程从演示环境转向共享环境时出现意外费用。
>expensive / fast
▲
│
vector indexes
search indexes
Redis caches
│
metadata DB
│
object storage
│
▼
cheap / large
热数据与冷数据可能需要不同的处理方式
在处理热数据与冷数据的阶段时,首先明确相关规范:所需的输入参数、成功信号以及部分失败时的处理方式。这样的清单能确保后续的代码修改始终符合要求。 应将配置信息与应用程序代码分开存放。环境文件、密钥存储以及功能开关应集中管理,这样操作人员无需查看整个系统结构即可进行审计。 在调整提示词之前,先使用固定的问题集来测试召回率。仅仅更换提示词往往无法解决检索效果不佳的问题。
Last 30 days → 70% of queries
Last 12 months → 25%
Older archive → 5%
Query
│
├────→ Hot index
│
└────→ Archive index when necessary
多租户模式会改变一切
在处理“多租户模式彻底改变一切”这一阶段时,首先需明确相关约定:所需的输入参数、成功标志以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改始终符合预期。 同时记录正常流程与故障恢复流程。重试机制、人工审核环节以及错误消息处理都是产品本身的组成部分,而非后续需要补充的功能。 在调整提示词之前,先使用固定的问题集来测试召回率。仅仅更换提示词往往无法解决检索效果不佳的问题。
10,000 organizations
10,000 completely independent vector clusters
Small tenants
↓
shared shard groups
Medium tenants
↓
partitioned shared infrastructure
Very large tenants
↓
dedicated shard groups
大语言模型应位于架构的末端
在处理“LLM应当具备的功能”这一阶段时,首先需明确相关规范:所需的输入参数、成功标志以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改保持一致性。 建议采用小型、可测试的单元而非庞大的脚本。当某个步骤出现故障时,故障应指向单一责任模块,而非复杂的流程链。 对稳定的系统指令和工具结构进行缓存。重复发送相同的开头信息是导致资源浪费的常见原因。 在处理“LLM应当具备的功能”这一阶段时,首先需明确相关规范:所需的输入参数、成功标志以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改保持一致性。 在记录功能结果的同时,还需标注执行时间以及Token或查询成本。提前了解成本情况,可避免在从演示环境过渡到共享环境时出现意外费用。
User
↓
API Gateway
↓
Authentication
↓
Authorization
↓
Rate Limiter
↓
Query Understanding
↓
Shard Routing
↓
Hybrid Candidate Retrieval
↓
Rank Fusion
↓
Reranker
↓
Deduplication
↓
Context Builder
↓
LLM
↓
Citation Validation
↓
Response
完整的生产环境架构
将“完整生产架构”阶段视为可度量的对象来处理时,其效果最佳。在扩大范围之前,先记录一份优秀的测试用例、一个故障案例以及回滚说明。 将配置与应用程序代码分开。环境文件、密钥存储和功能开关应集中存放于一处,这样操作人员无需查看整个架构就能进行审计。 将分块策略与检索策略分开。当质量指标发生变化时,修改其中一项不应迫使重新编写另一项。
CLIENTS
│
▼
┌──────────────┐
│ API Gateway │
└──────┬───────┘
│
┌──────▼───────┐
│ Auth / ACL │
│ Rate Limits │
└──────┬───────┘
│
▼
┌────────────────────┐
│ Query Orchestrator │
└─────────┬──────────┘
│
┌─────────────┼──────────────┐
│ │ │
▼ ▼ ▼
Cache Query Rewrite Metadata
Filters
│ │ │
└─────────────┼──────────────┘
▼
Shard Router
│
┌────────────┴────────────┐
▼ ▼
Lexical Search Vector Search
│ │
└───────────┬─────────────┘
▼
Rank Fusion
│
▼
Reranker
│
▼
Deduplicate
│
▼
Context Builder
│
▼
LLM
│
▼
Citation Validation
│
▼
RESPONSE
================================================================
INGESTION SYSTEM
Documents
│
▼
Object Store
│
▼
Event Queue
│
┌────────────┼────────────┐
▼ ▼ ▼
Parser Parser Parser
│ │ │
└────────────┼────────────┘
▼
Normalization
│
▼
Chunker
│
┌──────────────┴──────────────┐
▼ ▼
Embedding Queue Text Index Queue
│ │
┌─────┼─────┐ ▼
▼ ▼ ▼ Lexical Index
GPU GPU GPU
│ │ │
└─────┼─────┘
▼
Vector Index
================================================================
SUPPORTING SYSTEMS
Metadata DB → document state, versions, ownership
Object Storage → original source documents
Vector Cluster → semantic retrieval
Search Cluster → lexical retrieval
Redis → caches and rate limiting
Message Queue → asynchronous ingestion
Observability → traces, metrics, evaluation
Secrets / IAM → service authorization
Evaluation System → retrieval + answer-quality tests
不应采取的做法
“你不会去展示的内容”这一概念在被视为可度量的指标时效果最佳。在扩大范围之前,先记录一个成功的案例、一个失败案例以及回滚说明。 同时记录正常流程和恢复流程。重试机制、人工审核环节以及死信处理都是产品本身的一部分,而非后续需要补充的内容。 将分块策略与检索策略分开。当质量指标发生变化时,修改其中一项不应强制要求重新编写另一项。
One giant vector collection with no routing strategy
Synchronous PDF ingestion
Only vector retrieval, no lexical search
ACL filtering after retrieval
No document versioning
No embedding model version
No reranking
Sending top-100 chunks directly to the LLM
Using the LLM for every trivial classification task
No dead-letter queue
No retrieval-level evaluation
No tenant-level cost attribution
Treating the vector DB as permanent document storage
Re-embedding the entire corpus for every small content change
Benchmarking only average latency instead of tail latency
核心设计原则
将“核心设计原则”阶段视为可度量的对象来处理效果最佳。在扩大范围之前,先记录一份理想的执行案例、一个故障实例以及回滚说明。 优先选择小型且可测试的单元,而非庞大的脚本。当某个步骤出现故障时,故障应指向单一责任点,而非复杂的流程链。 将分块策略与检索策略分开。当质量指标发生变化时,修改其中一项不应迫使重新编写另一项。 将“核心设计原则”阶段视为可度量的对象来处理效果最佳。在扩大范围之前,先记录一份理想的执行案例、一个故障实例以及回滚说明。 除了功能结果外,还需记录执行时间以及令牌或查询成本。提前了解成本情况,可避免在从演示环境过渡到共享环境时出现意外费用。
question
→ vector search
→ LLM
billions of possible evidence units
↓
routing constraints
↓
relevant partitions
↓
cheap candidate search
↓
hundreds of items
↓
expensive reranking
↓
tens of passages
↓
context optimization
↓
LLM
↓
grounded answer
Cheap operation → huge search space
Moderate operation → smaller candidate set
Expensive operation → tiny candidate set
Most expensive model → final context only
最终结论
在最终落实阶段,应在修改代码之前明确输入参数、该步骤的负责人以及终止标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。 配置信息应置于应用程序代码之外。环境文件、密钥存储以及功能开关应集中存放于一个位置,以便操作人员无需查看整个系统结构即可进行审计。 需引用实际作为答案依据的段落。如果没有引用,操作人员就无法区分是幻觉内容还是索引缺失导致的错误。
操作检查清单
在处理操作检查清单阶段时,首先需明确相关约定:所需输入参数、成功标志,以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改保持一致性。
将此阶段视为输入与经过验证的输出之间的契约。为相关成果命名,明确成功标准,绝不允许出现无声的半完成状态。
在调整提示词之前,先使用固定的问题集来衡量召回率。频繁更换提示词很难改善较差的检索效果。
锁定依赖版本,并记录用于演示的图像摘要。可重复性比经验知识更为可靠。
在功能结果之外,还需记录处理时间以及token或查询成本。提前了解成本情况,可避免从演示环境过渡到共享环境时出现意外费用。
在调整提示词之前,先使用固定的问题集来衡量召回率。频繁更换提示词很难改善较差的检索效果。
在推广该技术栈之前,应先冻结版本,为关键流程记录标准输出日志,并明确回滚步骤。共享环境需要设置速率限制、租户验证机制,以及负责密钥轮换的明确责任人。与其展示花哨的一次性演示,不如注重扎实的可靠性。
关于1f03733b8d4b的批注:请将提供商密钥移出代码仓库,设定单会话令牌上限,并将日志存储在评估用示例文件旁,以便后续模型更换时仍能保持对比性。