lexifina/global-law · 上手攻略

  • 仓库:lexifina/global-law
  • 链接:https://github.com/lexifina/global-law
  • 分类:multimodal / 法律文本数据工程(研究型)
  • 作者:spark
  • 更新:2026-11-04

§0 自检清单

  • [x] GitHub URL 已 fetch(README 全文,2026-11-04 抓取)
  • [x] 仓库卡核对:HTML、1765 stars、周增 +224、最近提交 2026-11-04、许可 NOASSERTION(README 实为 CC0 + 「各国法条仓库自有条款」)
  • [x] 关键子文档锚点:MCP.md / REPRODUCE.md / CHANGELOG.md / performance/ / visualisations/ / LICENSE.md 均在 README 中出现并核对
  • [x] 版本信息:README 未给 release tag / 版本号;Hacker News 首登时间 2026-10-28 已在正文核对
  • ⚠️ 待补:manifest.json / jurisdiction.json 的实际覆盖国家数与日期区间未逐项核对(README 只给结构示例)
  • ⚠️ 待补:tools/mcp_server.py 的 18 个只读工具名未逐一比对 MCP.md
  • 说明:本文只读公开页面,未 clone、未运行代码

§1 它是什么

lexifina/global-law 的口号是 "The world's law in one git history"——把全世界各国法律放进一条 git 历史里,每一条法条都能追溯到「写下它的那部法」。

它的核心机制是用 git 提交当法律的时间轴:

  • 每个司法辖区有自己的仓库 lexifina/<country>-law;
  • 每次提交 = 一部生效的法律,由那部法律本身写成;
  • global-law 这个主仓库把这些语料库以 submodule 形式挂进来,按司法辖区排列,并把每个 submodule 的 pin 推到最新提交;
  • 工具读每个提交的 In-force(生效)日期,于是可以回答「任意国家、任意日期的法律」。

目录结构:

global-law/
├── manifest.json        每个语料库的:路径、仓库、覆盖范围与日期
├── jurisdiction.json    这个世界,以及其中的司法辖区
├── germany/bund/acts/   一个国家的法(submodule)
├── brazil/bahia/acts/   一个州的法
├── brazil/bahia/salvador/acts/   一个市的法
└── …

粒度可以细到「巴西巴伊亚州萨尔瓦多市」这种市级。README 说明这是同一个理念在 US Code 上的扩展版本,那个版本曾于 2026-10-28 登上 Hacker News 第一。

§2 解决什么问题

法律文本的检索一直卡在同一个点上:法条会变。「当时有效的法律是什么」「这条现在是谁改的」「这一行是哪部法写的」——这三个问题在普通法条数据库上很难回答,因为数据库只存最终快照,不存演进过程。

global-law 的做法是把法条演进变成 git 历史,于是:

  • 按日期读法条成为一次 checkout(git show <date>:<path> 的语义);
  • blame 到具体法律成为 git 原生能力(不是 blame 到某个人,而是到某部法律);
  • 两日期之间改了什么成为 git diff;
  • 某段时间内生效了哪些法成为对提交日期范围的查询。

换句话说,它把法条的「版本历史」这件在法学界既昂贵又常被忽略的事,变成了 git 这类已经被彻底工程化的操作。这是本项目最值得借鉴的思路,而不是某个具体的 CLI。

§3 快速安装

git clone https://github.com/lexifina/global-law && cd global-law

# 加一个语料库
python3 tools/countries.py add united-states/federal/usc

# 查一条法条在某个日期的文本
python3 tools/law.py show 2022-05-01 united-states/federal/usc/title-11/1182.md

两条硬性要求(README 明确警告):

  1. 每个国家都要用 --recurse-submodules 克隆;
  2. 绝对不要用 --depth——日期是从完整历史里读出来的,浅克隆会让时间轴失效。

代价是体积:README 原话是「每个国家好几个 GB(every country is several GB)」。

§4 核心用法

4.1 命令行工具

# 世界观:某一天所有语料库的快照
python tools/law.py world 2022-05-01

# 某条法条在某日期的文本
python tools/law.py show 2022-05-01 <path>

# 每一行背后的法律
python tools/law.py blame 2022-07-01 <path>

# 每个词背后的法律(比 blame 更细)
python tools/law.py words 2022-07-01 <path>

# 两个日期之间改了什么
python tools/law.py diff 2022-05-01 2022-07-01 <path>

# 某段时间内生效的所有法律
python tools/law.py laws 1990-01-01 1990-12-31 germany

日期一律 YYYY-MM-DD。首次读取某个语料库时,会把它的历史一次性索引并缓存在 .git/global-law-cache。

4.2 MCP 服务器(这是给 AI Agent 用的正路)

tools/mcp_server.py 是一个 Model Context Protocol 服务器,提供 18 个只读工具:查找法条、按日期读取、谁写了每个词、比较两个日期、法条沿革、搜索法条文本与变更、拿案件/书状对照当时生效的法律等。

只需要 Python 3.9+ 和 git,跑在你本机,不发起任何网络请求。

仓库自带 Claude Code / Cursor / VS Code / Codex 的配置,打开文件夹即自动启动。对于其他客户端,手动配置:

