RAG 生活档案切片:不要把回忆切成失去上下文的碎片
RAG 生活档案切片不要把回忆切成失去上下文的碎片一、生活档案的切片比企业文档更怕断章取义RAG 用在生活档案里数据可能来自照片说明、日记、语音转写、聊天记录和清单。它们不像技术文档那样结构稳定语义也更依赖时间和场景。如果只按固定字数切片很容易把一段回忆拆散让检索结果失去上下文。生活档案 RAG 的目标不是回答得像搜索引擎而是基于真实记录给出温和、准确的提示。切片策略必须保留时间、来源、人物关系和事件边界。否则相似度再高也可能回答到错误场景。二、先做事件分组再做文本切片一个更稳妥的链路是先把原始资料归并为事件再在事件内部切片。事件可以由时间窗口、地点、主题和来源共同确定。切片只在事件内发生并继承事件元数据。flowchart TD A[照片与文本] -- B[时间归一化] C[语音转写] -- B D[清单记录] -- B B -- E[事件聚合] E -- F[事件内切片] F -- G[向量化] F -- H[元数据索引] G -- I[检索] H -- I这样检索时可以先缩小到相关事件再找具体片段。回答也能引用事件时间和来源减少错配。三、切片代码要保留来源和邻接关系下面示例展示一个简单切片器。它不只输出文本还保留eventId、sourceId和前后片段引用。后续重排时可以把邻接片段一起带回。type Chunk { id: string; eventId: string; sourceId: string; text: string; prevId?: string; nextId?: string; }; export function chunkEvent(event: LifeEvent, maxLength 420): Chunk[] { if (!event.id || !event.text.trim()) throw new Error(invalid event); const parts event.text.match(new RegExp(.{1,${maxLength}}, g)) ?? []; return parts.map((text, index) ({ id: ${event.id}:${index}, eventId: event.id, sourceId: event.sourceId, text, prevId: index 0 ? ${event.id}:${index - 1} : undefined, nextId: index parts.length - 1 ? ${event.id}:${index 1} : undefined, })); }真实实现里还应按句子或段落切分避免硬切。这里的重点是元数据。没有元数据的向量只是漂浮的相似文本。四、检索回答要允许“不确定”生活档案问题经常带有模糊表达如“那次旅行”“上个月提到的礼物”。检索系统不能强行回答。候选片段分数接近、时间冲突或来源不足时应先追问或给出多个可能选项。还要避免把不同人的记录混在一起。多用户场景必须有权限过滤检索前就筛掉不可见数据而不是回答后再遮盖。RAG 的权限边界应放在召回层之前。另一个边界是删除。用户删除一条记录后对应向量和索引也要删除或失效。生活档案的数据删除必须彻底可验证否则“已删除”就只是界面状态。五、总结RAG 生活档案切片要先保留事件上下文再追求召回效果。工程上应先做事件聚合在事件内切片并为每个片段保留来源、时间和邻接关系。回答时要允许不确定权限过滤和删除同步必须前置。生活资料不是普通文本库切得太碎答案就会失去温度和准确性。