# 技术实现层（v2.1.2）

> **版本**：v2.1.2

> **原章节**：SKILL.md §6
> **主题**：MCP评估、环境预检、心跳监控、可靠性设计、变现执行

---

## 导航

- 📄 **返回SKILL.md主文档**：[FBS-BookWriter](../../SKILL.md)
- 📄 **相关文档**：[§3工作流](./section-3-workflow.full.md)

---

## 6.2 MCP扩展评估

| MCP类型 | 可行性 | 说明 |
|---------|--------|------|
| 知识库MCP | ✅ 可用 | 直接调用RAG_search工具，无需额外配置 |
| 文件操作MCP | ⚠️ 需配置 | 需修改宿主 MCP 配置文件（WorkBuddy 示例：`~/.workbuddy/mcp.json`），v2.0.1暂不集成 |


**2.0.1策略**：预留接口，标注「待扩展」占位符。

---

## 6.3 环境预检协议

每个阶段开始前自动执行环境预检，确保所需能力可用。

**CLI（复盘 P0）**：`node scripts/env-preflight.mjs`（Node 版本、Windows 下 `powershell -File` 变量探针；**禁止**依赖 `powershell -Command` 内联 `$变量`，宿主可能先吃掉 `$`）。

### 预检清单

| 检查项 | 验证方式 | 失败处理 |
|--------|----------|----------|
| Node.js | `node -v` / env-preflight | 无法运行脚本时中止并提示安装 |
| PowerShell（Windows） | **仅** `-File` 调用 `.ps1`；勿用 `-Command` 传 `$` | 字数/词频改用 `node` 脚本 |
| 联网能力 | 执行一次test搜索 | 降级为本地知识库 |
| Mermaid CDN | 检测unpkg/jsdelivr连通性 | 使用本地mermaid.js |
| 文件系统 | 测试写入权限 | 提示权限问题 |
| Task并行 | 检测team_create可用性 | 降级为串行执行 |
| 团队通信 | 检测send_message可用性 | 单Agent模式，禁用多成员协作 |
| 心跳机制 | 验证心跳发送/接收通道 | 降级为单Agent串行执行 |

### 6.3.1 工具不可用时的降级（禁止心算字数）

| 能力 | 优先 | 降级 | **禁止** |
|------|------|------|----------|
| 字数/字符统计 | `node` 读文件 + `length` / `expansion-word-verify` | 宿主 `read_file` 后人工点数 | 仅报模型估算字数 |
| 快速扫描 | `powershell -File scripts/quick-scan.ps1` | `node scripts/quality-auditor.mjs` | `powershell -Command` 内联含 `$` 的命令 |
| 章节合并 | `node scripts/merge-chapters.mjs` | 手工复制粘贴 | 依赖 bash 的 `$OUTPUT` 片段（Windows 常失败） |

### 预检执行时机

- S1开始前（定位阶段）
- S3开始前（写作阶段）
- S4开始前（审核阶段）

### 预检输出格式

```
🔍 环境预检
  联网搜索：✅ 可用
  Mermaid CDN：✅ unpkg可用
  文件写入：✅ 可用
  Task并行：✅ 可用
  团队通信：✅ 可用
  心跳机制：✅ 通道正常
  ✅ 环境就绪，开始执行
```

### 环境预检与心跳监控的协同关系

- 预检通过 → 启用完整心跳监控
- 预检失败但可降级 → 降级模式运行（串行/单Agent）
- 预检失败无法降级 → 中断执行，提示用户修复

---

## 6.4 心跳监控与关闭协议

### 6.4.1 心跳监控协议

**监控主体**：team-lead 是心跳监控的唯一主体。所有团队成员的心跳统一发送给team-lead，由team-lead汇总状态后向用户播报。

**心跳频率**：每60秒一次。

**心跳包格式**（JSON）：
```json
{
  "type": "heartbeat",
  "sender": "成员代号",
  "current_task": "当前执行的任务描述",
  "progress": 0-100,
  "status": "IDLE | WORKING | WAITING | COMPLETE",
  "timestamp": "2026-03-21T16:50:30Z"
}
```

**team-lead监控逻辑**：

| 场景 | 触发条件 | 执行动作 |
|------|---------|---------|
| 正常 | 按时收到心跳 | 更新成员状态记录 |
| 告警 | 120秒无心跳 | 发ambient notification告警给用户 |
| 异常 | 300秒无心跳 | 强制shutdown该成员，记录异常 |

**超时响应流程**：

```
首次告警（120秒无心跳）：
  → 向用户发送ambient notification
  → 内容："[成员]已超过120秒未更新状态，可能存在阻塞"

强制shutdown（300秒/10分钟无心跳）：
  → 调用shutdown_request到该成员
  → 记录异常到运行日志
  → 继续其他成员监控
```

**成员端职责**：
- 每个成员必须每60秒发送一次心跳
- 心跳内容应反映真实进度，不得虚假心跳
- 任务状态变化时立即发送状态变更通知

---

### 6.4.2 shutdown_response强制收齐协议

**原则**：team-lead调用shutdown时，必须等待**所有成员**返回shutdown_response后才执行team_delete。

**关闭流程**：

```
1. team-lead发送shutdown_request到所有成员
2. 等待所有成员返回shutdown_response
3. 收齐后执行team_delete
4. 输出关闭报告
```

**超时重试机制**：

