CaseCite:开源可自托管的法律 RAG 研究平台
Harvey raised 500M for legal AI, I built the same and open sourced it
作者开源了 CaseCite,一个可自托管的法律研究平台,支持上传律所文档后做带引用的检索问答、合同审查、起草和法官分析。
CaseCite — 私有法律 RAG
CaseCite 是一个开源、自托管的法律研究平台。上传贵所的文件、提出问题,并研究案例与法官——一切都在您掌控的基础设施上进行。文件、搜索索引和聊天记录都存储在您自己的服务器上。AI 功能会将您的问题和相关文档文本发送到您配置的 AI 提供商,使用您自己的 API 密钥(BYOK);不会向 CaseCite 维护者发送任何内容,也没有遥测。请参阅哪些内容会离开您的基础设施。
功能概览
一个登录入口背后有八种工具,全部读取同一文档语料库。
研究(/research) |
基于贵所文档的聊天——语义检索,并对候选结果进行关键词(BM25)重打分,同时提供指向来源的内联引用。 |
文档(/documents) |
上传、索引并组织您的语料库。可从 Google Drive、OneDrive、Box、Dropbox、Filevine 或 Clio 导入——支持 OAuth 同步,或在无需 OAuth 验证时使用文件选择器。iManage 和 NetDocuments 连接器已存在但处于实验阶段(未针对真实租户测试),除非 EXPERIMENTAL_CONNECTORS=true,否则默认关闭。 |
合同(/contracts) |
完整的合同审查流程:分析已索引的合同或粘贴的文本,与单份合同对话,将 2–4 份合同与基准逐条款比较,并导出红线、草稿或分析本身。 |
起草(/drafting) |
基于您从知识库中选取的最多四份文档起草文件,支持服务端文本提取和 PDF 转换。可为长文档(30 页的协议)设定目标长度:您先审阅章节计划,然后每个章节都在其独立的上下文窗口中对照完整参考资料起草,最后整体协调。对长草稿的修订仅限于其涉及的章节。 |
案例视图(/case/:id) |
打开 CourtListener 的判决意见并直接与其对话。 |
权威图谱(/case-citations) |
梳理您所选文档中引用的权威来源。 |
法官情报(/judge-intel) |
来自 CourtListener 的法官分析。 |
法律工具(/tools) |
案例查询、引证核查(扫描引用该案的判决意见中的负面处理措辞——不能替代 Shepard's/KeyCite)、先例、案卷、口头辩论和判例趋势。 |
截图
截取自真实 UI,针对模拟 API 和虚构的律所、事项及案件数据(frontend/e2e/screenshots.spec.ts)。不出现任何真实客户或案件。
| 基于律所文档的研究 | 知识库 |
|---|---|
![]() |
![]() |
| 合同分析 | 引证核查 |
|---|---|
![]() |
![]() |
执业画像。产品中没有内置任何关于执业领域的内容。您说明自己的执业范围,CaseCite 会起草一份关于该执业领域关键要素的画像,由您编辑并拥有(通过设置保存)。随后它会作为常驻上下文伴随每次审查、红线和起草。
每个 AI 生成的答案、分析和草稿都带有提示:在依赖之前,请对照源文档和现行法律进行核实。CaseCite 是研究辅助工具,不能替代律师的判断或引证工具。
哪些内容会离开您的基础设施
文档、向量索引、聊天记录和分析仅存储在您的部署中。使用 AI 功能会传输内容到您选择的第三方:
- 上传文档会将其文本发送到嵌入提供商(默认为 OpenAI;如已配置则为 Voyage 或 Cohere)。
- 提问、分析或起草会将问题和相关文档文本发送给 LLM 提供商(OpenAI、Anthropic 或 Gemini)。
- 判例法工具会将搜索查询和引文发送给 CourtListener。
要让文档文本完全保留在你的网络中,请自行运行两个模型:将 OPENAI_BASE_URL(聊天)和 EMBEDDING_BASE_URL(嵌入)都设置为
你托管的 OpenAI 兼容服务器。只设置第一个仍会将文档文本发送给 OpenAI 进行嵌入。出站数据流的完整列表,
以及如何限制它们,见 docs/subprocessors.md。
许可证与使用
Copyright 2026 Thomas Unise。CaseCite 是开源软件,采用 Apache License 2.0(LICENSE),这是 OSI 批准的宽松 许可证。通俗地说:
- ✅ 可自由自托管,用于内部用途或供他人使用,无论是否修改。
- ✅ 可自由修改、分叉、再分发和销售,包括在 专有产品中,只要你保留版权和许可证声明 以及 NOTICE.md 中的署名,并说明你做了哪些更改。
- ✅ 贡献者为其贡献授予明确的专利许可, 这是 MIT 许可证所没有的。
- 你的文档、提示词和输出都归你所有。许可证涵盖 CaseCite 代码,而非你通过它处理的内容。
维护者 @thomasunise 提供商业支持和私有部署。 见 SUPPORT.md。 1.3.0 及更早版本曾以 Elastic License 2.0 发布;该许可证 继续适用于那些版本。
快速开始
前提条件
- Docker + Docker Compose
openssl(用于生成密钥)- AI 提供商 API 密钥(OpenAI 是最简单的起点:它同时涵盖聊天和 嵌入)。在服务器层面是可选的——用户可以各自保存自己的密钥。
运行它(自包含:捆绑 Postgres、Redis 和 HTTPS 代理)
git clone https://github.com/thomasunise/casecite.git && cd casecite cp .env.example .env # 1. Generate the three REQUIRED secrets (the .env.example placeholders # intentionally refuse to boot). Copy each value into .env: openssl rand -hex 32 # -> SECRET_KEY openssl rand -hex 32 # -> AUDIT_HMAC_KEY openssl rand -hex 16 # -> ENCRYPTION_SALT # 2. In .env also set OPENAI_API_KEY (or leave it empty and save a key under # Settings after signing in), then uncomment and set DOMAIN, # POSTGRES_PASSWORD and REDIS_PASSWORD in the "Bundled production stack" # section (generation hints are in the file; use DOMAIN=localhost to try it # on your machine). CORS_ORIGINS and ALLOWED_HOSTS default from DOMAIN. # Set REGISTRATION_BOOTSTRAP_TOKEN too (openssl rand -hex 16) — you need it # to create the first account. # 3. Set DISK_ENCRYPTION_ACKNOWLEDGED=true in .env (required to boot). # What this acknowledges: the app encrypts BYOK keys and uploaded documents # at the application layer (AES-256-GCM), but derived text (vector chunks, # chat history, analyses) is stored in cleartext in the app, Postgres and # Redis volumes — full-disk encryption of the host is YOUR responsibility. # 4. Start the full stack (bundled Postgres + Redis + Caddy): docker compose -f docker-compose.prod.yml up -d
python3 scripts/setup_production.py --create-env --domain <host> 为你完成步骤
1–2(它会生成所有密钥并以 0600 权限写入 .env)。
然后打开 https://$DOMAIN(使用 DOMAIN=localhost 时:https://localhost)。
在 localhost 试用时,Caddy 会将 HTTP 重定向到 HTTPS,并提供来自其自有自签名本地 CA 的证书
——首次访问时的浏览器警告是预期内的。请参阅 docs/deployment.md 中的“内部网络上的 TLS”
以信任该 CA 或使用你自己的证书。
你注册的第一个账户将成为管理员,注册它需要
.env 中的 REGISTRATION_BOOTSTRAP_TOKEN——因此其他任何访问全新实例的人都无法认领它。确切命令见 docs/deployment.md 中的“创建管理员
账户”。之后,从设置 → 用户邀请
同事;自助注册默认关闭。
要部署在现有反向代理(Coolify/Traefik)之后?请改用根目录下的
docker-compose.yml(它需要外部 Postgres 和 Redis,并 声明持久数据卷),并阅读deploy/COOLIFY-SETUP.md—— 你还必须将TRUSTED_PROXIES设置为代理的子网,否则客户端 IP 会合并为一个。
密钥保管(BYOK)
用户通过设置模态框提供 AI 提供商密钥。律所评估人员 应了解的保管要点:
- 每用户密钥存储在服务器端,采用 AES-256-GCM 加密(PBKDF2 密钥 派生,HKDF 按记录分离),位于数据卷上的文件存储中。
- 密钥仅以掩码形式显示,绝不会发送到浏览器; 后端会在每次请求时按需解密它们。
- 通过环境变量配置的兜底密钥(例如
.env中的OPENAI_API_KEY)由该安装的 所有用户共享——按用户分摊成本需要使用按用户的 BYOK 密钥。 ENCRYPTION_SALT可以在不丢失已存储密钥的情况下轮换:将旧值保留在ENCRYPTION_SALT_PREVIOUS中,并在后端容器内运行python -m app.utils.reencrypt——参见docs/secret-rotation.md。SECRET_KEY无法在不使已存储文档变得不可读的情况下轮换;请妥善保管 并在服务器之外做好备份。
配置
必需的环境变量
如果其中任何一项缺失或仍为占位符,整个技术栈会在启动时失败关闭。
| 变量 | 说明 |
|---|---|
SECRET_KEY |
JWT/CSRF 签名密钥以及静态加密的根密钥——openssl rand -hex 32(首次运行后切勿更改) |
ENCRYPTION_SALT |
静态加密盐值——openssl rand -hex 16(首次运行后切勿更改,除非通过轮换流程) |
AUDIT_HMAC_KEY |
审计日志链密钥,至少 32 个字符——openssl rand -hex 32 |
POSTGRES_PASSWORD |
内置 Postgres 的密码 |
REDIS_PASSWORD |
内置 Redis 的密码 |
DOMAIN |
公共主机名(或 localhost);CORS_ORIGINS + ALLOWED_HOSTS 默认由它派生 |
DISK_ENCRYPTION_ACKNOWLEDGED |
设置 true 以确认主机卷的全盘加密由你负责(应用层 AES-256-GCM 覆盖 BYOK 密钥 + 文档原件;派生文本为明文) |
REGISTRATION_BOOTSTRAP_TOKEN |
注册第一个(管理员)账户所需——openssl rand -hex 16 |
启动时并非必需,但没有它们产品几乎无法使用:
| 变量 | 说明 |
|---|---|
OPENAI_API_KEY (或其他提供商) |
由所有用户共享的服务器级提供商密钥。没有它,每个用户必须在设置中保存自己的密钥,聊天、分析或索引才能工作。 |
COURTLISTENER_API_TOKEN |
CourtListener 是应用中唯一的判例法来源。引证检查需要令牌;其他判例法工具无需令牌即可使用,但会受到严格的速率限制。令牌免费;参见 CourtListener API token。 |
使用根
docker-compose.yml(外部数据库/Redis)而不是内置 技术栈?那么需要直接提供DATABASE_URL、REDIS_URL、CORS_ORIGINS和ALLOWED_HOSTS, 并为托管数据库设置DB_SSL=require。
可选的环境变量
| 变量 | 默认值 | 说明 |
|---|---|---|
ANTHROPIC_API_KEY |
— | Claude 访问 |
VOYAGE_API_KEY |
— | Voyage AI 法律嵌入 |
OPENAI_BASE_URL |
— | 用于聊天的 OpenAI 兼容端点(自托管模型或网关) |
EMBEDDING_BASE_URL |
— | 用于嵌入的 OpenAI 兼容端点;与 OPENAI_BASE_URL 一起设置可将文档文本保留在你的网络中 |
VECTOR_DB |
chroma |
chroma(本地)或 pinecone(将文档文本存储到 Pinecone) |
TRUSTED_PROXIES |
127.0.0.1 |
反向代理 IP/CIDR——在代理后面时必需 |
REQUIRE_MFA |
false |
要求每个密码账户注册 TOTP MFA |
SESSION_ABSOLUTE_TIMEOUT_HOURS / SESSION_IDLE_TIMEOUT_MINUTES |
8 / 120 |
会话生命周期和空闲超时 |
ALLOW_REGISTRATION |
false |
允许在第一个账户之后自助注册 |
SENDGRID_API_KEY |
— | 启用密码重置邮件(修改密码无需它即可工作) |
.env.example 记录了每一项设置。
连接器说明
- 同步 API 导入一个文件夹(
folder_id),或者在显式指定sync_all时导入整个账户。UI 目前没有文件夹选择器:“立即同步” 会在第二次确认(确认内容已说明这一点)后导入整个已连接账户。 要导入选定的文件,请改用文件选择器。Clio 的列表是 账户范围的,因此 Clio 无法同步单个文件夹。 - Filevine 使用一个全公司范围的 API 密钥,因此在设置
FILEVINE_ENABLED=true之前处于关闭状态,之后仅对管理员可用。 - iManage 和 NetDocuments 连接器是实验性的。它们
是针对供应商公开的 API 实现的,但尚未针对
实际租户进行测试,因此默认不注册:它们不会
出现在连接器列表中,并且它们的每条路由都会被拒绝。设置
EXPERIMENTAL_CONNECTORS=true以启用它们(启用后它们会以"experimental": true列出)。如果你针对真实租户测试了它们, 维护者欢迎你报告哪些有效、哪些无效。 - Microsoft 和 Google 连接请求只读范围。在此版本之前建立的连接 会保留其更广泛的授权,直到重新连接。
CourtListener API 令牌
法律工具、法官情报、案件视图以及策略引擎中判例法相关部分都从 CourtListener 读取。CourtListener 是应用中唯一的判例法来源。应用在没有令牌的情况下也能启动,但产品的判例法部分没有令牌就无法使用:
- 没有它,引证检查会直接失败 —
validate_citation拒绝运行并返回“需要令牌”错误,该错误会指明在哪里设置令牌(_check_token中的backend/app/services/courtlistener_client.py)。 - 其他所有 CourtListener 调用都会回退到匿名访问,而匿名访问的速率限制非常严格,在任何实际负载下研究功能都会变得不可用。
在 https://www.courtlistener.com/help/api/rest/#permissions 获取免费令牌,然后在 .env 中设置 COURTLISTENER_API_TOKEN,或由管理员将其保存为实例级配置(设置 → API 密钥,或 POST /api/v1/admin/integrations/courtlistener)——存储的令牌会在运行时覆盖 .env 的值,无需重启。
项目结构
backend/
app/
main.py FastAPI app, middleware, health
config.py Pydantic settings
routers/ API routers
services/
rag/ RAG pipeline (search, generation, citations, intent)
vectordb.py ChromaDB/Pinecone abstraction
embeddings.py Multi-provider embeddings
auth.py JWT auth
strategy.py Matter strategy briefs
courtlistener.py CourtListener API
...
middleware/ Security, CSRF
migrations/ Alembic migrations
frontend/
src/
App.tsx
api/ Per-domain API clients
views/ Page views
stores/ Zustand stores
components/ Shared components + modals
layout/ App shell
scripts/ Backup/restore, production setup, key rotation, NOTICE generator
docs/ Deployment, data flows, secret rotation, incident response, ADRs
Dockerfile Unified image (frontend + backend)
docker-compose.prod.yml Bundled stack: Caddy + Postgres + Redis + backend
docker-compose.yml Behind an existing proxy (Coolify/Traefik); external Postgres + Redis
docker-compose.dev.yml Local development
仅 API(尚无 UI)
这些功能已实现并可通过 API 访问,但前端尚未暴露它们。请将它们视为预览:
- 事项(
/api/v1/matters)——事项记录、成员资格,以及成员之间共享文档和聊天。创建事项和更改成员资格需要matters.manage权限。 - 策略简报(
/api/v1/strategy)——每个命题都会在 CourtListener 上搜索,读取候选判决意见,只有当能在真实判决意见文本中找到逐字引用时才会保留引证。不支持的引证会被丢弃,而不是显示出来。 - Azure AD SSO——仅后端令牌交换;没有登录按钮。不支持 SAML、通用 OIDC 和 SCIM。
上表功能中的其他所有内容,以及用户管理和审计日志(设置,仅管理员),都有 UI。
安全
- 密码登录(PBKDF2-SHA256),可选或强制 TOTP MFA 和恢复代码;通过电子邮件重置密码,以及在应用中更改密码
- JWT 访问令牌,配合 httpOnly cookie 中的轮换刷新令牌,Redis 中的 JTI 撤销(生产环境必需),“在所有位置退出登录”
- 每个用户最多 5 个会话,绝对生命周期为 8 小时,并有空闲超时
- 基于角色的权限(
require_permission),管理员可按角色调整 - 对每个文档、聊天和分析进行按用户(和按事项)的范围限定
- CSRF 双重提交 cookie,使用 HMAC 签名;按 IP 限流;账户锁定
- 对上传的原始文件、API 密钥、连接器令牌和 MFA 密钥使用 AES-256-GCM 静态加密。向量索引和数据库依赖您提供的磁盘加密
- CSP、HSTS、X-Frame-Options、Permissions-Policy 标头
- 审计日志使用 HMAC-SHA256 链式哈希,在启动时和按需验证
CaseCite 不持有任何安全认证(SOC 2、ISO 27001、HIPAA)。它做什么和不做什么在 SECURITY.md 中描述,该文件还说明了如何报告漏洞;已知缺口列在 ROADMAP.md 中。
贡献
参见 CONTRIBUTING.md。欢迎 PR。贡献在 Apache License 2.0 下接受,并需签署 Developer Certificate of Origin(git commit -s)。
来源:Hacker News · github.com



