sdtd-recode · 业务资料规整
> 一句话:把散记录变成"能被切片、能被检索、不会自己编答案"的单元。
定位与边界
| 内容 | |
|---|---|
| Use | 一线聊天/工单/转写/笔记、政策文件、内部规范、个人心得 → 知识库语料;语料清洗;出待分块 docx;零散问答结构化。客服、运营、销售、门店、售后都是同一套做法 |
| Skip | 标准问答库格式转换、文档美化排版、写文案、RAG 检索端开发、知识库使用答疑 |
| 产出 | 一个资料根,顶层最多 6 个目录:规则文档/ 培训资料/ 问答记录/ 个人文档/ 待定/ + 清单/,只建真用到的,不建空目录。每份输入资料落成 <主题><YYYY.MM.DD>.md,一个文件装多条单元 |
| 不做 | 不切片、不向量化、不写入任何知识库;分块与库内标识由平台负责 |
激活即执行
- 定输入:拿到原始资料路径,按 references/ingest.md 识别形态并抽取正文。
- 判类落盘:
python tools/kb_intake.py plan <原始资料目录>出提案(类别 / 建议文件名 / 理由 / 分数)。按提案写成单元 md,落到对应大类目录;判不出的进待定/,不猜。判据见 references/ingest.md 第五节。 - 标项目:在文件头写
项目:,判不出就写未标注并进待归属,不猜。项目只做记录,不拆文件、不建目录。规则见 references/units.md。 - 抽单元:按 references/units.md 的单元定义把记录切成候选知识。切出来的是单元,不是文件——同一份输入产生的单元写进同一个 md,用
## 标题分隔,见下方「文件粒度」。 - 标依据与时效:单元标 L1~L4,文件头填
依据 / 范围 / 生效 / 失效。这一步不能省——它是"政策"与"心得"共存于一个库而不互相打架的唯一保障。 - 跑检查:
python tools/kb_build.py check <资料根>,FAIL 必须归零才往下走。 - 出交付:
python tools/kb_build.py build <资料根> -o <资料根>,一份 md 出一份同名 docx,落在同一目录。 - 回验:
python tools/kb_build.py verify <docx>,PASS 才算交付。 - 人工抽查:结构合规不等于可入库,按 references/checks.md 抽 3 单元自读。
文件粒度:一个 md 装一份输入,不是一条知识
文件数跟着「输入资料份数」走,不跟着「知识条数」走。
一份 300 条的聊天记录导出 → 1 个 md,里面 300 个 ## 标题。
拆成 300 个文件,一进知识库就是几百个碎文件:目录翻不动、批次对不上、清单也失去意义。
只有下面三件事之一变了,才另起一个文件:
| 变化 | 为什么必须拆 |
|---|---|
项目 不同 |
一个文件只有一个 项目: 值,混了直接 FAIL |
依据 等级不同 |
L1 政策原文与 L4 个人心得共用一个文件头,追溯当场失效 |
生效 / 失效 不同 |
同上——时效压成一个值,等于对这个文件里的每个单元谎报新鲜度 |
其余一律合并:同一份工单导出里的 20 条问答,同项目、同依据、同时效、同批次 → 同一个文件。
判据:kb_core.GROUP_FIELDS 那七项(项目 / 类别 / 依据 / 生效 / 失效 / 来源 / 整理批次)全相同 → 必须同一个文件。
模块 / 范围 不在这七项里:它们是单元级属性(这一条适用哪个版本),拿它们当拆文件的理由,
等于每条各建一个文件——v1.2.2 就被这么坑过一次,别再走回去。
> 单文件上千条时,把一个文件拆成 <主题>_1.md <主题>_2.md 按模块分卷,仍不要按条拆。
> check 会统计同一批次里的「单单元文件」并报 WARN —— 那通常就是按条建文件了。
> 已经拆碎的不必手改:python tools/kb_intake.py merge <资料根> --apply 按同源同头合并回去。
纪律:
- 单元 md 是唯一事实源。 docx 与清单全部由它派生;绝不手改投送件。
- 先 check 后 build。 有 FAIL 时 build 会拒绝出件,这不是障碍,是防脏数据入库。
- 不合并冲突。 客服口头答复与产品资料、政策文件不一致时,两边都不收,进「待核实」。
- 收录判据只有一条底线:只有问句没有答案的片段,绝不入库——否则检索命中问句,模型会自己编答案。
- 过期资料不得入库。 判定基准日可用
--as-of拨动,但过期即 FAIL,不接受"大概还能用"。 - 同一份输入只抽一次。 已经生成过 md 的,改那一份,不另起
<主题>_2.md——
重跑一遍就多一份,两份内容大同小异,检索时互相抢位置,而人根本看不出哪份新。 - 大类只用这 5 个。 想加类先问:现有类真的装不下吗?加类要改
kb_core.CATEGORIES并过导入期断言,不能在磁盘上随手mkdir——目录疯长就是这么来的。
不要问用户
用户交进来一堆资料,换回去一堆整理好的文档。中间不该出现选择题。
凡是「要不要 A 还是 B」「这批分几组」这类问题,一律按下面这张表自己定,不打断用户。
| 以前会问的 | 现在怎么做 |
|---|---|
| 投知识集还是问答库 | 只有一条通道:docx。 企微知识集、ima 都直接吃,不做第二条,也不用选 |
| 这批涉及哪几个项目 | 从资料里读,读不出写 未标注。项目不影响出件粒度,不问你、也不分组 |
| 要不要按类别 / 按项目分组出件 | 不分组。一份输入出一份输出,同名同目录交回去 |
| 有没有会过期的资料 | 见到文号、「自 X 年起」、费率、价格就按会过期处理;失效日估一个并进「待核实」 |
| 这份资料该放哪个类 | kb_intake plan 判,判不出进 待定/,绝不硬猜 |
| 要不要脱敏 | 必须做,不问 |
只有两种情形该开口,其余一律按上表自己走:
- 缺必要输入——没给路径、文件打不开、读出来是空的。这时问一句「资料在哪」,一句话就够。
- 整份资料没有可用信息——全是寒暄、或全是图片读不出字。这时说「这份整理不出东西,因为 X」,原件留着。
除此之外,宁可判进 待定/、待核实 让人事后更正,也不要在开工前停下来问。
「不问」指的是不问无意义的选择题,不是不问必要的信息。 这两件事要分开:
把「知识集还是问答库」抛给用户是懒,缺路径还硬猜是莽。
> 这条是踩出来的:原先文档里写着「投送目标是知识集还是问答库,只能选一条,选错等于白做」,
> 于是每次开工,AI 都会先把这个问题抛给用户。文档里留下一个选项,就等于留下一个提问。
> 想让人不问,就别在文档里留分叉。
批次与去重
- 批次号格式
{YYYYMMDD}_{批次},只进清单文件名,不进 docx 名字。docx 跟源 md 同名,换个批次不该换个名字。 - 防重复投送:
build在资料根生成已投清单.tsv(两列:标题、投送日期)。投送完追加本行;下一批开跑前先比对标题,同题同答案的不再投。 - 同一内容只投一次。改了口径就覆盖同名 docx 重投,不要另起一份——两份都在库里,检索会同时命中新旧说法。
- 从旧命名(
{项目}_{类别}_{批次}.docx)升上来的目录,先删旧名产物再投。新旧两套名字并存,等于同一内容有两条,检索分不清哪条是新的。
判定速查
判"收不收",按 A1~A6 全满足才收;判"剔不剔",命中 X0~X6 任一即不收。
完整表格、六种类型(T1~T6)的填法、非问答形态怎么处理,见 references/units.md。
| 遇到 | 判 |
|---|---|
| 客户问 + 客服答 | T1 问答型,收 |
| 客服自述规则/口径、政策条文、制度条款("必须/只能/按 X 算") | T2 规则型,收(不是问答也收) |
| 客服自记的操作路径 | T3 路径型,收 |
| 坑点、易错点、前置条件 | T4 注意型,收 |
| 带时间/版本语境的规则变更 | T5 背景型,收 |
| 个人心得、话术、安抚方法("我一般先…") | T6 经验型,收,但依据只能是 L3/L4 |
| 只有问句、无人应答 | X1,剔除并转待补 |
| 寒暄、情绪、催单 | X2,剔除仅计数 |
| 含具体单据号/当事人/机构的个案 | X3,剔除 |
| 「转技术了」「等回复」 | X4,剔除 |
| 口径在争 / 涉价格承诺 / 涉合规与专业判断(诊断、用药、疗效) | X6,进待核实 |
| 「我觉得 / 好像 / 大概」当结论 | 不进库;能改写成"做法 + 适用条件"的转 T6,改不了的剔除 |
| 判不出属于哪个项目 | X0,进待归属 |
> 最常犯的错:把客服自述的规则当成"不完整的问答"剔掉。T2~T6 这五类恰恰最值钱。
依据分级(与类型正交,两个维度都要标)
类型说"这句话怎么写的",依据说"凭什么这么说"。不标依据,个人感觉会跟政策条文平起平坐。
| 级别 | 含义 | 典型资料 | 硬约束 |
|---|---|---|---|
| L1 外部权威 | 政策、法规、国标、厂商正式文档 | 医保文件、行业标准 | 必须写 【依据】 文号+条款,必须标 失效 |
| L2 内部正式 | 公司制度、官方口径、正式培训 | 收费制度、服务规范 | 必须写 【依据】 制度名+章节 |
| L3 一线实践 | 客服记录、实测、工单答复 | 聊天、交接备注 | 无(有出处更好) |
| L4 个人经验 | 心得、话术、方法 | 复盘、口头经验 | 不得承载事实结论;不得标 T6 以外想冒充权威 |
冲突裁决:高级别覆盖低级别,L4 永不覆盖任何级别;同级冲突两边都不收,进「待核实」。
时效:失效 过了当天就 FAIL(check --as-of 可拨基准日),到期前 60 天 WARN。
单元结构
四段必需 + 三段按需,段内不写项目名(项目只在文件头):
## {标题:能直接当搜索词}
【问题】{仅 T1 且有客户原话时填}
【内容】{是什么 / 能不能 / 在哪 / 怎么做 / 要注意什么}
【依据】{L1/L2 必填:文号/制度名 + 条款号;L3/L4 有出处才写}
【适用】{给谁用、什么场景用,要能缩小范围}
【步骤】{仅 T3 或含流程时填,1/2/3 有序}
【边界】{不适用情形、常见误解、前置条件}
【类型】{T1~T6}
- 必需段
【内容】【适用】【边界】【类型】;【问题】【步骤】【依据】有内容才写,不写空段。 - 正文 100~300 字为宜,硬上限 500 字,超了必须拆。
- 单元内不出现「这个 / 那个 / 如上 / 本通知 / 本制度 / 前款」——公文自指必须展开成具体文件与条款名。唯一例外是
【问题】,那里要保留客户口语。 【适用】不强制「模块 · 角色 · 端」三段(政策类没有"端"),但必须真的缩小范围:写「全部角色 · 全线」等于没写,会被判 WARN。- 语料 md 骨架(文件头十字段:8 项必填;
模块/范围可选,不确定就整行不写):
---
项目: {项目规范名}
类别: {规则文档|培训资料|问答记录|个人文档|待定}
来源: {具体来源:客服聊天记录 / 某政策文件 / 某制度 / 复盘会}
依据: {L1|L2|L3|L4}
生效: {YYYY-MM-DD}
失效: {YYYY-MM-DD 或 长期}
收录时间: {YYYY-MM-DD}
整理批次: {批次号}
---
# {模块}
## {单元标题}
【内容】…
> 模块: / 范围: 想写就加在 依据: 前后,不写不报错。
> 范围 是单元级的(这一条适用哪版),每条都不一样就别写进文件头——写进去会逼着你按条建文件。
> 细分需求放各单元的【适用】段。
> 文件头字段是文件级的,所以一个文件只能装一个 依据 级别。政策、制度、心得混在一份文件里就必须拆文件——合并会让 L1 政策和 L4 心得共用一个依据,追溯当场失效。
>
> 类别 决定它落在哪个顶层目录,且必须与所在目录同名(不一致会 WARN)。类别写在文件里而不只靠目录位置:文件会被复制、会被搬走,字段跟着内容走才是事实。
交付物
| 文件 | 用途 | 关键约束 |
|---|---|---|
{大类}/{主题}{YYYY.MM.DD}.md |
单元语料(唯一事实源) | 十字段文件头(8 必填 + 模块/范围 可选);类别与所在目录同名;check 必须能读回且 0 FAIL |
{大类}/{主题}{YYYY.MM.DD}.docx |
知识集上传(唯一交付) | 与源 md 同名同目录;只含正文;标题用 Heading1;无空段、无页眉页脚批注、无元数据 |
清单/{批次}_清单.md<br>清单/{批次}_待归属清单.md<br>已投清单.tsv |
批次账与去重台账 | 概况 / 类别分布 / 依据分布 / 过期临期 / 收录 / 剔除逐条 / 待补 / 待核实 / 待归属 |
_剔除清单.md<br>_待补清单.md<br>_待核实清单.md<br>_待归属清单.md(资料根层) |
人工填的过程记录,可选 | 名字固定、_ 开头;账本不是知识单元,不进校验、不被抽成条目;给了就原样进清单第三~五节(自带文件头会自动剥掉) |
> 一份输入一份输出。 给进来 5 份资料,就取回 5 份 docx,文件名和原 md 一模一样、躺在同一个大类目录里。
> 不按项目合并、不按类别合并——合并后交回去对不上号,用户还得翻清单猜哪段出自哪份原件。
> 一个 docx 只装一份输入,所以它天然只含一个项目、一个依据级别,串库和依据混淆都不会发生。
> 语料为什么不合并成一份:合并会把文件级的依据与有效期压成一个值,L1 政策与 L4 心得挤进同一个文件头,追溯就断了。
> 为什么交付只做 docx:平台本地上传白名单只认 pdf/doc/docx/xlsx。md 与 txt 上传后不报错,只会一直「学习中」最后「学习失败」。这条是踩过的坑,别试。
> 为什么不再有问答库 xlsx / qa.txt:不是它不能用,而是它是个选项。开关一在,每次开工都要先问「要知识集还是问答库」,
> 而这个选择对用户没有意义——同一份内容投两条通道,平台会把两份都当知识,检索时互相打架。通道只有一条,问题就不存在。
目录结构(顶层最多 6 个,不随资料增长;只建用到的):
> {资料根} 是一个长期复用的根,名字与项目无关。
> 不要建成 <项目名>知识库——五个项目就会长成五个库,同一套规则文档要在五个库里各存一份,
> 而政策更新时你只记得改其中一个。项目信息全部落在文件头的 项目: 字段里;
> 出件不看项目,只看「有几份 md」,所以一个根装多少项目都不会串。
> 建议就叫 业务知识库/ 或 知识库/,以后不再换。
{资料根}/
├─ 规则文档/ 政策、法规、制度、规范、通知、办法
├─ 培训资料/ 课件、讲义、培训、考试、操作手册
├─ 问答记录/ 客户问答、工单、聊天、转写
├─ 个人文档/ 心得、感悟、复盘、话术总结
├─ 待定/ 判不出归属,待人确认
└─ 清单/ 批次账
每个大类目录下一层平铺(不建子文件夹),形如 规则文档/医保门诊统筹政策2026.11.01.md,旁边是它的 .docx。多个项目的同类文件就在同一层,靠文件名和文件头区分。
不在大类下再建子文件夹。 日期放在文件名尾部而不是做成日期目录——同一主题不会散进几十个文件夹,按主题命名的文件在资源管理器里天然聚在一起。
命令
python tools/kb_intake.py plan <原始资料目录> # 出分类提案:类别/建议名/理由/分数(不动文件)
python tools/kb_intake.py place <资料根> --dry-run # 只看要归位什么,不动文件
python tools/kb_intake.py place <资料根> # 按「类别」把 md 归位
python tools/kb_intake.py merge <资料根> # 看哪些单单元文件该合并(默认不动文件)
python tools/kb_intake.py merge <资料根> --apply # 真合并(先自动备份到 _merge_backup_*)
python tools/kb_build.py check <资料根> # 只判定,不改文件
python tools/kb_build.py check <资料根> --as-of 2027-01-01 # 把时效判定拨到某天
python tools/kb_build.py build <资料根> -o <资料根> # 一份 md 出一份同名 docx + 清单
python tools/kb_build.py verify <file.docx> # 交付后回验
python tools/kb_verify.py docx <file.docx> # 只跑校验器(接 CI 用)
python tools/kb_verify.py corpus <资料根>
python tests/test_kb.py # 回归测试
tools/kb_verify.py 是独立校验器,不依赖生成流程;改完判定逻辑必须重跑它,FAIL 归零才算完。
零第三方依赖(只用标准库),不需要 pip install。
退出码:0 无 FAIL,1 有 FAIL——可直接接进流水线拦截。
按需阅读
| 遇到的情况 | 读取 |
|---|---|
| 资料是 txt/html/csv/docx/pdf/xlsx/截图/语音,不知道怎么抽 | references/ingest.md |
| 不知道这份资料该放哪个大类、想加大类、怀疑目录长乱了 | references/ingest.md 第五节 |
| 判不准归属、判不准 T1~T6、判不准 L1~L4、政策怎么拆条款、心得怎么改写 | references/units.md |
| 要交付前的完整验收清单、要判"能入库了吗" | references/checks.md |
| 要改判定逻辑、要加检查项、要知道为什么这么设计 | references/extending.md |
收尾与停止条件
- 回到用户原始诉求逐条核对:交进来几份资料、出几份 docx、每份多少单元,与清单数字对齐。
一份输入对应一份同名 docx,少一份或多一份都要说明。 - 交付前必须满足:
check的 FAIL 为 0;- 每个单元都有依据级别,清单里「依据未标」为 0;
- 「已过期」为 0;「60 天内到期」若非 0,须在交付说明里点明换版计划;
build成功;它生成完会自己重开文件数一遍标题,对不上就拒绝交付(退出码 1)——
这条不需要人再核,核过反而说明你不信它;verify返回 PASS;- 按 references/checks.md 抽 3 单元遮住其它单元自读,仍能独立读懂。
- 告知用户哪些是脚本判过的(结构、长度、指代、依据取值、过期、空话适用、元数据泄漏),哪些是人判的(归属、类型判对没、依据级别给准没、语义准确度)——不要把"脚本 PASS"说成"内容合格"。
- L4 经验类占比若超过三成,主动提示:这批资料偏"经验"、缺权威依据,涉及政策口径与收费标准的答案需要补 L1/L2 单元。