智能法律助手
法律领域是 RAG 的高价值应用场景:法规文件庞大、更新频繁、精确性要求极高。RAG 让法律工作者快速定位法条、分析案例、生成法律意见。
法律 RAG 架构
graph TB
A[法律知识源] --> B[文档处理]
A1[法律法规] --> A
A2[司法案例] --> A
A3[法律解释] --> A
A4[合同模板] --> A
B --> C[结构化切分
按条文/条款] C --> D[法律术语 Embedding] E[用户查询] --> F[意图识别] F --> G{查询类型} G -->|法条检索| H[精确匹配 + 向量检索] G -->|案例查找| I[案例相似度匹配] G -->|法律意见| J[多源检索 + 推理] H --> K[法律回答 + 引用] I --> K J --> K style E fill:#e3f2fd,stroke:#1976d2,stroke-width:2px style K fill:#c8e6c9,stroke:#388e3c,stroke-width:3px
按条文/条款] C --> D[法律术语 Embedding] E[用户查询] --> F[意图识别] F --> G{查询类型} G -->|法条检索| H[精确匹配 + 向量检索] G -->|案例查找| I[案例相似度匹配] G -->|法律意见| J[多源检索 + 推理] H --> K[法律回答 + 引用] I --> K J --> K style E fill:#e3f2fd,stroke:#1976d2,stroke-width:2px style K fill:#c8e6c9,stroke:#388e3c,stroke-width:3px
法律文档结构化切分
"""
法律文档结构化解析
"""
import re
from dataclasses import dataclass, field
@dataclass
class LegalArticle:
"""法律条文"""
law_name: str
article_number: str
content: str
chapter: str = ""
section: str = ""
effective_date: str = ""
keywords: list[str] = field(default_factory=list)
class LegalDocumentParser:
"""法律文档解析器"""
# 条文编号正则
ARTICLE_PATTERN = re.compile(
r"第([一二三四五六七八九十百千\d]+)条\s+(.*?)(?=第[一二三四五六七八九十百千\d]+条|$)",
re.DOTALL,
)
def parse_law(self, text: str, law_name: str) -> list[LegalArticle]:
"""解析法律文本为结构化条文"""
articles = []
matches = self.ARTICLE_PATTERN.finditer(text)
for match in matches:
article_num = match.group(1)
content = match.group(2).strip()
article = LegalArticle(
law_name=law_name,
article_number=f"第{article_num}条",
content=content,
keywords=self._extract_legal_terms(content),
)
articles.append(article)
print(f" 解析 {law_name}: {len(articles)} 条")
return articles
def _extract_legal_terms(self, text: str) -> list[str]:
"""提取法律术语"""
legal_terms = [
"合同", "违约", "赔偿", "侵权", "知识产权", "劳动",
"仲裁", "诉讼", "管辖", "时效", "担保", "抵押",
"股权", "债权", "继承", "婚姻", "监护",
]
return [term for term in legal_terms if term in text]
def article_to_embedding_text(self, article: LegalArticle) -> str:
"""将条文转为适合 Embedding 的文本"""
return (
f"{article.law_name} {article.article_number}\n"
f"{article.content}\n"
f"关键词:{'、'.join(article.keywords)}"
)
案例相似度匹配
"""
司法案例检索与匹配
"""
from dataclasses import dataclass, field
@dataclass
class LegalCase:
"""司法案例"""
case_id: str
title: str
case_type: str
court: str
judgment_date: str
facts: str
reasoning: str
verdict: str
related_laws: list[str] = field(default_factory=list)
class CaseRetriever:
"""案例检索器"""
def __init__(self, vector_store, embed_client):
self.store = vector_store
self.embedder = embed_client
def find_similar_cases(
self,
query_facts: str,
case_type: str | None = None,
top_k: int = 5,
) -> list[dict]:
"""根据案情检索相似案例"""
query_vector = self.embedder.embed(query_facts)
# 构建过滤条件
filters = {}
if case_type:
filters["case_type"] = case_type
results = self.store.search(
vector=query_vector,
top_k=top_k,
filters=filters,
)
return [
{
"case": r["metadata"],
"similarity": r["score"],
"relevant_laws": r["metadata"].get("related_laws", []),
}
for r in results
]
def analyze_case_trend(self, case_type: str, recent_count: int = 50) -> dict:
"""分析案例趋势(简化版)"""
cases = self.store.filter_by(
{"case_type": case_type},
limit=recent_count,
sort_by="judgment_date",
)
verdicts = {}
for case in cases:
verdict = case.get("verdict_type", "unknown")
verdicts[verdict] = verdicts.get(verdict, 0) + 1
return {
"case_type": case_type,
"total_cases": len(cases),
"verdict_distribution": verdicts,
}
法律意见生成
"""
法律意见生成引擎
"""
from dataclasses import dataclass
@dataclass
class LegalOpinion:
"""法律意见"""
question: str
analysis: str
applicable_laws: list[str]
similar_cases: list[str]
risk_assessment: str
recommendations: list[str]
disclaimer: str = "本意见仅供参考,不构成正式法律建议。具体事宜请咨询执业律师。"
class LegalRAGEngine:
"""法律 RAG 引擎"""
OPINION_PROMPT = """你是一名法律助手。根据以下法律条文和相关案例,对用户的法律问题进行分析。
相关法律条文:
{laws}
相关案例:
{cases}
用户问题:{question}
请按以下格式回答:
1. 法律分析
2. 适用法律依据
3. 类似案例参考
4. 风险评估
5. 建议
注意:回答必须基于提供的法律条文,不要编造不存在的法条。"""
def __init__(self, law_retriever, case_retriever, llm_client):
self.law_retriever = law_retriever
self.case_retriever = case_retriever
self.llm = llm_client
def generate_opinion(self, question: str) -> LegalOpinion:
"""生成法律意见"""
# 检索相关法条
laws = self.law_retriever.search(question, top_k=5)
laws_text = "\n".join(
f"- {l['law_name']} {l['article_number']}:{l['content'][:200]}"
for l in laws
)
# 检索相关案例
cases = self.case_retriever.find_similar_cases(question, top_k=3)
cases_text = "\n".join(
f"- {c['case']['title']}(相似度:{c['similarity']:.2f})"
for c in cases
)
# LLM 生成分析
analysis = self.llm.generate(
self.OPINION_PROMPT.format(
laws=laws_text,
cases=cases_text,
question=question,
)
)
return LegalOpinion(
question=question,
analysis=analysis,
applicable_laws=[l.get("article_number", "") for l in laws],
similar_cases=[c["case"]["title"] for c in cases],
risk_assessment="需要根据具体情况进一步评估",
recommendations=["建议咨询专业律师获取正式法律意见"],
)
法律 RAG 特殊要求
| 要求 | 说明 | 实现方案 |
|---|---|---|
| 精确引用 | 必须标注法条编号 | 结构化切分 + 引用追踪 |
| 时效性 | 法律会修订更新 | 版本管理 + 生效日期过滤 |
| 免责声明 | 不能替代律师建议 | 强制附加免责声明 |
| 保密性 | 案件信息高度敏感 | 租户隔离 + 数据加密 |
| 可解释性 | 结论必须有理有据 | 推理链 + 法条引用 |
本章小结
| 主题 | 要点 |
|---|---|
| 文档解析 | 按条文结构化切分,保留编号 |
| 案例检索 | 案情相似度匹配 + 案例趋势分析 |
| 意见生成 | 多源检索 + 结构化 Prompt |
| 特殊要求 | 精确引用、时效性、免责声明 |
| 关键原则 | 辅助而非替代,始终标注来源 |
下一章:代码检索与辅助开发