From e38ed5f32c22a6e8bb6cabd55091716f2e47853d Mon Sep 17 00:00:00 2001 From: Bain Date: Fri, 3 Apr 2026 11:47:22 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E6=89=80=E6=9C=89=20M?= =?UTF-8?q?ermaid=20=E5=9B=BE=E8=A1=A8=20GitHub=20=E6=B8=B2=E6=9F=93?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 替换换行符 \n 为
- 修复特殊字符语法错误(括号、等号、斜杠) - 避免使用保留关键字(default、loop) - 修复 mindmap 中 prompt() 的 () 被误解析为节点形状分隔符 --- 02-cli-bootstrap.md | 18 +++++------ 03-tool-system.md | 63 ++++++++++++++++++-------------------- 04-conversation-context.md | 4 +-- 05-agent-loop.md | 18 +++++------ 06-hooks-permissions.md | 28 ++++++++--------- 08-build-your-own.md | 40 ++++++++++++------------ 6 files changed, 84 insertions(+), 87 deletions(-) diff --git a/02-cli-bootstrap.md b/02-cli-bootstrap.md index e04ee86..175453c 100644 --- a/02-cli-bootstrap.md +++ b/02-cli-bootstrap.md @@ -580,18 +580,18 @@ main().catch(err => { ```mermaid graph TD - A["my-agent-cli.ts 入口"] --> B["顶层副作用\nvoid prefetchApiKey()"] - A --> C{args[0] == --version?} - C -->|是| D["输出版本号,return\n零模块加载"] - C -->|否| E["new Command()\nCommander.js 注册参数"] + A["my-agent-cli.ts 入口"] --> B["顶层副作用
void prefetchApiKey()"] + A --> C{"args[0] == --version?"} + C -->|是| D["输出版本号,return
零模块加载"] + C -->|否| E["new Command()
Commander.js 注册参数"] E --> F[".action() 回调触发"] - F --> G["判断 isInteractive\n!options.print && isTTY"] + F --> G["判断 isInteractive
!options.print && isTTY"] G --> H["initializeState(cwd, model, ...)"] H --> I["await setup(cwd)"] - I --> J{isInteractive?} - J -->|是| K["launchRepl()\nInk + React TUI"] - J -->|否| L["runHeadless(prompt)\n单次执行"] - L --> M["outputResult(result, format)\ntext / json 输出,退出"] + I --> J{"isInteractive?"} + J -->|是| K["launchRepl()
Ink + React TUI"] + J -->|否| L["runHeadless(prompt)
单次执行"] + L --> M["outputResult(result, format)
text / json 输出,退出"] ``` --- diff --git a/03-tool-system.md b/03-tool-system.md index 87ed0f2..5d17733 100644 --- a/03-tool-system.md +++ b/03-tool-system.md @@ -412,25 +412,25 @@ const ASSISTANT_BLOCKING_BUDGET_MS = 15_000 ```mermaid flowchart TD - Input[用户输入命令\ne.g. rm -rf /tmp/foo] --> Parse[parseForSecurity\n解析命令 AST] - Parse --> Pipes{有管道符?} - Pipes -->|是| AllParts[拆分所有管道片段\n逐一分析] - Pipes -->|否| Single[分析单条命令] - AllParts --> ReadCheck{所有片段\n都是只读命令?} + Input["用户输入命令
e.g. rm -rf /tmp/foo"] --> Parse["parseForSecurity
解析命令 AST"] + Parse --> Pipes{"有管道符?"} + Pipes -->|是| AllParts["拆分所有管道片段
逐一分析"] + Pipes -->|否| Single["分析单条命令"] + AllParts --> ReadCheck{"所有片段
都是只读命令?"} Single --> ReadCheck - ReadCheck -->|是\ncat/grep/ls...| IsReadOnly[标记 isReadOnly=true\nisConcurrencySafe=true] - ReadCheck -->|否| IsWrite[标记 isReadOnly=false] + ReadCheck -->|"是
cat/grep/ls..."| IsReadOnly["标记 isReadOnly=true
isConcurrencySafe=true"] + ReadCheck -->|否| IsWrite["标记 isReadOnly=false"] - IsReadOnly --> PermCheck[checkPermissions] + IsReadOnly --> PermCheck["checkPermissions"] IsWrite --> PermCheck - PermCheck --> RuleMatch{匹配用户配置规则?\ne.g. Bash(git *)} - RuleMatch -->|命中规则 allow| Allow[直接执行] - RuleMatch -->|命中规则 deny| Deny[拒绝执行] - RuleMatch -->|无匹配规则| AutoMode{auto 模式?} + PermCheck --> RuleMatch{"匹配用户配置规则?
e.g. Bash git *"} + RuleMatch -->|命中规则 allow| Allow["直接执行"] + RuleMatch -->|命中规则 deny| Deny["拒绝执行"] + RuleMatch -->|无匹配规则| AutoMode{"auto 模式?"} - AutoMode -->|是| AIClassifier[bashClassifier.ts\nAI 语义分类器] - AutoMode -->|否| AskUser[弹出确认框\n等待用户决策] + AutoMode -->|是| AIClassifier["bashClassifier.ts
AI 语义分类器"] + AutoMode -->|否| AskUser["弹出确认框
等待用户决策"] AIClassifier -->|安全| Allow AIClassifier -->|不确定/危险| AskUser @@ -438,8 +438,8 @@ flowchart TD AskUser -->|用户批准| Allow AskUser -->|用户拒绝| Deny - Allow --> ExecBash[执行命令\n超 15s 自动后台化] - Deny --> ErrorResult[返回拒绝信息] + Allow --> ExecBash["执行命令
超 15s 自动后台化"] + Deny --> ErrorResult["返回拒绝信息"] style Allow fill:#eafaf1,stroke:#27ae60 style Deny fill:#fdedec,stroke:#e74c3c @@ -552,48 +552,45 @@ isolation: z.enum(['worktree', 'remote']).optional() sequenceDiagram participant P as 父 Agent participant AT as AgentTool - participant R as runAgent() + participant R as runAgent participant SA as 子 Agent - participant FS as 文件系统 / Git + participant FS as 文件系统 Git - P->>AT: call({ prompt, tools, isolation?, run_in_background? }) + P->>AT: call prompt tools isolation run_in_background - AT->>AT: assembleToolPool()\n过滤 ALL_AGENT_DISALLOWED_TOOLS + AT->>AT: assembleToolPool 过滤 ALL_AGENT_DISALLOWED_TOOLS - alt isolation = "worktree" + alt isolation worktree AT->>FS: 创建独立 git worktree FS-->>AT: worktree 路径 end - alt run_in_background = true - AT-->>P: 立即返回 { agentId }\n父 Agent 继续工作 + alt run_in_background true + AT-->>P: 立即返回 agentId 父 Agent 继续工作 AT->>R: 异步启动子 Agent else 同步执行 - AT->>R: 启动子 Agent(阻塞) + AT->>R: 启动子 Agent 阻塞 end - R->>SA: 初始化 QueryEngine\n注入工具池 + 上下文 + R->>SA: 初始化 QueryEngine 注入工具池和上下文 loop Agent 执行循环 SA->>SA: 调用 LLM SA->>SA: 执行工具调用 end - SA-->>R: 执行完成 / 出错 + SA-->>R: 执行完成或出错 - alt isolation = "worktree" + alt isolation worktree R->>FS: 清理 worktree end - alt run_in_background = true - R->>P: 通知系统推送结果\n{ agentId, result } + alt run_in_background true + R->>P: 通知系统推送结果 agentId result else 同步执行 R-->>AT: SubAgentResult - AT-->>P: tool_result { output } + AT-->>P: tool_result output end - - style SA fill:#e8f4fd,stroke:#1a73e8 - style FS fill:#eafaf1,stroke:#27ae60 ``` --- diff --git a/04-conversation-context.md b/04-conversation-context.md index 8cf7ce0..6ef484a 100644 --- a/04-conversation-context.md +++ b/04-conversation-context.md @@ -763,7 +763,7 @@ mindmap root((对话与上下文管理)) 三层上下文 System Prompt - 工具描述 prompt() + 工具描述 prompt Git 状态快照 环境信息 User Context @@ -775,7 +775,7 @@ mindmap tool_use + tool_result 强制配对 mutableMessages 跨轮持久化 系统提示构建 - fetchSystemPromptParts() + fetchSystemPromptParts Promise.all 并行加载 Prompt Cache 友好设计 上下文窗口管理 diff --git a/05-agent-loop.md b/05-agent-loop.md index 745d41b..2c56a6b 100644 --- a/05-agent-loop.md +++ b/05-agent-loop.md @@ -376,28 +376,28 @@ for (const result of streamingToolExecutor.getCompletedResults()) { ```mermaid graph TD - ADD["addTool(block)\n加入执行队列"] --> PQ["processQueue()\n尝试调度"] + ADD["addTool(block)
加入执行队列"] --> PQ["processQueue()
尝试调度"] PQ --> CHECK{"canExecuteTool()?"} - CHECK --> |"无正在执行的工具"| RUN["立即执行"] - CHECK --> |"当前全是并发安全工具\n且新工具也是并发安全"| RUN - CHECK --> |"当前有非并发安全工具\n或新工具非并发安全"| WAIT["等待队列,status=queued"] + CHECK -->|"无正在执行的工具"| RUN["立即执行"] + CHECK -->|"当前全是并发安全工具
且新工具也是并发安全"| RUN + CHECK -->|"当前有非并发安全工具
或新工具非并发安全"| WAIT["等待队列,status=queued"] - subgraph 并发安全工具(只读) + subgraph Safe["并发安全工具 只读"] RT1["ReadFile #1"] RT2["ReadFile #2"] RT3["SearchCode #3"] RT1 & RT2 & RT3 --> PARALLEL["同时执行"] end - subgraph 非并发安全工具(写操作) + subgraph Unsafe["非并发安全工具 写操作"] WT1["BashCmd #4"] --> WT2["WriteFile #5"] WT2 --> WT3["BashCmd #6"] WT1 & WT2 & WT3 --> SERIAL["严格串行"] end - RUN --> COMPLETE["完成 → status=completed\n有序放入结果队列"] - COMPLETE --> GCR["getCompletedResults()\n按添加顺序返回结果"] - WAIT --> |"前序工具完成后重新调度"| PQ + RUN --> COMPLETE["完成 status=completed
有序放入结果队列"] + COMPLETE --> GCR["getCompletedResults()
按添加顺序返回结果"] + WAIT -->|"前序工具完成后重新调度"| PQ ``` --- diff --git a/06-hooks-permissions.md b/06-hooks-permissions.md index 84d49d4..3834b28 100644 --- a/06-hooks-permissions.md +++ b/06-hooks-permissions.md @@ -110,28 +110,28 @@ export type ToolPermissionContext = { ```mermaid stateDiagram-v2 - [*] --> default: 会话启动 + [*] --> DefaultMode: 会话启动 - default --> acceptEdits: 用户开启"自动接受编辑" - default --> plan: 进入规划模式\n(保存 prePlanMode) - default --> bypassPermissions: CI/CD 启动参数\n⚠️ 高风险,标红色 - default --> dontAsk: 非交互式场景 + DefaultMode --> acceptEdits: 用户开启自动接受编辑 + DefaultMode --> plan: 进入规划模式 保存 prePlanMode + DefaultMode --> bypassPermissions: CI/CD 启动参数 高风险标红色 + DefaultMode --> dontAsk: 非交互式场景 - acceptEdits --> default: 关闭自动接受 + acceptEdits --> DefaultMode: 关闭自动接受 acceptEdits --> plan: 进入规划模式 - plan --> default: 退出规划模式\n(还原 prePlanMode) - plan --> acceptEdits: 退出到 acceptEdits\n(prePlanMode=acceptEdits) + plan --> DefaultMode: 退出规划模式 还原 prePlanMode + plan --> acceptEdits: 退出到 acceptEdits prePlanMode=acceptEdits - bypassPermissions --> default: 重置权限模式 + bypassPermissions --> DefaultMode: 重置权限模式 - dontAsk --> default: 恢复交互式 + dontAsk --> DefaultMode: 恢复交互式 - default --> auto: 启用 TRANSCRIPT_CLASSIFIER\nAI 自动判定 + DefaultMode --> auto: 启用 TRANSCRIPT_CLASSIFIER AI 自动判定 - note right of bypassPermissions: 绕过所有权限检查\nhooks 仍然执行 - note right of plan: 只读操作\n禁止写入 - note right of dontAsk: ask → deny\n完全非交互 + note right of bypassPermissions: 绕过所有权限检查 hooks 仍然执行 + note right of plan: 只读操作 禁止写入 + note right of dontAsk: ask 转 deny 完全非交互 ``` --- diff --git a/08-build-your-own.md b/08-build-your-own.md index de7ce7f..b2add3a 100644 --- a/08-build-your-own.md +++ b/08-build-your-own.md @@ -1119,44 +1119,44 @@ export class AgentLoop { sequenceDiagram participant User as 用户 participant CLI as CLI REPL - participant Loop as AgentLoop + participant AL as AgentLoop participant Ctx as ContextManager participant API as Claude API participant Tools as ToolSystem User->>CLI: 输入任务 - CLI->>Loop: run(userMessage, onDelta) + CLI->>AL: run userMessage onDelta - Loop->>Ctx: addUserMessage(text) - Ctx-->>Loop: 当前消息历史 + AL->>Ctx: addUserMessage text + Ctx-->>AL: 当前消息历史 loop Agent 主循环 - Loop->>API: messages.create(messages, tools) - API-->>Loop: 流式响应 + AL->>API: messages.create messages tools + API-->>AL: 流式响应 - alt stop_reason = "end_turn" - Loop->>CLI: 输出最终文本 - Loop-->>CLI: 循环结束 - else stop_reason = "tool_use" - Loop->>CLI: 输出思考文本(流式) + alt stop_reason end_turn + AL->>CLI: 输出最终文本 + AL-->>CLI: 循环结束 + else stop_reason tool_use + AL->>CLI: 输出思考文本 流式 loop 每个 tool_use block - Loop->>Tools: checkPermission(tool, input) - Tools-->>Loop: allow / deny + AL->>Tools: checkPermission tool input + Tools-->>AL: allow deny alt allow - Loop->>Tools: executeTool(name, input) - Tools-->>Loop: 结果字符串 - Loop->>CLI: 显示 [工具调用] + [工具结果] + AL->>Tools: executeTool name input + Tools-->>AL: 结果字符串 + AL->>CLI: 显示工具调用和工具结果 else deny - Loop->>Ctx: 添加拒绝消息 + AL->>Ctx: 添加拒绝消息 end end - Loop->>Ctx: addAssistantMessage(tool_use blocks) - Loop->>Ctx: addUserMessage(tool_result blocks) + AL->>Ctx: addAssistantMessage tool_use blocks + AL->>Ctx: addUserMessage tool_result blocks - Note over Ctx: 检查是否需要压缩\n(丢弃旧 tool_result) + Note over Ctx: 检查是否需要压缩 丢弃旧 tool_result end end ```