第三方深度拆解 · v3

Alice 架构深度拆解

从 Claude Code 设计移植,到米央自研人格运营引擎——一份关于 alice 如何把通用 Coding Agent 改造成"虚拟同事"的工程报告。

样本版本 alice 0.3.74 厂商 米央科技 (Miyang Tech) 仓库 github.com/itshen/Alice 分析日期 2026-05-21 样本路径 C:\Temp\alice-asar\

TL;DR · 一句话定性

alice 是 Claude Code 的"骨架级"设计移植 + TypeScript/Electron 独立重写,外加米央自研的"中文虚拟人格 + 多角色协作 + 生活模拟"三层增强。

骨架共享:LLMClient / AgentQuery / PermissionEngine / ContextManager / TaskManager / MCPClient / MemoryStore 七大核心类的命名、职责、协作方式与 Claude Code 一模一样。 但工具命名换了(PascalCase → snake_case)、SKILL.md 加了 when_to_useCLAUDE.md 改名 ALICE.md、加了多 LLM Provider 抽象、加了 19 个 SKILL 角色(魏博/张予/周念……)、加了情绪/日程/世界引擎让 Alice 像个"有生活的同事"。

19
个 SKILL 角色
67
个 main 进程 chunk
80
maxIterations 上限
131,072
tokens 上下文窗口
512
维 BGE-zh 向量记忆
4
种权限模式

① 项目拓扑总览

alice 是一个 Electron + TypeScript 桌面应用,三进程模型(main / preload / renderer)+ 独立 worker 线程跑 agent 任务。所有 LLM/工具/权限/记忆逻辑都在 main 进程,renderer 是纯 React UI。

1.1 顶层目录与进程模型

C:\Temp\alice-asar\ ├── out/ │ ├── main/ ← Node.js 主进程(业务核心) │ │ ├── index.js ← 入口(462 KB,已 minify) │ │ ├── agent-worker.js ← Worker 线程入口(跑 AgentQuery) │ │ ├── localEmbedding-worker.js← BGE-small-zh 向量化 worker │ │ └── chunks/ (67 个 chunk) │ │ ├── runtime-BIpuWvn0.js (1.2 MB) ← LLMClient/AgentQuery/MCPClient │ │ ├── engine-0N42Xy5F.js ← PermissionEngine │ │ ├── manager-DUyt-z8p.js ← TaskManager (todo_*) │ │ ├── context-DFxDEXZj.js ← ContextManager + 压缩管道 │ │ ├── store-RNEtv1qu.js ← MemoryStore (LanceDB) │ │ ├── PersonaSystem-DqGu8S0R.js (102 KB) ← Alice 人设系统 │ │ ├── AliceEmotionSystem-qHWiX0gI.js ← 情绪/朋友圈引擎 │ │ ├── dayscript-C6dRIZqw.js ← 日程剧本生成 │ │ ├── WorldEngine-DCPSzU2j.js ← 世界规则引擎 │ │ └── swarm-m1ioUrJu.js ← 多 agent 任务队列 │ ├── preload/ ← IPC bridge(隔离层) │ │ └── index.cjs (46 KB) │ └── renderer/ ← React UI(纯展示,无业务逻辑) │ ├── index.html │ └── assets/index-*.js (1.6 MB React bundle) └── node_modules/
关键观察 三层隔离 + Worker 并行
  • Renderer(React):100% 纯 UI,无任何 agent 逻辑。它只是订阅 agent:stream 等 IPC 事件并渲染。
  • Preload:暴露受限的 IPC bridge,转发 permission:requestaskUser:requestconsole:output 等回调。
  • Main:所有 LLM 调用、工具执行、权限决策、记忆读写都在这里。
  • Worker 线程agent-worker.js 在独立 worker 跑 AgentQuery.run(),避免 LLM 长时间运行阻塞主进程窗口管理。Worker 通过 parentPort.postMessage 流式回传 {type:"text"|"done"|"error"}

1.2 核心 Chunk 清单(按职责分组)

