想象一下:一位刚从法学院毕业的实习生小秦到法院报到,法官王老师把一摞卷宗递给他:“小秦,三部曲走一遍——第一,读完案情判断这是什么罪;第二,翻开法典找出应援引的法条;第三,掂量一下该判几年。”小秦每天的工作,就是对着案情描述做这三件事。 CAIL2018(中国法律智能挑战赛)干的事情,和培养小秦一模一样——只是把“实习生”换成了“AI 模型”。主办方从公开裁判文书网抽出数万份真实刑事判决书,让各路 AI 模型像小秦一样:读案情、定罪名、查法条、估刑期,再用统一的评分标准排名。CAIL2022 延续了这套核心玩法,并扩展出更丰富的新任务。这就像一场“AI 版司法实习资格考试”。 在这篇文章里,我们跟着小秦的实习之旅,把 CAIL 的赛事概况、三大核心任务、文本预处理、模型架构、实战挑战和工程落地一一拆解。读完你会发现,让 AI“读案卷”这件事,既不像想象中那么神秘,也比想象中更有讲究。

岗位关联

对 AI 从业者而言,CAIL2018 是司法 NLP 最经典的基准任务之一:吃透它的三大任务与多标签、多任务建模套路,你就能把同样的技能复用到金融合规、政府文书、企业法务等任何需要“读懂专业文本并给出结构化预测”的垂直场景,求职履历上也多了一张过硬的行业名片。

目录
  1. 可视化演示
  2. 赛事概况:法律 AI 的“实习比武”
  3. 罪名预测:实习生的第一判断
  4. 法条预测:翻出正确的法典
  5. 刑期预测:称一称刑罚的天平
  6. 文本预处理:先读懂卷宗再说
  7. 模型架构:搭建实习生的“头脑”
  8. 实战挑战:真实案件的“魔鬼细节”
  9. 工程落地:从比武场走向审判庭
  10. AI 应用场景
  11. Python 演示
  12. 常见误区
  13. 面试题

可视化演示

展示CAIL2018/2022中国法律AI挑战赛的任务分布、年份对比和排行榜进展曲线,理解赛事演进。

本节配有交互动效(进入视口后自动加载,约 3KB)。

任务分布 罪名预测 判决预测 多任务 中国法律AI基准

赛事概况:法律 AI 的“实习比武”

法院里来了个实习生小秦。正式上岗前,法院给他安排了一场“摸底比武”:发下数万份真实刑事判决书,要求他读完案情后完成三连问——这是什么罪?对应哪条法条?该判几年?整个过程中,裁判组只打分不说话,最后排个名次。CAIL2018 中国法律智能挑战赛,就是把这场比武原封不动搬上了互联网:只不过参赛的“实习生”是一支支 AI 队伍。CAIL2022 延续了这场比武的核心理念,并在任务设置上持续演进。

CAIL2018 的任务设置由三部分组成:罪名预测、法条预测、刑期预测。数据集来自裁判文书网公开的刑事判决书,一个样本通常包含一段案情描述(如“被告人翻窗入户窃取现金两万元”)、一个或多个罪名、一个或多个法条编号,以及一个刑期值。罪名与法条预测本质是“多标签”问题——一个案子可能同时触犯多个罪名、援引多条法条;刑期预测则是“数值”问题,需要输出一个量化的刑罚长度。数据集刻意保留真实分布的噪声:有的判决书长、有的短,有的罪名动辄上万样本、有的只有零星几条。

为了公平排序,主办方采用 micro-F1 作为主评测指标。背景目标是推动 AI 辅助司法决策,而不是取代法官;数据集设计原汁原味地保留了真实司法场景的复杂分布;评测指标则用 F1 做公正的“裁判”。

对参赛的 AI 模型来说,这场比武的“裁判”极其严格:如果模型只会挑出简单的大案要案(精确率高但召回率低),或者只要沾边就全判有罪(召回率高但精确率低),F1 都会无情拉低总分。就像王老师对小秦说的:偏科不是好实习生,两个指标得同时过硬。

F1=2×P×RP+R\displaystyle F_1 = \frac{2 \times P \times R}{P + R}
F1 是精确率 P 与召回率 R 的“握手言和”:模型既不能当了“漏网之鱼”的帮凶(召回率低),也不能草木皆兵(精确率低),两个指标必须同时过硬。
  1. 真阳样本 TP预测为某罪名且真实就是该罪名的样本数,是精确率和召回率的共同起点
    TP=∣{ i:y^i=yi=1 }∣\text{TP} = |\{\,i : \hat{y}_i = y_i = 1\,\}|
  2. 精确率 P模型所有“预测为该罪名”的结果中,真正正确的占比,衡量“抓得准不准”
    P=TPTP+FP\displaystyle P = \frac{\text{TP}}{\text{TP} + \text{FP}}
  3. 召回率 R所有“真实为该罪名”的样本中,被模型找出来的占比,衡量“抓得全不全”
    R=TPTP+FN\displaystyle R = \frac{\text{TP}}{\text{TP} + \text{FN}}
  4. 调和平均 F1把 P 和 R 折中成一个分数,任何一边偏低都会显著拉低结果
    F1=2×P×RP+R\displaystyle F_1 = \frac{2 \times P \times R}{P + R}

