跳到正文
Hacker News· zztopisgreat·· 5 小时前AI 评分58

CaseCite:开源可自托管的法律 RAG 研究平台

Harvey raised 500M for legal AI, I built the same and open sourced it

AI 导读

作者开源了 CaseCite,一个可自托管的法律研究平台,支持上传律所文档后做带引用的检索问答、合同审查、起草和法官分析。

正文 · AI 翻译

CaseCite — 私有法律 RAG

License: Apache-2.0

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)。不出现任何真实客户或案件。

基于律所文档的研究 知识库
Research view: a question about a liability cap answered with inline citations to three source documents and the AI-review notice Knowledge Base: indexed documents grouped in matter folders with chunk counts
合同分析 引证核查
Contracts view: analysis card with parties, executive summary and verified key terms over the contract text Citation check: result card with a negative-treatment badge, citing opinions and the AI-review notice

执业画像。产品中没有内置任何关于执业领域的内容。您说明自己的执业范围,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