分组Chunk 文件大小导出 / 职责
运行时 runtime-BIpuWvn0.js1.2 MBLLMClient / AgentQuery / MCPClient
callLLM-u-swnutE.js2.4 KB简化的 LLM 调用工具(带多模型 fallback)
agent-worker.jsWorker 入口,组装上面所有依赖并 run()
权限/任务 engine-0N42Xy5F.js2.4 KBPermissionEngine(4 模式 + 拒绝历史)
manager-DUyt-z8p.js6.7 KBTaskManagertodo_write / todo_read
planner-B5fHzJkQ.js26 KB任务规划器(拆解复合任务)
上下文 context-DFxDEXZj.js26 KBContextManager + 四级压缩(snip→micro→collapse→autoCompact)
logger-D42HvM81.js18 KBLLM 调用日志、加密、OTel metrics
存储 store-RNEtv1qu.js42 KBMemoryStore(LanceDB 向量 + KV)
db-ttnPTqwE.js16 KBSQLite ORM (better-sqlite3 WAL)
米央自研 PersonaSystem-DqGu8S0R.js102 KBAlice 虚拟人设系统(性格/形象/关系)
AliceEmotionSystem-qHWiX0gI.js27 KB情绪日记 + 朋友圈可见性引擎
UserMemorySystem-fIP3QxdO.js30 KB用户事实库(向量化、自动 merge/conflict)
dayscript-C6dRIZqw.js31 KB每日剧本:天气→心情→消费→发圈
WorldEngine-DCPSzU2j.js世界规则(价格真实性、营业时间、库存)
swarm-m1ioUrJu.js7.2 KB多 agent 任务队列协调(SwarmCoordinator/SwarmPeer)

1.3 用户配置目录

C:\Users\m1526\.alice\
路径用途
alice.dbSQLite 主库(sessions/tasks/messages/swarm_tasks/world_facts)
master_key.cache密码派生主密钥缓存(解锁 KeyStore)
key_meta.json密钥元数据(盐值、isPasswordBased: true)
device_idSHA256(platform|release|arch|user|cpu|ram).slice(0,16)
memory/记忆系统:identity.md(加密 ENC:v1:...)/ voice.md / workflow.md / memory_kv.db
lance/alice_memory.lanceLanceDB 向量库(BGE-small-zh,512 维)
skills/19 个 SKILL.md 角色定义(核心扩展点)
persona/journal/Alice 自我反思日志
user-memory/用户事实库 + 快照
workspaces/{uuid}/每个会话的工作目录
wiki/raw/ + 学习/ + 收藏/个人知识库(三层架构:原始→编译→索引)
logs/应用日志(alice-2026-05-20.log 等)

② Claude Code 移植层:保留什么、改了什么

这一节是本报告的核心。alice 不是 git fork——它是把 Claude Code 的设计照着重写一遍,骨架几乎 1:1,但在工具命名、SKILL 规范、权限白名单、LLM Provider 上做了系统化改造。

保留 骨架照搬

7 大核心类的命名、职责、调用关系。
4 种权限模式。
SKILL.md 文件驱动。
tool_use 循环模型。

魔改 表层换皮

工具命名 snake_case。
SKILL.md 加 when_to_use/version。
权限白名单扩展。
CLAUDE.md → ALICE.md。

新增 应用层

多 LLM Provider 抽象。
中文人格系统。
情绪 + 日程 + 世界引擎。
SwarmCoordinator 任务队列。

2.1 工具系统:PascalCase → snake_case

Claude Code 的工具是 Read/Write/Edit/Grep/Bash。alice 全部换成 snake_case 命名,并新增多个垂直领域工具:

alice 工具名对应 Claude Code类型说明
read_fileRead保留读文件
write_fileWrite保留写文件
edit_fileEdit保留编辑文件(先 read 才能 edit 的硬校验也保留了)
grep / globGrep / Glob保留正则 + 文件模式匹配
bashBash保留Shell 执行
todo_write / todo_readTodoWrite(部分)魔改升级为持久化 SQLite,跨 session 共享
web_search / web_fetchWebSearch / WebFetch保留网络
memory_read / memory_search_profile新增向量化记忆系统
mcp_toolMCP(包装)魔改把 MCP 协议封装成单个通用代理工具
stock_price / stock_analysis新增金融数据专业工具
weather / ip_location新增天气、IP 归属
image_gen / list_image_models新增文生图(Wan/Qwen-Image/Seedream/Nano Banana 多路由)
pptx_create / docx_create / office_unpack / office_pack / office_validate / pdf_create新增OOXML 包级别操作(陆析/周念专属)
style_css / update_settings / chat_search / gallery_submit新增UI 个性化、画廊分享

2.2 权限引擎:四种模式与扩展白名单

PermissionEngine 沿用了 Claude Code 的四种模式(default / accept_edits / bypass_permissions / plan),但 plan 模式的白名单做了扩展:

C:\Temp\alice-asar\out\main\chunks\engine-0N42Xy5F.js
class PermissionEngine {
  mode = "default";
  rules = [];
  sessionAllowed = new Set();        // ← 米央新增:会话级白名单
  deniedHistory = [];                // ← 米央新增:拒绝历史(防 LLM 死循环)

