145 lines
6.3 KiB
Markdown
145 lines
6.3 KiB
Markdown
# 运行手册
|
|
|
|
> 怎么把 zcbot 跑起来。env / 常用命令 / 故障兜底。设计看 `DESIGN.md`,进度看 `PROGRESS.md`。
|
|
|
|
最后更新:2026-05-14(Phase G G2)
|
|
|
|
---
|
|
|
|
## 环境
|
|
|
|
- **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/zcbot
|
|
```
|
|
> litellm 在 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)。
|
|
|
|
---
|
|
|
|
## 一次性初始化
|
|
|
|
```bash
|
|
# 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)
|
|
```
|
|
|
|
---
|
|
|
|
## 日常命令
|
|
|
|
### 聊天 / 任务
|
|
|
|
```bash
|
|
# 新建 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>]`
|
|
|
|
### 列表 / 导出
|
|
|
|
```bash
|
|
# 看最近 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 管理
|
|
|
|
```bash
|
|
# 实测对账模型 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)
|
|
|
|
```bash
|
|
# 默认 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=active|completed|abandoned` filter + `/tasks/{uuid}` 占位(G3 来填消息流);G3-G6 待。task_dir 显示统一 forward-slash(Win 存 `\` 也归一)。Linux:`.venv/bin/python cli.py web` 一致。
|
|
|
|
---
|
|
|
|
## 故障兜底
|
|
|
|
| 现象 | 原因 / 处理 |
|
|
|---|---|
|
|
| `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 炸 |
|
|
|
|
---
|
|
|
|
## 关键路径与文件
|
|
|
|
- **入口**:`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 写"怎么跑"。
|