197 lines
6.3 KiB
Markdown
197 lines
6.3 KiB
Markdown
# LaodingBot 技术说明文档(2026-02-28 最新实现)
|
||
|
||
> 本文档基于当前代码状态,描述真实可运行架构与能力边界。
|
||
|
||
---
|
||
|
||
## 1. 项目定位
|
||
|
||
LaodingBot 当前已从“单进程工具调用 MVP”演进为:
|
||
- **父进程 Agent 编排**(技能路由 + ReAct + 记忆)
|
||
- **子进程 ToolHost 执行**(JSON-RPC)
|
||
- **workspace 隔离运行空间**(配置与工具权限收敛)
|
||
- **能力缺口闭环**(落库、聚类、自动生成技能并热加载)
|
||
|
||
核心目标:让 Agent 在安全边界内持续补全能力,而不是仅做静态问答。
|
||
|
||
---
|
||
|
||
## 2. 目录与模块
|
||
|
||
- `cmd/bot/main.go`:应用入口、workspace 引导、toolhost 启动、通道分发
|
||
- `internal/config/config.go`:配置加载、workspace 路径解析、安全策略归一化
|
||
- `internal/runtimews/bootstrap.go`:运行时 workspace 准备与种子目录复制
|
||
- `internal/agent/orchestrator.go`:主编排器(技能匹配、ReAct、能力缺口闭环)
|
||
- `internal/toolhost/*`:工具子进程协议、服务端、客户端、远程工具适配
|
||
- `internal/tools/filetool/filetool.go`:文件工具(`read/list/write`)
|
||
- `internal/tools/shelltool/shelltool.go`:命令工具(白名单 + 超时 + 输出限制)
|
||
- `internal/memory/store_sqlite.go`:消息与能力缺口存储、聚类查询
|
||
- `internal/knowledge/loader.go`:skill/soul 加载
|
||
- `internal/knowledge/drafts.go`:能力缺口驱动的 skill 自动生成
|
||
|
||
---
|
||
|
||
## 3. 启动链路(当前)
|
||
|
||
`main()` 执行顺序:
|
||
1. 建立可取消上下文(SIGINT/SIGTERM)。
|
||
2. 调用 `runtimews.PrepareFromEnv()`:
|
||
- 解析 `AGENT_WORKSPACE_DIR`(默认 `./workspace/agent_runtime`)
|
||
- 将 `configs/data/skills/bot_context` 种子复制到 runtime workspace(缺失才复制)
|
||
- 设定 `CONFIG_ENV_FILE=<workspace>/configs/env`
|
||
3. 调用 `config.Load()`,优先读取 workspace env。
|
||
4. 若 `--toolhost` 模式,进入子进程服务。
|
||
5. 正常父进程:初始化日志、SQLite、ToolHost Client、知识、Orchestrator。
|
||
6. 根据 `MESSAGE_CHANNEL` 启动 Telegram 或 Feishu transport。
|
||
|
||
---
|
||
|
||
## 4. 配置加载与优先级(关键变更)
|
||
|
||
`config.Load()` 的 env 读取优先级:
|
||
1. `CONFIG_ENV_FILE`(强覆盖)
|
||
2. `<workspace>/configs/env` 与 `<workspace>/.env`(强覆盖)
|
||
3. 根目录 `configs/env` 与 `.env`(仅兜底,不覆盖已有值)
|
||
|
||
这保证 VS Code Debug 场景下,**workspace 配置优先于根目录配置**。
|
||
|
||
### 关键配置
|
||
- `REACT_MAX_STEPS`:必须来自 env(无代码默认值)
|
||
- `AGENT_WORKSPACE_DIR`:agent 运行空间根目录
|
||
- `ALLOWED_DIRS` / `ALLOWED_COMMANDS` / `WORK_DIR`:工具安全边界
|
||
- `AUTO_SKILL_DIR`:自动生成 skill 的目标目录(默认 workspace/skills)
|
||
- `GAP_DRAFT_TRIGGER_COUNT` / `GAP_CLUSTER_LOOKBACK_HOURS`:缺口聚类触发参数
|
||
|
||
---
|
||
|
||
## 5. workspace 隔离策略
|
||
|
||
当前实现中,Agent 与工具默认都在 workspace 内高权限运行:
|
||
- 相对路径统一按 `AGENT_WORKSPACE_DIR` 解析
|
||
- `ALLOWED_DIRS` 强制补齐:
|
||
- workspace 根
|
||
- `workspace/skills`
|
||
- `workspace/data`
|
||
- `workspace/workspace`
|
||
- `ALLOWED_COMMANDS` 自动补齐:`go`、`curl`、`curl.exe`
|
||
|
||
`filetool` 对相对路径优先按 workspace 根解析,避免写到代码仓库根目录。
|
||
|
||
---
|
||
|
||
## 6. ToolHost 子进程架构
|
||
|
||
当前工具调用已迁移到 JSON-RPC 子进程:
|
||
- 协议方法:`ping`、`tool.list`、`tool.call`
|
||
- 父进程 `Client` 能力:
|
||
- 调用超时
|
||
- 心跳检测
|
||
- 失败重启与重试
|
||
- 并发限制(信号量)
|
||
- 子进程 stdout 仅承载协议数据(避免日志污染 RPC)
|
||
|
||
效果:工具崩溃不会直接拖垮 Agent 主编排逻辑。
|
||
|
||
---
|
||
|
||
## 7. ReAct 与技能路由
|
||
|
||
`Orchestrator` 流程:
|
||
1. 保存用户消息到 SQLite
|
||
2. 读取最近对话并压缩
|
||
3. LLM 进行技能路由(最多命中 2 个)
|
||
4. 若无技能命中:尝试回退到 `创建skill` 技能
|
||
5. 进入 ReAct 多轮决策(`action/final`)
|
||
6. 工具调用观察写入 scratchpad
|
||
7. 保存 assistant 回复
|
||
|
||
工具错误会结构化为:
|
||
- `ERROR_CODE=...; TOOL=...; REASON=...`
|
||
|
||
---
|
||
|
||
## 8. 能力缺口闭环(已落地)
|
||
|
||
当出现“不会做”信号(如无 skill、解析失败、工具失败)时:
|
||
1. 写入 `capability_gaps` 表
|
||
2. 进行意图归一化聚类(按 `intent_key + reason`)
|
||
3. 高频达到阈值后自动生成 skill 文件
|
||
4. 自动调用 `ReloadSkills()` 热加载
|
||
|
||
可通过消息命令查看与控制:
|
||
- `/capability_gaps`:输出当前高频缺口清单
|
||
- `/reload_skills`:手动热加载 skills
|
||
|
||
---
|
||
|
||
## 9. 自动生成 skill 的当前行为
|
||
|
||
自动生成由 `internal/knowledge/drafts.go` 执行:
|
||
- 目标目录:`AUTO_SKILL_DIR`(默认 workspace/skills)
|
||
- 命名:`auto_<intent_key>/skill.md`
|
||
- 仅在文件不存在时创建,避免重复覆盖
|
||
- 模板内包含:触发背景、执行流程、工具建议、测试建议
|
||
|
||
并额外提供基础引导技能:
|
||
- `skills/skill_builder/skill.md`
|
||
|
||
---
|
||
|
||
## 10. file/shell 工具现状
|
||
|
||
### file tool
|
||
支持:
|
||
- `read <path>`
|
||
- `list <path>`
|
||
- `write <path>\n<content>`
|
||
|
||
特性:
|
||
- 白名单路径检查
|
||
- 目录误读防护:`read` 目录返回 `PATH_IS_DIRECTORY`
|
||
- 输出长度限制
|
||
|
||
### shell tool
|
||
特性:
|
||
- 命令白名单(首 token)
|
||
- 超时中断
|
||
- 固定工作目录
|
||
- 输出截断
|
||
- Windows 不可执行命令友好报错
|
||
|
||
---
|
||
|
||
## 11. 数据存储
|
||
|
||
SQLite 表:
|
||
1. `messages`:对话消息
|
||
2. `capability_gaps`:能力缺口事件
|
||
|
||
提供查询:
|
||
- 最近消息
|
||
- 最近缺口事件
|
||
- 高频缺口聚类(含计数与最近出现时间)
|
||
|
||
---
|
||
|
||
## 12. 与最初文档相比的变化
|
||
|
||
当前代码已经完成并替代旧文档中的以下“待实现项”:
|
||
- ToolHost 子进程隔离(已实现)
|
||
- 能力缺口闭环(已实现)
|
||
- 自动 skill 生成与热加载(已实现)
|
||
- workspace 配置优先与运行空间隔离(已实现)
|
||
|
||
仍属于持续演进项:
|
||
- 新工具代码自动注册与生效的全自动化流水线
|
||
- 更细粒度权限域(按 skill/tool 分级)
|
||
- 更强的自动化验收(e2e + 故障注入)
|
||
|
||
---
|
||
|
||
## 13. 下一步建议
|
||
|
||
1. 为 `toolhost client/server` 增加专项故障单测(心跳失败、子进程崩溃、并发压力)。
|
||
2. 增加“自动生成 tool 后自动接线注册”的流水线模块。
|
||
3. 为 skill 自动生成增加结构门禁(frontmatter/章节完整性校验)。
|
||
4. 引入操作审计视图,串联 trace_id 与 capability_gap。
|