问答集
第一类:架构设计类问题
为什么选择 ReAct 模式而不是 Plan-and-Execute?
Situation(情景) 在设计企业级 AI Agent 系统时,需要在 ReAct(Reasoning + Acting)和 Plan-and-Execute 两种主流 Agent 范式之间做出架构决策。业务场景包括客服问答、知识检索、工具调用等多种任务类型。
Task(任务) 选择一种既能满足实时交互需求,又能处理复杂多步任务的 Agent 架构范式。
Action(行动)
- 对比分析两种范式:
- **ReAct:**思考-行动-观察的循环模式,每一步都基于当前观察做出决策,具有强交互性和动态适应能力。
- **Plan-and-Execute:**先制定完整计划,再按步骤执行,适合任务结构明确、步骤可预见的场景。
- 基于业务场景评估:
- 企业客服场景中,用户意图经常在对话中变化(如从查订单变成要退款),ReAct 能实时调整策略。
- Plan-and-Execute 在计划阶段就需要确定所有步骤,一旦中间步骤失败,整个计划需要重做。
- ReAct 的流式特性天然支持"边思考边输出",用户体验更好。
- 技术可行性评估:
- ReAct 的 Prompt 模板更灵活,可以通过 few-shot 快速调整行为。
- ReAct 与 Function Calling 天然兼容,每次思考后可以调用工具。
- 通过设置最大迭代次数(max_iterations=10)和超时机制,可有效防止死循环。
- 混合方案设计:
- 实际落地中采用 ReAct 为主、Plan 为辅的混合方案。
- 简单查询(单步任务):直接走 ReAct 单次循环。
- 复杂任务(多步骤):先用 LLM 生成粗粒度 Plan,每个步骤内部用 ReAct 执行。
Result(结果)
- 系统平均响应时间从纯 Plan-and-Execute 的 8s 降低到 ReAct 模式的 3.2s(简单任务直接缩短为单步)。
- 任务完成率从 78% 提升到 91%,因为 ReAct 能根据中间结果动态调整策略。
- 用户满意度提升 15%,因为流式输出让用户感知到更快的响应。
为什么采用多路检索而不是单一向量检索?
Situation(情景) 企业知识库包含大量结构化和非结构化数据,单一向量检索在某些场景下召回率不足。例如,精确的编号查询(如"工单号 WO-20240315-001")在纯语义检索中表现很差。
Task(任务) 设计一个兼顾语义理解和精确匹配的检索架构,提升知识检索的准确率和召回率。
Action(行动)
- 多路检索架构设计:
- **向量检索(语义通道):**使用 Milvus 存储文档向量,基于 embedding 相似度做语义召回,top_k=20。
- **关键词检索(精确通道):**使用 Elasticsearch 做 BM25 检索,处理精确查询、编号匹配等场景,top_k=20。
- **知识图谱检索(关系通道):**针对实体关系类问题(如"张三负责哪些项目"),从 Neo4j 中检索实体关系。
- 结果融合策略:
- 采用 RRF(Reciprocal Rank Fusion)算法融合多路结果。
- 公式:RRF_score = Σ 1/(k + rank_i),其中 k=60 是平滑常数。
- 每路检索结果独立排序后,通过 RRF 算法统一排名。
- 查询路由策略:
- 意图识别模块判断查询类型,动态激活不同检索通道。
- 精确查询(含编号、代码等)→ 优先走关键词通道。
- 概念性问题("什么是微服务")→ 优先走向量通道。
- 关系查询("谁负责某项目")→ 启用知识图谱通道。
Result(结果)
- 整体检索准确率(Precision@5)从单一向量检索的 72% 提升到多路融合的 89%。
- 召回率(Recall@20)从 65% 提升到 93%。
- 精确编号类查询的命中率从 30% 提升到 98%。
Agent 编排器是怎么设计的?为什么这样设计?
Situation(情景) 系统需要协调多个组件(意图识别、检索、生成、工具调用等)的执行流程,需要一个灵活且可扩展的编排机制。
Task(任务) 设计一个能支持多种执行模式(顺序、并行、条件分支)且易于扩展的 Agent 编排器。
Action(行动)
- 核心架构 —— 状态机 + 事件驱动:
- 用户输入 → 意图识别 → 路由决策 → 执行计划 → 工具/检索调用 → 结果整合 → 响应生成
- 定义了 7 个核心状态:INIT → INTENT_PARSED → PLANNED → EXECUTING → TOOL_CALLED → SYNTHESIZING → COMPLETED
- 每个状态转换由事件触发,通过状态转换表控制流程。
- 编排器核心组件:
- **AgentOrchestrator(总编排器):**管理整体流程,维护执行上下文。
- **TaskPlanner(任务规划器):**将复杂任务分解为子任务 DAG(有向无环图)。
- **ToolDispatcher(工具分发器):**根据 Function Calling 结果调用对应工具。
- **ContextManager(上下文管理器):**维护对话历史、工具调用结果等上下文信息。
- 设计决策的考量:
- **为什么用状态机?**可枚举所有合法状态转换,便于 debug 和异常处理,比纯 LLM 链式调用更可控。
- **为什么用事件驱动?**解耦各组件,支持异步执行和并行工具调用,提升系统吞吐量。
- **为什么用 DAG 而非线性队列?**支持并行子任务(如同时查数据库和调 API),减少总执行时间。
- 可扩展性设计:
- 新增工具只需实现 BaseTool 接口并注册到 ToolRegistry。
- 新增 Agent 类型只需定义新的状态转换规则。
- 通过配置文件管理流程编排,无需修改核心代码。
Result(结果)
- 支持了 12 种不同的业务流程编排,每种只需配置不覅改代码。
- 新工具接入时间从原来的 2 天缩短到 2 小时(标准化接口)。
- 并行工具调用使复杂任务执行时间缩短 40%。
多 Agent 协作和单 Agent 有什么区别?你怎么选择?
Situation(情景) 随着业务复杂度增加,单个 Agent 的 Prompt 越来越长,工具数量越来越多,开始出现能力退化和维护困难的问题。
Task(任务) 评估是否需要从单 Agent 架构迁移到多 Agent 协作架构,以及如何设计协作机制。
Action(行动)
- 单 Agent 的瓶颈分析:
- 单 Agent 的系统 Prompt 超过 4000 tokens 后,指令遵循能力明显下降。
- 工具数量超过 15 个时,LLM 选择工具的准确率从 95% 下降到 78%。
- 所有逻辑耦合在一个 Prompt 中,修改一个功能可能影响其他功能。
- 多 Agent 架构设计:
- **Supervisor Agent(主管 Agent):**负责意图识别和任务路由,不直接执行任务。
- **RAG Agent(检索 Agent):**专注于知识检索和答案生成。
- **Tool Agent(工具 Agent):**专注于外部 API 调用和数据处理。
- **Summary Agent(摘要 Agent):**专注于长文本摘要和对话总结。
- 协作机制:
- **通信方式:**Agent 之间通过结构化消息传递(JSON Schema 定义),避免自然语言传递导致的信息损失。
- **执行策略:**Supervisor 判断任务类型后,将任务分派给专业 Agent;支持顺序执行和并行执行。
- **结果汇总:**由 Supervisor Agent 整合各子 Agent 结果,生成最终回答。
- 选择标准:
- 工具数 ≤ 8 且业务逻辑简单 → 单 Agent。
- 工具数 > 8 或需要专业分工 → 多 Agent。
- 有跨域协作需求(如同时查知识库和调外部 API)→ 多 Agent。
Result(结果)
- 迁移到多 Agent 后,工具选择准确率回升到 96%。
- 每个 Agent 的 Prompt 控制在 2000 tokens 以内,维护性大幅提升。
- 新增业务场景只需新增专业 Agent,不影响现有功能。
- 系统整体任务完成率从 85% 提升到 93%。
为什么选择 Milvus 而不是其他向量数据库?
Situation(情景) 项目需要一个向量数据库来存储和检索文档 embedding,候选方案包括 Milvus、Pinecone、Weaviate、Qdrant、Chroma、FAISS 等。
Task(任务) 综合评估各方案的性能、功能、运维成本,选择最适合企业级场景的向量数据库。
Action(行动)
- 排除不适合的方案:
- **FAISS:**单机库,不支持分布式,无法满足高可用和数据持久化需求。
- **Chroma:**定位轻量级,不适合大规模生产环境。
- **Pinecone:**全托管方案,数据出境合规问题(数据必须存在海外)。
- 深度对比 Milvus vs Weaviate vs Qdrant:
- **性能:**Milvus 在 1000 万级向量上 QPS 达到 2000+,Qdrant 约 1500,Weaviate 约 1200。
- **扩展性:**Milvus 原生支持分布式部署(计算存储分离),可水平扩展。Qdrant 的分布式能力相对较弱。
- **索引类型:**Milvus 支持 IVF_FLAT、IVF_SQ8、HNSW、DiskANN 等多种索引,可根据数据规模选择最优方案。
- **混合搜索:**Milvus 2.x 支持标量过滤 + 向量搜索的混合查询,满足"按部门+语义"的业务需求。
- **生态:**Milvus 有 LangChain、LlamaIndex 等主流框架的官方集成。
- **社区:**Milvus 是 LF AI & Data 基金会毕业项目,社区活跃,长期维护有保障。
- POC 验证(基于 200 万文档的真实数据):
- 建立测试基准,对比查询延迟、召回率、资源占用。
- **Milvus:**P99 延迟 45ms,召回率 98.2%,内存占用 16GB。
- **Qdrant:**P99 延迟 62ms,召回率 97.8%,内存占用 14GB。
Result(结果)
- 最终选择 Milvus,部署了 3 节点集群。
- 线上稳定运行 8 个月,P99 延迟稳定在 50ms 以内。
- 数据量从 200 万增长到 800 万文档,通过水平扩展平滑支撑。
如果让你重新设计这个系统,你会怎么改进?
Situation(情景) 系统已经稳定运行一段时间,积累了很多实践经验和教训,有一些当初的设计决策在回头看是可以优化的。
Task(任务) 基于实际运行经验,总结需要改进的点,给出具体的优化方案。
Action(行动)
- 评估引入(Evaluation-Driven Development):
- 当初测试主要靠手动验证,应该从项目开始就建立自动化评估体系。
- 改进:引入 RAGAS、DeepEval 等框架,建立 CI 流水线中的自动评估。
- 每次提交自动跑评估集(500+ case),防止回归。
- 可观测性增强:
- 当初的日志系统是后补的,trace 不够完整。
- 改进:从第一行代码就接入 LangSmith / LangFuse,实现全链路 trace。
- 每个 Agent 步骤都有 span,可以在 dashboard 上看到完整的推理链路。
- Streaming 优先架构:
- 当初是先实现同步接口,后来改成流式,改造成本很高。
- 改进:从设计阶段就以 SSE/WebSocket 流式为默认通信方式。
- 更细粒度的模型路由:
- 当初只有简单/复杂两档路由。
- 改进:根据任务类型(分类/生成/推理/摘要)、输入长度、质量要求,做更细粒度的模型选择。
- Agent 记忆系统重构:
- 当初的记忆系统比较粗糙,只是简单的窗口截断。
- 改进:实现分层记忆(工作记忆 + 情景记忆 + 语义记忆),引入记忆索引和检索机制。
Result(结果) 这些改进方案已经在新版本中逐步实施,形成了团队的最佳实践文档。这个反思过程本身也体现了持续优化的工程思维。
怎么设计的对话管理和上下文维护?
Situation(情景) 企业客服场景中多轮对话非常普遍,需要在多轮交互中维护一致的上下文,同时控制 token 消耗。
Task(任务) 设计对话管理系统,在有限的 context window 内高效利用上下文信息。
Action(行动)
- 分层上下文管理:
- **系统层:**System Prompt(固定,约 800 tokens),定义 Agent 角色和行为规范。
- **会话层:**对话历史(动态,滑动窗口),最近 N 轮对话。
- **检索层:**RAG 检索到的知识上下文(动态,按相关性排序)。
- **工具层:**工具调用结果(临时,用完即清)。
- 窗口管理策略:
- 维护最近 10 轮对话的完整记录。
- 超过 10 轮时,前面的对话自动摘要压缩。
- 摘要保留关键信息:用户意图、关键决策、未解决的问题。
- Token 预算分配:
- 假设总 context window 为 8K tokens:
- **System Prompt:**800 tokens(10%)
- **对话历史 + 摘要:**2400 tokens(30%)
- **检索上下文:**3200 tokens(40%)
- **预留输出:**1600 tokens(20%)
Result(结果)
- 多轮对话的上下文一致性从 76% 提升到 94%(基于人工评估)。
- token 消耗控制在预算内,无超限导致的截断问题。
- 支持最长 50 轮对话不丢失关键上下文。
你怎么看待 MCP(Model Context Protocol)?在你的系统中是怎么使用的?
Situation(情景) Anthropic 发布了 MCP 协议,提供了一种标准化的方式让 AI 模型与外部工具和数据源交互。需要评估是否在系统中采用 MCP。
Task(任务) 评估 MCP 的价值,决定是否以及如何在现有系统中集成 MCP。
Action(行动)
- MCP 核心价值分析:
- **标准化接口:**定义了 tools、resources、prompts 三大原语,统一了不同工具的接入方式。
- **双向通信:**基于 JSON-RPC 2.0,支持服务端主动推送通知。
- **传输灵活:**支持 stdio(本地进程)和 SSE(远程服务)两种传输方式。
- 与 Function Calling 的对比:
- Function Calling 是模型厂商的私有协议,每个厂商格式不同。
- MCP 是开放协议,理论上可以跨模型、跨客户端复用工具。
- MCP 更适合构建工具生态,Function Calling 更适合简单集成。
- 在系统中的应用:
- 将现有工具封装为 MCP Server,对外提供标准化接口。
- 数据库查询、API 调用、文件操作等工具都通过 MCP Server 暴露。
- 内部 Agent 调用工具时,通过 MCP Client 发起请求。
- 落地挑战和解决:
- MCP 生态还在早期,部分工具的 MCP 封装需要自己开发。
- 安全审核:每个 MCP Server 的权限需要严格控制。
- 性能开销:MCP 协议的序列化/反序列化有额外开销(约 5ms),可接受。
Result(结果)
- 工具接入标准化后,新工具的平均接入时间从 2 天缩短到 4 小时。
- 工具可以在不同项目之间复用,减少重复开发。
- 为后续接入社区 MCP 工具生态奠定基础。
如何设计 Agent 的错误恢复和重试机制?
Situation(情景) 生产环境中 Agent 执行过程会遇到各种错误:LLM API 超时、工具调用失败、检索无结果等。简单的重试可能导致资源浪费或无限循环。
Task(任务) 设计一套智能的错误恢复机制,让 Agent 能优雅地处理各种异常情况。
Action(行动)
- 分层错误处理:
- **可恢复错误(Retryable):**网络超时、API 限流 → 指数退避重试(最多 3 次)。
- **可降级错误(Degradable):**主模型不可用 → 切换到备用模型。
- **不可恢复错误(Fatal):**权限不足、参数错误 → 向用户报告错误原因。
- 指数退避重试:
- retry_delay = base_delay * (2 ^ attempt) + random_jitter
- base_delay = 1s, max_delay = 30s, max_attempts = 3
- Agent 级别的自愈:
- 工具调用失败时,Agent 会收到错误信息,由 LLM 决定下一步:
- 换一种方式调用工具(修改参数)。
- 尝试使用替代工具。
- 告知用户无法完成并解释原因。
- 断点续传:
- 复杂任务的中间状态持久化到 Redis。
- 系统崩溃后可以从最近的检查点恢复执行。
Result(结果)
- 因 API 超时导致的用户可见错误从 5% 降低到 0.3%。
- 模型降级机制确保了 99.5% 的可用性。
- 断点续传避免了复杂任务的重复执行,节省了约 15% 的 token 成本。
你的系统支持多租户吗?怎么实现的?
Situation(情景) 系统需要同时服务多个企业客户,每个客户有自己的知识库、配置和数据隔离要求。
Task(任务) 设计多租户架构,确保数据隔离、配置独立、性能互不影响。
Action(行动)
- 数据隔离策略:
- **知识库隔离:**每个租户在 Milvus 中使用独立的 Collection(分区方案在数据量大时性能不好)。
- **对话数据隔离:**每个租户的对话记录存储在独立的数据库 schema 中。
- **缓存隔离:**Redis 中使用 tenant_id: 作为 key 前缀。
- 配置独立:
- 每个租户可以自定义:System Prompt、工具集合、模型选择、检索策略。
- 配置存储在数据库中,支持热更新(无需重启服务)。
- 资源限制:
- 每个租户有独立的 QPS 限制和 token 配额。
- 使用 Redis 令牌桶算法实现限流。
- 超出配额时返回 429 Too Many Requests。
Result(结果)
- 支持了 20+ 企业客户同时使用。
- 零数据泄露事故(严格的 tenant_id 过滤)。
- 单个客户的异常不会影响其他客户(资源隔离)。
第二类:技术实现类问题
向量数据库是怎么选型的?分块策略是什么?
Situation(情景) 企业知识库包含多种格式的文档(PDF、Word、HTML、Markdown),需要建立高效的向量检索系统。文档分块质量直接影响检索效果。
Task(任务) 选择合适的向量数据库并设计科学的文档分块策略。
Action(行动)
- **向量数据库选型(详见架构类 Q6):**最终选择 Milvus。
- 分块策略设计:
- 递归字符分块(默认策略):
- 分隔符优先级:\n\n → \n → 。 → , → 空格
- chunk_size = 512 tokens,chunk_overlap = 50 tokens(约 10%)
- 语义分块(高质量场景):
- 先计算每个句子的 embedding。
- 相邻句子的余弦相似度低于阈值 0.7 时,视为语义断点。
- 在语义断点处切分,保证每个 chunk 语义完整。
- 结构化分块(特殊文档):
- Markdown:按标题层级分块(#、##、###)。
- 代码文档:按函数/类分块。
- 表格:整表作为一个 chunk,附加上下文描述。
- 递归字符分块(默认策略):
- 分块元数据管理:
- 每个 chunk 存储元数据:文档ID、标题、章节路径、页码、分块位置。
- 检索时可利用元数据做过滤(如"只查某个文档的内容")。
- 分块质量评估:
- 自建评估集,对比不同分块策略的检索命中率。
- 定期抽样检查分块质量,调整参数。
Result(结果)
- 语义分块比固定长度分块的检索准确率提升 12%。
- 结构化分块在技术文档场景下准确率提升 18%。
- 分块参数经过 3 轮调优后趋于稳定。
记忆系统的短期和长期记忆是怎么配合的?
Situation(情景) Agent 需要在单次对话中维护上下文(短期记忆),同时在跨会话中记住用户偏好和历史交互(长期记忆)。
Task(任务) 设计分层记忆系统,实现短期和长期记忆的协同工作。
Action(行动)
- 短期记忆(Working Memory):
- **存储位置:**内存(进程内 + Redis 备份)。
- **内容:**当前会话的对话历史、中间推理结果、工具调用结果。
- 管理策略:
- 滑动窗口:保留最近 10 轮完整对话。
- 超出窗口的对话自动摘要压缩。
- 会话结束后 30 分钟过期清理。
- 长期记忆(Long-term Memory):
- **存储位置:**PostgreSQL(结构化信息)+ Milvus(语义检索)。
- 内容:
- 用户画像:偏好、常用术语、业务领域。
- 历史摘要:过往会话的关键信息摘要。
- FAQ 记忆:用户高频问的问题和答案对。
- 更新策略:
- 会话结束时,提取关键信息更新用户画像。
- 每日批量处理,对历史对话做摘要归档。
- 短期 → 长期记忆的转化:
- 会话结束时,LLM 自动提取本次对话的关键信息(如新偏好、已解决/未解决问题),提取结果写入长期记忆。
- 长期 → 短期记忆的召回:
- 新会话开始时,根据用户 ID 加载用户画像,并根据当前话题检索相关历史信息注入 context。
Result(结果)
- 跨会话上下文一致性从 30% 提升到 78%。
- 用户偏好记忆准确率 85%(基于 200 个测试 case)。
- 长期记忆占用控制在每用户 50MB 以内。
重排序是怎么做的?用的什么模型?
Situation(情景) 多路检索后得到大量候选 chunk(通常 30-60 个),需要精排后选出最相关的 top-5 给 LLM 生成答案。粗排的向量相似度和 BM25 分数不够精确。
Task(任务) 实现高质量的重排序(Reranking)模块,提升最终检索精度。
Action(行动)
- Reranker 模型选择:
- **BGE-Reranker-v2-M3(最终选择):**支持中英文,精度高,模型大小适中(568MB)。
- **Cohere Rerank:**效果好但需要调 API,增加延迟和成本。
- **Cross-encoder/ms-marco-MiniLM-L-12-v2:**英文效果好,中文不行。
- 重排序流程:
- 多路检索结果(~40条)→ 去重 → Reranker 打分 → 按分数排序 → 取 Top-5
- Reranker 输入:(query, chunk) pair,输出相关性分数 [0, 1]。
- 去重策略:基于 chunk 内容的 MinHash 去重(相似度 > 0.9 视为重复)。
- 性能优化:
- Reranker 模型部署在 GPU 服务器上(T4 显卡),batch 推理。
- 40 条候选的 rerank 耗时约 120ms(batch_size=40, GPU)。
- 对于实时性要求极高的场景,可跳过 rerank 直接取 top-5。
- 分数阈值策略:
- **高相关 (rerank_score ≥ 0.7):**直接使用。
- **中等相关 (0.4 ≤ rerank_score < 0.7):**作为补充信息。
- **低相关 (rerank_score < 0.4):**丢弃。
- 如果所有 chunk 分数 < 0.4 → 触发"知识库中没有找到相关信息"的回复。
Result(结果)
- 重排序后 Precision@5 从 78% 提升到 92%。
- NDCG@5 从 0.72 提升到 0.89。
- Rerank 延迟 120ms,在整体 3s 响应时间中占比可接受。
会话摘要压缩的阈值是多少?怎么确定的?
Situation(情景) 长对话会导致 context window 超限,需要对历史对话做摘要压缩。但压缩太早会丢失信息,压缩太晚会超出 token 限制。
Task(任务) 确定最优的摘要压缩阈值和策略。
Action(行动)
- 阈值设定:
- **触发阈值:**当对话历史占用超过 context window 的 40% 时触发压缩(如 8K 窗口超过 3200 tokens)。
- **保留窗口:**最近 3 轮对话始终保留原文,不压缩。
- 阈值确定过程:
- **30%:**压缩太频繁,信息损失明显,回答质量下降 8%。
- **40%(最终选择):**平衡点,信息保留度和 token 效率最优。
- **50%:**在长对话(>15 轮)时 context 容易超限。
- 摘要策略:
- 使用特定 Prompt 提取核心诉求、关键信息(订单/用户等)、已完成操作及待解决问题。
- 压缩比通常在 4:1 到 6:1 之间(3000 tokens 压缩至 500-800 tokens)。
- 增量摘要(渐进式压缩):
- 每次只压缩最旧的 3-5 轮,新摘要与旧摘要合并形成递进式摘要,避免单次大量压缩导致信息丢失。
Result(结果)
- 40% 阈值下,支持最长 50 轮对话不丢失关键上下文。
- 摘要后的对话理解准确率为 91%(完整历史为 96%)。
- Token 在长对话场景下节省约 60%。
知识图谱是怎么构建和使用的?
Situation(情景) 纯向量检索难以处理实体关系类查询(如“张三负责哪些项目”、“A 产品和 B 产品有什么关联”),需要知识图谱补充。
Task(任务) 构建领域知识图谱,并与向量检索系统协同工作。
Action(行动)
- 知识图谱构建流程:
- **实体抽取:**使用 LLM 从文档中抽取人名、产品、部门、项目等实体。
- **关系抽取:**使用 LLM 识别负责、属于、依赖等实体间关系。
- **Schema 设计:**定义 Person, Product, Department, Project, Document 等节点及 MANAGES, BELONGS_TO 等关系。
- **存储:**Neo4j 图数据库。
- 自动化构建管道:
- 文档 → 分段 → LLM 抽取出实体/关系 → 去重合并 → 写入 Neo4j。
- 人工审核:抽取结果置信度 < 0.8 时进入审核队列。
- 查询集成:
- 意图识别模块判断是否需要图谱查询。
- 自动生成 Cypher 查询语句(如
MATCH (p:Person)-[:MANAGES]->(proj:Project)...)。 - 图谱查询结果与向量检索结果融合后送入 LLM。
Result(结果)
- 知识图谱包含 5 万个实体、12 万条关系。
- 实体关系类查询准确率从纯向量检索的 45% 提升到 87%。
- 知识图谱月均查询量约 2000 次。
怎么做的数据预处理和数据清洗?
Situation(情景) 企业文档质量参差不齐:有 OCR 错误、格式混乱、重复内容、过时信息等。低质量数据直接影响检索和生成质量。
Task(任务) 建立数据预处理管道,确保入库数据的质量。
Action(行动)
- 数据清洗管道:
- 原始文档 → 格式转换 → 文本提取 → 清洗 → 去重 → 质量评估 → 分块 → 入库。
- 清洗规则:
- **去除噪音:**页眉页脚、水印文字、无意义空白。
- **格式标准化:**统一编码(UTF-8)、统一标点(全角/半角)。
- **OCR 纠错:**基于语言模型的拼写纠错(如“己术”→“技术”)。
- **脱敏:**手机号、身份证号等敏感信息自动打码。
- 去重策略:
- **完全重复:**MD5 hash 去重。
- **近似重复:**MinHash + LSH 算法,Jaccard 相似度 > 0.85 视为重复。
- **跨版本去重:**同一文档不同版本只保留最新版。
- 质量评估打分:
- 依据文本长度、语义完整性、信息密度(关键词/实体密度)进行打分。
- 分数低于阈值的 chunk 标记为低质量,不参与检索。
Result(结果)
- 数据清洗后,检索准确率提升 8%。
- 去重减少了 15% 的存储空间。
- 低质量 chunk 过滤后,LLM 生成的幻觉率降低 12%。