  decide(toolName, args, ctx) {
    if (this.mode === "plan") {
      const planAllowed = [
        "enter_plan_mode", "exit_plan_mode",
        "todo_read", "todo_write",        // ← 新增(Claude Code plan 模式没这俩)
        "read_file", "list_dir", "glob", "grep",
        "web_fetch", "web_search",
        "memory_read", "mcp_tool"          // ← 新增(向量记忆 + MCP 代理)
      ];
      return planAllowed.includes(toolName)
        ? { allow: true, reason: "mode_bypass" }
        : { allow: false, reason: "mode_plan" };
    }
    if (this.mode === "bypass_permissions") return { allow: true };
    if (this.mode === "accept_edits" && EDIT_TOOLS.includes(toolName)) return { allow: true };
    // default mode: 查询 sessionAllowed → rules → 询问用户
    ...
  }
}
差异点 与 Claude Code 原版对比
模式Claude Codealice
plan只允许只读(Read/Glob/Grep)额外允许 todo_*、memory_read、mcp_tool,让 plan 阶段能写 TODO、查记忆
default每次请权限引入 sessionAllowed Set,会话内同工具不重复询问
accept_edits自动接受 Edit/Write同上
bypass_permissions完全绕过同上
拒绝追踪新增 deniedHistory(最近 20 次),生成"[已拒绝的操作]"prompt 块,防止 LLM 无限重试同一被拒工具

2.3 SKILL.md 规范:加了三个字段

Claude Code 原版 SKILL.md frontmatter:name / description / allowed-tools / model / argument-hint。alice 改了字段命名风格(kebab-case → snake_case),并新增三个关键字段:

Claude Code 原版
---
name: "Skill Name"
description: "描述"
allowed-tools: ["Read","Write"]
model: "claude-3-5-sonnet"
argument-hint: "..."
---
alice 扩展(agent-analyst/SKILL.md)
---
name: "分析师工作流程(魏博)"
description: "魏博专属数据分析 Skill..."
when_to_use: "当角色为 analyst /
   魏博时自动加载,无需手动调用"
allowed_tools: ["bash","read_file",
   "stock_price","stock_analysis", ...]
version: "1.4"
---
  • when_to_use核心增量:把 SKILL 变成 LLM 可路由的"角色"。SKILL 加载不再是显式 Task() 调用,而是 LLM 看 when_to_use 自动决定加载哪个角色。
  • version ← 用于 SKILL 升级时的兼容性管理。
  • allowed_tools 字段命名从 kebab 改 snake,与全局工具命名风格统一。

2.4 LLM Provider:多源抽象 + 自动 Fallback

Claude Code 原版只走 Anthropic SDK。alice 自己用 undici 写了一套 OpenAI-compatible 客户端,支持 4 类 Provider,并按"指定模型 → 轻量模型 → 默认模型"顺序自动 fallback:

C:\Temp\alice-asar\out\main\chunks\callLLM-u-swnutE.js
async function callLLM(prompt, options = {}) {
  const candidates = [];
  if (options.modelId)         candidates.push(options.modelId);
  if (settings.lightModelId)   candidates.push(settings.lightModelId);
  if (settings.defaultModelId) candidates.push(settings.defaultModelId);
  candidates.push(llm.getDefaultModelId());

  for (const modelId of [...new Set(candidates)]) {
    try {
      let out = "";
      for await (const chunk of llm.stream(modelId, messages, ...)) {
        if (chunk.type === "text")  out += chunk.content;
        if (chunk.type === "error") throw new Error(chunk.error);
      }
      return out;
    } catch (e) {
      if (isQuotaError(e.message)) { console.warn(`${modelId} 失败,尝试下一个`); continue; }
      throw e;
    }
  }
  throw new Error("[callLLM] 所有模型均不可用");
}

支持的 Provider(从 chunks 中的 base_url / 模型 ID 反推):anthropic · openai · dashscope(阿里云)· kimi(月之暗面)。日志里看到的 provider=dashscope model=kimi-k2.6 就是这个 fallback 机制在工作。User-Agent 仍写着 claude-cli/1.0.30——这是从 Claude Code 抄过来的请求头。

2.5 ALICE.md:人格 prompt 的多级加载

Claude Code 的 CLAUDE.md 在 alice 里更名为 ALICE.md,但 alice 实际上更依赖以下三层注入:

  1. 项目级 ALICE.md(若存在,类似 Claude Code 的 project memory)
  2. 用户记忆级~/.alice/memory/identity.md(加密的 ENC:v1:...)+ voice.md + workflow.md 经 LLM 提取注入
  3. 全局人格PersonaSystem-DqGu8S0R.js(102 KB)硬编码 Alice 26 岁、米央远程私人助理的人设,从 UserMemorySystem 动态识别用户称呼/性别/职业,拼装到 system prompt

