Files
HomeAgent/docs/zh/kernel-performance.md
JianFeeeee cf14b840ef docs: 补齐文档状态分类 + 校正两轮代码改动后的失真
## 背景

上一次文档校订(b9b5ac0)之后又有两次代码提交(5194a96 / 8293282),
把 future-plan §1.1 整节变成了错的 —— 它还写着「档位没有生效点」
和「在 prepareInputTask 里加一次 activateSecurityProfile 调用」,
而后者正是被后来的收敛**否定掉的方案**。

## 新增 docs/zh/README.md(文档索引)

32 篇文档此前混着三种时态(当时实测 / 历史推演 / 设计规划),外观相同。
索引给出**状态分类与可信度规则**:

| 状态 | 能不能当事实用 |
|---|---|
| 已实现并部署 | ✅ 直接信 |
| 部分实现 | ⚠️ 只信标了"生效"的部分 |
| 设计 / 未实现 | ❌ 只能当设计意图 |
| 归档说明 | ❌ 不要改、也不要信 |

并写死**判据名可信度规则**:文档里的 `TestXxx` 不保证还存在。
给了核对命令,以及当前基线(27 条缺失的分布 —— 18 条属"设计未实现"类
文档的规划名、7 条是 §2.7.3 有意保留的历史对照表左栏、2 条属视频能力
未纳入契约)。判定标准:**在"已实现"类文档正文里找不到才是缺陷**。

## 重写 future-plan §1.1(已结案)

原节写的是错的方案。改成记录**真正的缺陷分三层**:

```
第 3 层(表面):activateSecurityProfile 零调用方
第 2 层:agent/core 在替 security 做策略决策
         (自己抠 security_profile / 自己选判定链 /
           自己写 Kind:"resident" 声明主体类别 —— 提权口子)
第 1 层(根因):security 缺少「输入接入点」
```

并补上「每 agent 一个实例」的最终形态(共享注册表 + per-agent 执行视图,
sessionProfile / longtimeProfile 两层,优先级 session > longtime 本身是安全语义)。

§〇「机制 ≠ 接线」表格里档位那一条从 🔴 改为 ✅。

## 各文档状态行

此前 14 篇缺状态行(runbook / 实测报告 / 计划类)。逐篇补上**符合实际内容**
的声明,而不是统一套一句。特别地:

- `commondev-design.md` 标题本就写「设计 · 未实现」→ 归到"设计"类
- `live-run-evidence-2026-10-04.md` → 明确标注"历史证据快照,不要用它的
  结论覆盖现在的实现判断"
- `legacy-issues.md` → 写明它与 future-plan 的分工(前者收已知问题,
  后者收能力缺失与零调用方)

## 正文里两处判据名漂移

- `TestBootCtxCloseAllIsReverseOrder` → 实际是
  `TestKernelStateCloseAllIsReverseOrder`(`BootCtx` 改名时判据跟着改的)
- `TestNilTypedBusSafety` → 标注为"规划名,仓库中不存在"

## 新增 §2.7.5 模块产物的实例化粒度

依赖图保证"设施已就绪",但没说该有几个实例 —— 这是独立决策。
记下 security 的两个答案:全局基线共享(否则插件声明对部分 agent 不生效)、
轮次状态 per-agent。并给出给未来新模块的两条判断标准。

## 安全文档

状态头补「架构形态」段(防火墙定位、per-agent 视图、两层档位);
接线状态表里 `ActivateProfile` 从 🔴 改为 ✅(2026-10-31 接通)。

## README

文档列表加索引与 future-plan 入口 —— 此前从 README 找不到 docs/zh 的任何指引。

## 核对

- docs/zh 32 篇全部有状态行
- 索引里列的文档全部存在,无遗漏
- 分类与各文档自述一致(逐篇抽查)
- go build 仍通过(纯文档改动)
2026-10-31 07:50:58 +08:00

