mirror of
https://github.com/ThearchyHelios/AgentLab.git
synced 2026-11-15 04:41:57 +00:00
12 KiB
12 KiB
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自动找agentlabconda 环境,不存在时按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-checkpoint4.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」,用来验收写外部系统的各种结果;接口见脚本开头。
前端检查
# 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一个字都不会说。
文档检查
python3 scripts/check-docs.py
它检查三件事:README.md 和 docs/en/ 下不许出现中文字符和全角符号(代码块也算);README.md、README.zh-CN.md、docs/ 下全部文档和 deploy/README.md 里的相对链接和锚点都要通;docs/zh-CN/ 和 docs/en/ 的文件一一对应、每一对的标题层级相同。改文档后跑一遍。