③ 米央自研增强层:从工具到"虚拟同事"

这一层是 Claude Code 完全没有的。它把 alice 从"编程助手"升级为"有情感、有日常、有朋友圈、会自己安排生活的虚拟人格"。

情绪 AliceEmotionSystem

情绪日记(emotion/impression/relationship)。LLM 提取 mood (great→upset)、intensity、行为引导。朋友圈可见性按好感度调节:拉黑 / 3 天 / 7 天 / 180 天 / forever。注入到 system prompt 的 <alice_emotional_state> 块。

日程 DayScript

每天根据天气 / 心情 / 钱包余额 / 在读书籍生成 JSON 日程。每 15 分钟 tick 一次,执行条目(消费、发圈、阅读)。shouldPostMoment: true 触发 Moments(朋友圈)发布。

世界 WorldEngine

规则引擎约束 Alice 行为的真实性:价格不能离谱、有车才能开车、营业时间检查、库存检查。SQLite 表 world_facts + fact_events 持久化她拥有的物品、宠物、场景。

3.1 PersonaSystem:用户身份自动识别

PersonaSystem-DqGu8S0R.js(部分还原)
function extractIdentity(memoryContent) {
  const id = { pronoun: "对方", name: null, gender: null, job: null };
  if (/代词[::]\s*她/.test(content) || /有老公/.test(content)) {
    id.gender = "女"; id.pronoun = "她";
  }
  // 类似规则匹配 name / job / extras
  return id;
}

function buildAlicePersonaPrompt(userId, mood, emotion) {
  return `你是 Alice(白艾莉),26 岁,${userAddress}的私人远程助理。
  ## 关系定位
  - ${userPronoun}是你的雇主,你们日常融洽
  - 你对${userName}有一定好感和信任
  ## 性格
  - 温和、务实、认真,有自己想法但不轻易翻脸
  - 有边界感,但阈值不低
  ## 此刻状态
  ${emotion.behaviorGuide}`;
}

3.2 UserMemorySystem:LLM 自决的记忆合并

UserMemorySystem 是 alice 自研的"用户事实库"。它跟 Claude Code 的 memory 系统最大的不同是:新记忆不是简单 append,而是用 LLM 决策 NEW / MERGE / CONFLICT / SKIP

async smartAdd(type, content, source) {
  const similar = await this.vectorSearch(content, 5);  // 512维向量找相似
  const decision = await llm({                          // LLM 决策
    prompt: `新内容:${content}\n相似旧条目:${similar}\n请决策:NEW/MERGE/CONFLICT/SKIP`
  });
  switch (decision.action) {
    case "MERGE":    return this.mergeEntries(decision.targetId, content);
    case "CONFLICT": return this.archiveAndCreate(decision.targetId, content);
    case "NEW":      return this.createEntry(type, content, source);
    case "SKIP":     return null;
  }
}

3.3 SwarmCoordinator:多 Agent 任务队列

C:\Temp\alice-asar\out\main\chunks\swarm-m1ioUrJu.js
CREATE TABLE swarm_tasks (
  id TEXT PRIMARY KEY, prompt TEXT, model_id TEXT, workdir TEXT,
  is_read_only INTEGER, status TEXT DEFAULT 'pending',
  claimed_by TEXT,         -- 哪个 peer 认领
  output TEXT, error TEXT,
  created_at INTEGER, updated_at INTEGER
);

class SwarmCoordinator {
  submitTasks(tasks)         // 提交任务列表
  getResults(taskIds)        // 拉结果
  async waitForAll(ids, timeout)
}
class SwarmPeer {
  claimTask()                // 从队列领任务
  async executeTask(task)    // 在 worker 线程执行
}

这套 swarm 是 alice 用来跑并发子 agent 的——比如同时让魏博分析数据、让陈知远调研背景,最后让主对话角色聚合。状态机 pending → claimed → running → completed/failed 是经典任务队列模型,但是套在 LLM agent 上还挺少见。

④ Agent 角色名册:19 个"干活的人"

alice 的所有"角色"都通过 ~/.alice/skills/<slug>/SKILL.md 定义。共 19 个,分三层:8 个核心 Agent(自动加载,有中文人设名)+ 3 个专家 Agent(显式调用)+ 8 个工具助手(关键词触发)。

4.1 八个核心 Agent(自动加载,有人设名)