罪名预测:实习生的第一判断

小秦上班第一天的任务,是给卷宗“定性”。王法官递给他一张纸条,上面只有一句话:“被告人深夜翻窗进入他家中,窃取现金两万元。”小秦必须在心里回答:这是什么罪?往“盗窃罪”上想很容易,但如果案子里同时有“入户”情节,答案就可能是“盗窃罪+非法侵入住宅罪”两条都勾上。罪名预测最微妙的地方就在这儿——它不是单选题,而是一张多选题。

在 CAIL2018 中,输入输出很明确:输入是案情描述文本,输出是一个罪名子集。官方将任务定义为多标签分类:每个样本不是只属于一个类别,而是可以同时命中多个罪名。模型对每个候选罪名输出一个 0 到 1 之间的概率,再由阈值决定是否命中——这个阈值通常调到验证集上 F1 最高为止。

比赛专门设计了混淆罪名评测:盗窃、抢劫、抢夺等罪名案情极其相似,区别往往只在“暴力程度”“是否入室”等细节上,模型必须捕捉到这些细微线索。许多强队因此引入法条信息作为辅助——先预测法条,再用法条约束罪名。损失函数则采用 BCE,把每个罪名当作独立的二分类问题逐项计算。

小秦后来总结:定罪名就像医生看片子,不能只看“有没有阴影”,还要看阴影的位置和边界。BCE 这个损失函数就是他的错题本——每判断错一次,就把出错的那个罪名对应的判断权重往正确方向推一步,翻错的次数越来越少。

LBCE=−1N∑i=1N[yilog⁡(p^i)+(1−yi)log⁡(1−p^i)]\displaystyle \mathcal{L}_{\text{BCE}} = -\frac{1}{N}\sum_{i=1}^{N}\left[y_i \log(\hat{p}_i) + (1-y_i)\log(1-\hat{p}_i)\right]
BCE 就像小秦的“错题本”:每判断错一次,就记下一笔损失;真实标签是 1 时模型概率越低,记的“红叉”越大。
  1. 真实标签第 i 个样本对某个罪名是否成立,成立为 1,不成立为 0
    yi∈{0,1}y_i \in \{0, 1\}
  2. 预测概率模型输出该罪名成立的概率,越接近 1 表示模型越有把握
    p^i∈(0,1)\hat{p}_i \in (0, 1)
  3. 单项交叉熵真实为 1 时惩罚“预测偏向 0”,真实为 0 时惩罚“预测偏向 1”
    −[yilog⁡(p^i)+(1−yi)log⁡(1−p^i)]-\left[y_i \log(\hat{p}_i) + (1-y_i)\log(1-\hat{p}_i)\right]
  4. 全体平均对所有样本、所有罪名求和取平均,得到最终损失
    −1N∑i=1N[yilog⁡(p^i)+(1−yi)log⁡(1−p^i)]\displaystyle -\frac{1}{N}\sum_{i=1}^{N}\left[y_i \log(\hat{p}_i) + (1-y_i)\log(1-\hat{p}_i)\right]

法条预测:翻出正确的法典

定性之后,小秦要翻书了。王法官说:“中国刑法有四百多条,盗窃罪对应第二百六十四条,抢劫罪对应第二百六十三条……你可别翻错页。”法条预测就是让 AI 干这件事:给定案情描述,找到应当援引的刑法条文。法条不是名字,是法律的“经纬度”——罪名是结论,法条是依据,二者互相校验。

CAIL2018 的法条预测同样按多标签建模:一个判决书通常援引多条法条体系相关的规定。与罪名预测相比,法条类别数更多、分布更稀疏,很多法条只有零星样本。于是模型必须学会法条关联:例如“抢劫”字样出现时,第二百六十三条的概率就该上升;如果伴随“为窝藏赃物而当场使用暴力”,还可能关联“转化型抢劫”条款。

多分类模型的输出层通常用 softmax 把打分变成一组和为 1 的概率分布,适合“只选一个答案”的场景;而 CAIL 场景因一个案子可援引多条法条,主流方案实际是多个 sigmoid 并联,再借助罪名与法条的共现矩阵施加输出约束——比如预测出“盗窃罪”时,第二百六十四条的得分必须被拉高,避免翻错页。

小秦最开始背法条靠硬记,后来他发现:法条之间是有“朋友圈”的——盗窃事实和第二百六十四条总是一起出现。模型也是一样,学会法条共现结构之后,就像拿到了法典的地图,翻页速度飞快,而且一翻一个准。

