寓言
档案馆的两种编号方式
市档案馆做了一次数字化改造。第一批资料是会议纪要——每份三十页,按决议编号归档。技术组决定每五页切成一个文件包,理由是检索速度更快。他们把三十页的纪要切成了六个独立包,每个包都有独立编号,存进系统。检索时输入关键词,系统返回若干个五页包,工作人员从里面找答案。
问题出在年度总结。有人查询“去年通过了哪些环保决议”,系统返回了两个五页包——分别包含了某次会议的第十一页到第十五页,和另一次会议的第六页到第十页。两个包里都有“环保”“决议”这些词,但工作人员打开一看,前一个讨论的是污水处理预算,后一个是公园扩建。缺少原始纪要的上下文,两个碎片凑不出任何可用的结论。
档案室的老主任提了一个方案:每份会议纪要仍然切块,但额外保留一份全量版。检索的时候,系统先用全量版定位到相关纪要的编号,再从那个编号底下调出最匹配的那几页切片。全量版负责判断“这份纪要在讲什么”,切片负责回答“具体哪几页讲到了关键细节”。
技术组照做了。他们把每份纪要存成两份:一份叫父块,是完整的纪要,用来做语义匹配和定位;另一份叫子块,是五页切片,用来返回精确段落。检索流程变成两步:先拿用户的问题去父块里找最相关的几份纪要,再在这些纪要的子块里挑出最贴切的段落。
效果立竿见影。同样的查询“去年通过了哪些环保决议”,系统先定位到三份相关纪要,然后从每份纪要下各自提取了最相关的两三段。工作人员看到的是带原始编号和上下文的精确摘录,而不是一堆孤立的碎片。
后来有人问主任,这和原来只切块的区别到底在哪。主任在白板上画了两层:第一层是“怎么切”——块大小、重叠度、分隔符,这是分块策略。第二层是“切完之后谁跟谁有关系”——父块和子块之间那条索引线,这是父子分块。他说只做第一层,检索结果是一堆散装豆腐块。做了第二层,每块豆腐都带了它原本属于哪盘菜的标签。
档案系统改造完后,主任把配置表贴在了机房门口:chunk_size 管的是子块切多大,parent_chunk_size 管的是父块拿多大去匹配语义。两行参数各管各的,但缺了父块那一行,子块再精准也只能在断章取义中打转。