后端依赖锁到测过的那一套:pyproject 卡版本范围,requirements.lock 写精确版本

langgraph 和四个 langchain 包原来完全不写版本,fastapi、sqlalchemy、aiosqlite 只有下限,
uv.lock 还在 .gitignore 里。按旧写法今天新装,22 个包和测过的版本不同,其中 sqlalchemy
会从 2.0.52 跳到 2.1.1。

1. pyproject.toml:LangGraph / LangChain 一族放行到下一个小版本——引擎依赖它们的断点
   格式、interrupt / resume、流式事件和 thinking 块,这些在小版本里也改过行为。aiosqlite
   与 SQLAlchemy 同样卡小版本:db/base.py 给 aiosqlite 0.22 的 stop() 打了补丁,连接池
   强制断开时会走到它。mcp 卡在大版本 1。
2. backend/requirements.lock:后端全部依赖(含间接依赖、全部 extras)的精确版本,
   --universal 跨平台。锁的是 473 条测试跑过的那个 conda 环境:本机要装的 96 个包逐一
   对上,另外 3 个只在 Windows / emscripten 上装。
3. environment.yml 装包时以锁文件为约束(-c),换机器装到的是同一套。
4. scripts/lock-deps.sh 重新生成锁文件:已锁的版本默认不动,升级用 --upgrade-package /
   --upgrade。README 补了用法,补装 extras 的命令都带上 -c。