P(y=k∣x)=exp⁡(wk⊤h+bk)∑j=1Kexp⁡(wj⊤h+bj)\displaystyle P(y = k \mid \boldsymbol{x}) = \frac{\exp(\boldsymbol{w}_k^{\top}\boldsymbol{h} + b_k)}{\sum_{j=1}^{K}\exp(\boldsymbol{w}_j^{\top}\boldsymbol{h} + b_j)}
softmax 就像把法典里所有法条摊开、给每一页贴一个“匹配度”标签,谁的分数高谁被选中——而且总分数永远是 100%,不会互相打架。
  1. 特征向量案情文本经编码器压缩后的向量表示,d 是向量维度
    h∈Rd\boldsymbol{h} \in \mathbb{R}^{d}
  2. 类别打分每个法条类别 k 用权重向量与特征点积,得到该类的匹配分
    sk=wk⊤h+bks_k = \boldsymbol{w}_k^{\top}\boldsymbol{h} + b_k
  3. 指数归一化对 K 个类别的打分取指数并归一,得到和为 1 的概率分布
    P(y=k)=exp⁡(sk)∑j=1Kexp⁡(sj)\displaystyle P(y = k) = \frac{\exp(s_k)}{\sum_{j=1}^{K}\exp(s_j)}

刑期预测:称一称刑罚的天平

第三关最难。王法官对小秦说:“定罪名靠判断力,估刑期靠分寸感。同样是盗窃,初犯、退赃、自首可以轻判;多次、入户、数额巨大就得重判。”刑期预测要输出一个具体数字,而这个数字受数十个量刑特征影响,像在天平上放砝码。

直接回归一个连续刑期(比如“32.7 个月”)看似最自然,比赛结果却表明:把刑期切成离散区间再分类,效果更好,这就是区间量化。原因在于真实判决的刑期分布并不平滑——法定刑是离散档位,而且区间化能把“8.9 个月 vs 9.1 个月”这种无意义的细微差异变成同一个答案。CAIL2018 的评测也按区间精度给分。

主流做法分三步:区间量化——把 0 到无期切成若干区间(例如 0-1 年、1-3 年、3-5 年……无期),每个区间取中心值 c_k;离散分类——用 softmax 输出落在各区间内的概率 q_k;中心回归——用概率对区间中心值加权求和,得到期望刑期。量刑特征(累犯、自首、金额、伤亡情况)常被显式编码,与文本特征拼接后一起送入模型,相当于把“砝码”直接摆在秤上。

小秦后来明白了:估刑期不是“称重”而是“分档”。现实中的法官也是先定档——十年以上还是三年以下——再在档内微调。AI 用区间分类学到的,正是这套“先定档再微调”的司法直觉。

S^=∑k=1Mqk⋅ck,qk=exp⁡(sk)∑j=1Mexp⁡(sj)\displaystyle \hat{S} = \sum_{k=1}^{M} q_k \cdot c_k, \qquad q_k = \frac{\exp(s_k)}{\sum_{j=1}^{M}\exp(s_j)}
期望刑期不是直接“称”出来的,而是先给每个刑期档位发一张“可能性彩票”,再用彩票概率去加权平均,最后得到一个既有档位稳定性、又能连续微调的数字。
  1. 区间切分把刑期从 0 到无期切成 M 个档位,每档取中心值作为代表
    {c1,c2,…,cM}\{c_1, c_2, \dots, c_M\}
  2. 档位概率模型用 softmax 输出落入每个档位的概率
    qk=exp⁡(sk)∑j=1Mexp⁡(sj)\displaystyle q_k = \frac{\exp(s_k)}{\sum_{j=1}^{M}\exp(s_j)}
  3. 期望刑期以档位概率为权重,对各档中心值加权求和得到预测刑期
    S^=∑k=1Mqk⋅ck\displaystyle \hat{S} = \sum_{k=1}^{M} q_k \cdot c_k

文本预处理:先读懂卷宗再说

小秦刚拿到卷宗时险些崩溃:判决书里有大量套话、编号、括号、“本院认为”这类固定句式,还有“入户窃取”“流窜作案”这样的专业黑话。他必须先做一遍“翻译”,把卷宗整理成清晰的要点,才能开始判断。AI 面对的原始文本更脏——这就是文本预处理。

法律文本预处理是一套组合拳。分词清洗:把“被告人翻窗入户窃取现金”切分成有意义的词单元,同时去掉乱码、空格和判决书模板里的固定抬头——这些固定抬头如果不清掉,模型会偷懒地“抄答案”:看到“公诉机关指控”就直接输出罪名,导致评估虚高。停用词过滤:“的”“了”“本院”“依法”这类词对判断罪名没有信息量,滤掉可以降噪。

