mirror of
https://github.com/ThearchyHelios/AgentLab.git
synced 2026-11-15 15:51:59 +00:00
2714890d0d
README.zh-CN.md / README.md 只留:这是什么、为什么用它、主要功能(按领域一行一条,链到文档)、快速开始、部署、文档索引、 开发与测试、许可(原文不动)。原来的每一节按读者和任务分到 17 篇主题文档:ask-data、workflows、evidence、 data-sources(新增:接入数据库、只读保证、上传表格、跨库合并、遮罩列)、data-catalog、tools(新增:工具、审批档位、 能力登记、端点、网络规则——它们管所有工作流,不只应用)、apps、evaluation-and-ledger、schedules(含通知)、deployment、 configuration、postgresql-and-scaling、identity-and-security、architecture、development、upgrade-notes(按时间倒序, 每波先写要做的事)、faq。删掉的只有模块名(api/copilot_gen.py、chat/drive.py、data/schema_view.py)、重复的话和 「以前…现在…」的叙述;操作步骤、命令、配置名、限制、权限边界都有归宿。中文是原文,英文按新的中文写;英文里界面文字 只写英文名,开头注明界面目前只有简体中文,中文占位符换成英文占位符,中文数字的例子改成不依赖中文的说法。 数据剖析可以同时剖析 2–3 张表(baf23998)收进 data-catalog。 新增 scripts/check-docs.py:英文文档(README.md、docs/en/**)不许有中日韩字符和全角符号(代码块也算), README、docs/**、deploy/README.md 的相对链接和锚点都要通,docs/zh-CN 与 docs/en 文件一一对应、标题层级相同。 中文提示里指向 README 章节的地方改指新文档:cluster/guard.py、cluster/version.py、db/base.py 两处报错, data/schema_view.py 文档串,.env.example 三处,scripts/prod.sh、scripts/test-postgres.sh,terms.ts 两处、 DataSourcesTab.tsx、check-manage.mjs 注释,deploy/README.md 三处链接。deploy/agentlab.env 未动。 验收:check-docs 0 问题(英文文档 18 个 0 处中文,相对链接 369 条 0 断链,18 对标题层级一致);相关后端测试 117 通过、7 跳过;tsc -b、check-copy 通过。
163 lines
12 KiB
Markdown
163 lines
12 KiB
Markdown
[English](../en/development.md) | 简体中文
|
||
|
||
# 开发
|
||
|
||
这篇讲本地开发:环境、启动、目录结构、依赖与锁文件、测试和检查脚本。给改代码的人看。系统为什么这样设计见[架构与设计决策](architecture.md)。
|
||
|
||
## 开发环境
|
||
|
||
- 需要 conda([miniforge](https://conda-forge.org/miniforge/) 即可)、Node 20+、pnpm。
|
||
- **不需要 Docker**:代码沙箱基于操作系统自带的隔离原语,可选升级到 microVM(见[配置](configuration.md#启用-microvm))。
|
||
- 不配 API Key 也能完整体验:内置的 Mock provider 会把编排链路完整走一遍(见[配置](configuration.md#模型接入))。
|
||
|
||
## 启动
|
||
|
||
```bash
|
||
conda env create -f environment.yml # 首次:创建 agentlab 环境并安装依赖
|
||
./scripts/dev.sh # 之后:一条命令启动前后端
|
||
```
|
||
|
||
- 打开 http://localhost:5273 。
|
||
- `dev.sh` 自动找 `agentlab` conda 环境,不存在时按 `environment.yml` 创建。要用别的环境名,设 `AGENTLAB_CONDA_ENV`。
|
||
- 端口:前端默认 5273、后端 8000,用 `AGENTLAB_WEB_PORT` / `AGENTLAB_PORT` 改。
|
||
- `--host`:前端监听所有网卡,启动时打印局域网地址,同一网络里的手机、别的电脑也能打开。后端仍只听 127.0.0.1,页面里的 `/api` 由前端开发服务器在本机转发。默认不开登录,只在信得过的网络里这样用(见[登录方式](identity-and-security.md#登录方式))。
|
||
- `--postgres`:应用库用 PostgreSQL,本机 docker 起一个开发用的库(见[和库一起起](postgresql-and-scaling.md#和库一起起))。
|
||
- 认不出的参数直接报错,`./scripts/dev.sh --help` 看用法。
|
||
- `dev.sh` 开着热重载:改一个后端文件就是一次服务重启,正在跑的运行显示中断,断点完好,可以接着跑(见[断点续跑](workflows.md#断点续跑))。
|
||
|
||
## 目录结构
|
||
|
||
```
|
||
backend/ FastAPI + LangGraph
|
||
app/engine/ 画布 JSON → StateGraph 的编译与执行
|
||
schema.py 图定义与静态校验
|
||
compiler.py 编译:节点包装、事件、重试、条件路由
|
||
runner.py 执行调度、事件总线、中断与恢复
|
||
issuance.py 出具契约:数字回指与三档判定
|
||
evidence.py 可点击证据:证据台账、引用标记、报告文档的切块与核对(纯函数)
|
||
judge.py 结论句裁判:预筛、成本上限、判定写回
|
||
governance.py 发布门禁:受管 lint 与证据门禁 G1–G5
|
||
autofix.py 发布前自动修复;upgrade.py 一键升级为可追溯结构
|
||
guards.py agent 护栏:重复调用、预算、上下文压缩
|
||
review.py 产出复核:事件流规则扫描 + 模型复核
|
||
expressions.py 模板插值 + AST 白名单表达式求值
|
||
nodes/ 各类节点的执行器(report.py 是报告撰写)
|
||
app/data/ 数据源接入:连接、SQL 守卫、结构探查、表格导入
|
||
app/providers/ 多模型接入与成本估算
|
||
app/sandbox/ microVM / Seatbelt / bubblewrap / 裸子进程四后端
|
||
app/tools/ 工具注册表、内置工具、MCP、自定义工具
|
||
app/memory/ 记忆、知识库、倒排索引、混合检索、文档解析
|
||
app/api/ REST + WebSocket(证据接口在 evidence.py)
|
||
frontend/ React 19 + React Flow + Zustand
|
||
src/canvas/nodeDefs.ts 节点元数据——属性面板、节点库、连接桩均由其驱动
|
||
src/canvas/routing.ts 连线走线:端口错开、走廊车道、长边绕行
|
||
src/run/decode.ts 事件流 → 人类可读步骤的唯一翻译层
|
||
src/run/EvidenceDoc.tsx 报告逐段渲染:数字、名字、原话都是可点的片段;EvidencePanel.tsx 是出处链
|
||
src/store/studio.ts 画布状态 + 事件流到高亮的映射
|
||
environment.yml conda 环境定义
|
||
scripts/dev.sh 一键启动
|
||
scripts/check-all.mjs 前端检查的总入口:分道并行跑全部 check-*.mjs,汇总成一张表
|
||
```
|
||
|
||
## 依赖与锁文件
|
||
|
||
- `backend/pyproject.toml` 写版本范围,`backend/requirements.lock` 写精确版本:后端全部依赖(含间接依赖、全部 extras)锁在测试跑过的那一套上,跨平台通用。
|
||
- `environment.yml` 装包时以锁文件为约束,所以换一台机器装到的也是同一套,不是当天的最新版。
|
||
- LangGraph / LangChain 一族在 `pyproject.toml` 里只放行到下一个小版本:引擎直接依赖它们的断点格式、interrupt / resume 和流式事件,这些在小版本里也改过行为。
|
||
- 断点格式本身在 `langgraph-checkpoint` 里(langgraph 只要求它 <5,所以单独卡住)。SQLite、PostgreSQL 两个断点库(`langgraph-checkpoint-sqlite`、`langgraph-checkpoint-postgres`)都按它读写;`copy-to-postgres` 能搬断点,也靠两边是同一版格式。
|
||
- `langgraph-checkpoint-postgres` 从 3.1.3 起要 `langgraph-checkpoint` 4.3,所以锁在 3.1.2;升级时三个一起动。
|
||
- aiosqlite 与 SQLAlchemy 同理:`db/base.py` 给 aiosqlite 打了补丁,连接池断开连接时会走到它。应用库换成 PostgreSQL 之后补丁照样打着,因为上传表格、手工登记的 SQLite 数据源还走 aiosqlite。
|
||
- `[postgres]` 里是应用库用 PostgreSQL 时要的:SQLAlchemy 这边走 asyncpg(和 `[db]` 里连业务库的是同一个包),断点库走官方的 `langgraph-checkpoint-postgres`,它只认 psycopg 3 和 `psycopg-pool`。psycopg 带 `[binary]`:wheel 里自带 libpq,镜像和本机都不用另装 PostgreSQL 客户端。
|
||
|
||
### 可选依赖
|
||
|
||
`environment.yml` 默认已经全部装上。单独补装时带上锁文件,版本才和测过的一致:
|
||
|
||
```bash
|
||
pip install -e 'backend[docs]' -c backend/requirements.lock # PDF / Word / PowerPoint / Excel 解析
|
||
pip install -e 'backend[db]' -c backend/requirements.lock # MySQL / PostgreSQL / Oracle 驱动
|
||
pip install -e 'backend[microvm]' -c backend/requirements.lock # microVM 沙箱
|
||
pip install -e 'backend[postgres]' -c backend/requirements.lock # 应用库用 PostgreSQL(asyncpg、psycopg 3、官方断点库)
|
||
pip install -e 'backend[dev]' -c backend/requirements.lock # pytest
|
||
```
|
||
|
||
### 升级依赖
|
||
|
||
升级依赖要主动做,改完跑一遍测试再提交:
|
||
|
||
```bash
|
||
./scripts/lock-deps.sh --upgrade-package langgraph # 升一个包(连带它必须跟着动的)
|
||
./scripts/lock-deps.sh --upgrade # 全部升到 pyproject 允许的最新
|
||
./scripts/lock-deps.sh # 只加了新依赖:补上它,已锁的不动
|
||
pip install -e 'backend[microvm,dev,db,docs,postgres]' -c backend/requirements.lock # 装到当前环境
|
||
```
|
||
|
||
重新生成锁文件需要 [uv](https://docs.astral.sh/uv/);装依赖本身只用 pip。
|
||
|
||
## 测试
|
||
|
||
```bash
|
||
# 后端:约 14300 个测试,-n auto 并行约 1–2 分钟
|
||
cd backend && env -u ANTHROPIC_API_KEY -u ANTHROPIC_BASE_URL -u ANTHROPIC_AUTH_TOKEN -u OPENAI_API_KEY \
|
||
python -m pytest -n auto
|
||
|
||
# 前端类型检查
|
||
cd frontend && npx tsc -b
|
||
|
||
# 应用库换成 PostgreSQL 跑同一套后端测试(起临时的 postgres:16 容器,跑完删掉)
|
||
PYTHON=$(conda run -n agentlab which python) ./scripts/test-postgres.sh
|
||
```
|
||
|
||
- pytest 前面的 `env -u` 不能省:没配 Key 的 provider 会退回环境变量里的密钥,启动时的 seed 也会拿它种一个 provider。环境里留着真密钥,测试就可能真的去调接口。
|
||
- PostgreSQL 和多进程的测试细节见 [PostgreSQL 与多进程](postgresql-and-scaling.md#测试)。
|
||
|
||
### 验收用的假外部系统
|
||
|
||
```bash
|
||
python scripts/fake-erp.py --port 8765
|
||
```
|
||
|
||
它可以切换「正常 / 写成功后超时 / 500 / 4xx」,用来验收写外部系统的各种结果;接口见脚本开头。
|
||
|
||
## 前端检查
|
||
|
||
```bash
|
||
# 43 项,默认 8 道并行。连 5273 / 8000,先起 ./scripts/dev.sh
|
||
node scripts/check-all.mjs
|
||
# 另起 2 套只给检查用的「后端 + vite」,各用一份数据拷贝,约 6.5 分钟;边改代码边跑也不被打断
|
||
CHECK_DATA_SRC=<数据目录> node scripts/check-all.mjs --stacks 2 --lanes 12
|
||
# 只跑某几项(名字去掉 check- 前缀)
|
||
node scripts/check-all.mjs evidence publish
|
||
```
|
||
|
||
- 完整输出写进 `/tmp/agentlab-checks/<时间>/`,终端只给汇总。并行时没过的,最后单独重跑一遍;重跑才过的单列成「偶发」。
|
||
- `--stacks` 每套拷一份数据、端口自动挑空闲的;后端不热重载、vite 不监听文件;跑完、出错或被中断都收干净。`--stacks` 只支持 SQLite。
|
||
- `scripts/e2e-check.mjs` 真发起一次运行(Mock,不花钱),会在库里留下记录,所以不在 check-all 里。
|
||
- `scripts/check-auth.mjs`(登录、按角色收起的导航、401 跳登录)要另起一套开着本地账号登录的服务单独跑,也不在 check-all 里。
|
||
|
||
`check-all` 的 43 项按 `scripts/check-all.mjs` 里 `ORDER` 的顺序排:
|
||
|
||
| 类别 | 检查 |
|
||
|---|---|
|
||
| 不开浏览器 | `tokens`(设计令牌的静态扫描)`copy`(界面文案)`trace`(运行态内核的纯函数)`decode`(事件翻译层) |
|
||
| 走线、组件与护栏 | `canvas-layout` `ui-kit` `guards` |
|
||
| 外壳、回答流与运行态 | `shell` `stream` `evidence`(可点击证据)`run-states`(节点卡)`canvas-fx`(画布表层) |
|
||
| 各页面 | `studio` `publish`(发布前检查与自动修复)`chat` `runs` `manage` `versions`(上传表格的版本)`catalog`(数据目录)`catalog-loop`(表助手、审阅队列、导出导入)`catalog-profile`(数据剖析的逐表任务)`catalog-changes`(变化、表详情的变化一节、定时维护、后台任务条)`ui`(端到端,连真数据) |
|
||
| 复核套件与导出 | `schedules`(定时任务)`compare`(运行对比)`verify`(双盲复算、反方审稿)`inquiry`(审批质询)`challenge`(反方审稿)`bundle`(可验证报告)`whatif`(数字推演)`report-export`(报告导出) |
|
||
| 评测与口径账本 | `evals`(题集、加题、发起与进度、结果、对比与 A/B、口径命中与重复度)`ledger`(证据里的「口径」一步、轮次摘要、出具与对账、可沉淀的问题) |
|
||
| 应用平台 | `apps`(应用页、印章、点数字看出处、入口校验、实例页)`inbox`(会签进度、超时、动作确认的哈希卡、核实)`app-editor`(应用编辑、派生、检查、发布时选处置、助手)`capabilities`(能力、端点、身份、通知、审计)`access-keys`(访问密钥)`share`(分享链接与 /s 页)`blueprint`(新建应用、蓝图卡片、试运行、发布摘要)`personal`(个人应用)`records`(记录列表)`files`(文件控件) |
|
||
|
||
### 三层验证的分工
|
||
|
||
- `check-decode` 守「翻译对不对」,`check-stream` 守「画出来对不对」,`check-ui` 守「整条路走得通不通」。三者可以各自通过、合起来却是坏的:例如 Step 字段全部正确,组件却把它渲染成一屏转义的 JSON。
|
||
- `check-canvas-fx` 守「事件对了但界面没跟上」:把脚本化的事件灌进 store(走的是页面上那一份 applyEvent / NodeCard / FlowEdge,只有事件来源是脚本),断言协作矩阵真的长出来了、并行度算对了、条形长度和耗时成正比、分支命中的出口被点亮、系统关了动效时光效确实不绘制。真跑一张多 agent 的图要连模型、要等十几秒,而且撞不上「三个人同时还在跑」那一瞬间,那样的检查会变成偶发失败。
|
||
- `check-canvas-layout` 单独守「图好不好看」里唯一能算的那部分:它把夹具图交给后端 `/api/copilot/layout` 排版,再直接 `import('/src/canvas/routing.ts')`,用页面上正在跑的那份走线代码算路径,然后按几何断言:没有两条线压在同一段上、没有线从别人的卡片中间穿过去、每条线的两端都接在节点边缘。连线叠成一团时,`check-ui` 和 `e2e-check` 一个字都不会说。
|
||
|
||
## 文档检查
|
||
|
||
```bash
|
||
python3 scripts/check-docs.py
|
||
```
|
||
|
||
它检查三件事:`README.md` 和 `docs/en/` 下不许出现中文字符和全角符号(代码块也算);`README.md`、`README.zh-CN.md`、`docs/` 下全部文档和 `deploy/README.md` 里的相对链接和锚点都要通;`docs/zh-CN/` 和 `docs/en/` 的文件一一对应、每一对的标题层级相同。改文档后跑一遍。
|