7.2 KiB
运行手册
怎么把 zcbot 跑起来。env / 常用命令 / 故障兜底。设计看
DESIGN.md,进度看PROGRESS.md。
最后更新:2026-05-15(Phase G G4)
环境
- Python:虚拟环境
.venv/,所有依赖装在里面。一律用.venv/Scripts/python.exe ...(Windows)/.venv/bin/python ...(Unix),不要全局python(litellm/python-pptx 等会 ModuleNotFoundError)。 - 配置文件
.env(项目根,git 忽略,litellm 自动加载):DEEPSEEK_API_KEY=sk-... ZCBOT_DB_URL=postgresql://user:pass@host:5432/zcbotlitellm 在 import 时副作用加载 .env;CLI 入口直接走
cli.py,.env会自动生效。直跑python -c "from core.storage import ..."不经 litellm 链路时记得自己import litellm触发,或手动export ZCBOT_DB_URL=...。 - 依赖:
pip install -r requirements.txt(已在.venv里)。 - PG:
ZCBOT_DB_URL必填。本地 docker compose 起 / 远端 dev / 生产任选。未设置时启动会清晰报错,不引导 docker(§7.4)。
一次性初始化
# 1) 装依赖(若 .venv 不在)
python -m venv .venv
.venv/Scripts/python.exe -m pip install -r requirements.txt
# 2) 准备 .env(见上)
# 3) DB schema 上车
.venv/Scripts/python.exe cli.py db upgrade head
.venv/Scripts/python.exe cli.py db current # 应输出 0001 (head)
日常命令
聊天 / 任务
# 新建 task,默认派生 workspace/tasks/<uuid>/
.venv/Scripts/python.exe cli.py chat
# 带模式 + 描述(便于后续 list 识别)
.venv/Scripts/python.exe cli.py chat --mode coding --desc "修 X 的 Y"
# 项目化 task —— 产物落到指定目录(§7.1 task-primary + dir 副视图)
.venv/Scripts/python.exe cli.py chat --task-dir /path/to/proj --mode proposal
# 恢复最近一个 task
.venv/Scripts/python.exe cli.py chat --resume last
# 恢复指定 task(UUID 完整或 ≥8 字符前缀)
.venv/Scripts/python.exe cli.py chat --resume 76c6bd25
# 切模型
.venv/Scripts/python.exe cli.py chat --model deepseek_v4.pro
REPL 内命令:/exit /reset /new /resume [last|<id>] /id /status /done /abandon /desc <文本> /export [<id>]
列表 / 导出
# 看最近 20 个 task
.venv/Scripts/python.exe cli.py tasks
# 只看 active
.venv/Scripts/python.exe cli.py tasks --status active --limit 50
# 导出某 task 的对话为 .docx(自动从 PG 找 task_dir 作为输出目录)
.venv/Scripts/python.exe cli.py export 76c6bd25
# 导出最近的
.venv/Scripts/python.exe cli.py export last -o /tmp/chat.docx
能力探测 / DB 管理
# 实测对账模型 yaml 声称的能力(费 token,有 API 开销)
.venv/Scripts/python.exe cli.py probe --model deepseek_v4.flash
# DB migration
.venv/Scripts/python.exe cli.py db upgrade head
.venv/Scripts/python.exe cli.py db downgrade -1
.venv/Scripts/python.exe cli.py db current
Web UI(§7 Phase G,本地 sentinel user 无 auth)
# 默认 127.0.0.1:8765 启,浏览器开 http://127.0.0.1:8765
.venv/Scripts/python.exe cli.py web
# 自定义端口 / 监听 0.0.0.0(配合 firewall 慎用,本地形态无 auth)
.venv/Scripts/python.exe cli.py web --port 9000
# dev:文件改动自动重启(uvicorn 工厂模式 reload)
.venv/Scripts/python.exe cli.py web --reload
G1 ✅ 脚手架 + /healthz;G2 ✅
/task 列表 +?status=filter;G3 ✅/tasks/{uuid}消息流渲染(markdown-it-py + pygments syntax,tool_call 走<details>默认折叠);G4 ✅ chat 发送 + SSE 流式回复(POST/tasks/{tid}/messages启 run、GET/tasks/{tid}/runs/{rid}/eventsSSE 流;HTMXsse-swap追加 DOM,无 JS);G5-G6 待。task_dir 显示统一 forward-slash(Win 存\也归一)。Linux:.venv/bin/python cli.py web一致。SSE 经 nginx 反代记得关 buffering(响应头已带X-Accel-Buffering: no默认起效)。
故障兜底
| 现象 | 原因 / 处理 |
|---|---|
ZCBOT_DB_URL is not set |
.env 没写 / litellm 链路没触发。直跑脚本时 import litellm,或 export ZCBOT_DB_URL=... |
ModuleNotFoundError: litellm |
用了全局 python,改 .venv/Scripts/python.exe ... |
| Windows 控制台 emoji 崩 | Python stdout 是 GBK,emoji 不能直 print。用 [OK] / [ng] 等 ASCII 标签(见 memory) |
db upgrade 报 column already exists |
DB 已被改过,先 db current 确认 revision,必要时手 ALTER 或 db downgrade base 重来 |
| Resume 找不到 task | cli.py tasks 看 task_id 是否在;前缀冲突报 ambiguous 时给完整 UUID |
--task-dir 指定后 /exit 没清 task_dir |
设计如此 —— 用户路径绝不 rmtree;DB 行该删还是删。要彻底删手动 rm -rf <dir> |
| Export 报 "无可导出内容" | task 没 messages(只 system 不算);先在 REPL 发条消息再 export |
NoSubtaskError: task_dir ... 与已有 task ... 前缀嵌套 |
§7.4 no-subtask:同 user 不允许 task_dir 嵌套(child 或 parent)。同项目多对话请传完全相同的 --task-dir;否则改路径成 sibling(平级) |
cli.py web 启动后浏览器开不了 |
检查 proxy(HTTP_PROXY / HTTPS_PROXY):本地形态服务在 127.0.0.1,系统 proxy 拦截会 502。临时 unset HTTP_PROXY HTTPS_PROXY 或浏览器配 bypass。curl 验通走 curl --noproxy '*' http://127.0.0.1:8765/healthz(应返 ok) |
TypeError: unhashable type: 'dict' from Jinja templating |
Starlette 新版签名:TemplateResponse(request, name, context),旧式 (name, {"request":..., "...":...}) 在 newer Starlette 会把 context dict 当 cache key 炸 |
| SSE 卡住不流(经 nginx) | 反代要关 buffering — 后端响应头已带 X-Accel-Buffering: no,nginx ≥ 1.5.6 默认认。仍卡看 nginx 配 proxy_buffering off; proxy_read_timeout 3600s; |
| 浏览器 send 后没反应 | 看 console:HTMX 报 connect failed → 看 /tasks/{tid}/messages 响应;200 但流不到 → 看 EventSource 状态(devtools Network → EventStream tab) |
UniqueViolation idx already exists from messages |
同 task 连续两次快速 POST,messages idx 冲突。已知 TODO:G6/D 阶段加 task 级 lock_for_update 或 advisory lock |
关键路径与文件
- 入口:
cli.py(REPL +chat / tasks / probe / db / web子命令)→main.py::build_agent(装配) - 核心:
core/loop.py(ReAct)/core/session.py(PG messages)/core/task.py(PG tasks)/core/llm.py(LiteLLM 封装) - 工具:
tools/{fs,shell,run_python,skill_tool}.py - 存储:
core/storage/{engine,models,utils}.py(SQLAlchemy 2.x ORM)+db/migrations/(alembic) - Web:
web/{app.py, templates/, static/}(§7 Phase G,FastAPI + Jinja2 + HTMX) - 配置:
config/agent.yaml(全局)/config/models/*.yaml(模型档案,§3.2 Model Profile) - Skill:
skills/{coding,ppt,proposal}/SKILL.md(渐进披露,§3.5) - Workspace:
workspace/memory/{core.md, extended/}(跨 task 记忆,FS 永久)/workspace/tasks/<uuid>/(默认派生 task_dir,只放 skill 产物)
维护约定
- 每改一个对外行为(CLI 选项 / REPL 命令 / env 变量 / 文件布局)→ 同步更新本文档。bug 修不动这个,只动 PROGRESS。
- 故障兜底表新增条目:用过一次的真实坑,写一行(现象 + 处理),不预测。
- 跟 DESIGN/PROGRESS 的边界:DESIGN 写"为什么",PROGRESS 写"做到哪",RUN 写"怎么跑"。