数据增强:对案情描述做同义词替换、随机删词、句序打乱,扩充小样本罪名的训练数据。要素抽取:从文本中抽取出金额、时间、地点、暴力手段、伤亡结果等量刑关键要素,这些要素很多时候比整段原文更有预测力。预处理阶段的另一件武器是 TF-IDF 加权——给“盗窃”“持刀”这类稀有但关键的词更高的权重,给“本院”“依法”这类套话更低的权重。

小秦的“翻译”功夫越深,后面的判断越准。AI 也一样:分词就是断句,清洗就是擦掉错别字,要素抽取就是画重点。卷宗读得明白,后面的罪名、法条、刑期才谈得上有意义。

tf-idf(t,d)=tf(t,d)×log⁡Ndf(t)+1\displaystyle \text{tf-idf}(t, d) = \text{tf}(t, d) \times \log\frac{N}{\text{df}(t) + 1}
TF-IDF 的思路很朴素:一个词在一份案卷里出现很多次(词频高)、但在所有案卷里很少见(文档频率低),它才是“关键情报”;人人都写的套话反而不值钱。
  1. 词频词 t 在文本 d 中出现的次数,体现该词在本文中的重要性
    tf(t,d)=nt,d\text{tf}(t, d) = n_{t,d}
  2. 逆文档频率包含词 t 的文档越少,idf 越大,说明该词越有区分度
    idf(t)=log⁡Ndf(t)+1\displaystyle \text{idf}(t) = \log\frac{N}{\text{df}(t) + 1}
  3. 加权融合两者相乘得到特征权重,低频关键词被放大、高频套话被压制
    tf-idf(t,d)=tf(t,d)×log⁡Ndf(t)+1\displaystyle \text{tf-idf}(t, d) = \text{tf}(t, d) \times \log\frac{N}{\text{df}(t) + 1}

模型架构:搭建实习生的“头脑”

小秦为什么能越干越熟练?因为他的“实习脑”有三层知识:第一层是语言能力——看得懂汉语;第二层是法律知识——背得下条文;第三层是办案经验——知道什么情节该重判。CAIL 的冠军模型架构,本质上就是在模仿这个三层结构:文本编码、注意力机制、多任务学习、层级分类四件套。

模型架构的核心是多任务学习加共享编码器:一段案情文本先经过文本编码器(BiLSTM 或 Transformer)变成一组向量,再分别接出罪名头、法条头、刑期头三个输出层。三个任务共享底层文字理解能力,就像小秦的“语言能力”同时服务定罪、找法条、估刑期三件事。共享参数能互相提供监督信号,还能缓解小样本任务过拟合。

注意力机制是编码器的点睛之笔:案情文本几百字,真正决定罪名的往往只有几个关键短语(“持刀”“入户”“致人轻伤”)。注意力层让模型给每个词算一个权重,把关键信息聚集起来。层级分类则把三任务串成流水线:先预测罪名,再用罪名过滤法条候选,最后结合罪名和法条一起预测刑期——这种结构把法律知识直接织进了模型里,也让每个任务的“错题”能顺着链路回溯修正。

小秦的实习脑这么组织:读一遍卷宗(编码),划出重点(注意力),先想罪名再翻法条最后掂刑期(层级),三个环节共享同一套语言理解(多任务)。模型架构不是一个黑箱,而是把实习生的经验结构搬进了数学公式里。

αt=exp⁡(u⊤ht)∑s=1Texp⁡(u⊤hs)\displaystyle \alpha_t = \frac{\exp(\boldsymbol{u}^{\top}\boldsymbol{h}_t)}{\sum_{s=1}^{T}\exp(\boldsymbol{u}^{\top}\boldsymbol{h}_s)}
注意力就像小秦读卷宗时用荧光笔划重点:“持刀”“入户”这些词被重重标记,而“的”“了”这些虚词直接跳过——最后他脑子里留下的全是关键情节。
  1. 位置向量第 t 个词经过编码器后得到向量 h_t,包含该词及其上下文的语义
    ht∈Rd\boldsymbol{h}_t \in \mathbb{R}^{d}
  2. 注意力打分用一个可学习向量 u 与每个位置向量点积,得到该位置的重要度分
    at=u⊤hta_t = \boldsymbol{u}^{\top}\boldsymbol{h}_t
  3. 权重归一对 T 个位置的打分做 softmax,得到权重并加权求和所有位置
    αt=exp⁡(at)∑s=1Texp⁡(as)\displaystyle \alpha_t = \frac{\exp(a_t)}{\sum_{s=1}^{T}\exp(a_s)}

实战挑战:真实案件的“魔鬼细节”

实习三个月后,小秦遇到了一系列“超纲题”:判决书动辄五千字,读到一半前面的案情忘了;“危险驾驶罪”的卷宗堆成山,“危害国家安全罪”的卷宗一年见不到一份;同样是“入户盗窃”,有的法院判三年,有的法院判一年半——他彻底懵了。