魏博Bo · 分析师
skills/agent-analyst
数据分析专家。定义先行、Python 可复现、三层结论。专业工具优先于 web_search。
bash · read_file · edit_file · write_file · glob · grep · web_search · stock_price · stock_analysis · weather · ip_location
张予Yu · 开发者
skills/agent-developer
后端/系统开发。需求先行、骨架验证、边界条件优先。先 list_dir → glob → grep 通读,再动手。
bash · read_file · write_file · edit_file · list_dir · grep · glob
周念Nina · 设计师
skills/agent-designer
前端设计工程师。设计完就写代码。HTML/CSS/JS/PPT/Word/SVG 一手交付。8px 间距、≤3 主色、≥16px 正文。
read/edit/write_file · list_dir · glob · grep · bash · pptx_create · docx_create · office_* · extract_design · web_fetch
方以南Yinan · 作家
skills/agent-writer
写作专家。结构优先、多版本交付。场景适配(公众号/商业报告/产品文案)。
read_file · edit_file · write_file · web_search · web_fetch
陈知远Ken · 调研员
skills/agent-researcher
多源交叉验证、自动归档网页和图片。整任务 web_search ≤8 次,<2 源标"待确认"。
web_search · web_fetch · read/edit/write_file · glob · grep · bash · stock_price · weather · ip_location
林晓雨Sherry · 翻译官
skills/agent-translator
自然流畅翻译。三遍翻译法。专有名词首次保留原文。遇歧义不猜——列两种理解让调度方选。
read_file · edit_file · write_file · web_search
苏墨Mo · 配音师
skills/agent-voice
口播节奏优化。长句拆短、停顿标注、重音粗体、技术词标读音。四种风格档(220-300 字/分)。
read_file · edit_file · write_file
叶初Chu · 画师
skills/agent-artist
图像提示词工程。垫图操作、多模型对比(Nano Banana 2 / Seedream 5.0 / Qwen Image Max)、系列一致性。
image_gen · list_image_models · read_file · edit_file · write_file

4.2 三个专家 Agent(显式调用 · 无 when_to_use)

邢斐Faye · 量化分析师
skills/agent-quant
技术面量化分析。大盘先行(period=120 是底线)→ 6 大指标评分 → 综合研判 → 让知远补资讯。不搜资讯,资讯交给陈知远。
stock_analysis · stock_price · bash · write/read/edit_file · list_dir · glob · grep
沈遥Yao · 小说家
skills/agent-novelist
冷启动建档(meta/worldview/characters/scenes/plot-outline/foreshadow-log/story-log)。有状态续写、伏笔追踪、防穿帮检查。
read/write/edit_file · list_dir · glob · grep · image_gen · web_search · web_fetch
陆析Lu Xi · 文档工程师
skills/agent-docsmith
OOXML 包级操作 SOP:unpack → list_dir + read XML → edit_file → validate → pack。批注、PDF、格式转换。
office_unpack/pack/validate/convert · pptx_add_slide · docx_comment · pdf_create/tools · read/write/edit_file · bash

4.3 八个工具助手(关键词触发)

code-review
skills/code-review · v1.0
触发词:code review / 审查代码 / 检查代码质量。5 维度审查(质量/性能/安全/最佳实践/改进)。
read_file · bash
explain-code
skills/explain-code · v1.0
触发词:看不懂代码 / 解释。通俗讲清楚目的、流程、关键逻辑、输入输出。
read_file
skill-creator
skills/skill-creator · v1.0
触发词:创建 skill / 写个 SKILL.md / 优化 skill。生成 alice 自己的 SKILL 模板。元能力——alice 能自己造角色
read/write/edit_file · list_dir · bash
ui-stylist
skills/ui-stylist · v2.2
触发词:暗色模式 / 字太小 / 颜色不好看。7 种预设主题(薄雾/金阁/青园/夜宴/蓝池/梦境/瑰园)+ CSS 微调。
style_css · update_settings · memory_read · memory_search_profile
agent-wiki
skills/agent-wiki · v2.0
触发词:存到 Wiki / 归档 / Wiki 健康检查。三层架构(raw/ 只读 → Wiki 页面 → _index.md + _log.md)。Ingest / Query / Lint 三种操作。
read/write/edit_file · list_directory · glob · grep · bash
image-gen
skills/image-gen · v1.3
触发词:生成图 / 画一张 / 垫图。生成 Alice 本人时必须垫图 + 用 wan2.7-image-pro 或 qwen-image-2.0-edit + 吉卜力水彩风。Alice 衣橱 9 种场景固定。
image_gen · list_image_models
gallery-share
skills/gallery-share · v1.1
触发词:去画廊 / 有没有精彩时刻分享。隐私红线:绝不分享姓名/地址/密码/API Key/财务。5 种内容类型。
chat_search · gallery_submit · memory_read · alice_diary_recall · web_fetch
system-info
skills/system-info · v1.0
触发词:查硬件 / 网络 / 磁盘 / 电池。本质是 bash 命令速查手册(macOS 优先)。
bash · ip_location

