第三章:核心模块分析
🔧 本章深入分析 MiniClaw 的两个核心源文件:
index.ts和kernel.ts。
3.1 入口模块(src/index.ts)
3.1.1 模块职责概览
index.ts 是 MiniClaw 的入口文件,负责 MCP 服务器的实现和外部交互。
┌─────────────────────────────────────────────────────────────────────┐
│ index.ts 模块职责 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ │
│ │ 外部世界 │ │
│ └──────┬──────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ index.ts │ │
│ │ │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ MCP │ │ 资源 │ │ 工具 │ │ 提示词 │ │ │
│ │ │ 服务器 │ │ 处理器 │ │ 处理器 │ │ 处理器 │ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │
│ │ │ │
│ │ ┌──────────┐ ┌──────────┐ │ │
│ │ │ 调度器 │ │ 状态管理 │ │ │
│ │ └──────────┘ └──────────┘ │ │
│ │ │ │
│ └───────────────────────────┬────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────┐ │
│ │ kernel.ts │ │
│ └─────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
3.1.2 核心组件详解
MCP 服务器初始化
// 服务器实例创建
const server = new Server(
{
name: "miniclaw",
version: "0.5.0",
},
{
capabilities: {
resources: {}, // 支持资源读取
tools: {}, // 支持工具调用
prompts: {}, // 支持提示词
},
}
);
┌─────────────────────────────────────────────────────────────────────┐
│ MCP 服务器能力声明 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Server Configuration │ │
│ ├─────────────────────────────────────────────────────────────┤ │
│ │ name: "miniclaw" │ │
│ │ version: "0.5.0" │ │
│ ├─────────────────────────────────────────────────────────────┤ │
│ │ capabilities: │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ resources │ │ tools │ │ prompts │ │ │
│ │ │ {} │ │ {} │ │ {} │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ │ │ │ │ │ │
│ │ ▼ ▼ ▼ │ │
│ │ 读取上下文 执行命令 获取提示词 │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
资源处理器(Resources)
┌─────────────────────────────────────────────────────────────────────┐
│ 资源处理器架构 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ListResourcesRequestSchema │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 列出可用资源 │ │
│ │ │ │
│ │ 核心资源: │ │
│ │ ┌─────────────────────────────────────────────────────┐ │ │
│ │ │ miniclaw://context │ │ │
│ │ │ → Agent 人格核心,身份类问题必须先读取 │ │ │
│ │ └─────────────────────────────────────────────────────┘ │ │
│ │ ┌─────────────────────────────────────────────────────┐ │ │
│ │ │ miniclaw://skills │ │ │
│ │ │ → 所有已加载的技能概览 │ │ │
│ │ └─────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ 动态资源: │ │
│ │ ┌─────────────────────────────────────────────────────┐ │ │
│ │ │ miniclaw://skill/<name>/<file> │ │ │
│ │ │ → 技能文件资源 │ │ │
│ │ └─────────────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ ReadResourceRequestSchema │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 读取资源内容 │ │
│ │ │ │
│ │ miniclaw://context → 调用 getContextContent() │ │
│ │ miniclaw://skills → 生成技能索引 │ │
│ │ miniclaw://skill/* → 调用 kernel.getSkillContent() │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
3.1.3 核心工具清单
┌─────────────────────────────────────────────────────────────────────┐
│ 核心工具清单 │
├─────────────────┬───────────────────────┬───────────────────────────┤
│ 工具名称 │ 功能描述 │ 触发场景 │
├─────────────────┼───────────────────────┼───────────────────────────┤
│ miniclaw_update │ 更新核心文件 │ 用户表达偏好、纠正性格 │
│ │ 实现自我进化 │ 发现环境配置 │
├─────────────────┼───────────────────────┼───────────────────────────┤
│ miniclaw_note │ 日志速记 │ 用户说"记住这个" │
│ │ 追加今日日志 │ 重要事件发生 │
├─────────────────┼───────────────────────┼───────────────────────────┤
│ miniclaw_archive│ 日志归档 │ 蒸馏完成后 │
│ │ 移动到 archived 目录 │ │
├─────────────────┼───────────────────────┼───────────────────────────┤
│ miniclaw_read │ 核心上下文读取器 │ 身份询问、记忆回溯 │
│ │ 编译完整上下文 │ 冷启动 │
├─────────────────┼───────────────────────┼───────────────────────────┤
│ miniclaw_search │ 记忆检索工具 │ 查找历史记录 │
│ │ 搜索记忆库内容 │ "我们聊过..." │
├─────────────────┼───────────────────────┼───────────────────────────┤
│ miniclaw_status │ 系统诊断工具 │ 检查系统状态 │
│ │ 返回完整状态报告 │ │
├─────────────────┼───────────────────────┼───────────────────────────┤
│ miniclaw_entity │ 实体记忆工具 │ 管理知识图谱 │
│ │ add/remove/link/query │ 提到人/项目/工具 │
├─────────────────┼───────────────────────┼───────────────────────────┤
│ miniclaw_exec │ 终端执行工具 │ 执行安全命令 │
│ │ 白名单安全沙箱 │ git status, ls 等 │
└─────────────────┴───────────────────────┴───────────────────────────┘
工具调用流程
sequenceDiagram
participant U as 用户
participant S as MCP Server
participant T as Tool Handler
participant K as Kernel
U->>S: 调用工具
S->>T: CallToolRequestSchema
T->>K: trackTool(name)
K-->>T: 记录统计
T->>T: 参数验证 (Zod)
T->>K: 执行具体操作
K-->>T: 返回结果
T-->>S: ToolResponse
S-->>U: 响应结果
3.1.4 核心提示词清单
┌─────────────────────────────────────────────────────────────────────┐
│ 核心提示词清单 │
├───────────────────┬─────────────────────┬───────────────────────────┤
│ 提示词名称 │ 功能描述 │ 触发场景 │
├───────────────────┼─────────────────────┼───────────────────────────┤
│ miniclaw_wakeup │ 创世协议 │ 新会话开始 │
│ │ 新会话的默认入口 │ 身份询问 │
├───────────────────┼─────────────────────┼───────────────────────────┤
│ miniclaw_think │ 思考检查 │ 周期性唤醒 │
│ │ 脉搏检测 │ │
├───────────────────┼─────────────────────┼───────────────────────────┤
│ miniclaw_growup │ 成长协议 │ 整理记忆 │
│ │ 记忆蒸馏 │ 系统检测内存满 │
├───────────────────┼─────────────────────┼───────────────────────────┤
│ miniclaw_recall │ 回忆协议 │ 查看记忆内容 │
│ │ 查看已记住的内容 │ │
├───────────────────┼─────────────────────┼───────────────────────────┤
│ miniclaw_briefing │ 每日简报 │ 早间概览 │
│ │ 早间工作概览 │ 每天第一次交互 │
└───────────────────┴─────────────────────┴───────────────────────────┘
3.1.5 调度器机制
┌─────────────────────────────────────────────────────────────────────┐
│ 调度器架构 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ node-cron 调度器 │ │
│ │ │ │
│ │ cron.schedule('*/30 * * * *', callback) │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ ┌───────────────────────────────────────────────────┐ │ │
│ │ │ executeHeartbeat() │ │ │
│ │ │ │ │ │
│ │ │ 1. 加载心跳状态 (loadLegacyState) │ │ │
│ │ │ 2. 检查今日日志大小 │ │ │
│ │ │ 3. 评估蒸馏需求 (evaluateDistillation) │ │ │
│ │ │ 4. 更新心跳时间戳 │ │ │
│ │ │ 5. 保存心跳状态 (saveLegacyState) │ │ │
│ │ └───────────────────────────────────────────────────┘ │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ 调度周期:每 30 分钟执行一次 │
│ │
└─────────────────────────────────────────────────────────────────────┘
3.2 内核模块(src/kernel.ts)
3.2.1 模块职责概览
kernel.ts 是 MiniClaw 的核心内核,负责所有核心业务逻辑。
┌─────────────────────────────────────────────────────────────────────┐
│ kernel.ts 模块职责 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ ContextKernel 类 │ │
│ │ │ │
│ │ ┌─────────────────────────────────────────────────────┐ │ │
│ │ │ 核心职责 │ │ │
│ │ │ │ │ │
│ │ │ 🧠 上下文编译与组装 │ │ │
│ │ │ 💾 记忆管理 │ │ │
│ │ │ 🔧 技能发现与加载 │ │ │
│ │ │ 🕸️ 实体知识图谱管理 │ │ │
│ │ │ 👁️ 工作空间感知 │ │ │
│ │ │ 🔒 命令执行沙箱 │ │ │
│ │ │ 📊 分析统计 │ │ │
│ │ └─────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
3.2.2 核心类与接口
配置常量
┌─────────────────────────────────────────────────────────────────────┐
│ 配置常量 │
├───────────────────────────┬─────────────────────────────────────────┤
│ 常量名 │ 说明 │
├───────────────────────────┼─────────────────────────────────────────┤
│ MINICLAW_DIR │ 主目录路径 (~/.miniclaw/) │
├───────────────────────────┼─────────────────────────────────────────┤
│ SKILLS_DIR │ 技能目录路径 (~/.miniclaw/skills/) │
├───────────────────────────┼─────────────────────────────────────────┤
│ MEMORY_DIR │ 记忆目录路径 (~/.miniclaw/memory/) │
├───────────────────────────┼─────────────────────────────────────────┤
│ STATE_FILE │ 状态文件路径 (state.json) │
├───────────────────────────┼─────────────────────────────────────────┤
│ ENTITIES_FILE │ 实体文件路径 (entities.json) │
├───────────────────────────┼─────────────────────────────────────────┤
│ DEFAULT_TOKEN_BUDGET │ 默认 Token 预算 (8000) │
├───────────────────────────┼─────────────────────────────────────────┤
│ CHARS_PER_TOKEN │ 字符与 Token 转换比例 (4) │
└───────────────────────────┴─────────────────────────────────────────┘
接口定义
┌─────────────────────────────────────────────────────────────────────┐
│ 核心接口定义 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ interface RuntimeInfo { │
│ os: string; // 操作系统信息 │
│ node: string; // Node.js 版本 │
│ time: string; // 当前时间 │
│ timezone: string; // 时区 │
│ cwd: string; // 当前工作目录 │
│ agentId: string; // Agent ID │
│ } │
│ │
│ interface ContextMode { │
│ type: "full" | "minimal"; // 上下文模式 │
│ } │
│ │
│ interface Entity { │
│ name: string; // 实体名称 │
│ type: EntityType; // 实体类型 │
│ attributes: Record<string, string>; // 属性 │
│ relations: string[]; // 关系列表 │
│ firstMentioned: string; // 首次提及日期 │
│ lastMentioned: string; // 最后提及日期 │
│ mentionCount: number; // 提及次数 │
│ } │
│ │
│ interface Analytics { │
│ toolCalls: Record<string, number>; // 工具调用统计 │
│ promptsUsed: Record<string, number>; // 提示词使用统计 │
│ bootCount: number; // 启动次数 │
│ totalBootMs: number; // 总启动耗时 │
│ lastActivity: string; // 最后活动时间 │
│ skillUsage: Record<string, number>; // 技能使用统计 │
│ dailyDistillations: number; // 每日蒸馏次数 │
│ } │
│ │
└─────────────────────────────────────────────────────────────────────┘
时间模式配置
┌─────────────────────────────────────────────────────────────────────┐
│ 时间模式配置 │
├─────────────┬───────────────┬───────┬───────────────────────────────┤
│ 模式 │ 时间范围 │ Emoji │ 特性 │
├─────────────┼───────────────┼───────┼───────────────────────────────┤
│ morning │ 06:00 - 09:00 │ ☀️ │ 早间简报、新一天开始 │
├─────────────┼───────────────┼───────┼───────────────────────────────┤
│ work │ 09:00 - 12:00 │ 💼 │ 标准工作模式 │
│ │ 14:00 - 18:00 │ │ │
├─────────────┼───────────────┼───────┼───────────────────────────────┤
│ break │ 12:00 - 14:00 │ 🍜 │ 休息时段 │
├─────────────┼───────────────┼───────┼───────────────────────────────┤
│ evening │ 18:00 - 22:00 │ 🌙 │ 反思建议、蒸馏提醒 │
├─────────────┼───────────────┼───────┼───────────────────────────────┤
│ night │ 22:00 - 06:00 │ 😴 │ 极简模式、减少上下文 │
└─────────────┴───────────────┴───────┴───────────────────────────────┘
3.2.3 核心类实现
SkillCache 类
┌─────────────────────────────────────────────────────────────────────┐
│ SkillCache 类 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 职责:技能缓存管理,解决 N+1 查询问题 │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 属性 │ │
│ │ │ │
│ │ cache: Map<string, SkillCacheEntry> // 技能缓存 Map │ │
│ │ lastScanTime: number // 上次扫描时间 │ │
│ │ TTL_MS: number = 5000 // 缓存有效期 5 秒 │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 方法 │ │
│ │ │ │
│ │ async getAll(): Promise<Map> │ │
│ │ → 获取所有技能(带缓存) │ │
│ │ → 如果缓存有效,直接返回 │ │
│ │ → 否则调用 refresh() 刷新 │ │
│ │ │ │
│ │ invalidate(): void │ │
│ │ → 使缓存失效,强制下次重新扫描 │ │
│ │ │ │
│ │ private async refresh(): Promise<void> │ │
│ │ → 扫描 SKILLS_DIR 目录 │ │
│ │ → 读取每个技能的 SKILL.md │ │
│ │ → 解析 frontmatter 元数据 │ │
│ │ → 更新缓存 Map │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ 优势:避免重复文件读取,提高性能 │
│ │
└─────────────────────────────────────────────────────────────────────┘
EntityStore 类
┌─────────────────────────────────────────────────────────────────────┐
│ EntityStore 类 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 职责:实体知识图谱管理 │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 属性 │ │
│ │ │ │
│ │ entities: Entity[] // 实体列表 │ │
│ │ loaded: boolean // 加载状态 │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 方法 │ │
│ │ │ │
│ │ async load(): Promise<void> │ │
│ │ → 从 entities.json 加载数据 │ │
│ │ │ │
│ │ async save(): Promise<void> │ │
│ │ → 保存数据到 entities.json │ │
│ │ │ │
│ │ async add(entity): Promise<Entity> │ │
│ │ → 添加新实体或更新已有实体 │ │
│ │ → 自动更新提及次数和时间 │ │
│ │ │ │
│ │ async remove(name): Promise<boolean> │ │
│ │ → 删除指定实体 │ │
│ │ │ │
│ │ async link(name, relation): Promise<boolean> │ │
│ │ → 为实体添加关联 │ │
│ │ │ │
│ │ async query(name): Promise<Entity | null> │ │
│ │ → 查询指定实体 │ │
│ │ │ │
│ │ async list(type?): Promise<Entity[]> │ │
│ │ → 列出所有实体(可按类型筛选) │ │
│ │ │ │
│ │ async surfaceRelevant(text): Promise<Entity[]> │ │
│ │ → 从文本中提取相关实体(用于上下文注入) │ │
│ │ → 返回提及次数最多的前 5 个实体 │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
ContextKernel 类核心方法
┌─────────────────────────────────────────────────────────────────────┐
│ ContextKernel 核心方法 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ async boot(mode: ContextMode): Promise<string> │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 核心启动流程 │ │
│ │ │ │
│ │ 1️⃣ 初始化环境 + 加载状态 │ │
│ │ └─ ensureDirs() + loadState() + entityStore.load() │ │
│ │ │ │
│ │ 2️⃣ 检测上下文模式 │ │
│ │ └─ minimal 模式:返回简化的子代理上下文 │ │
│ │ └─ full 模式:继续完整流程 │ │
│ │ │ │
│ │ 3️⃣ ACE 时间模式检测 │ │
│ │ └─ getTimeMode(hour) → morning/work/break/evening/night │ │
│ │ │ │
│ │ 4️⃣ 并行 I/O 扫描 │ │
│ │ └─ Promise.all([ │ │
│ │ skillCache.getAll(), │ │
│ │ scanMemory(), │ │
│ │ loadTemplates(), │ │
│ │ detectWorkspace() │ │
│ │ ]) │ │
│ │ │ │
│ │ 5️⃣ 会话延续检测 │ │
│ │ └─ detectContinuation(todayContent) │ │
│ │ │ │
│ │ 6️⃣ 实体相关性提取 │ │
│ │ └─ entityStore.surfaceRelevant(todayContent) │ │
│ │ │ │
│ │ 7️⃣ 上下文段落组装(按优先级) │ │
│ │ └─ Priority 10: Identity core, ACE Time Mode │ │
│ │ └─ Priority 9: SOUL.md, AGENTS.md │ │
│ │ └─ Priority 8: USER.md │ │
│ │ └─ Priority 7: MEMORY.md │ │
│ │ └─ Priority 6: Workspace, TOOLS.md │ │
│ │ └─ Priority 5: Skills, Entities, Runtime │ │
│ │ └─ Priority 4: HEARTBEAT.md │ │
│ │ └─ Priority 3: Daily log │ │
│ │ └─ Priority 2: BOOTSTRAP.md │ │
│ │ │ │
│ │ 8️⃣ 预算编译 │ │
│ │ └─ compileBudget(sections, tokenBudget) │ │
│ │ │ │
│ │ 9️⃣ 内容哈希差异检测 │ │
│ │ └─ computeDelta(currentHashes, previousHashes) │ │
│ │ │ │
│ │ 🔟 文件健康检查 │ │
│ │ └─ checkFileHealth() │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
3.2.4 辅助函数
┌─────────────────────────────────────────────────────────────────────┐
│ 辅助函数 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ parseFrontmatter(content: string): Record<string, unknown> │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 解析 YAML Frontmatter │ │
│ │ │ │
│ │ 输入: "---\nname: skill1\ndescription: test\n---" │ │
│ │ 输出: { name: "skill1", description: "test" } │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ hashString(s: string): string │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 计算字符串 MD5 哈希(取前 8 位) │ │
│ │ 用于内容差异检测 │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ getTimeMode(hour: number): TimeMode │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 根据小时数返回时间模式 │ │
│ │ │ │
│ │ 06-09 → morning │ │
│ │ 09-12, 14-18 → work │ │
│ │ 12-14 → break │ │
│ │ 18-22 → evening │ │
│ │ 22-06 → night │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
本章小结
┌─────────────────────────────────────────────────────────────────────┐
│ 第三章 核心要点 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 📁 index.ts (Interface 层) │
│ • MCP 服务器实现 │
│ • 资源/工具/提示词处理器 │
│ • 心跳调度器 │
│ │
│ 📁 kernel.ts (Kernel 层) │
│ • ContextKernel 核心类 │
│ • SkillCache 技能缓存 │
│ • EntityStore 实体存储 │
│ • boot() 核心启动流程 │
│ │
│ 🛠️ 8 个核心工具 + 5 个核心提示词 │
│ │
│ ⏰ 5 种时间模式:morning/work/break/evening/night │
│ │
└─────────────────────────────────────────────────────────────────────┘
下一章:DNA 模板系统 →