204 lines
6.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 内核性能指标(实测基线)
> **状态:实测基线。** 数据来自标注的日期/版本;引用前先确认它是否仍对应当前版本。
本文记录**实测**数据,不是估算。每条都标出测量方法与采集时间,
便于复现与追回归。
> 采集环境:`main` @ `ecffb8a`,Linux amd64,Go 1.27.1,
> 生产实例 `/home/newqqagent`(21.4GB 数据目录),
> 22 个外部插件 + 5 层 / 17 模块内核。
> 采集时间:2026-10-18 18:12(冷启动)。
---
## 1. 冷启动
`systemctl restart homeagent` → `内核装配完成`。
| 阶段 | 时刻 | 累计 | 说明 |
| --- | --- | --- | --- |
| 启动 | 18:12:15 | 0s | 依赖图加载(`depgraph.bin`,digest `2067c913`) |
| 第 0 层完成 | 18:12:15 | ~0.1s | 2 个:`config`, `kernel-api` |
| 第 1 层完成 | 18:12:18 | **3.1s** | 9 个:`doc-store`, `knowledge-migration`, `lua`, `memory`, `migration`, `multimodal`, `onnx-parser`, `supervisor`, `tracker` |
| 第 2 层完成 | 18:12:18 | 3.2s | 3 个:`knowledge-store`, `llm`, `text-memory` |
| 第 3 层完成 | 18:12:18 | 3.3s | 1 个:`stage-host` |
| 第 4 层完成 | 18:12:20 | **5.5s** | 2 个:`agent`, `plugin-host` |
| 装配完成 | 18:12:30 | **15.4s** | 含 22 个外部插件建链 |
峰值并发 4(原为 17 步串行)。
### 耗时分布
```text
第 0→1 层 3.1s ████████████████ 20% 内存/ONNX/文档存储初始化
第 1→4 层 2.4s ████████████ 16% LLM/知识库/agent 装配
第 4→完成 9.9s ████████████████ 64% 22 个插件子进程建链
```text
**结论**:启动时间主要由**插件建链**决定(64%),不是内核模块本身。
每多一个 proc 插件约 +0.45s。
> ⚠️ 与早期记录(1538–1709ms)的差异:那是**纯内核**(5 层 17 模块)
> 的装配时间,不含插件。两者口径不同,不要混用。
### 复现
```bash
systemctl restart homeagent
journalctl -u homeagent --since "1 min ago" \
| grep -E "启动顺序来自|第 [0-9] 层完成|内核装配完成"
```text
---
## 2. 资源占用
稳态(启动完成、空闲):
| 指标 | 值 |
| --- | --- |
| 内核 RSS | **26 MB** |
| 内核 VSZ | 2104 MB(含 Go 保留地址空间,非常驻) |
| 插件子进程数 | 12(其余按需加载) |
| 二进制体积 | 84 MB(未 strip,含 debug_info) |
> 12 而非 22:13 个插件声明了 `auto_start: false`(按需加载),
> 只有被 `plugin_enable` 拉起时才起进程。
---
## 3. 超时与容量
这些是**硬约束**,决定"一个任务最多能占用多久"。
### 工具超时(三层)
| 层 | 值 | 位置 |
| --- | --- | --- |
| `cmd_run` 自身 ctx | 默认 **30s**,可由参数调 | `internal/plugins/cmd/plugin.go` |
| 内核工具等待 | `max(声明值, 参数值)` | `internal/agent/core/toolcall.go:37` |
| 硬上限 | **10m** | `toolcall.go:28` `maxToolTimeout` |
计算规则(`resolveToolTimeout`):
```text
base = 60s(默认)
↓ 若 ToolDef 声明了 Timeout
base = 声明值
↓ 若调用参数带 timeout 且 > base
base = 参数值
↓ 若 base > 10m
base = 10m
```text
**实测验证**:
```text
cmd_run command="sleep 200"(不传 timeout)
→ 工具 cmd_run 失败: 命令执行超时(30s)
```text
⚠️ **参数可以合法绕过默认值**:模型传 `timeout="2m"` 时,
`cmd_run` 的 30s 保护被提高到 2 分钟。这是设计允许的(长命令确有需要),
但也意味着**单个工具最长可占用 10 分钟**,期间调度器只能等。
### 上下文预算
运行时日志(`task.go:599`):
```text
tool call loop start, max_ctx=1048576 target=600000 fixed=3004 mem=198998 ctx=397
```text
| 项 | 值 | 含义 |
| --- | --- | --- |
| `max_ctx` | 1048576 | 模型上下文上限(1M) |
| `target` | 600000 | 目标使用量(60 万,留 40% 余量) |
| `fixed` | 3004 | 固定开销(system prompt 等) |
| `mem` | 198998 | 记忆注入占用 |
| `ctx` | 397 | 当前对话占用 |
### 记住-遗忘阈值
| 键 | 值 | 说明 |
|---|---|---|
| `core.agent.offload_busy_after` | **1m** | 忙超过此时长则转投 offload 子 agent |
---
## 4. 安全层开销
| 项 | 值 |
| --- | --- |
| 密钥来源 | `embedded`(构建期注入,指纹 `0db8e9c5`) |
| 变量条数 | 8 |
| 加密算法 | AES-GCM(`enc:v1:` 前缀) |
| 出向/入向扫描 | 每次工具调用与工具返回各一次(`security.Patterns`) |
| 日志脱敏 | `scrubForLog`(幂等,nil-store 安全) |
扫描是**纯内存正则匹配**,未观测到成为瓶颈(工具调用耗时由工具本身主导)。
---
## 5. 插件建链
| 指标 | 值 |
| --- | --- |
| 建链数(本次启动) | 11 |
| `loaded` 事件 | 28 |
| 单插件建链均摊 | ~0.45s(9.9s / 22) |
协议版本:`sdk=1.4.0 core=1.4.0`。
---
## 6. 已知的性能陷阱
以下都是**实测踩过**的,不是理论风险。
### 6.1 长工具执行期间 `stop` 无法生效
`stop` 请求只在 `pre_action` 被消费:
```text
[agent] stop requested by webui (queued=1 will be short-circuited at pre-action)
```text
若 agent 正卡在 `sleep 150` 这类长命令里,**没有 pre_action 可以插入** ⇒
停止按钮要等到当前工具跑完才生效。
现场(2026-10-18):`task#3` 跑了 10 分钟,期间 `task#4`~`task#8`
全部堵在队列,两次 stop 请求都无效,最后只能重启。
### 6.2 同阶段重复注册 = 静默覆盖
插件侧 `stageHandlers` 是 `map[阶段名]handler`,同阶段注册两次后者覆盖前者。
除了功能丢失,还意味着**权限门可能被覆盖掉**。hmapdev 在构建期告警。
### 6.3 `before_output` 有两条触发路径
一轮结束 vs 单次 `output_send__`。误用会让"正在输入"漏触发,
或让状态归位过于频繁(干活期间反复跳回空闲)。
详见 SDK README「阶段钩子」一节。
---
## 7. 复现与回归
```bash
# 冷启动
systemctl restart homeagent && sleep 20
journalctl -u homeagent --since "1 min ago" | grep "内核装配完成"
# 资源
ps -o rss= -p $(pgrep -f "homed" | head -1) | awk '{printf "RSS: %.0f MB\n", $1/1024}'
# 插件进程
pgrep -c -f "plugin.bin"
# 工具超时(应 30s 失败)
# 经 agent 调:cmd_run command="sleep 200"
```text