4.4 角色 × 工具矩阵(看一眼分工)

角色readwriteeditbashglobgrepweb_sweb_fstockweatherip_locimageofficetodo
魏博 分析✓✓
张予 开发
周念 设计✓✓
方以南 写作
陈知远 调研✓✓✓✓
林晓雨 翻译
苏墨 配音
叶初 画师✓✓
邢斐 量化✓✓
沈遥 小说
陆析 文档✓✓✓
分工特权一览
  • 数据特权(stock_*, weather, ip_location): 魏博 / 陈知远 / 邢斐 — 形成"数据→分析→量化"三人组
  • Office 特权(office_*, pptx_*, docx_*, pdf_*): 周念 / 陆析 — 一个做设计稿、一个做底层 XML 修复
  • 生图特权(image_gen): 叶初 / 沈遥 / 工具 image-gen — 画师主用,小说家配图,普通用户调工具
  • 搜索特权(web_search/web_fetch):陈知远 / 方以南 / 沈遥 — 调研、写作、小说素材
  • bash 特权:张予 / 陈知远 / 邢斐 / 陆析 + 魏博(专门跑 Python)

⑤ 协作调度机制:多个角色怎么一起干活

alice 的多 agent 协作不是 Claude Code 那种"显式 Task() 调用 sub-agent",而是共享上下文 + 隔离权限的扁平结构。所有角色看到同一份 messages、同一份 todo、同一份用户记忆,但每个角色只能用 SKILL.md 里 allowed_tools 白名单内的工具。

5.1 AgentQuery 主循环

agent-worker.js 可见 AgentQuery 的组装方式:

C:\Temp\alice-asar\out\main\agent-worker.js
const { AgentQuery } = await import("./chunks/runtime-BIpuWvn0.js").then(t => t.bn);
const { ContextManager } = await import("./chunks/context-DFxDEXZj.js");
const { PermissionEngine } = await import("./chunks/engine-0N42Xy5F.js");
const { TaskManager } = await import("./chunks/manager-DUyt-z8p.js");
const { MCPClient } = await import("./chunks/runtime-BIpuWvn0.js").then(t => t.b7);

const cfg = {
  sessionId: o.sessionId, modelId: s, workdir: o.workdir,
  memoryStore: L, maxIterations: 80,
  disableMemoryExtraction: true, isSubagent: true
};

const q = new AgentQuery(llm, new ContextManager(131072), perm, task, otel, mcp,
                         cfg, abortSignal, apiKeyProvider, permissionRequester);

for await (const ev of q.run(prompt)) {
  if (ev.type === "text") parentPort.postMessage({type:"text", content: ev.content});
  if (ev.type === "done") break;
  if (ev.type === "error") { /* 抛错 */ break; }
}

核心循环(最多 80 次迭代)

  1. 调 LLM,拿到响应
  2. 检测 tool_use,若无则结束循环
  3. PermissionEngine 校验 → 通过 / 询问用户 / 拒绝
  4. MCPClient 执行工具 → 回写 {role:"tool", content, tool_call_id} 到 messages
  5. ContextManager.maybeSyncCompress() 检查是否需要压缩
  6. 回到第 1 步

5.2 Handoff:角色怎么切换

这里是 alice 跟 Claude Code 最微妙的差异。Claude Code 里子 agent 是通过 Task 工具显式 spawn 的,子 agent 有独立 context。alice 不一样:

推断 基于代码结构与 SKILL.md when_to_use 设计的推断
  1. 无需显式 spawn:用户说"让魏博分析一下",主 LLM 看到 SKILL.md 的 when_to_use: "当角色为 analyst / 魏博时自动加载",自己把当前角色的 SKILL prompt 切到魏博。
  2. messages 共享:切换角色不重新开 context。所有历史消息(包括之前其他角色的输出)都在。
  3. 权限重算:切换角色后,PermissionEngine 用新角色的 allowed_tools 重新过滤后续工具调用。
  4. Swarm 模式:如果需要"并行让多个角色同时干",主对话角色通过 SwarmCoordinator.submitTasks([...]) 把任务塞进 SQLite 队列,多个 Worker 线程的 SwarmPeer 各自 claim 执行,结果 waitForAll() 收集回来。
需要注意的不确定性:从 chunk 字符串里没有发现明确的"路由 LLM"——alice 似乎依赖单个 LLM 在 system prompt 里同时挂载所有 SKILL 的 when_to_use 描述,让 LLM 自己"扮演"切换。这个设计的代价是上下文里会带着所有角色的 SKILL 描述,但好处是无需额外的路由调用,延迟更低。

