Files
AgentLab/docs/zh-CN/development.md
T
ThearchyHelios 46a2988dc1 问数据双轨重构:快速直查与深度分析分流、可点击数字证据闭环及双语文档
- 重构问数据执行架构为「快速直查(fast)」与「深度分析(deep)」双模式,内置语义预命中(Grounding)注入指标卡片、标准实体编码与表目录血缘
- 快速直查免工作流生成单节点执行,新增零额外模型调用的数字证据归一与封存(direct_evidence),打通可点击数字溯源与 /verify 校验
- 深度分析与助手编排接入跨源本体穿透(自动升级重跑与一键沿本体排查关联数据源),优化数据源范围智能收敛与往返缓存
- 补齐端到端回归测试矩阵与中英文全量文档说明
2026-11-12 12:58:42 +08:00

12 KiB
Raw Blame History

English | 简体中文

开发

这篇讲本地开发:环境、启动、目录结构、依赖与锁文件、测试和检查脚本。给改代码的人看。系统为什么这样设计见架构与设计决策。

开发环境

  • 需要 conda(miniforge 即可)、Node 20+、pnpm。
  • 不需要 Docker:代码沙箱基于操作系统自带的隔离原语,可选升级到 microVM(见配置)。
  • 不配 API Key 也能完整体验:内置的 Mock provider 会把编排链路完整走一遍(见配置)。

启动

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 由前端开发服务器在本机转发。默认不开登录,只在信得过的网络里这样用(见登录方式)。
  • --postgres:应用库用 PostgreSQL,本机 docker 起一个开发用的库(见和库一起起)。
  • 认不出的参数直接报错,./scripts/dev.sh --help 看用法。
  • dev.sh 开着热重载:改一个后端文件就是一次服务重启,正在跑的运行显示中断,断点完好,可以接着跑(见断点续跑)。

目录结构

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 默认已经全部装上。单独补装时带上锁文件,版本才和测过的一致:

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

升级依赖

升级依赖要主动做,改完跑一遍测试再提交:

./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;装依赖本身只用 pip。

测试

# 后端:约 16000 个测试,-n auto 并行约 2–3 分钟
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 与多进程。

验收用的假外部系统

python scripts/fake-erp.py --port 8765

它可以切换「正常 / 写成功后超时 / 500 / 4xx」,用来验收写外部系统的各种结果;接口见脚本开头。

前端检查

# 45 项,默认 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 的 45 项按 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(证据里的「口径」一步、轮次摘要、出具与对账、可沉淀的问题)caliber-drafts(口径草稿工作台、增量重导入与一句话改口径)ontology(标准业务实体、口径本体拓扑、源健康证据链、异常升级与本体穿透归因)
应用平台 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 一个字都不会说。

文档检查

python3 scripts/check-docs.py

它检查三件事:README.md 和 docs/en/ 下不许出现中文字符和全角符号(代码块也算);README.md、README.zh-CN.md、docs/ 下全部文档和 deploy/README.md 里的相对链接和锚点都要通;docs/zh-CN/ 和 docs/en/ 的文件一一对应、每一对的标题层级相同。改文档后跑一遍。