🤖 架构解析

核心实现在 ui.htmlrunAgentLoop(userMessage) 函数(约 1388 行)。流程如下:

1. MUD 命令预拦截

纯机械命令(/save/load/status、开关配图等)直接调 apiCall('mud_action', ...) 走 GameEngine,不经过 LLM,避免浪费 token 和延迟。

2. 记忆注入

登录用户的消息会先调 fetchMemoryContext(userMessage),从 MySQL/JSONL 中检索相关记忆(语义搜索 + 用户画像 + 当前场景),拼入 system prompt。

3. 构建 System Prompt

buildSystemPrompt() 根据登录/访客、MUD 模式、MUD 开关状态、当前游戏状态动态组装 prompt,包含文件目录规则、工具列表、EDIT_PRIORITY、AGENT_DRIFT_GUARD、MUD 叙事规则等。

4. Agent Loop(核心)

while (loopCount < MAX_LOOPS) {   // MAX_LOOPS = 10
  // 4a. 上下文压缩(非 MUD 模式下,token 超阈值则调用 LLM 做 compactContext)
  // 4b. 调 proxyRequest 请求 LLM(deepseek-v4-flash),带 tools 参数
  // 4c. LLM 返回 message.tool_calls → 执行工具 → 结果追加到 messages → 继续循环
  // 4d. LLM 返回纯文本(无 tool_calls)→ 展示给用户 → break
}

5. 工具执行

EnhancedToolExecutor.executeToolCalls() 遍历所有 tool_calls,调用对应的 handler(web_searchreadwriteeditmud_actionimage_generation 等 12 个工具),结果截断至 50KB 后回传给 LLM。

6. 通信层

proxyRequest(provider, path, body) 构造 {_token, _provider, _path, ...body},POST 到 proxy.php,后者做 CORS 校验、Token 验证、多 Key 轮换、curl 转发到 MiniMax/OpenCode-Go。遇到 429 自动换下一个 Key,全部耗尽返回 proxy_all_keys_exhausted

7. 后续处理

  • MUD 模式下消费 _mudPendingImage/_mudPendingVoice(配图/语音)
  • 非 MUD 模式异步触发 triggerMemoryExtraction 提取记忆
  • 执行命令队列中的下一条(commandQueue / processQueue

流程图

用户消息
    │
    ▼
┌─────────────────────┐
│ MUD 命令预拦截       │ → 纯机械命令 → apiCall('mud_action') → GameEngine
└─────────────────────┘
    │ 非机械命令
    ▼
┌─────────────────────┐
│ 记忆注入             │ → fetchMemoryContext() → MySQL/JSONL 语义搜索
└─────────────────────┘
    │
    ▼
┌─────────────────────┐
│ 构建 System Prompt   │ → buildSystemPrompt() → 动态组装 prompt
└─────────────────────┘
    │
    ▼
┌─────────────────────┐
│ Agent Loop           │ ← MAX_LOOPS = 10
│  ├─ 上下文压缩       │
│  ├─ proxyRequest()   │ → LLM (deepseek-v4-flash)
│  ├─ tool_calls       │ → EnhancedToolExecutor → 12 个工具 handler
│  └─ 纯文本           │ → 展示给用户 → break
└─────────────────────┘
    │
    ▼
┌─────────────────────┐
│ 后续处理             │
│  ├─ MUD: 配图/语音   │
│  ├─ 非MUD: 记忆提取  │
│  └─ 命令队列         │
└─────────────────────┘

关键设计决策

决策 原因
MUD 命令不经过 LLM 避免浪费 token 和延迟
MAX_LOOPS = 10 防止无限循环
工具结果截断至 50KB 防止上下文溢出
429 自动换 Key 提高可用性
记忆注入在构建 prompt 前 确保 LLM 有足够上下文