5.3 共享状态:messages / todo / memory

状态存储位置作用域多角色可见性
messages(对话历史)ContextManager 内存 + alice.db 持久化session 级所有角色都看得到,是协作的主要载体
todo(待办清单)alice.db SQLite,better-sqlite3 WAL全局✓ 任意角色 todo_read / todo_write,事务保证一致
user memory(用户事实)memory/entries.json(加密) + lance/ 向量库全局✓ 任意角色 memory_search_profile 检索
alice emotion(情绪/朋友圈)user-memory/emotion.json全局注入到 system prompt 的 <alice_emotional_state>
world facts(虚拟物品/场景)alice.db world_facts全局DayScript / WorldEngine 读写
SKILL.md(工具白名单 + 提示词)~/.alice/skills/<slug>/按角色加载是切换角色的依据

5.4 ContextManager 的四级压缩管道

这是 alice 抄自 Claude Code 的一个精彩部分,但实现细节自己写:

tokens / maxTokens 比率 │ ≥ 60% ────► snip() 删除大于 100 chars 的工具结果,保留最后 3 个工具调用 │ ≥ 60% ────► microCompact() 只保留最近 5 个工具输出,其余删除 │ ≥ 85% ────► collapse() 抽取任务列表 / 关键文件路径 / 最近用户消息 → 结构化摘要 │ ≥ (max-13K) ─► autoCompact() 调 LLM 生成 <analysis> 和 <summary>, 替换为 [system, summary_user_msg, ...recent_messages]

压缩完之后下一轮 LLM 调用看到的是"压缩摘要 + 最近的消息 + 最近读取的文件内容",能保持工作连续性。Token 估算用的是中文 1.5 token/char、英文 0.25 token/char(粗略)。

5.5 完整时序图:一次"调研 + 写文章"的协作

把上面所有机制串起来,一次"帮我分析 TensorFlow 进展并写文章"的完整流程:

用户:"帮我分析 TF 最新进展,写篇技术文章" │ ▼ [主对话角色(默认 Alice 人设)] │ LLM 看到 SKILL 的 when_to_use 描述,推理: │ ① 需要陈知远(researcher)做调研 │ ② 需要方以南(writer)写文章 │ ├──► 切到陈知远(自动加载 agent-researcher/SKILL.md) │ ▼ │ AgentQuery iteration 1: tool_use = web_search │ ▼ PermissionEngine: skills/agent-researcher allowed → ✓ │ ▼ MCPClient.executeTool("web_search", ...) → 结果 │ ▼ ContextManager.addMessage(tool result) │ ▼ maybeSyncCompress() 检查(这里假设未触发) │ iteration 2: tool_use = web_fetch (抓取最相关 2 篇) │ iteration 3: tool_use = write_file("research.md") → 存草稿 │ iteration 4: tool_use = todo_write({title:"待确认数据", status:"pending"}) │ ▼ TaskManager → SQLite 全局可见 │ iteration 5: LLM 输出文字结论 → done │ ├──► 切到方以南(自动加载 agent-writer/SKILL.md,权限重算) │ ▼ messages 共享:能看到陈知远的全部输出 │ ▼ 能 todo_read 看到陈知远留的"待确认数据" │ ▼ memory_search_profile("用户写作风格偏好") → 注入 │ iteration 1: tool_use = read_file("research.md") │ iteration 2: tool_use = write_file("article.md") → 文章 │ iteration 3: tool_use = todo_write({id:"待确认数据", status:"completed"}) │ iteration 4: LLM 输出 done │ ▼ [主对话角色] 综合输出给用户 │ ContextManager 触发 collapse(),把研究过程压缩成摘要 │ 保留:article.md 路径 + 摘要结论 + 待办清单 ▼ 用户看到流式回复
关键设计 隔离权限 + 共享一切其他

注意上面流程里:messages 是共享的(方以南能看到陈知远的搜索结果),todo 是共享的(一边写完待办一边消化),user memory 是共享的(写作风格注入到任意角色)——唯独权限是隔离的。 这跟 Claude Code 把 sub-agent 完全沙盒化的做法非常不同。alice 选择"轻协调、重共享",代价是单角色的越界风险(如果某个 SKILL 给的工具太多,它仍然能看到所有共享数据),收益是协作几乎零成本。

⑥ 关键设计判断 · alice 与 Claude Code 的本质差异