这些真实难题对应 CAIL 实战中的四大挑战。长文本截断:模型输入通常限制在几百到一两千字,超长判决书只能截头去尾,关键情节可能恰好被截掉。数据不均衡:热门罪名样本上万、冷门罪名样本个位数,模型天然偏向预测头部类别。类案偏差:判决受地域、法官风格影响,模型学到的是“数据里的平均值”而非“法律上的应然”。可解释性:法官可以接受 AI 打小抄,但不能接受一句“模型就是这么预测的”。

应对长文本,常用分层编码:先对段落编码,再对段落表示做注意力融合;应对不均衡,重采样搭配 Focal Loss——聚焦那些模型没把握的难样本;应对类案偏差,引入判决理由文本做对比学习,或加入地域、时间特征再评估差异;应对可解释性,用注意力分数定位关键句,用 LIME 做局部解释,把“为什么判盗窃罪”讲给人听。

小秦把这些“超纲题”逐一整理成错题本,AI 也在用同样的思路解决实战挑战:难样本加权、长文分段读、判例对比、解释报告——每一条都是在补齐“练习环境”与“真实法庭”之间的差距。

Lfocal=−α(1−p^t)γlog⁡(p^t)\displaystyle \mathcal{L}_{\text{focal}} = -\alpha (1 - \hat{p}_t)^{\gamma} \log(\hat{p}_t)
Focal Loss 的巧妙之处在于:对高置信度的简单样本降权、对低置信度的难样本升权,相当于小秦把错题本翻来覆去地做——越难的题,练得越狠。
  1. 基础交叉熵预测概率越低,这一项越大,难样本天然贡献更多损失
    −log⁡(p^t)-\log(\hat{p}_t)
  2. 调制因子当预测概率很高时该因子接近 0,把简单样本的损失压下去
    (1−p^t)γ(1 - \hat{p}_t)^{\gamma}
  3. 类别平衡权重α 用于放大少数类、缩小多数类的整体贡献
    Lfocal=−α(1−p^t)γlog⁡(p^t)\displaystyle \mathcal{L}_{\text{focal}} = -\alpha (1 - \hat{p}_t)^{\gamma} \log(\hat{p}_t)

工程落地:从比武场走向审判庭

比武归来,小秦终于转正了。但他发现,实习期的高分和真正的日常工作完全是两码事:案子要实时分析、法官要复核理由、系统要留痕审计。从“比武场”到“审判庭”,是法律 AI 的最后一公里。

工程落地第一件事是推理优化:比赛模型可以慢慢跑,线上系统不行。模型蒸馏(用大模型教小模型)、参数量化(把浮点权重压缩成整数)、批处理加速,都是常用手段。第二件事是评估体系:除了 F1,还要补充对抗鲁棒性(输入错别字会不会翻车)、公平性(不同地区是否偏差过大)和人工抽检通过率,建立多维度“体检报告”。

第三件事是伦理合规:司法 AI 的定位是“辅助”而非“决策”——预测结果必须有人工复核环节,系统要记录完整的推理依据,这是责任划分的基础。第四件事是人机协作闭环:AI 先给出罪名、法条、刑期预测并标注置信度和证据片段,法官复核后把最终结果反馈回系统,模型定期增量微调——预测、复核、反馈、再训练,形成持续进化的闭环。整个系统的总损失,由三任务损失加权组合,权重 λ 的调参也是一门手艺。

小秦转正那天,王法官对他说:“记住了,AI 是你的实习助手,不是你的上司。它判得再准,签字的是你,查错的是你,负责的也是你。”法律 AI 的工程落地,说到底就是把“实习生的冲劲”装进“老法官的流程”里——快而不越位,准而不僭越。

Ltotal=λ1Lcharge+λ2Larticle+λ3Lsentence\displaystyle \mathcal{L}_{\text{total}} = \lambda_1 \mathcal{L}_{\text{charge}} + \lambda_2 \mathcal{L}_{\text{article}} + \lambda_3 \mathcal{L}_{\text{sentence}}
总损失就像王法官给三个任务分配“考核权重”:罪名判断占多少、法条引用占多少、刑期准确占多少——权重不同,模型的学习重点就不同。
  1. 分任务损失罪名、法条、刑期三个任务各自的预测损失
    Lcharge,Larticle,Lsentence\mathcal{L}_{\text{charge}}, \quad \mathcal{L}_{\text{article}}, \quad \mathcal{L}_{\text{sentence}}
  2. 任务权重λ 调节各任务在总损失中的话语权,通常由验证集搜索确定
    λ1,λ2,λ3∈[0,1]\lambda_1, \lambda_2, \lambda_3 \in [0, 1]
  3. 联合优化三损失加权求和,反向传播同时更新共享编码器与各任务头
    Ltotal=λ1Lcharge+λ2Larticle+λ3Lsentence\displaystyle \mathcal{L}_{\text{total}} = \lambda_1 \mathcal{L}_{\text{charge}} + \lambda_2 \mathcal{L}_{\text{article}} + \lambda_3 \mathcal{L}_{\text{sentence}}