验证:用同版本 Python 新建空环境,照 conda 的方式按 environment.yml 的 pip 行安装——
装到的 96 个包和测过的环境完全一致,473 passed。
This commit is contained in:
ThearchyHelios
2026-09-26 09:49:16 +08:00
parent e46a3f0d62
commit 95ff6470d1
5 changed files with 401 additions and 13 deletions
+29 -4
View File
@@ -34,6 +34,8 @@ conda env create -f environment.yml # 首次:创建 agentlab 环境并安装
`dev.sh` 自动定位 `agentlab` conda 环境;环境不存在时依 `environment.yml` 创建。
如需使用其他环境名,设置 `AGENTLAB_CONDA_ENV`。
后端依赖的版本以 `backend/requirements.lock` 为准,装到的是测试跑过的那一套,
不是当天的最新版(见[依赖与锁文件](#依赖与锁文件))。
服务启动于 http://localhost:5273 。
@@ -399,13 +401,36 @@ conda run -n agentlab python -c "import asyncio,microsandbox as m; asyncio.run(m
### 可选依赖
`environment.yml` 默认已经全部装上。单独补装时带上锁文件,版本才和测过的一致:
```bash
pip install -e 'backend[docs]' # PDF / Word / PowerPoint / Excel 解析
pip install -e 'backend[db]' # MySQL / PostgreSQL / Oracle 驱动
pip install -e 'backend[microvm]' # microVM 沙箱
pip install -e 'backend[dev]' # pytest
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[dev]' -c backend/requirements.lock # pytest
```
### 依赖与锁文件
`backend/pyproject.toml` 写版本范围,`backend/requirements.lock` 写精确版本:后端全部
依赖(含间接依赖、全部 extras)锁在测试跑过的那一套上,跨平台通用。`environment.yml`
装包时以它为约束,所以换一台机器装到的也是同一套。
LangGraph / LangChain 一族在 `pyproject.toml` 里只放行到下一个小版本:引擎直接依赖
它们的断点格式、interrupt / resume 和流式事件,这些在小版本里也改过行为。aiosqlite
与 SQLAlchemy 同理——`db/base.py` 给 aiosqlite 打了补丁,连接池断开连接时会走到它。
升级依赖要主动做,改完跑一遍测试再提交:
```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]' -c backend/requirements.lock # 装到当前环境
```
重新生成锁文件需要 [uv](https://docs.astral.sh/uv/);装依赖本身只用 pip。
### 数据位置
全部位于 `data/`:`agentlab.db` 业务数据、`checkpoints.db` 执行断点、
+15 -9
View File
@@ -8,18 +8,24 @@ dependencies = [
"uvicorn[standard]>=0.32",
"pydantic>=2.9",
"pydantic-settings>=2.6",
"sqlalchemy[asyncio]>=2.0.36",
"aiosqlite>=0.20",
# db/base.py 给 aiosqlite 0.22 的 stop() 打了补丁(并发调用会死锁),SQLAlchemy 连接池
# 强制 terminate 时也会走到它。两个一起卡住小版本,换版本前先确认补丁还成立
"sqlalchemy[asyncio]>=2.0.36,<2.1",
"aiosqlite>=0.22.1,<0.23",
"greenlet>=3.1",
"httpx>=0.28",
"python-multipart>=0.0.17",
"langgraph",
"langgraph-checkpoint-sqlite",
"langchain-core",
"langchain-anthropic",
"langchain-openai",
"langchain-mcp-adapters",
"mcp",
# 引擎直接依赖这一族的运行时语义:断点格式、interrupt / resume、流式事件、
# thinking 块。小版本也改过行为(resume 发 Command 在当前版本会直接崩),
# 所以上限卡到下一个小版本——升级要主动改这里、重新锁、跑一遍测试。
# 精确版本在 requirements.lock 里
"langgraph>=1.2.11,<1.3",
"langgraph-checkpoint-sqlite>=3.1.1,<3.2",
"langchain-core>=1.6.3,<1.7",
"langchain-anthropic>=1.7.2,<1.8",
"langchain-openai>=1.6.2,<1.7",
"langchain-mcp-adapters>=0.3.2,<0.4",
"mcp>=1.30,<2",
"numpy>=2.0",
"jsonschema>=4.23",
"beautifulsoup4>=4.12",
+331
View File
@@ -0,0 +1,331 @@
# This file was autogenerated by uv via the following command:
# ./scripts/lock-deps.sh
aiomysql==0.3.2
# via agentlab-backend (pyproject.toml)
aiosqlite==0.22.1
# via
# agentlab-backend (pyproject.toml)
# langgraph-checkpoint-sqlite
annotated-doc==0.0.5
# via fastapi
annotated-types==0.8.0
# via pydantic
anthropic==1.5.0
# via langchain-anthropic
anyio==4.15.1
# via
# anthropic
# httpx
# httpx2
# langsmith
# mcp
# openai
# sse-starlette
# starlette
# watchfiles
asyncpg==0.31.0
# via agentlab-backend (pyproject.toml)
attrs==26.1.0
# via
# jsonschema
# referencing
beautifulsoup4==4.15.0
# via agentlab-backend (pyproject.toml)
certifi==2026.7.22
# via
# httpcore
# httpx
# langchain-openai
# requests
cffi==2.1.1 ; platform_python_implementation != 'PyPy'
# via cryptography
charset-normalizer==3.5.1
# via requests
click==8.5.0
# via uvicorn
colorama==0.4.6 ; sys_platform == 'win32'
# via pytest
cryptography==50.0.1
# via
# agentlab-backend (pyproject.toml)
# oracledb
# pyjwt
distro==1.9.0
# via langsmith
docstring-parser==0.18.0
# via anthropic
et-xmlfile==2.0.0
# via openpyxl
fastapi==0.141.1
# via agentlab-backend (pyproject.toml)
greenlet==3.5.5
# via
# agentlab-backend (pyproject.toml)
# sqlalchemy
h11==0.16.0
# via
# httpcore
# httpcore2
# uvicorn
httpcore==1.0.9
# via httpx
httpcore2==2.12.0 ; sys_platform != 'emscripten'
# via httpx2
httptools==0.8.0
# via uvicorn
httpx==0.28.1
# via
# agentlab-backend (pyproject.toml)
# langchain-core
# langgraph-sdk
# mcp
httpx-sse==0.4.3
# via mcp
httpx2==2.12.0
# via
# anthropic
# langsmith
# openai
httpx2-jsfetch==1.0 ; sys_platform == 'emscripten'
# via httpx2
idna==3.19
# via
# anyio
# httpx
# httpx2
# requests
iniconfig==2.3.0
# via pytest
jiter==0.17.0
# via
# anthropic
# openai
jsonpatch==1.33
# via langchain-core
jsonpointer==3.1.1
# via jsonpatch
jsonschema==4.26.0
# via
# agentlab-backend (pyproject.toml)
# mcp
jsonschema-specifications==2025.9.1
# via jsonschema
langchain-anthropic==1.7.2
# via agentlab-backend (pyproject.toml)
langchain-core==1.6.3
# via
# agentlab-backend (pyproject.toml)
# langchain-anthropic
# langchain-mcp-adapters
# langchain-openai
# langgraph
# langgraph-checkpoint
# langgraph-prebuilt
# langgraph-sdk
langchain-mcp-adapters==0.3.2
# via agentlab-backend (pyproject.toml)
langchain-openai==1.6.2
# via agentlab-backend (pyproject.toml)
langchain-protocol==0.0.19
# via
# langchain-core
# langgraph-sdk
langgraph==1.2.11
# via agentlab-backend (pyproject.toml)
langgraph-checkpoint==4.2.0
# via
# langgraph
# langgraph-checkpoint-sqlite
# langgraph-prebuilt
langgraph-checkpoint-sqlite==3.1.1
# via agentlab-backend (pyproject.toml)
langgraph-prebuilt==1.1.0
# via langgraph
langgraph-sdk==0.4.4
# via langgraph
langsmith==0.12.4
# via langchain-core
lxml==6.1.3
# via
# python-docx
# python-pptx
mcp==1.30.0
# via
# agentlab-backend (pyproject.toml)
# langchain-mcp-adapters
microsandbox==0.6.18
# via agentlab-backend (pyproject.toml)
numpy==2.5.3
# via agentlab-backend (pyproject.toml)
openai==3.13.0
# via langchain-openai
openpyxl==3.1.5
# via agentlab-backend (pyproject.toml)
oracledb==26.0.0
# via agentlab-backend (pyproject.toml)
orjson==3.12.0
# via
# langgraph-sdk
# langsmith
ormsgpack==1.12.2
# via langgraph-checkpoint
packaging==26.3
# via
# langchain-core
# langsmith
# pytest
pillow==12.3.0
# via python-pptx
pluggy==1.6.0
# via pytest
pycparser==3.0 ; implementation_name != 'PyPy' and platform_python_implementation != 'PyPy'
# via cffi
pydantic==2.13.5
# via
# agentlab-backend (pyproject.toml)
# anthropic
# fastapi
# langchain-anthropic
# langchain-core
# langgraph
# langsmith
# mcp
# openai
# pydantic-settings
pydantic-core==2.46.5
# via pydantic
pydantic-settings==2.15.0
# via
# agentlab-backend (pyproject.toml)
# mcp
pygments==2.21.0
# via pytest
pyjwt==2.14.0
# via mcp
pymysql==1.2.0
# via aiomysql
pypdf==6.19.0
# via agentlab-backend (pyproject.toml)
pytest==9.1.1
# via
# agentlab-backend (pyproject.toml)
# pytest-asyncio
pytest-asyncio==1.4.0
# via agentlab-backend (pyproject.toml)
python-docx==1.2.0
# via agentlab-backend (pyproject.toml)
python-dotenv==1.2.3
# via
# pydantic-settings
# uvicorn
python-multipart==0.0.32
# via
# agentlab-backend (pyproject.toml)
# mcp
python-pptx==1.0.2
# via agentlab-backend (pyproject.toml)
pywin32==312 ; sys_platform == 'win32'
# via mcp
pyyaml==6.0.3
# via
# langchain-core
# uvicorn
referencing==0.37.0
# via
# jsonschema
# jsonschema-specifications
regex==2026.9.10
# via tiktoken
requests==2.34.2
# via
# langsmith
# requests-toolbelt
# tiktoken
requests-toolbelt==1.0.0
# via langsmith
rpds-py==2026.6.3
# via
# jsonschema
# referencing
sniffio==1.3.1
# via
# anthropic
# langsmith
# openai
soupsieve==2.9.2
# via beautifulsoup4
sqlalchemy==2.0.52
# via agentlab-backend (pyproject.toml)
sqlite-vec==0.1.9
# via langgraph-checkpoint-sqlite
sse-starlette==3.4.11
# via mcp
starlette==1.6.0
# via
# fastapi
# mcp
# sse-starlette
tenacity==9.1.4
# via langchain-core
tiktoken==0.14.0
# via langchain-openai
truststore==0.10.4 ; sys_platform != 'emscripten'
# via
# httpcore2
# httpx2
typing-extensions==4.16.0
# via
# anthropic
# anyio
# beautifulsoup4
# fastapi
# httpx2
# langchain-core
# langchain-mcp-adapters
# langchain-protocol
# langsmith
# mcp
# openai
# oracledb
# pydantic
# pydantic-core
# pytest-asyncio
# python-docx
# python-pptx
# referencing
# sqlalchemy
# starlette
# typing-inspection
typing-inspection==0.4.4
# via
# fastapi
# mcp
# pydantic
# pydantic-settings
urllib3==2.7.0
# via requests
uuid-utils==0.17.1
# via
# langchain-core
# langsmith
uvicorn==0.52.4
# via
# agentlab-backend (pyproject.toml)
# mcp
uvloop==0.22.1 ; platform_python_implementation != 'PyPy' and sys_platform != 'cygwin' and sys_platform != 'win32'
# via uvicorn
watchfiles==1.2.0
# via uvicorn
websockets==16.1.1
# via
# langgraph-sdk
# langsmith
# uvicorn
xlsxwriter==3.2.9
# via python-pptx
xxhash==4.0.1
# via
# langgraph
# langsmith
zstandard==0.25.0
# via langsmith
+3
View File
@@ -12,6 +12,9 @@ dependencies:
- python=3.12
- pip
- pip:
# 版本以锁文件为准:装到的就是测过的那一套,不是当天的最新版。
# 升级依赖见 scripts/lock-deps.sh
- -c backend/requirements.lock
# [microvm] 带上独立内核的沙箱后端(约 35MB wheel,首次运行还要下载
# 约 50MB 运行时,外加一次 OCI 镜像拉取)。不需要就把方括号去掉,
# 沙箱会退回 Seatbelt —— 代价是内存限额在 macOS 上限不住。
+23
View File
@@ -0,0 +1,23 @@
#!/usr/bin/env bash
# 重新生成 backend/requirements.lock:后端全部依赖(含间接依赖、全部 extras)的精确版本。
#
# ./scripts/lock-deps.sh 加了依赖:只补新的,已锁的版本不动
# ./scripts/lock-deps.sh --upgrade-package langgraph 升一个包(连带它必须跟着动的)
# ./scripts/lock-deps.sh --upgrade 全部升到 pyproject 允许的最新
#
# 升级之后跑一遍 pytest 和前端检查再提交——锁文件的意义就是"这一套测过"。
# 锁是跨平台的(--universal),Linux / Windows 上装到的也是同一套版本。
# 需要 uv(brew install uv);装包慢可以在命令前加 UV_INDEX_URL=<镜像地址>。
set -euo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
command -v uv >/dev/null || { echo "缺少 uv:https://docs.astral.sh/uv/"; exit 1; }
cd "$ROOT/backend"
uv pip compile pyproject.toml \
--all-extras \
--universal \
--python-version 3.12 \
--custom-compile-command "./scripts/lock-deps.sh" \
-o requirements.lock \
"$@"