法律问答:基于法规库与判例的咨询系统

FreeGuideOnline 最新 2026-06-26

如何构建一个法律问答系统:法规库与判例检索实战

对于法律从业者或普通公众,快速从浩瀚的法条和判例中找到准确答案是一项挑战。本教程将带你从零开始,理解并搭建一个基于真实法规与判例的智能问答系统。你不需要是机器学习专家,只需掌握基本的Python和文本处理知识,就能构建出可用的法律助手。

系统核心原理:检索增强生成(RAG)

传统问答系统要么完全依赖预训练模型“记忆”,容易产生幻觉;要么只能做简单关键词匹配。法律领域容错率极低,答案必须有据可查。我们采用的**检索增强生成(Retrieval-Augmented Generation)**模式,结合了搜索与生成的优点:

  • 法规/判例库:结构化存储法律文本的知识源头。
  • 召回器:根据用户问题,从库中检索最相关的法条或判例片段。
  • 阅读器:将检索到的文本作为“参考资料”,引导大语言模型(LLM)生成有引用依据的答案。

整个流程就像一位勤勉的法律研究员:先翻阅档案(检索),再结合案情撰写意见(生成)。

第一步:环境搭建与工具准备

我们将使用全免费的开源技术栈,让学习无门槛。

  • 编程语言:Python 3.9+
  • 核心库
    • llama-index:处理数据索引和问答管线的框架。
    • sentence-transformers:提供免费的文本嵌入模型,将法律条文转为向量。
    • chromadb:轻量级向量数据库,存储和检索文本片段。
    • transformers 与免费模型(如 Qwen2-0.5B 或通过API调用云端免费模型):用于最终答案生成,若本地算力不足,可接入免费的智谱AI GLM-4-Flash等在线服务。

快速安装命令

pip install llama-index sentence-transformers chromadb transformers torch

第二步:构建你的法律知识库

没有高质量数据,系统就是空壳。我们需要收集并整理法规与判例文本。

2.1 获取法律文本数据

  • 公开法规库:从“国家法律法规数据库”等政府公开站点下载完整法条的 PDF 或 HTML,使用 pdfplumberBeautifulSoup 提取纯文本。
  • 判例文书:裁判文书网公开了大量判决书,可通过合规方式下载或使用第三方开源数据集(如CAIL2018,需注意版权和使用条款)。
  • 本教程示例数据:为了快速验证,我会准备一个简化版资料包,内含《民法典》前100条及三个借贷纠纷判例的摘要(可从教程配套仓库获取:sample_legal_data.zip)。

2.2 文本清洗与结构化

原始法律文本充满编号、换行和无关空格。需要统一处理:

import re

def clean_legal_text(text):
    # 去除多余换行,保留段落
    text = re.sub(r'\n+', '\n', text)
    # 去除页眉页脚常见噪音
    text = re.sub(r'第[一二三四五六七八九十]+页', '', text)
    return text.strip()

# 示例:将民法典文本按条分割
def split_law_articles(full_text):
    # 假设每条以“第X条”开头
    articles = re.split(r'(?=第[一二三四五六七八九十百千]+条)', full_text)
    return [art.strip() for art in articles if len(art.strip()) > 5]

判例则需要提取“案件事实”“争议焦点”“判决结果”等段落,作为独立的知识片段。

第三步:建立向量索引,让机器读懂法律

计算机无法直接比较两段文字的含义,需要将它们转为向量。

3.1 文本分块策略

我们把法条和判例切分为合适长度的小块(chunk),通常每块200~500字,保留足够上下文。

from llama_index.core import SimpleDirectoryReader
from llama_index.core.node_parser import SentenceSplitter

# 假设清理后的文本文件存放在 ./law_texts 目录
documents = SimpleDirectoryReader('./law_texts').load_data()
splitter = SentenceSplitter(chunk_size=300, chunk_overlap=50)
nodes = splitter.get_nodes_from_documents(documents)

3.2 生成向量并存入数据库

使用高效的 all-MiniLM-L6-v2 嵌入模型(免费且轻量),将所有文本块转为向量,存入ChromaDB。

from llama_index.embeddings.huggingface import HuggingFaceEmbedding
from llama_index.vector_stores.chroma import ChromaVectorStore
import chromadb

# 初始化嵌入模型
embed_model = HuggingFaceEmbedding(model_name="all-MiniLM-L6-v2")

# 创建向量存储
db = chromadb.PersistentClient(path="./legal_db")
chroma_collection = db.get_or_create_collection("law_qa")
vector_store = ChromaVectorStore(chroma_collection=chroma_collection)

# 构建索引
from llama_index.core import VectorStoreIndex, StorageContext