AI 应用场景

法院类案检索与导诉分流

阶段:推理与决策辅助

解决的问题:传统类案检索靠法官记忆和关键词查询,效率低且容易漏掉关键判例。基于 CAIL 训练出的案情编码器,可以把新案情的描述向量化,在判决库中做语义检索,自动推送相似类案及对应量刑区间,帮助法官快速锚定裁判尺度。

具体案例:某基层法院在导诉台接入罪名预测模型,当事人描述纠纷经过后,系统自动提示“可能涉及的罪名 + 对应法条 + 参考量刑区间”,引导当事人选择调解、速裁或普通程序,立案材料准备时间从半天缩短到十几分钟。

律所与企业法务的刑事风险预警

阶段:数据分析与风险研判

解决的问题:合规审查中,人工甄别某个业务行为是否可能触刑,既依赖经验又容易遗漏。AI 对业务文本做罪名与刑期双预测,输出风险等级和依据片段,相当于给合规团队配了一位不知疲倦的“实习助理”。

具体案例:某互联网公司法务部每月将新业务文案批量输入系统,系统自动标记“可能涉嫌非法吸收公众存款罪”,并给出量刑区间与相关法条、高危关键词位置。合规团队据此修改话术和业务流程,在监管介入前完成自查。

Python 演示

python95 行
# -*- coding: utf-8 -*-"""CAIL2018 罪名预测简化演示 - 从案情描述判断罪名"""  class TinyTokenizer:    """简易分词器: 单字 + 相邻双字构成特征"""     def __init__(self):        self.vocab = {}     def tokens(self, text):        words = []        for i in range(len(text)):            words.append(text[i])            if i + 1 < len(text):                words.append(text[i:i + 2])        return words     def fit(self, texts):        for text in texts:            for w in self.tokens(text):                if w not in self.vocab:                    self.vocab[w] = len(self.vocab)     def transform(self, text):        vec = [0] * len(self.vocab)        for w in self.tokens(text):            if w in self.vocab:                vec[self.vocab[w]] += 1        return vec  class Perceptron:    """多类别感知机: 每个罪名学一套权重, 输出得分最高者"""     def __init__(self, n_features, n_classes):        self.w = [[0.0] * n_features for _ in range(n_classes)]        self.b = [0.0] * n_classes        self.lr = 0.1     def predict_one(self, x):        scores = []        for c in range(len(self.b)):            total = self.b[c]            for i in range(len(x)):                total += self.w[c][i] * x[i]            scores.append(total)        return max(range(len(scores)), key=lambda i: scores[i])     def train_one(self, x, y):        pred = self.predict_one(x)        if pred == y:            return        for i in range(len(x)):            self.w[pred][i] -= self.lr * x[i]            self.w[y][i] += self.lr * x[i]        self.b[pred] -= self.lr        self.b[y] += self.lr  def main():    cases = [        ("被告人翻窗入户窃取现金两万元", 0),        ("被告人持刀威胁路人抢走手机", 1),        ("被告人醉酒驾驶机动车撞伤行人", 2),        ("被告人多次潜入仓库盗走贵重货物", 0),        ("被告人蒙面持械闯入银行劫走现金", 1),        ("被告人酒后驾车在高速公路上逆行", 2),        ("被告人虚构项目骗取老人存款后逃匿", 3),        ("被告人伪造合同骗取公司货款", 3),    ]    names = ["盗窃罪", "抢劫罪", "危险驾驶罪", "诈骗罪"]     tok = TinyTokenizer()    tok.fit([c[0] for c in cases])    X = [tok.transform(c[0]) for c in cases]    model = Perceptron(len(tok.vocab), len(names))    for _ in range(40):        for x, y in zip(X, [c[1] for c in cases]):            model.train_one(x, y)     tests = [        "被告人深夜翻窗盗窃他人财物",        "被告人持刀抢劫出租车司机",        "被告人醉酒驾车撞伤路人",        "被告人虚假宣传骗取投资款",    ]    for t in tests:        vec = tok.transform(t)        pred = model.predict_one(vec)        print("案情: %s -> 预测罪名: %s" % (t, names[pred]))  if __name__ == "__main__":    main()
目的:用纯 Python 实现一个微型“罪名预测”系统——先把案情文本切分成单字和双字特征,再训练一个多类别感知机,对测试案情输出预测罪名。它是 CAIL2018 罪名预测任务的可运行玩具版,展示了“文本特征化 + 分类器”的核心流程。
  1. tok.fit([c[0] for c in cases])用全部训练案情建立词典,每个特征获得一个整数编号
  2. X = [tok.transform(c[0]) for c in cases]把每条案情转成词频向量,作为模型的输入特征
  3. model = Perceptron(len(tok.vocab), len(names))建感知机:输入维度=词典大小,输出类别=罪名数量
  4. total += self.w[c][i] * x[i]每个特征按权重累加打分,相当于给“盗窃”“持刀”等线索加权投票
  5. self.w[pred][i] -= self.lr * x[i]预测错时把错误类别的权重压低,让“错票”下次不再投出
  6. self.w[y][i] += self.lr * x[i]同时抬高正确类别的权重,相当于把“对票”的分量加重
  7. pred = model.predict_one(tok.transform(t))测试文本走一遍相同的特征转换和分类流程,输出最终罪名