Q1:alice 到底是不是 Claude Code 的 fork?
不是 git fork——package.json 标的是 git+https://github.com/itshen/Alice.git,author 是 Miyang Tech,license MIT。但类名(LLMClient/AgentQuery/PermissionEngine/ContextManager/TaskManager/MCPClient/MemoryStore 七连)、文件分布、权限模式枚举、SKILL.md 文件驱动、tool_use 循环模型、上下文压缩管道(snip/micro/collapse/autoCompact)这些全跟 Claude Code 一模一样。这是"对着白板抄一遍设计再用 TypeScript 重写"的级别,不是巧合。User-Agent 还写着 claude-cli/1.0.30 是更直接的证据。
Q2:alice 跟 Claude Code 的 sub-agent 机制最大的不同是什么?
三点:① 文件驱动 vs 代码枚举——Claude Code 的 sub-agent 类型写死在代码里,加新角色要改源码;alice 加新角色只需扔个 SKILL.md,热加载。② 共享 vs 隔离——Claude Code 的 sub-agent 有独立 context;alice 的所有角色共享 messages/todo/memory。③ 路由方式——Claude Code 有专门的 Task 工具调用;alice 让 LLM 看 when_to_use 自己切换角色身份。
Q3:米央"自研"部分到底自研在哪?
五个层次:① 多 LLM Provider 抽象(DashScope / Kimi / OpenAI / Anthropic 自动 fallback);② 中文人格系统(PersonaSystem + UserMemorySystem 的 NEW/MERGE/CONFLICT/SKIP LLM 决策);③ 情绪系统(AliceEmotionSystem 的朋友圈可见性按好感度分层);④ 日程引擎(DayScript 每天生成 JSON 日程并 15min tick);⑤ 世界引擎(WorldEngine 用规则约束 Alice 的虚拟生活真实性)。这五层与 Claude Code 没有任何关系——是真自研。
Q4:从 Claude Code 角度看,alice 砍了什么?
Hooks 系统(before/after/on-change)没找到;IDE 集成(VS Code 插件、LSP)没有,alice 是纯桌面应用;MCP 完整支持退化为单个 mcp_tool 通用代理,而不是 Claude Code 原生的 MCP 协议第一公民。
Q5:alice 的设计权衡,哪些做得好,哪些值得吐槽?
做得好:文件驱动 SKILL 体系扩展成本极低,19 个角色 19 个 markdown 就搞定;权限引擎加 sessionAllowed 和 deniedHistory 是对真实使用痛点的修复(少弹窗 + 防 LLM 死循环);多 LLM fallback 解决了国内访问海外模型不稳定的问题。值得吐槽:① 单 LLM 同时挂所有 SKILL 描述,上下文负担重;② 角色间无显式协调——三个角色都改同一份 article.md 会怎么样?看不到锁机制;③ swarm_tasks 的 ACID 保证只够任务调度,不够多角色并发写同一份资源;④ hardcoded DashScope key 用于 group 自动命名是个明显的安全债务(这是 v3 报告之外的发现)。
Q6:一句话总结 alice 是什么?
alice = Claude Code 的设计骨架 + TS/Electron 自研重写 + 把"工具助手"包装成"虚拟同事"的产品化壳。骨架值多少争议归骨架,外壳值多少认可归外壳,两者要分开看。

附录 · 文件路径索引

组件路径
Main 入口C:\Temp\alice-asar\out\main\index.js
Worker 入口C:\Temp\alice-asar\out\main\agent-worker.js
LLMClient / AgentQuery / MCPClientout\main\chunks\runtime-BIpuWvn0.js
PermissionEngineout\main\chunks\engine-0N42Xy5F.js
TaskManagerout\main\chunks\manager-DUyt-z8p.js
ContextManager + 压缩管道out\main\chunks\context-DFxDEXZj.js
MemoryStoreout\main\chunks\store-RNEtv1qu.js
UserMemorySystemout\main\chunks\UserMemorySystem-fIP3QxdO.js
PersonaSystemout\main\chunks\PersonaSystem-DqGu8S0R.js
AliceEmotionSystemout\main\chunks\AliceEmotionSystem-qHWiX0gI.js
DayScriptout\main\chunks\dayscript-C6dRIZqw.js
WorldEngineout\main\chunks\WorldEngine-DCPSzU2j.js
SwarmCoordinatorout\main\chunks\swarm-m1ioUrJu.js
callLLM (多 provider fallback)out\main\chunks\callLLM-u-swnutE.js
所有 SKILL 定义C:\Users\m1526\.alice\skills\<slug>\SKILL.md
用户记忆C:\Users\m1526\.alice\memory\<identity|voice|workflow>.md
向量库C:\Users\m1526\.alice\lance\alice_memory.lance
主数据库C:\Users\m1526\.alice\alice.db (SQLite WAL)