
简介本资源面向法律科技方向的学习者与开发者提供一套基于知识图谱与自然语言处理技术的法务智能问答完整方案适合具备一定NLP与深度学习基础、希望切入法律智能应用场景的中高级读者。项目围绕案由知识库、法务资讯对话知识库与基础法律知识图谱展开覆盖案由预测模型、法务问题类型分类、法务问题自动问答服务以及知识图谱知识查询四大任务并附有完整码源可供复现与二次开发。压缩包整体约33.88MB内含项目源码及相关数据文件目录结构按功能模块划分便于按任务定位代码与数据。目前已有675人学习下载读者可借此掌握从数据收集、知识库构建到模型训练与问答服务落地的完整链路理解知识图谱在金融、医疗、法律等垂直领域的工程化思路并可直接在码源基础上调试与扩展。1. 法务智能知识图谱落地20W 法务问答与法律资讯问答到底怎么跑通很多团队第一次做法务问答第一反应是接个大模型直接怼法条结果上线三天就被业务方投诉问“试用期辞退要不要赔”它给你背《劳动合同法》第三十九条原文一个字不差但没人知道到底赔不赔。问题不在模型在于它没有一张能把「法条—情形—结论」串起来的知识图谱。这套基于法务智能知识图谱的方案核心就是拿 20W 量级的法务问答对和法律资讯做底座把非结构化的问答沉淀成实体和关系再让法律资讯问答走图谱检索而不是纯向量召回。它适合两类人一类是手上已经有几万条法务 FAQ、想让它真正能推理的工程团队另一类是想评估「码源」这套东西值不值得投入的二线开发。下面按选型、建图、问答链路、避坑、进阶的顺序讲透。2. 法务知识图谱的选型为什么不用纯向量库硬扛2.1 法务问答和通用问答的本质差别通用问答里「苹果」既可以是水果也可以是公司靠上下文消歧就够了。法务问答不行同一个「赔偿」在劳动、合同、侵权三个领域里计算基数、上限、举证责任完全不同。纯向量库把「违法解除劳动合同赔偿」和「合同违约赔偿」召回到一起是因为它们在字面语义上高度相似但法律结论南辕北辙。这就是为什么必须上知识图谱图谱用实体类型和关系把领域隔离开(劳动者)-[被违法解除]-(劳动合同)和(合同方)-[违约]-(买卖合同)走的是两条完全不同的推理路径不会互相污染。另一个差别是法务问答对「依据」的要求极高。用户问一句你得能回出「根据《劳动合同法》第八十七条」这种可追溯的出处。向量库只能给你一段相似文本图谱能给你一条从问题实体到法条实体的路径路径本身就是依据。20W 问答对的价值不在于数量而在于它们覆盖了足够多的「情形—结论」配对能拿来抽关系。2.2 图谱 schema 怎么定实体、关系、属性三件套schema 定错后面全白干。法务领域我一般会先定四类核心实体法条、法律概念、情形事实场景、结论裁判或解答。关系上至少要有依据结论依据哪条法条、适用法条适用于哪种情形、包含概念之间的上下位、冲突两条法条或两个结论互斥。属性里最关键的是生效时间和地域法务知识有时效性和属地性2021 年前的解答放到今天可能已经失效。下面是一段最小可跑的 schema 定义用 Python 字典表达方便直接喂给图数据库# 法务知识图谱最小 schema实体四类关系四类 SCHEMA { entities: { Law: {props: [title, article_no, content, effective_date, region]}, Concept: {props: [name, domain, definition]}, # domain: 劳动/合同/侵权... Situation: {props: [desc, domain, keywords]}, # 事实场景 Conclusion:{props: [text, confidence, source_id]}, # 解答或裁判结论 }, relations: { 依据: (Conclusion, Law), # 结论引用哪条法条 适用: (Law, Situation), # 法条适用于哪种情形 包含: (Concept, Concept), # 概念上下位 冲突: (Conclusion, Conclusion),# 结论互斥用于消歧 }, }逻辑说明entities里每个实体带自己的属性列表relations用元组声明头尾实体类型这样建图时能做类型校验防止把Situation错连到Law的依据关系上。参数上domain字段是后面做领域隔离的关键检索时先按 domain 过滤再走图能砍掉大量跨域误召回。effective_date和region别省法务问答里「上海」和「北京」的工伤认定口径就不一样。2.3 20W 问答对怎么变成图抽取流水线20W 条问答对不可能手工建图得走抽取流水线。常见做法是三步先做实体识别把问答里的法条引用、法律概念、情形关键词抽出来再做关系分类判断这条问答的结论依据哪条法条最后做对齐把抽出来的实体链接到已有节点上避免「劳动合同法」和「劳动合同法2012修正」变成两个节点。import re # 第一步从问答文本里抽法条引用正则先兜底模型再补 LAW_PATTERN re.compile(r《([^》])》第([一二三四五六七八九十百零\d])条) def extract_law_refs(text): refs [] for name, art in LAW_PATTERN.findall(text): refs.append({law: name.strip(), article: art}) return refs # 第二步实体对齐把简称归一到标准名 ALIAS {劳动合同法: 中华人民共和国劳动合同法, 民法典: 中华人民共和国民法典} def normalize(ref): ref[law] ALIAS.get(ref[law], ref[law]) return ref逻辑说明正则先跑一遍能覆盖大部分显式引用剩下的隐式引用比如只说「第八十七条」不说法名再交给 NER 模型补。ALIAS字典做实体对齐这是图谱质量的分水岭——对齐没做好同一个法条会有多个节点后面按法条聚合结论时就会漏。参数上正则里的条号要支持中文数字和阿拉伯数字两种写法法务文本里两种都常见。跑完这一步20W 问答对大概能抽出几十万条依据关系这才是图谱真正的血肉。3. 法律资讯问答的检索链路图谱召回加向量兜底3.1 为什么资讯问答要单独走一条链路法务问答FAQ 型和资讯问答长文型是两种东西。前者是「问—答」配对直接命中结论后者是「问—资讯」用户想知道最近某类案件的裁判趋势、某条新规的解读。资讯是长文本直接塞进图谱不现实所以资讯问答走的是「图谱定位领域 向量召回段落 图谱校验结论」的混合链路。图谱在这里的作用是缩小检索范围先根据问题里的实体定位到 domain 和相关法条节点再只在挂在这些节点下的资讯段落里做向量召回召回精度比全库向量高一大截。3.2 混合检索的最小实现def hybrid_retrieve(question, kg, vector_store, top_k5): # 1. 图谱侧抽实体定位 domain 和候选法条 ents extract_entities(question) # 复用 2.3 的抽取 domains {e[domain] for e in ents if domain in e} law_nodes kg.query_laws_by_entities(ents) # 2. 向量侧只在图谱圈定的范围内召回 candidates vector_store.search( question, filter{domain: list(domains)} if domains else None, top_ktop_k * 3, ) # 3. 图谱校验资讯段落若引用了冲突结论降权 scored [] for c in candidates: penalty 1.0 for concl in c.get(conclusions, []): if kg.has_conflict(concl): penalty * 0.5 scored.append((c, c[score] * penalty)) return [c for c, _ in sorted(scored, keylambda x: -x[1])[:top_k]]逻辑说明第一步用图谱把检索范围从全库缩到相关 domain这是精度提升的主要来源。第二步向量召回时带filter只在圈定范围内搜。第三步是关键——如果召回段落里的结论和图谱里标记为冲突的结论一致说明这条资讯可能过时或口径不一致降权处理。参数上top_k * 3是先多召回再重排的常规做法penalty系数 0.5 可以按业务容忍度调法务场景我一般调到 0.3宁可保守。3.3 问答链路的参数怎么调参数作用建议值调大后果domain 过滤开关是否按领域隔离检索开关掉后跨域误召回明显上升图谱跳数从问题实体沿关系走几跳2跳数过多引入无关法条向量 top_k召回段落数15过大拖慢重排噪声增多冲突降权系数冲突结论的惩罚0.3调高会误伤正常资讯时效过滤是否按 effective_date 过滤开关掉会召回已废止法条这张表是上线前必调的五个旋钮。图谱跳数是最容易翻车的一个很多人图省事设成 3 跳以上结果从「试用期辞退」一路走到「劳动合同订立」召回一堆不相关法条。2 跳基本够用一跳找到直接法条二跳找到相关概念。4. 避坑与排查法务图谱上线后最常见的五个坑4.1 现象同一法条在图上出现多个节点聚合结论时漏数据原因实体对齐没做全简称、全称、带修正年份的版本各建了一个节点。解决建图前先跑一遍别名归一把ALIAS字典补全并在入库时对law article_no做唯一约束重复的直接 merge 而不是新建。4.2 现象问答结果引用了已废止的法条原因effective_date字段没填或没参与检索过滤。解决抽取阶段强制要求法条节点带生效和废止时间检索时默认加effective_date now且未被废止的条件。法务场景这条不能省引用废止法条是硬伤。4.3 现象跨领域误召回问劳动问题返回合同结论原因domain 过滤没开或者实体抽取时没识别出 domain。解决在 schema 里给Situation和Concept都打 domain 标签检索第一步就按 domain 圈范围。如果问题里没抽到 domain宁可让用户澄清也别全库搜。4.4 现象图谱跳数一调大召回法条数量爆炸原因关系设计里有大量包含这类传递性关系跳数一多就沿着概念树爬满全图。解决把依据、适用这类强关系设为可跳包含这类弱关系限制跳数或只在特定查询里用。我一般给关系打权重检索时按权重截断。4.5 现象20W 问答对建完图问答准确率反而比纯向量低原因抽取噪声进了图错误关系污染了推理路径。解决建图后加一道人工抽检按 domain 分层抽样每条依据关系核对是否成立噪声率超过 5% 就回炉重抽。图谱不是越多越好错的关系比没有关系更糟。5. 进阶用图谱做结论一致性校验和增量更新图谱建完不是终点它最大的隐藏价值是能当「后悔药」用——校验新进来的问答和资讯结论是否和已有图谱冲突。做法很简单新结论入库前先沿依据关系找到它引用的法条再看这些法条下已有哪些结论如果新结论和已有结论在冲突关系上被标记过就拦下来人工复核。这一步能挡住大部分口径不一致的脏数据。def check_consistency(new_conclusion, kg): laws kg.get_laws_of(new_conclusion) # 新结论依据的法条 for law in laws: existing kg.get_conclusions_by_law(law) # 该法条下已有结论 for e in existing: if kg.has_conflict(new_conclusion, e): return {ok: False, conflict_with: e[id]} return {ok: True}逻辑说明get_laws_of走依据关系拿到法条get_conclusions_by_law反向拿同法条下的结论has_conflict查冲突关系。参数上冲突判定可以先用规则结论文本里的关键词互斥如「需要赔偿」vs「无需赔偿」规则覆盖不了的再上模型。这套校验跑在入库前比事后清洗便宜得多。增量更新是另一个进阶点。法条会修订资讯会新增图谱不能每次重建。常见做法是给节点和关系加version和updated_at新法条生效时只更新受影响的子图沿依据关系找到所有引用该法条的结论标记为「待复核」。这样一次修订只动局部不用全量重跑 20W 问答对的抽取。最后说个我自己的习惯每次 schema 改动我都会先拿 200 条问答对跑一遍回归看准确率和召回率有没有掉。图谱这东西改一处动全身没有回归集就是盲改。法务问答的容错率低宁可上线慢一点也别让用户拿到一条引错法条的答案。希望帮到你。本文还有配套的精品资源点击获取