常见误区

误区CAIL2018 训练的模型就是为了让电脑直接出判决书,以后法官都要失业了。新闻里不都说了吗,“AI 法官”上线了。

正解CAIL 的三大任务输出的是罪名、法条、刑期的“预测建议”,不是具有法律效力的判决。司法责任制要求法官对裁判终身负责,模型只能做辅助参考。工程落地方案里专门保留人工复核环节,正是为了守住“辅助而非替代”的边界——就像实习生的建议必须由主审法官签字才生效,AI 永远只是那个递纸条的实习生。

为何常见:媒体喜欢用“AI 法官”这类标题制造爆点,读者容易把比赛宣传与真实司法流程混为一谈,忽略了判决背后的责任归属和程序正义。

误区只要把“盗窃”“抢劫”“诈骗”这些词做成关键词词典,看案情里出现哪个词就判哪个罪,准确率肯定不低。

正解真实案情中,“抢”既可以出现在抢劫罪,也可以出现在抢夺罪;“偷”可能是盗窃罪也可能是职务侵占罪。CAIL 特意设置“混淆罪名”任务,模型必须结合上下文、金额、暴力程度等细节才能区分。关键词缺失语义理解,遇到“以借为名实施抢劫”这类表述就完全失灵。注意力机制能锁定“暴力胁迫”这类真正决定罪名的细节,而不是生硬的词典命中。

为何常见:入门者看过一些基于规则匹配的简单 demo 之后,误以为法律文本的语义空间稀疏到几个词就能覆盖,低估了自然语言的灵活性。

误区罪名和法条一一对应,知道罪名自然知道法条,训练一个任务就够了,何必搞两个任务?

正解罪名与法条存在多对多关系:一个罪名可能关联多条法条(如转化型抢劫),一条法条也可能涵盖多个罪名(如刑法第二百六十四条包括多种盗窃情形)。CAIL 之所以单独设置法条任务,正是因为它们在数据中只是一定程度共现,并非确定的映射。多任务学习利用这种相关性互相纠偏,但不等于二者等价。

为何常见:初学者先接触“盗窃罪→第二百六十四条”这种最典型的对照表,看到整齐的对应关系就以偏概全,忽略了法律条文的交叉与竞合。

误区刑期是一个数字,用回归模型输出一个连续年数最自然,比如“3.47 年”,多精确。

正解比赛和真实工程都表明,直接回归对数值敏感、难以处理“无期”这类特殊刑期,且完全忽略了法定刑档位结构。区间量化 + 离散分类 + 中心期望值是主流方案,因为它既尊重法律的分档逻辑,又对判决噪声更鲁棒——判 8.9 个月还是 9.1 个月在实务上没有意义,法官不会这么判。

为何常见:从教科书回归问题的直觉出发,容易忽略法律判决是离散档位制而不是连续量这个领域先验,把“数字输出”等同于“数值预测”。

误区比赛里 F1 排前五的模型,直接部署到法院系统就能给法官当助手,准确率摆在那里。

正解比赛数据来自历史判决书,模型可能学到地域偏差、法条更新前的旧规则,甚至从“公诉机关指控”这类模板句里抄答案。上线前需要做对抗鲁棒性测试、公平性评估和可解释性审计,否则一个错别字就可能导致预测翻车。就像小秦实习期模拟考满分,不代表他就能独立签发判决书——真实法庭的变量远比赛场多。

为何常见:把线下评测指标等同于线上真实效果,忽视了训练分布与部署环境的差异,也低估了司法场景对错误的高代价容忍度。

面试题

Q1. CAIL2018 设置的核心任务有哪些?

单选题 · easy

  • A.罪名预测、法条预测、刑期预测← 正确答案
  • B.证据提取、证人识别、文书生成
  • C.语音识别、人脸识别、指纹识别
  • D.合同审查、风险评估、合规检查

答案:A。CAIL2018 三大任务瞄准刑事判决中最核心的三步:罪名预测、法条预测、刑期预测。选项 B、D 是其他法律科技方向,C 是通用 AI 技术,都不属于 CAIL2018 的任务设置。

Q2. 罪名预测为什么要建模为多标签分类?

