From 323ee23cd650d4a644fe91dc96a216d2ae7611f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=AD=A6=E9=98=B3?= Date: Fri, 8 May 2026 21:30:15 +0800 Subject: [PATCH] Refresh README for general agent platform --- README.md | 615 ++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 508 insertions(+), 107 deletions(-) diff --git a/README.md b/README.md index 98084b6..7113e0c 100644 --- a/README.md +++ b/README.md @@ -1,67 +1,456 @@ # ZK Data Agent -ZK Data Agent 是面向中控数据开发流程的 Agent 服务。当前仓库包含: +ZK Data Agent 是基于 `claw-code-agent` 改造的团队通用 Agent 工作台。 -- Python 后端:负责 Agent loop、工具调用、会话持久化和数据开发工具。 -- Next.js 前端:提供 Web UI、会话管理、工具调用展示和数据开发交互入口。 -- Skill / Tools:承载产品定义到数据生成、线上数据挖掘等数据开发链路。 +它不是一个单点数据工具,也不是只会聊天的 Web UI。这个项目的核心目标是把“通用 Agent 能力”稳定下来:让 Agent 能理解任务、选择 Skill、调用 Tools、读写文件、执行 Python、保留会话、展示工具链路,并把团队反复使用的工作经验沉淀成可维护的能力包。 -## 快速部署 +数据开发、线上挖掘、ELK 查询、数据工场 SQL 查询,都是已经通过 Skill 和 Tools 落地的子能力。 -### 从 Git 一键部署 +## 这个项目解决什么 -适合首次部署。首次安装会默认初始化 Ubuntu 系统依赖,必要时请求 sudo;应用本身仍部署在用户目录。 +团队日常有很多任务不只是“问模型一句话”: + +- 要读文件、查日志、跑 SQL、分析线上数据。 +- 要生成中间结果、落盘文件、继续追问和修正。 +- 要把某类任务的经验固化下来,下一次让 Agent 按同样的方法做。 +- 要让用户看到 Agent 做了什么、调用了什么工具、文件生成在哪里。 +- 要让多人共用一套平台,而不是每个人本地各跑一份零散脚本。 + +ZK Data Agent 做的是这层通用底座。业务能力通过 Skill 和 Tools 逐步沉淀。 + +## 核心设计 + +### Agent Loop + +Agent 每轮对话不是一次性生成文本,而是一个循环: + +```text +用户输入 + -> 组装系统提示词、Skill 提示词、会话上下文、工具定义 + -> 模型决定直接回复或返回 tool_calls + -> 后端执行对应 tool handler + -> 工具结果写入会话 + -> 下一轮模型继续判断 + -> 直到输出最终回复、等待用户 review 或被取消 +``` + +这个循环让 Agent 可以边观察、边执行、边修正,而不是只能一次性回答。 + +### Skill + +Skill 是“经验层”。它用 `SKILL.md` 描述某类任务应该怎样做、什么时候需要用户确认、可以调用哪些工具、产物应该放在哪里。 + +项目级 Skill 统一放在: + +```text +skills//SKILL.md +``` + +Skill 适合承载: + +- 工作流程 +- 业务边界 +- review 门禁 +- 工具调用经验 +- 输入输出格式约定 +- 常见错误和注意事项 + +Skill 不应该写成大段不可执行代码。稳定、强格式、可复用的能力应该下沉到 Tool。 + +### Tools + +Tools 是“执行层”。工具负责稳定地做事情,例如读写文件、执行 Python、查询 parquet、转换 records、导出 JSONL。 + +主要位置: + +```text +src/agent_tools.py +src/agent_tool_specs/ +src/data_agent_records.py +src/data_agent_inputs.py +src/data_agent_router_sessions.py +``` + +工具适合承载: + +- 强格式转换 +- 数据校验 +- 路径归一 +- 线上数据读取 +- 账号级 Python 执行环境 +- 需要审计和约束的外部调用 + +原则是:不要长期让 Agent 手写易错脚本来完成稳定流程。能工具化的,尽量工具化。 + +### 会话工作区 + +每个用户、每个会话都有独立目录: + +```text +.port_sessions/accounts//sessions// + input/ 用户输入文件 + scratchpad/ 临时脚本、中间分析、草稿 + output/ 最终产物 + session.json 会话历史 +``` + +会话工作区是这个项目和普通聊天机器人很不一样的地方。Agent 的产物不是散落在项目根目录,而是跟随当前会话保存,方便回看、下载和继续追问。 + +### Review 门禁 + +一些任务不能让 Agent 一步到位,例如: + +- 数据生成目标还不清楚。 +- 标签边界存在歧义。 +- 线上候选需要人工抽样确认。 +- 输出格式会影响训练、评测或对外交付。 + +这类流程要通过 Skill 和 Tool 实现 review 门禁。目标、计划、候选样本、最终导出都应该分阶段展示给用户确认。 + +### 可观测性 + +Web UI 会展示: + +- 当前模型和上下文状态 +- Skill 列表和启用状态 +- 工具调用过程 +- 总结版思考阶段 +- 历史会话 +- 当前会话输入/输出文件 +- 后台运行和刷新恢复状态 + +目标是让用户知道 Agent 正在做什么,而不是只看到一个黑盒回复。 + +## 和 Claude Code 的区别 + +这个项目继承了 Claude Code 类工具的基本思路:Agent 可以读写文件、执行工具、维护上下文,并围绕一个工作区完成任务。 + +但当前项目的定位更偏团队内部 Agent 平台: + +| 维度 | Claude Code 类工具 | ZK Data Agent | +|------|--------------------|---------------| +| 使用形态 | 个人本地 CLI/IDE 工作流为主 | 团队共享 Web 服务 | +| 任务范围 | 代码开发为核心 | 通用任务底座,数据开发只是能力之一 | +| 能力沉淀 | 个人 prompt、命令、脚本较多 | 项目级 Skill + Tools 统一管理 | +| 文件空间 | 通常围绕当前代码仓库 | 每个用户/会话独立 `input/scratchpad/output` | +| 可观测性 | 终端输出为主 | Web UI 展示工具链路、活动、文件、历史 | +| Python 执行 | 常用 shell 自行管理 | 优先 `python_exec`,走账号级环境和工具约束 | +| 人工确认 | 通常是权限批准或终端交互 | 更强调业务 review:目标、计划、样本、导出 | +| 内部系统 | 需要用户自行接脚本 | 可以通过 Skill/Tools 接 ELK、SQL、线上数据 | + +因此,它不是要替代 Claude Code 的个人编码体验,而是把 Agent 变成团队可共享、可扩展、可治理的工作台。 + +## 能力目录 + +### 通用 Agent 能力 + +当前底座已经支持: + +- OpenAI 兼容模型调用 +- Web UI 多会话管理 +- 模型选择 +- Skill 发现和会话级启用 +- 工具调用展示 +- 文件输入和会话产物管理 +- 后台 run 状态和刷新恢复 +- 总结版思考过程展示 +- Python 执行和包安装工具 +- 用户级 systemd 部署 + +### 数据开发能力 + +Skill:`product-data` + +适用于从产品定义、标签规则、手写边界或示例 query 生成数据集。 + +典型流程: + +```text +输入定义/规则/样例 + -> 抽取 generation goal + -> 用户 review + -> 生成 generation plan + -> 用户确认数量、标签、边界、路径 + -> 生成 dataset draft text + -> 转换为 canonical records + -> 校验 + -> 导出 records.jsonl +``` + +默认最终产物: + +```text +当前会话/output/records.jsonl +``` + +### 线上挖掘能力 + +Skill:`online-mining` + +适用于从线上 router session 中按 query 特征、domain、设备、日期等条件挖掘候选样本。 + +典型流程: + +```text +需求/badcase/标签定义 + -> 构造挖掘策略 + -> profile 数据 + -> search 候选 + -> sample 抽样 review + -> 策略调整 + -> 候选转换为 canonical records + -> 导出 records.jsonl +``` + +默认线上数据路径: + +```text +/data/online_data/router_session_parquet/date=YYYYMMDD/ +``` + +重要分支: + +- 如果用户要“直接把线上候选作为样本”,只做转换,不生成新 query。 +- 如果用户明确要“补充生成/扩写类似 case”,才切换到数据生成链路。 + +### 评测修复能力 + +Skill:`eval-repair` + +用于评测错误分析、错误类型归纳和后续补数流程。目前主要是流程占位和约定沉淀,工具还会继续补齐。 + +### 日志查询能力 + +Skill:`elk-fetch` + +用于按 request id 查询小米内网 ELK 日志,覆盖 NLP 主链路、拒识、免唤醒、小米汽车 OneTrack 等场景。 + +原则: + +- 通过 `python_exec` 执行 skill 内脚本。 +- 不让 Agent 直接用 `bash python ...` 绕过工具链路。 + +### 数据工场 SQL 能力 + +Skill:`data-factory-sql` + +用于通过 Kyuubi HTTP API 执行 SQL、轮询状态并下载 CSV 结果。 + +适用于: + +- 用户直接给 SQL。 +- 用户要求“跑个 SQL”“数据工场查一下”。 +- Agent 基于表结构和字段说明生成 SQL 草稿,再请求用户确认后执行。 + +## 团队公约 + +### 空间公约 + +业务任务默认在当前会话空间内工作: + +```text +input/ 用户上传或指定的输入材料 +scratchpad/ 临时脚本、中间文件、抽样缓存 +output/ 最终交付文件 +``` + +约定: + +- 最终产物优先写入当前会话 `output/`。 +- 临时脚本和中间文件写入当前会话 `scratchpad/`。 +- 数据 records 默认导出到逻辑路径 `output/records.jsonl`,工具会自动路由到当前会话 output。 +- 不要把业务任务产物写到项目根目录的 `output/`、`tasks/`、`src/`、`skills/`。 +- 读取外部数据可以用明确路径,但写入外部路径前需要用户明确确认。 +- 平台源码目录默认只读。只有用户明确要求开发平台功能时,才修改 `src/`、`frontend/`、`skills/`、`scripts/` 等项目文件。 + +### Skill 公约 + +项目级 Skill 统一放在: + +```text +skills//SKILL.md +``` + +`SKILL.md` frontmatter 至少包含: + +```yaml +--- +name: product-data +description: 简短说明这个 skill 做什么。 +when_to_use: 说明什么场景应该触发。 +aliases: optional-alias +allowed_tools: read_file, write_file, python_exec +--- +``` + +维护规则: + +- 用中文写主要流程说明,方便团队后续维护。 +- Skill 写“怎么做”和“什么时候停下来问用户”。 +- 不要把稳定格式转换、校验、复杂查询长期写在 Skill 里,应沉淀为 Tool。 +- Skill 如果依赖脚本,脚本放在该 Skill 目录下,并通过 `python_exec` 调用。 +- 新增业务 Skill 后,可以在 Web UI Skill 列表中按会话启用或关闭。 + +### Tool 公约 + +工具是稳定执行边界。 + +约定: + +- 强格式输出必须工具化,例如 canonical records、JSONL 导出、数据校验。 +- 需要持久化状态的 review 流程应由工具记录 pending/confirmed 状态。 +- Python 分析优先用 `python_exec`。 +- 缺 Python 包时用 `python_package`。 +- 除非没有专用工具,否则不要让 Agent 通过 `bash` 绕过已有工具。 + +### Python 公约 + +Agent 执行 Python 优先使用: + +```text +python_exec +python_package +``` + +原因: + +- 可以进入账号级 Python 环境。 +- 可以把临时脚本和输出放在当前会话 scratchpad。 +- Web UI 能看到工具调用过程。 +- 后续更容易加超时、取消、审计和资源限制。 + +### Git 公约 + +不要提交: + +- `.env.deploy` +- `.venv/` +- `.port_sessions/` +- `router_session_parquet/` +- 用户数据、模型输出、临时任务产物 + +可以提交: + +- `skills/` 下经过确认的项目级 Skill +- `src/` 下稳定工具和运行时代码 +- `frontend/app/` 下 Web UI 代码 +- `scripts/` 和 `deploy/` 下部署维护脚本 +- README 中面向团队维护的约定 + +## 系统组成 + +```text +frontend/app/ Next.js Web UI +backend/ FastAPI Web 后端 +src/ Agent runtime、提示词、工具实现、会话持久化 +skills/ 项目级 Skill,使用 SKILL.md 定义 +scripts/ 本地启动、服务器部署、systemd 启动脚本 +deploy/systemd/ 用户级 systemd service 模板 +.port_sessions/ 本地/服务端运行数据,禁止提交 +.env.deploy 本机私有部署配置,禁止提交 +``` + +前端负责账号、会话列表、模型选择、对话流式展示、活动面板和会话文件面板。 + +后端负责 Agent loop、OpenAI 兼容模型调用、工具执行、run 状态、会话持久化和数据开发工具。 + +## 本地开发启动 + +首次准备 Python 依赖: + +```bash +pyenv install 3.10.14 +pyenv local 3.10.14 +python -m venv .venv +.venv/bin/python -m pip install --upgrade pip setuptools wheel +.venv/bin/python -m pip install -e . +``` + +准备前端依赖: + +```bash +cd frontend/app +npm install +``` + +本地启动 Web UI: + +```bash +bash scripts/start-webui.sh +``` + +默认地址: + +```text +前端:http://127.0.0.1:3000 +后端:http://127.0.0.1:8765 +``` + +`scripts/start-webui.sh` 会优先读取 `.env.deploy`,也可以直接使用当前 shell 里的环境变量: + +```bash +export OPENAI_API_KEY="..." +export OPENAI_BASE_URL="http://model.mify.ai.srv/v1" +export OPENAI_MODEL="xiaomi/mimo-v2-flash" +``` + +停止本地 Web UI: + +```bash +kill $(cat .port_sessions/webui-frontend.pid) $(cat .port_sessions/webui-backend.pid) +``` + +## 部署和更新 + +### 首次部署 + +推荐把应用部署在用户目录,不需要把代码放到 `/opt`: ```bash git clone git@git.n.xiaomi.com:wuyang6/zk-data-agent.git "$HOME/zk-data-agent" || true bash "$HOME/zk-data-agent/scripts/install-from-git.sh" ``` -后续更新不需要安装系统依赖,可以使用: +首次部署会: -```bash -bash "$HOME/zk-data-agent/scripts/install-from-git.sh" +- 拉取 `main` 分支。 +- 交互式生成 `.env.deploy`。 +- 必要时请求 sudo 安装 Ubuntu 系统依赖。 +- 用 pyenv 准备 Python `3.10.14`。 +- 创建项目 `.venv`。 +- 安装前端依赖并构建。 +- 安装并启动用户级 systemd 服务。 + +`.env.deploy` 会保存: + +```text +OPENAI_API_KEY +OPENAI_BASE_URL +OPENAI_MODEL +CLAW_BACKEND_HOST +CLAW_BACKEND_PORT +CLAW_FRONTEND_HOST +CLAW_FRONTEND_PORT +CLAW_API_URL ``` -默认部署目录是 `$HOME/zk-data-agent`,默认分支是 `main`。修改部署目录或分支时再加变量: +该文件包含敏感信息,只保存在部署机器本地,权限设置为 `600`,并已被 `.gitignore` 忽略。 + +### 日常更新 + +已经完成首次部署后,普通代码更新使用: ```bash -git clone git@git.n.xiaomi.com:wuyang6/zk-data-agent.git "$HOME/zk-data-agent-test" || true -APP_DIR="$HOME/zk-data-agent-test" bash "$HOME/zk-data-agent-test/scripts/install-from-git.sh" +cd "$HOME/zk-data-agent" +bash scripts/update-server-fast.sh ``` -这个命令会自动完成: - -- 目标目录不存在时执行 `git clone` -- 目标目录已存在时执行 `git fetch` / `git pull --ff-only` -- 进入仓库后执行 `bash scripts/deploy-ubuntu.sh` - -说明:仓库是私有仓库,`curl | bash` 拉 raw 文件时容易拿到登录页 HTML;因此推荐直接走 SSH git 权限。 - -### 仓库内一键部署/更新 - -如果已经在仓库目录中,日常更新直接执行: +如果改动包含依赖、systemd 模板或部署脚本,使用完整部署脚本: ```bash bash scripts/deploy-ubuntu.sh ``` -已完成首次部署后,如果只是普通代码更新,可以使用快速更新: - -```bash -bash scripts/update-server-fast.sh -``` - -快速更新只会拉取代码、构建前端并重启用户服务;如果本次改动包含依赖、systemd 模板或部署脚本变化,请使用 `scripts/deploy-ubuntu.sh`。 - -如果是全新 Ubuntu 机器,首次安装可以让脚本顺手安装系统依赖: - -```bash -bash scripts/deploy-ubuntu.sh --bootstrap-system -``` - -`--bootstrap-system` 会使用 `sudo apt-get` 安装 Python 编译依赖、`git`、`curl` 等系统包;应用代码、`.venv`、前端依赖、运行数据和 systemd 用户服务仍然都在当前用户目录下。 - 部署指定分支: ```bash @@ -74,41 +463,11 @@ bash scripts/deploy-ubuntu.sh main bash scripts/deploy-ubuntu.sh main --force ``` -## 部署配置 +### 服务管理 -首次执行 `scripts/deploy-ubuntu.sh` 时,如果仓库根目录不存在 `.env.deploy`,脚本会交互式提示输入: - -- `OPENAI_API_KEY` -- `OPENAI_BASE_URL` -- `OPENAI_MODEL` -- 后端监听地址和端口 -- 前端监听地址和端口 - -配置会写入: +部署脚本会安装两个用户级 systemd 服务: ```text -.env.deploy -``` - -该文件包含敏感信息,只保存在部署机器本地,权限会设置为 `600`,并且已被 `.gitignore` 忽略,不会提交到 git。 - -如需修改模型或 key: - -```bash -vim .env.deploy -``` - -可参考示例: - -```bash -cp .env.deploy.example .env.deploy -``` - -## 运行方式 - -部署脚本会安装两个用户级 systemd 服务,不需要 sudo: - -```bash zk-data-agent-backend zk-data-agent-frontend ``` @@ -139,24 +498,15 @@ systemctl --user restart zk-data-agent-backend zk-data-agent-frontend systemctl --user stop zk-data-agent-backend zk-data-agent-frontend ``` -## 本地开发启动 - -本地调试可以使用: +如果机器要求用户退出 SSH 后服务仍保持运行,可由管理员执行: ```bash -bash scripts/start-webui.sh +loginctl enable-linger ``` -默认端口: - -- 前端:`http://127.0.0.1:3000` -- 后端:`http://127.0.0.1:8765` - -`scripts/start-webui.sh` 会优先读取本机 `.env.deploy`,也可以直接使用当前 shell 中的环境变量。 - ## 环境要求 -Ubuntu 部署建议准备: +Ubuntu 部署建议: - `git` - `bash` @@ -167,35 +517,86 @@ Ubuntu 部署建议准备: - Node.js `20` 或 `22` - `npm` -如果机器缺少 Python 编译依赖,首次执行时可加 `--bootstrap-system`,脚本会请求 sudo 安装系统包。日常部署和更新不需要 sudo。 - -Python 后端依赖由部署脚本安装到项目根目录 `.venv`。 - -前端依赖由部署脚本在 `frontend/app` 下执行 `npm ci` 安装,并执行 `npm run build`。 - -部署脚本会把当前 shell 中可用的 `npm` 路径写入 `.env.deploy`,避免用户级 systemd 服务启动时读取不到 zsh/nvm 环境。 - -默认部署使用用户级 systemd,不需要 sudo。若机器要求服务在用户退出 SSH 后仍保持运行,可由管理员额外执行: +首次安装如果缺 Python 编译依赖,可以执行: ```bash -loginctl enable-linger +bash scripts/deploy-ubuntu.sh --bootstrap-system ``` -## 目录说明 +`--bootstrap-system` 会使用 `sudo apt-get` 安装系统依赖;应用代码、虚拟环境、前端依赖、运行数据和 systemd 用户服务仍然位于当前用户目录。 + +## 开发验证 + +后端基础校验: + +```bash +.venv/bin/python -m compileall src backend +``` + +前端校验: + +```bash +cd frontend/app +npm run lint +npx tsc --noEmit +npm run build +``` + +提交前建议确认: + +```bash +git status --short +git diff --check +``` + +## 常见问题 + +### Web UI 能打开,但模型调用失败 + +先检查 `.env.deploy`: + +```bash +cat .env.deploy +``` + +重点确认: + +- `OPENAI_API_KEY` +- `OPENAI_BASE_URL` +- `OPENAI_MODEL` + +然后看后端日志: + +```bash +journalctl --user -u zk-data-agent-backend -f +``` + +### systemd 服务找不到 npm + +重新执行完整部署脚本: + +```bash +bash scripts/deploy-ubuntu.sh +``` + +脚本会把当前可用的 `npm` 路径写入 `.env.deploy`,避免用户级 systemd 读取不到 zsh/nvm 环境。 + +### 新增 Skill 后前端看不到 + +项目级 Skill 放在: ```text -backend/ FastAPI Web 后端 -frontend/app/ Next.js 前端 -src/ Agent runtime、tools、skills -scripts/ 本地启动、部署、systemd 启动脚本 -deploy/systemd/ systemd service 模板 -.port_sessions/ 本地运行数据,禁止提交 -.env.deploy 本机私有部署配置,禁止提交 +skills//SKILL.md ``` -## 注意事项 +确保 frontmatter 至少包含 `name`、`description`、`when_to_use`。Web UI 会通过 `/api/claw/skills` 读取 Skill 列表。 -- 不要把 `OPENAI_API_KEY` 写入可提交文件。 -- `.env.deploy`、`.venv`、`.port_sessions` 都是本机文件,不进入 git。 -- 服务器更新优先使用 `bash scripts/deploy-ubuntu.sh`,不要手工分散执行依赖安装和服务重启。 -- 生产/长期运行使用 systemd 服务;`scripts/start-webui.sh` 只用于本地调试。 +### Agent 产物没有出现在“聊天中的文件” + +最终产物必须写入当前会话 `output/`。数据 records 推荐使用数据工具导出到逻辑路径: + +```text +output/records.jsonl +``` + +工具会自动路由到当前会话 output 目录。