中文 AI 实验工作台:把 RAG 和多模态里的每个环节拆开来调参、对比、验证。
| 实验 | 状态 | 内容 |
|---|---|---|
| 文本分块 | 可用 | 11 种分块策略,参数可调,提供分块预览和长度统计 |
| Embedding 对比 | 可用 | 7 个向量模型;按查询相似度排名,用同一组候选文本对比各模型 |
| 图像理解 | 可用 | 机械图纸逐步理解与重绘:多个视觉模型读同一张图,Claude 按细则打分、比较一致性,再按理解生成几何并导出 PDF/DXF |
- 前端:React 19 + TypeScript + Vite,Vitest 单元测试,Playwright 端到端测试
- 后端:FastAPI(Python 3.12),分块与 Embedding 各有策略注册表,本地模型按需加载
- 部署:前后端各一个 Docker 镜像,由 GitHub Actions 构建并推送到 GHCR,再通过 SSH 按提交版本发布
架构和 API 说明见 docs/architecture.md。
frontend/ React 前端(pages/ 下每个实验一个页面)
src/ragent_lab/api/ FastAPI 路由、schema、实验目录
src/ragent_lab/chunking/ 分块策略与注册表
src/ragent_lab/embedding/ Embedding 模型与注册表
src/ragent_lab/vision/ 图像理解:模型调用、样例加载、评分与 PDF/DXF 渲染
docker/ 前后端镜像与 compose 配置
deploy/ 服务器发布与回滚脚本
tests/ 后端单元测试
需要 Python 3.12、Node.js 24。
python -m venv .venv
source .venv/bin/activate
pip install -r requirements-api.txt
python -m nltk.downloader punkt punkt_tab
python -m uvicorn ragent_lab.api.app:app --app-dir src --reload --port 8000另开终端:
cd frontend
npm ci
npm run dev打开 http://127.0.0.1:5173。Vite 将 /api 代理到后端。API 文档位于 http://127.0.0.1:8000/docs。
基础 API 无需安装 PyTorch。需要本地语义分块或本地 Embedding 时,再安装 CPU/GPU 对应的 PyTorch 和 requirements-models.txt:
pip install torch==2.6.0 --index-url https://download.pytorch.org/whl/cpu
pip install -r requirements-models.txt生产 API 镜像已包含 CPU 推理依赖。模型首次调用时下载并缓存;E5 Mistral 7B 和 GME 默认禁用,需要额外算力并设置 ENABLE_HEAVY_MODELS=true。当前 GME 接口仅用于文本嵌入。
python -m unittest discover -s tests -v
cd frontend
npm test
npm run build
npx playwright install chromium
npm run test:e2e端到端测试会启动 React 和 API;分块测试使用真实后端,Embedding UI 使用固定的服务响应,不调用付费接口。
docker compose -f docker/docker-compose.yml up -d --build --wait前端监听 127.0.0.1:8501,通过 /api 转发至独立 API 容器。向量模型缓存在 Docker volume 中。默认仅允许浏览器提交用户自己的 API Key,不向前端提供服务器密钥。
可选 .env 设置见 env.example。ALLOW_SERVER_API_KEYS=true 会允许客户端使用服务器额度,只应在可信访问环境开启;默认关闭。应用不提供账号系统。
内置测试图和评分细则不进仓库,放在仓库外的目录里,由 VISION_SAMPLES_DIR 指定(容器内为 /samples,宿主机为 /opt/rag-lab/vision-samples,只读挂载)。目录为空或不存在时,页面只提供上传。
每个样例一个子文件夹,文件夹名与细则 id 相同:
vision-samples/
bracket01/
image.jpg 图纸(PNG、JPG 或单页 PDF)
rubric.json 评分细则
rubric.json 格式:
{
"id": "bracket01",
"name": "支架01",
"image": "image.jpg",
"rubric_status": "approved",
"items": [
{"id": "C01", "target": "66", "expected": "正确解释", "uncertain_if": "什么情况算保留疑点", "wrong_if": "什么情况算错误"}
]
}rubric_status 为 approved 时才打分;为 draft 时,这张图按没有标准答案处理,只显示一致性。image 必须位于样例文件夹内。
仓库里只带一个自绘的简单示例 tests/fixtures/vision-samples/demo_plate/(120×60 板、φ20 中心孔、2-φ8,带已审定细则),供测试和本机调试使用;重新生成图片:python tests/fixtures/vision-samples/make_demo_plate.py。
本机调试(用仓库示例:VISION_SAMPLES_DIR=tests/fixtures/vision-samples;用真实测试图:):
VISION_SAMPLES_DIR=~/Documents/AI/ragent-lab-vision-samples python -m uvicorn ragent_lab.api.app:app --app-dir src --reload --port 8000同步到服务器(rsync 到 /opt/rag-lab/vision-samples/,带 --delete,然后重启 API 容器):
bash deploy/sync-vision-samples.sh ~/Documents/AI/ragent-lab-vision-samples上传图片上限 15 MB。上传的图纸存进 API 容器的 Docker 卷 vision-uploads(VISION_UPLOAD_DIR=/data/vision-uploads),重启和发版后仍在,VISION_UPLOAD_TTL_HOURS(默认 168,即 7 天)后自动删除,最多保留 VISION_UPLOAD_MAX_FILES(默认 2000)张;未设置 VISION_UPLOAD_DIR 时只存内存。服务器上找不到图片时,页面会用浏览器里的原文件自动重新上传一次。前端容器的 Nginx 已设置 client_max_body_size 16m;生产主机 Nginx 转发 lab.ragents.net 时,也必须允许不小于 16 MB 的请求体(client_max_body_size 16m; 或更大),否则上传会被主机 Nginx 以 413 拒绝。
侧栏底部的「模型设置」页决定图像理解页和评判模型里能选哪些模型。设置只存在访客浏览器的 localStorage 里(可选择不保存 Key),服务器不保存任何访客 Key。
- 代理平台:填 OpenRouter / Kie.ai 的 Key,并为模型目录里的每个模型选择经哪个平台调用(Kie.ai 只提供 Claude、GPT、Gemini、Kimi)。
- 内置模型:由服务器付费,配置在 API 的环境变量里,访客输入访问码后可用,每个 IP 每小时有调用上限。Key 和接口地址都不会发给浏览器。
- 自定义模型:访客自己填接口地址、模型名和 Key。预设可一键填好 OpenRouter、Kie.ai、DeepSeek、Moonshot(Kimi)、阿里云百炼(Qwen)、智谱(GLM)、OpenAI、Anthropic 的地址和格式;支持 OpenAI Chat Completions、OpenAI Responses、Anthropic Messages 三种格式。服务器只调用公网 https 地址,解析到本机或内网的地址会被拒绝,也不跟随重定向。
内置模型的环境变量(见 env.example):
LAB_ACCESS_CODE=choose-a-long-random-code # 不设置则不开放内置模型
VISION_BUILTIN_PER_HOUR=60 # 每个访客 IP 每小时的调用次数
DEEPSEEK_API_KEY=sk-...
VISION_BUILTIN_MODELS='[{"id":"deepseek","name":"DeepSeek(内置)","api":"chat",
"url":"https://api.deepseek.com/chat/completions","model":"<视觉模型名>",
"key_env":"DEEPSEEK_API_KEY","json":"object"}]'每个条目:id(小写短名)、name、api(chat | responses | anthropic)、url(https)、model、key_env(存放 Key 的环境变量名)、json(schema | object | prompt,默认 prompt)、auth(bearer | x-api-key)、max_tokens、notes(显示在设置页)。缺 Key 或格式不对的条目会被跳过并写入日志。改完 .env 后重启 API 容器生效。
配置文件:.github/workflows/ci-cd.yml。
- PR、
dev和feat/**:API 单元测试、前端单元测试、TypeScript 检查、构建、浏览器测试。 master:检查通过后构建两个 GHCR 镜像,以提交 SHA 标记,SSH 发布到服务器。- 部署目录:
/opt/rag-lab/releases/<sha>;成功后更新current链接。 - 部署会先拉取镜像,再更新容器;校验前端代理和 API 提交版本。失败恢复上一版本;首次迁移失败会重启旧
rag-lab容器。 - 服务器现有 Nginx 继续将
lab.ragents.net转发到127.0.0.1:8501。无需修改其他应用的容器或网络。
仓库 Secrets:
| 名称 | 内容 |
|---|---|
DEPLOY_SSH_KEY |
此仓库专用的服务器 SSH 私钥 |
DEPLOY_KNOWN_HOSTS |
已核对的 209.209.40.180 SSH host key |
Actions 使用内置 GITHUB_TOKEN 发布和拉取 GHCR 镜像。服务器需要 Docker Compose v2.30+、curl、flock、tar;首次迁移保留 /opt/rag-lab/.env 和旧容器,部署有短暂重启窗口。
手工回滚:
cd /opt/rag-lab/releases/<previous-sha>
LAB_SKIP_PULL=true bash deploy/deploy.sh <previous-sha>- 在
src/ragent_lab/api/catalog.py注册实验 ID、名称、状态和说明。 - 在 API 下增加独立路由/服务,并在
api/app.py注册。 - 在
frontend/src/pages添加页面,在App.tsx中绑定对应 ID。 - 实验未实现前使用
planned状态,展示规划而非模拟执行结果。
模型使用 embedding/registry.py 注册;分块策略使用 chunking/registry.py 注册。
旧 Streamlit 文件保留用于迁移参考,不参与生产构建或运行。其依赖仍见 requirements.txt。