单选题 · easy

  • A.一个案件可同时触犯多个罪名← 正确答案
  • B.一个案件只能属于一个罪名
  • C.法条顺序会影响罪名判断
  • D.罪名数量会随案情动态变化

答案:A。现实中数罪并罚很常见,一个案件可能同时触犯盗窃罪和非法侵入住宅罪,因此每个样本可命中多个标签,这正是多标签分类的适用场景。B 是单标签思维,C、D 与分类问题的定义无关。

Q3. softmax 输出层的核心特性是什么?

单选题 · mid

  • A.各类概率总和恒为 1← 正确答案
  • B.各类概率相互独立取值
  • C.输出概率可能大于 1
  • D.输出概率不依赖输入

答案:A。softmax 先对每个类别打分取指数,再除以所有类别指数之和,保证输出是合法的概率分布:非负、和为 1。B、C 与这一性质矛盾,D 则完全背离了 softmax 作为分类头对输入特征的依赖特性。

Q4. 在多标签分类场景中,最常使用的是哪个损失函数?

单选题 · mid

  • A.二分类交叉熵 BCE← 正确答案
  • B.平均绝对误差 MAE
  • C.余弦相似度对比损失
  • D.三元组距离度量损失

答案:A。多标签分类把每个标签看作独立的二分类问题,BCE 对每个标签计算真实标签与预测概率之间的交叉熵并取平均,与 CAIL 罪名预测的建模方式一致。MAE 用于回归,后两者多用于表征学习和度量学习。

Q5. 哪些手段可以缓解法律文本的数据不均衡问题?

多选题 · mid

  • A.对少数罪名样本做数据增强← 正确答案
  • B.采用 Focal Loss 聚焦难样本← 正确答案
  • C.对多数类样本进行欠采样← 正确答案
  • D.删除所有低频罪名样本

答案:ABC。数据增强和欠采样都是经典的重平衡手段,Focal Loss 则通过对低置信度样本升权缓解类别失衡。直接删除低频罪名相当于放弃对该类别的预测能力,会让模型彻底无视少数类,属于错误做法。

Q6. 刑期预测中,区间量化加期望值方案相比直接回归的好处是?

单选题 · mid

  • A.贴合法定刑分档结构且更稳健← 正确答案
  • B.回归模型在数值上完全不可用
  • C.区间化后可以不需要任何特征
  • D.期望值计算可以绕过训练过程

答案:A。真实量刑遵循法定刑档位,直接连续回归对微小噪声敏感。区间量化把“8.9 个月 vs 9.1 个月”归入同一档,再对区间中心值加权求和得到期望刑期,兼顾分类稳定性与数值输出。B、C、D 的表述均不成立。

Q7. 注意力机制中 softmax 的作用是什么?

单选题 · hard

  • A.对位置打分归一化成权重← 正确答案
  • B.提升模型训练时的梯度大小
  • C.压缩输入文本的维度空间
  • D.替代损失函数完成参数更新

答案:A。注意力先把每个位置与查询向量算出一个标量分,再用 softmax 把分数转换成非负且和为 1 的权重,从而对各位置向量加权求和得到上下文向量。B、C、D 都不是 softmax 在注意力机制中承担的角色。

Q8. 多任务学习在 CAIL 三任务联合建模中的优势有哪些?

多选题 · hard

  • A.任务间共享底层编码特征← 正确答案
  • B.罪名与法条提供互补监督← 正确答案
  • C.缓解个别任务的过拟合风险← 正确答案
  • D.消除数据集中的类别不均衡

答案:ABC。共享编码器让三个任务互相传递归纳偏置,罪名与法条的天然相关性提供了额外监督,尤其对样本稀少的任务有利。但多任务学习只是缓解而非消除数据不均衡,仍需重采样、Focal Loss 等手段配合,因此 D 错误。

Q9. F1 分数的计算依赖哪两个指标?

单选题 · easy

  • A.精确率与召回率的调和平均← 正确答案
  • B.测试集上的整体准确率
  • C.模型每秒可推理的样本数
  • D.训练损失下降到零的程度

答案:A。F1 是精确率(预测为正的样本中真阳的占比)和召回率(真实为正的样本中被找出的占比)的调和平均,用来平衡“少判错”和“不漏判”。B 是准确率,C 是吞吐量,D 是训练状态,都不是 F1 的构成指标。

Q10. 法律 AI 工程落地需要重点关注哪些环节?

多选题 · hard

  • A.长文本分段编码避免截断丢失← 正确答案
  • B.对抗鲁棒性与公平性评估← 正确答案
  • C.人机协作与审计留痕机制← 正确答案
  • D.模型参数量越大错误率越低

答案:ABC。真实判决书常超长,分段编码是刚需;上线前要评估模型对错别字、篡改文本的鲁棒性以及不同地区的公平性;辅助决策必须有复核与留痕。D 是无根据的直觉,模型越大推理成本越高,未必更稳,错误率与参数量没有必然关系。