{
  "mcpServers": {
    "global-law": {
      "command": "git",
      "args": [
        "-C", "/path/to/global-law",
        "-c", "alias.global-law-mcp=!sh tools/mcp.sh",
        "global-law-mcp"
      ]
    }
  }
}

然后就可以问:

"What did 11 U.S.C. §1182(1) say on 1 May 2022, and which law last changed it?"

全部 18 个工具的说明在 MCP.md。

4.3 语料库迁移后的处理

一个语料库换了新目录后,仍能用旧路径提问(数据在 data/moved-paths.tsv)。但 pull 之后如果语料库位置变了,要跑:

git submodule sync
git submodule update --init

manifest.json 和 jurisdiction.json 由 tools/describe.py 生成,不是手写的。

4.4 测试与其它文档

python -m unittest discover -s tests
  • MCP.md——MCP 服务器全部工具与细节
  • REPRODUCE.md——这个仓库是怎么造出来的
  • CHANGELOG.md——变更记录
  • performance/——工具实测速度
  • visualisations/——各国法律之间的图表与桥接

§5 典型适用场景

  • 法律研究 / 立法史考证:某条法在某个时点的有效文本、是哪部法改的
  • 合规与尽职调查:批量核对某国法规在特定时间窗口内的变动
  • AI 法律助手:通过 MCP 把「带时间维度的法条检索」接进 Claude Code / Cursor / Codex
  • 跨境产品:一个产品同时受多个辖区规则约束时,用 jurisdiction 树做统一查询
  • 数据工程参考:把「有版本演进的领域数据」建模成 git 仓库 + submodule pin 的范式

§6 坑与注意

  1. 不要 --depth 浅克隆:日期是从完整历史读出来的,浅克隆会让时间轴直接失效——这是本项目最容易犯的致命错误。
  2. 必须 --recurse-submodules:不递归克隆等于只拿到空壳索引,所有查询都会失败。
  3. 体积巨大:每个国家好几个 GB。全量克隆需要预留相当可观的空间与时间。
  4. 语料库本身不在本仓库:法条文本住在各 lexifina/<country>-law 仓库里,受各自条款约束。主仓库是 CC0,不代表法条文本是 CC0——README 明确写了「The law text sits in each country's repository, under that repository's own terms」。做商用分发前必须逐国核对条款。
  5. 历史只增不减:每个提交只做三件事——新增语料库、把 pin 往前推、改工具与文档。tools/verify.py 负责校验这一点。
  6. 历史是冻结的:截至 2026-10-29,仓库是从零构建的,一个法律一个提交,按生效顺序排列。这段历史被冻结保留,REPRODUCE.md 记录了构建方式。
  7. 首次读取慢:每个语料库第一次访问要索引整段历史,缓存写在 .git/global-law-cache。
  8. submodule pin 移动后忘记 sync:pull 后出现路径失效、查询报找不到文件,多半是没跑 git submodule sync && git submodule update --init。
  9. tools/law.py words 的粒度是「词」:比 blame(行)更细,但这种极细粒度在法律文本上的语义边界并不总是清晰——它是字符级归因,不等于立法意图。
  10. 覆盖率不保证完整:manifest.json 记录每个语料库的覆盖范围与日期,但「某国某时段是否有完整覆盖」需自行核对元数据,不能默认。
  11. ⚠️ README 未标注每个语料库的法律体系边界(成文法/判例法混合程度),也没说明非成文法辖区的覆盖情况——用前需自查。
  12. 许可状态不一致:仓库卡记的是 NOASSERTION,README 写主仓 CC0、法条另论。二次分发前务必按第 4 条逐国核对。

§7 与同类对比

方案 时间维度 可追溯到具体立法 本地离线 成本
global-law 完整 git 历史,按提交 In-force 日期 能(blame 到「哪部法」) 是(git + Python,无网络调用) 磁盘大(每国数 GB)、首次索引慢
Westlaw / LexisNexis 有历史版本 部分(多为注释与修订记录) 否,订阅制 昂贵、封闭
政府公报网站(如 EUR-Lex) 原始公告最全 能,但要从 PDF/HTML 自己解析 是(自己爬) 无结构化接口,解析成本高
GitHub 上的法条文本 dump 通常只有最新快照 否 是 免费但不回答「当时是什么」
自建 etl + PostgreSQL 时态表 可做时态 取决于 ETL 质量 是 工程量大,版本演进易丢

它的独特位置是唯一把「法条的沿革」当成 git 历史本体的方案——因此 MCP 接入 AI Agent 的成本几乎为零,因为 git 的语义就是现成的语义。

§8 一句话推荐结论

如果你的需求是「某条法在某年某月说了什么、是哪部法改的」,这是目前少见的开箱即用方案——它把法律演进建模成 git 提交,MCP 18 个只读工具直接让 Claude Code / Cursor / Codex 用自然语言查任意国家任意日期的法条,零网络请求;但用之前先想清楚两件事:磁盘要留好几个 GB,以及法条文本的版权在各子仓库、不在 CC0 主仓。

本文只读公开页面(GitHub README,2026-11-04 抓取)。未 clone、未运行代码,命令均转录自 README。⚠️ 标记处为待核项。