storage_context = StorageContext.from_defaults(vector_store=vector_store)
index = VectorStoreIndex(nodes, storage_context=storage_context, embed_model=embed_model)
print("索引构建完成,法律知识库已就绪。")

第四步:搭建问答查询引擎

现在已经有了“懂法”的检索器,接下来要将它与答案生成器连接。

4.1 配置检索与生成管线

llama-index 提供了封装好的查询引擎,我们可以自定义生成模型。这里演示接入免费的云端模型(以OpenAI兼容接口的免费模型为例,如通过Groq提供的LLaMA 3 8B或国产ModelScope免费API)。

from llama_index.llms.openai_like import OpenAILike

# 假设你已获取某免费LLM的API key和base_url
llm = OpenAILike(
    model="llama3-8b-8192",  # 示例,根据实际免费模型名修改
    api_key="your-free-api-key",
    api_base="https://api.groq.com/openai/v1",
    temperature=0.1  # 法律场景低温度保证确定性
)

# 构建查询引擎
query_engine = index.as_query_engine(llm=llm, similarity_top_k=3)  # 取最相关的3个片段作为参考

如果希望完全离线且免费,可使用本地轻量模型,如 Qwen2-0.5B-Instruct,但需注意效果可能稍弱。

from llama_index.llms.huggingface import HuggingFaceLLM

# 本地模型加载(需预先下载模型文件)
local_llm = HuggingFaceLLM(
    model_name="Qwen/Qwen2-0.5B-Instruct",
    tokenizer_name="Qwen/Qwen2-0.5B-Instruct",
    model_kwargs={"trust_remote_code": True},
    generate_kwargs={"temperature": 0.1, "do_sample": False}
)
query_engine = index.as_query_engine(llm=local_llm, similarity_top_k=3)

4.2 设计法律问答的提示词模板

为了保证答案格式规范并附上引用,可以在查询时指定prompt模板。

from llama_index.core import PromptTemplate

qa_prompt_tmpl = (
    "你是一位严谨的法律助手。请根据以下法律条文或判例片段,用中文回答用户的问题。\n"
    "如果片段无法支撑回答,请明确说明“根据当前资料无法给出确切结论”。\n"
    "在答案末尾列出引用的具体法条编号或判例名称。\n"
    "参考资料:\n{context_str}\n\n用户问题:{query_str}\n回答:"
)
query_engine.update_prompts(
    {"response_synthesizer:text_qa_template": PromptTemplate(qa_prompt_tmpl)}
)

第五步:测试你的法律问答系统

现在可以提出真实的法律问题,观察系统如何利用知识库给出有据可查的答案。

# 问一个关于借贷利息的问题
response = query_engine.query("民间借贷中,约定年利率24%是否受法律保护?")
print("回答:", response.response)
print("引用来源:", response.get_formatted_sources())

预期输出示例(基于《民法典》及判例摘要):

回答:根据《民法典》第680条及最高法司法解释,民间借贷利率的司法保护上限为合同成立时一年期LPR的四倍。以当前LPR计算,24%已超过保护上限。超过部分利息的约定无效。此外,在(2023)沪01民终XXX号判例中,法院仅支持了LPR四倍部分的利息,超出部分不予支持。
引用来源:《民法典》第680条;(2023)沪01民终XXX号判例摘要。

进阶优化与部署建议

这个基础系统已经可以解答许多法条理解类问题。为了让其更实用,你可以:

  • 增量更新知识库:定期添加新法规和判例,重新索引。
  • 混合检索:结合关键词检索(如Elasticsearch)和向量检索,提升召回精度。
  • 引用高亮:实现答案中的法条号自动链接到原始文本。
  • Web界面:使用 streamlit 快速搭建一个在线法律咨询页面,方便自己和同事使用。

总结与免费资源清单

你已完整掌握了基于法规库与判例构建智能问答系统的技术链路。即使是非法律专业人士,也能用这套方案快速查询法律要点,但需注意:AI输出仅供参考,不构成正式法律意见。

本教程使用的所有免费资源

  • 嵌入模型all-MiniLM-L6-v2(HuggingFace)
  • 向量数据库:ChromaDB(开源免费)
  • 编排框架:LlamaIndex(MIT许可)
  • 免费LLM接入:Groq(免费额度)、ModelScope 免费Notebook环境、智谱AI开放平台(GLM-4-Flash免费调用)
  • 法律数据:国家法律法规数据库、公开裁判文书(请遵守使用协议)

现在,打开你的代码编辑器,开始构建属于你自己的法律数字助手吧。你不需要背诵法条,让机器帮你检索和理解。