| 等待时长 | 处理方式 |
|----------|---------|
| 0~30秒 | 正常等待 |
| 30~60秒 | 重发shutdown_request |
| 60~120秒 | 标记为强制关闭，跳过该成员 |
| >120秒 | 直接执行team_delete，记录异常 |

**异常处理**：

- 成员无响应：记录日志，继续关闭流程
- 部分成员失联：强制执行team_delete
- team_delete失败：提示用户手动清理

**完整关闭序列示例**：

```
team-lead: [shutdown] 准备关闭所有成员
  → shutdown_request → writer-1
  → shutdown_request → writer-2
  → shutdown_request → researcher-1

writer-1: [shutdown_response] 已完成当前任务，准备关闭
writer-2: [shutdown_response] 中止写作，保存进度
researcher-1: [shutdown_response] 研究完成，关闭

team-lead: 所有成员已确认关闭
  → 执行 team_delete
  → 输出：团队已安全关闭
```

---

### 6.4.3 多Agent协作通用规范

**团队创建**：

```
- team_create 在 S1-B 阶段（有并行研究需求时）
- 成员命名规范：{角色}-{序号}，如 researcher-1, writer-1
- 每个成员独立处理任务，通过send_message通信
```

**研究阶段心跳协议**（S1-B专用）：

```
研究成员心跳格式：
{
  "type": "heartbeat",
  "sender": "researcher-N",
  "current_task": "正在研究：[具体主题]",
  "progress": 当前完成百分比,
  "status": "WORKING",
  "findings": "本轮关键发现摘要（50字内）"
}

team-lead汇总播报（每120秒）：
📡 研究进度汇总
  researcher-1: [主题A] 60% - 找到N条有效资料
  researcher-2: [主题B] 40% - 正在交叉验证
  预计完成：约X分钟
```

---

## 6.5 可靠性设计原则（2026最佳实践）

**硬性限制**（防止Agent失控，**目标口径**）：

| 限制类型 | 阈值 | 触发动作 |
|----------|------|---------|
| 单次工具调用超时 | 30秒 | 重试1次，失败则降级 |
| 连续失败次数 | 3次 | 中断并报告 |
| 单Agent最大运行时长 | 4小时 | 自动保存进度，请求用户确认续行 |
| 内存使用 | >80% | 触发GC，必要时分批处理 |
| 文件写入大小 | 单次>10MB | 分批写入 |

**故障分类与响应策略**：

| 故障类型 | 严重程度 | 响应策略 |
|----------|---------|---------|
| 联网失败 | 中 | 降级本地知识库，继续执行 |
| 工具调用失败 | 中 | 重试+降级 |
| 成员失联 | 高 | 尝试重连，超时强制关闭 |
| 文件写入失败 | 高 | 立即停止，提示用户修复磁盘 |
| 状态机异常 | 严重 | 回滚到上一安全状态 |

**降级机制**：

```
降级层级（从优先到兜底）：
L1: 正常执行（所有能力可用）
L2: 禁用并行（team_create不可用时）
L3: 禁用联网（网络失败时，使用本地知识）
L4: 单章模式（大文件分批处理）
L5: 仅输出骨架（极端降级，保证交付）
```

**状态终端定义**：

| 终端状态 | 含义 | 后续动作 |
|---------|------|---------|
| DELIVER | 成功交付 | 归档，等待用户反馈 |
| ABORT | 主动中止 | 保存进度，提示恢复方式 |
| ERROR | 错误终止 | 输出错误报告，建议修复步骤 |
| TIMEOUT | 超时终止 | 保存已完成内容，提示续行 |

---

### 6.5.1 宿主侧联网、心跳与写盘（交付审核约束）

**联网约束**（宿主侧）：

```
规则：AI不能主动触发联网，联网调用须通过工具显式发起
合规操作：search_web("query")、fetch_url("url")
违规操作：在回复中直接引用"据XX网站最新数据..."（无工具调用记录）
审核要求：所有联网引用必须有对应工具调用记录
```

**心跳约束**（宿主侧）：

```
规则：心跳必须通过send_message工具显式发送
格式：严格遵守 §6.4.1 心跳包格式
频率：60秒/次，±10秒容差
违规：沉默超过120秒（无心跳、无进度更新）
```

**写盘约束**（宿主侧）：

```
规则：所有写盘操作必须通过write_to_file工具显式执行
禁止：在回复文本中声称"已写入"但无工具调用
验证：每次write_to_file后输出文件摘要（路径+行数+关键内容）
审核：delivery前检查所有write_to_file调用，确保文件确实存在
```

**交付前审核清单**：

```
☐ 所有联网引用均有工具调用记录
☐ 所有写盘操作均有write_to_file记录
☐ 文件确实存在（通过read_file或list_files验证）
☐ 心跳无断档（无120秒以上沉默）
☐ 状态机正确转移（无跳步）
```

---

## 代码索引

本节技术规范的关键代码实现位置：

| 规范 | 实现位置 | 说明 |
|------|---------|------|
| 心跳监控 | SKILL.md §6.4 | team-lead监控逻辑 |
| 环境预检 | SKILL.md §6.3 | 预检清单与触发时机 |
| 关闭协议 | SKILL.md §6.4.2 | shutdown_response收齐 |
| 降级机制 | SKILL.md §6.5 | L1~L5降级层级 |
| 交付审核 | SKILL.md §6.5.1 | 联网/心跳/写盘约束 |

---
