Roo Code
一句话定位
Roo Code 是一个以 VS Code 扩展形态运行的编码 Agent(Cline 的分支),核心是 src/core/task/Task.ts 驱动的栈式任务循环,采用原生 function-calling 工具协议、Mode 系统(Orchestrator/Boomerang 做多任务委派)、Claude-Code 风格 Skills,以及针对 Anthropic 模型的深度请求层适配(prompt caching、extended thinking、:thinking 虚拟模型 ID);项目已于 2026-05-15 正式关停归档,社区分叉为 ZooCode。
核心架构总览
Monorepo(pnpm + turbo),非独立 CLI(虽有 apps/cli 无头封装,见下):
src/— 扩展本体:激活入口、核心 agent 逻辑(src/core/)、工具实现、API provider 适配、服务层(skills/mcp/checkpoints)webview-ui/— React 聊天面板前端,与 agent 逻辑无关apps/cli/— 独立无头 CLI(“Roo CLI”),通过apps/cli/src/agent/extension-host.ts/extension-client.ts的 IPC shim 复用同一套src/core引擎——反映关停前有把 harness 与 VS Code 解耦的尝试apps/docs/— Docusaurus 文档源(docs.roocode.com)packages/types/— 共享 Zod schema,含RooCodeEventName事件枚举与消息/工具 schemapackages/ipc/— IPC client/server,供 CLI/extension-host 拆分使用packages/core—customToolRegistry、formatNative,被src/core/task/build-tools.ts引用- 仓库根目录
.roo/(commands、rules、rules-<mode>、skills、guidance)——Roo Code 用自己的 Mode/Skill/Rule 体系构建自身(dogfooding)
引用 commit:b867ec9145750d0ae1ff7f02d35406e9bf2a0b16(2026-05-15,也是仓库最后一次提交——与官方关停公告日期完全吻合,docs.roocode.com 有 “Extension Shutdown” 横幅,指向社区分叉 ZooCode 与上游 Cline)。本 dossier 所有结论均来自这份最终态、可构建的完整源码,非文档摘要。
Agent Loop(主循环 / 何时继续何时停)
- 入口
Task.initiateTaskLoop()(Task.ts:2427):while (!this.abort)循环,反复调用recursivelyMakeClineRequests()(Task.ts:2437)。若返回didEndLoop = true则外层break;否则下一轮 user content 被合成为formatResponse.noToolsUsed()——换言之”继续循环”的信号本质就是”模型没调工具,那就提醒它”。 - 内层引擎
recursivelyMakeClineRequests()(Task.ts:2461)尽管命名带 “recursively”,实际不是递归,而是显式栈机(const stack: StackItem[] = [...],while (stack.length > 0))——从递归重构为迭代栈式实现,代码里残留 “RooCode#recursivelyMakeRooRequests” 之类的错误字符串,暴露出从 “Cline” fork 而来的命名演化痕迹。 - 循环体内发现的停止条件:
consecutiveMistakeCount >= consecutiveMistakeLimit(默认值DEFAULT_CONSECUTIVE_MISTAKE_LIMIT,字段见Task.ts:317,构造时可覆盖见Task.ts:419/484)→ 通过ask("mistake_limit_reached", ...)询问用户。consecutiveNoToolUseCount >= 2(Task.ts:3487-3494)→ 连续两轮模型不调用任何工具,发出"MODEL_NO_TOOLS_USED"错误并计入 mistake 计数。consecutiveNoAssistantMessagesCount >= 2(Task.ts:3524-3613)→ 处理空 API 响应;若开启autoApprovalEnabled则带退避自动重试,否则询问用户。- 每次栈迭代顶部检查
this.abort,命中则抛出以展开栈。 - Auto-approval 的请求数/费用上限(
AutoApprovalHandler,见”安全与权限”)也可暂停/门控推进。 attempt_completion工具(在presentAssistantMessage.ts的 switch 中)是模型发出的”我做完了”信号——但源码注释明确说明结构上并不硬性终止于此:“For now a task never ‘completes’. This will only happen if the user hits max requests and denies resetting the count.”,完成更多是靠 prompting(getObjectiveSection())约定俗成,而非代码强制状态机。
- 子任务暂停/恢复:
isPaused标志——设置后栈循环仍会 push 一个空 item “so the loop continues to the pause check”(Task.ts:3506-3508),使 Orchestrator/Boomerang 委派流程(见”Router / 编排”)能在子任务运行期间挂起父任务。
记忆与上下文管理(压缩、长期记忆、会话持久化)
- 压缩(“condense”):
src/core/condense/index.ts的summarizeConversation()(694 行文件的第 254 行)。使用专门的SUMMARY_PROMPT,明确指示模型 “DO NOT call any tools or functions… Respond with text only”,并把这次总结请求当作独立于用户当前工作的 “SYSTEM OPERATION”。阈值:MIN_CONDENSE_THRESHOLD = 5,MAX_CONDENSE_THRESHOLD = 100(占上下文窗口百分比)。 - 压缩前工具/工具结果块会被转成纯文本(
convertToolBlocksToText、toolUseToText、toolResultToText)——原因是部分 provider(注释提到 Bedrock)只要历史里出现 tool 块就强制要求同时传tools参数;转成文本后压缩阶段就不用重新声明工具 schema。 - 非破坏性压缩:
ApiMessage类型(src/core/task-persistence/apiMessages.ts)携带condenseId/condenseParent与truncationId/truncationParent字段——旧消息只是被”标记”为已被取代,只有在发送 API 时若存在有效的 summary/truncation 标记才会被过滤掉。也就是说磁盘上的完整原始历史在”压缩”之后依然完整保留。 - Folded file context:
src/core/condense/foldedFileContext.ts的generateFoldedFileContext()用 tree-sitter(parseSourceCodeDefinitionsForFile)为对话中读过的文件生成”仅签名、无函数体”的表示,包裹在独立的<system-reminder>块中,maxCharacters默认上限 50000。这段内容在压缩阶段被注入,让模型保留”我见过这个文件的结构”而不必为完整文件体付出 token 成本。 - 上下文窗口超限处理:
Task.handleContextWindowExceededError()(Task.ts:3717)——读取按 API-profile 分组的profileThresholds。 - 会话持久化:每个任务目录两个文件(
src/shared/globalFileNames.ts):api_conversation_history.json(原始 Anthropic/OpenAI 格式消息数组,经apiMessages.ts的readApiMessages/saveApiConversationHistory读写)与ui_messages.json(面向 UI 的ClineMessage[]时间线,say/ask事件,经taskMetadata.ts的combineApiRequests/combineCommandSequences组合用于重建 webview)。 - 推理/思考持久化:
ApiMessage还携带各 provider 特有的 reasoning 字段(summary、encrypted_content、reasoning_details、reasoning_content),用于在多轮工具调用间往返回传 OpenAI o 系列的加密推理、OpenRouter/Gemini 3 的reasoning_details、DeepSeek/Z.ai 的reasoning_content——这部分与”模型协同设计”维度有重叠。 - 未发现长期/跨会话记忆存储:没有向量数据库,没有持久化的 “memory bank” 文件——记忆仅限于单个任务的磁盘 JSON,加上仅在压缩阶段内部使用的 “folded file context”。
RooIgnoreController/skills 发现机制会在文件变更时重新扫描,但那是配置而非对话记忆。
工具体系(定义/调用协议/注册/权限)
- 协议:
system.ts:74-75注释明确写道// Tool calling is native-only.,紧接着const toolsCatalog = ""——已在源码中直接核实(grep命中key-files/prompts-system.ts第 74/83 行)。确认 Roo Code 已完全迁移出早期的 XML 标签式工具调用解析,改用 OpenAI 风格原生 function-calling(build-tools.ts中大量使用OpenAI.Chat.ChatCompletionTool类型)。Anthropic 请求经convertOpenAIToolsToAnthropic/convertOpenAIToolChoiceToAnthropic(src/core/prompts/tools/native-tools/converters.ts,被anthropic.ts引用)转换——即工具只用 OpenAI 形态的 schema 定义一次,再按 provider 各自转换。 - 注册:
buildNativeToolsArrayWithRestrictions()(src/core/task/build-tools.ts:82)汇总三个来源:(a)getNativeTools()(src/core/prompts/tools/native-tools/index.ts)提供的内置原生工具;(b)getMcpServerTools(mcpHub)提供的 MCP 服务器工具;(c)customToolRegistry.loadFromDirectoriesIfStale(toolDirs)提供的自定义工具,需experiments?.customTools开关,工具目录来自getRooDirectoriesForCwd(cwd)/tools(项目级与全局级.roo/tools/)。 - 按 Mode 过滤:
filterNativeToolsForMode()/filterMcpToolsForMode()(src/core/prompts/tools/filter-tools-for-mode.ts,456 行)按当前 Mode 声明的工具”组”(read/edit/command/mcp)过滤工具目录(例如 Architect 模式只拿到read+mcp+受限于 markdown 的edit;Orchestrator 不拿这些组,只有new_task)。还做工具别名解析(resolveToolAlias)——如edit_file依配置可能别名到search_and_replace/edit,且对话历史中记录的是别名而非规范名,避免模型对话中途被改名搞混(Task.ts:3392-3396注释)。 - 调度:
src/core/assistant-message/presentAssistantMessage.ts有一个大的switch (block.type)("mcp_tool_use" | "text" | "tool_use"),在"tool_use"分支内再嵌套一个按block.name的switch(一处约 325 行构建审批 UI 用的工具”消息”,另一处约 651 行实际调用各工具的.execute())。已确认的约 20 个一级工具:execute_command、read_file、write_to_file、apply_diff、apply_patch、search_files、edit/search_and_replace/search_replace/edit_file(别名族)、list_files、use_mcp_tool、access_mcp_resource、ask_followup_question、attempt_completion、switch_mode、codebase_search、read_command_output、update_todo_list、new_task、run_slash_command、skill、generate_image。 - 工具类结构:每个工具是继承
BaseTool<"tool_name">(src/core/tools/BaseTool.ts)的类,实现execute(params, task, callbacks);callbacks含askApproval、handleError、pushToolResult——即审批门控是分散穿透到每个工具调用里,而非集中在一处。 - 重复检测:
src/core/tools/ToolRepetitionDetector.ts,与 mistake 计数机制分离,专门跟踪连续相同的工具调用(用Task.ts:513处的consecutiveMistakeLimit构造)。
Prompt 设计(系统提示结构、动态组装)
- 入口
SYSTEM_PROMPT()(src/core/prompts/system.ts:112),调用generatePrompt()(第 41 行)。提示词按固定顺序字符串拼接标注区块(system.ts:85-107):roleDefinition(Mode 特定人设,如 “A skilled software engineer…“)markdownFormattingSection()getSharedToolUseSection()+toolsCatalog(显式设为空字符串,因为原生 function-calling 已通过 API 的tools参数带外传递工具 schema,不需要内联文本目录——已在源码核实)getToolUseGuidelinesSection()getCapabilitiesSection(cwd, mcpHub-若启用)getModesSection()(异步,与 skills 区块并行 await)getSkillsSection()(异步,仅非空时加入)getRulesSection(cwd, settings)getSystemInfoSection(cwd)getObjectiveSection()addCustomInstructions(baseInstructions, globalCustomInstructions, cwd, mode, {language, rooIgnoreInstructions, settings})——用户/项目级.roorules*、AGENTS.md、按 Mode 的自定义指令在此最后合并
- Mode 感知:
getModeSelection(mode, promptComponent, customModeConfigs)解析roleDefinition/baseInstructions,允许对内置或自定义 Mode 做完整覆盖(ModeConfig、CustomModePrompts,来自@roo-code/types)。 - MCP 区块按条件构建:
shouldIncludeMcp = hasMcpGroup && hasMcpServers——只有当前 Mode 的工具组包含"mcp"且至少一个 MCP 服务器实际已连接时才生成,避免无服务器配置时的提示词膨胀。 settings: SystemPromptSettings把若干 feature flag 传入提示词构建:todoListEnabled、useAgentRules(VS Code 设置,默认 true)、enableSubfolderRules、newTaskRequireTodos、isStealthModel(针对 OpenRouter 类聚合平台上匿名/隐身模型的提示词变体渲染)。
Router / 编排(任务分解、多 agent、子 agent)
- Roo Code 的多 agent 机制是 “Orchestrator Mode”(又称 Boomerang Mode/Tasks)——代码与官方文档(
docs.roocode.com/features/boomerang-tasks,2026-07-07 抓取)双重确认。 - 机制:
new_task工具(src/core/tools/NewTaskTool.ts),参数{mode, message, todos?}。校验 mode+message 存在;若 VS Code 设置newTaskRequireTodos开启,还要求 markdown 复选框格式的todos参数(经parseMarkdownChecklist解析)。调用task.startSubtask(message, initialTodos, mode)(Task.ts:2335),暂停父任务(isPaused)并在目标 Mode 下派生一个拥有独立对话历史的子Task实例——不自动继承父任务上下文(官方文档确认:“Context Isolation… does not automatically inherit the parent’s context”;只有初始message下传,只有子任务通过attempt_completion产出的最终总结上传回父任务)。 Task.ts:2361的resumeAfterDelegation()在子任务完成后恢复父任务,推测是把子任务的完成总结作为下一轮 user-content 注入。- 委派隔离的强制执行:若模型在同一轮响应里把
new_task和其他工具一起调用,Task.ts:3408-3437会截断new_task之后列出的所有工具调用,并为它们注入合成的错误tool_result(提示”因为本轮已调用 new_task 而未执行”)——因为委派会处置/暂停父任务,孤立的工具调用会破坏 API 历史的顺序完整性。 - Orchestrator 本身是一个内置 Mode,工具组为空集(不含
read/edit/command/mcp)——依官方 FAQ:“Orchestrator mode is intentionally limited… Giving it the ability to read files by default causes the context to become filled with file reads.”。它只能调用new_task做委派,这是刻意设计,用于保持编排者自身上下文窗口小且专注于高层级任务排序。 - 审批:子任务的创建与完成默认都走普通的
askApproval门(依文档 “Subtasks” 一节,可通过 Auto-Approve 设置自动化)。 - 未在已读文件中发现子任务嵌套子任务的显式最大深度限制——除了 pause/resume 栈机制外,任何拥有相应工具组的 Mode 理论上都可再调用
new_task派生下一层子任务,但未找到显式深度守卫代码。
Skill / 插件体系
src/services/skills/SkillsManager.ts(719 行)——与 Claude Code 的 Skills 功能高度类似。Skill 从文件系统目录发现:getGlobalRooDirectory()、getGlobalAgentsDirectory()、getProjectAgentsDirectoryForCwd()(辅助函数来自../roo-config)——同时支持通用Skill 目录(skills/)和按 Mode 划分的目录(skills-{mode}/)。- 每个 Skill 是一个子目录,元数据经
gray-matter解析(YAML frontmatter)——SkillMetadata/SkillContent类型(src/shared/skills.ts)。名称经validateSkillName/SkillNameValidationError/SKILL_NAME_MAX_LENGTH(来自@roo-code/types)校验。 - 显式支持符号链接:顶层
.roo/skills目录本身与单个 Skill 子目录均可为符号链接;scanSkillsDirectory()经fs.realpath()解析真实路径,但保留符号链接自身的名字作为 Skill 名(使一个被符号链接的共享 Skill 仓库可以在本地”重命名”)。 - 基于文件监视的实时重载:
setupFileWatchers()——Skill 在文件系统变更时重新扫描,无需重启扩展。 - 调用:
src/services/skills/skillInvocation.ts(54 行,较短)+skill原生工具(src/core/tools/SkillTool.ts),在presentAssistantMessage.ts的工具 switch 中经case "skill"调度。 - 还存在一个独立、更轻量的机制:
run_slash_command工具 + 仓库根目录可见的.roo/commands/目录——slash command 是与 Skills 相区分的更轻概念(一个命令也可以在 frontmatter 中请求切换 Mode,见Task.ts:2554-2564注释 “Switch mode if specified in a slash command’s frontmatter”)。 - 该仓库自身践行 dogfooding:根目录同时存在
.roo/skills、.roo/commands、.roo/rules、.roo/rules-<mode>(code/debug/docs-extractor/issue-fixer/issue-investigator/issue-writer/merge-resolver/pr-fixer/translate)、.roo/guidance——即 Roo Code 团队用 Roo Code 自身的 Skill+Mode+Rule 体系来构建 Roo Code。 - 文档导航中另有 Marketplace 功能引用,用于分享 Mode/MCP 配置——未深挖代码,仅作为后续阶段的线索标记(未在代码层验证)。
自进化能力(自我改进 / 学习型记忆 / eval 驱动纠错)
未发现自进化、自我改进或 eval 驱动的自纠错机制。 在 src/**/*.ts(排除测试)中搜索 fine-tuning/training-data/RLHF/self-improvement 相关关键词,零命中。
最接近的相邻概念是”Agent Loop”一节提到的连续 mistake 计数机制,但那纯粹是同一会话内的护栏(询问用户/停止循环),不构成跨会话的学习信号。
结论:该维度未实现 / 不适用于此 harness(与其作为人机协同编码助手产品、而非自主/自我改进型 agent 框架的定位一致)。
可观测性(日志 / trace 格式)
- 事件总线:
packages/types/src/events.ts定义enum RooCodeEventName,约 25 种事件类型,分几类:任务提供者生命周期(TaskCreated)、任务生命周期(TaskStarted、TaskCompleted、TaskAborted、TaskFocused/Unfocused、TaskActive、TaskInteractive、TaskResumable、TaskIdle)、子任务生命周期(TaskPaused、TaskUnpaused、TaskSpawned、TaskDelegated、TaskDelegationCompleted、TaskDelegationResumed)、任务执行(Message、TaskModeSwitched、TaskAskResponded、TaskUserMessage、QueuedMessagesUpdated)、任务分析(TaskTokenUsageUpdated、TaskToolFailed)、配置变更(ModeChanged、ProviderProfileChanged)、查询响应(CommandsResponse、ModesResponse、ModelsResponse)。每个事件配有 Zod 元组 schema(rooCodeEventsSchema)——这是 IPC 层(packages/ipc)用来让外部进程(如无头apps/cli)订阅任务事件的强类型契约。 Task继承EventEmitter,直接调用this.emit(RooCodeEventName.TaskStarted)等(见Task.ts:2434)。- 本次 depth-1 克隆中未发现专门的遥测/分析客户端(如 PostHog)——在
src、packages中搜索posthog/PostHog/TelemetryClient,零命中。(据公开信息 Roo Code 历史上其 monorepo 中曾有云端遥测 package,但本 commit/深度下不存在——可能是关停时被移除,也可能拆分到了未公开的私有 package。此处标注为”本快照中未找到”而非断言”从未存在”。) - 磁盘上的 trace 格式:没有独立于”记忆与上下文管理”一节所述两个持久化文件之外的结构化 “trace” 文件——
ui_messages.json(顺序排列的ClineMessage[],含say/ask类型,每条带时间戳ts)是最接近人类/机器可读执行轨迹的东西;api_req_started消息把协议/费用/token 的 JSON 内联嵌入其text字段(见Task.ts:2660-2669,ClineApiReqInfo结构:tokensIn、tokensOut、cacheWrites、cacheReads、cost、cancelReason、streamingFailedMessage)。 - 日志:代码中散布
console.log/console.error,加上一个provider?.log(message)透传到 VS Code 输出面板(见checkpoints/index.ts的log()辅助函数)——未发现结构化/分级的日志抽象。
安全与权限(审批门、密钥管理)
- 审批门(“ask”):每个工具的
execute()都接收一个askApproval回调(从presentAssistantMessage.ts穿透传入);这是逐工具调用的人机在环确认提示,在 VS Code webview 中展示——代码与官方文档(auto-approving-actions页面)双重确认,文档含明确的”安全警告”横幅:“Auto-approve settings bypass confirmation prompts, giving Roo direct access to your system. This can result in data loss, file corruption, or worse.” - 自动审批上限:
AutoApprovalHandler(src/core/auto-approval/AutoApprovalHandler.ts)即使开启自动审批,也强制两个独立上限:allowedMaxRequests(自上次重置以来的api_req_started消息计数)与allowedMaxCost(经getApiMetrics)。超出任一上限都会重新询问用户("auto_approval_max_req_reached"ask 类型),即便处于自动审批会话中途。 - 命令白/黑名单:
src/core/auto-approval/commands.ts的findLongestPrefixMatch()实现最长前缀匹配(支持"*"通配符),用于判断execute_command调用能否跳过审批提示。另有containsDangerousSubstitution():一个硬编码的正则黑名单,检测 shell 元字符技巧(无论白名单是否匹配都始终需要审批)——包括参数展开操作符${var@P}/${var@Q}/${var@E}/${var@A}/${var@a}、间接变量引用${!var}、带命令替换的 here-string(<<<$(...))、zsh 进程替换=(...)、zsh glob 限定符代码执行*(e:cmd:)。 - 文件写保护:
src/core/protect/RooProtectedController.ts——静态 glob 模式列表(.rooignore、.roomodes、.roorules*、.clinerules*、.roo/**、.vscode/**、*.code-workspace、AGENTS.md、AGENT.md),使用ignorenpm 包(gitignore 语法)对自动审批的编辑始终加以写保护,UI 上以盾牌 emoji(SHIELD_SYMBOL = "🛡")展示。 - 文件读取/访问门控:
src/core/ignore/RooIgnoreController.ts——.rooignore文件(经ignore包实现 gitignore 语法)限制 LLM 可读取/访问/引用的文件;文件监视实时更新;还有一个validateCommand()方法,在任何 shell 命令执行前由ExecuteCommandTool调用(命令文本会被扫描是否引用了被忽略的文件,命中则以rooignore_errorsay-event 阻断)。 - MCP 工具权限:
McpHub.ts为每个服务器存储逐工具的alwaysAllow: string[]列表(支持"*"通配符),从服务器 JSON 配置读取;新工具默认alwaysAllow: false除非命中匹配。 - 密钥管理:本轮未深入(需要读
src/core/config及 provider-settings 存储层),标记为阶段二待补的空白;已注意到anthropic.ts中apiKeyFieldName的逻辑(在apiKey和authToken字段间选择),但未追踪底层密钥实际存于何处(推测是 VS Code 标准SecretStorageAPI,但本轮未通过读实际存储代码确认)。
沙箱与执行隔离
- 未发现容器/虚拟机/沙箱层。
execute_command(src/core/tools/ExecuteCommandTool.ts)通过 VS Code 集成终端/shell-integration API(src/integrations/terminal/Terminal.ts、TerminalProcess.ts、TerminalRegistry.ts)直接在宿主机上运行 shell 命令,或以execa作为后备路径(ExecaTerminal.ts、ExecaTerminalProcess.ts——仅目录列表确认,未深读)。 - 隔离完全依赖”安全与权限”一节所述的审批门 + 白/黑名单 + 受保护文件模式三层,而非操作系统级沙箱(未在已读文件或目录名中发现 seccomp、Docker、VM、chroot 相关引用)。
resolveAgentTimeoutMs()(ExecuteCommandTool.ts)显示一个 CLI 专用覆盖:当process.env.ROO_CLI_RUNTIME === "1"时,忽略模型提供的后台命令超时,改用单一用户配置的commandExecutionTimeout(注释:“In CLI runtime, stdin harnesses expect command lifetime to be governed solely by commandExecutionTimeout.“)。- 检查点作为安全网(非沙箱):
src/services/checkpoints/ShadowCheckpointService.ts使用simple-git为每个任务维护一个影子 git 仓库(RepoPerTaskCheckpointService extends ShadowCheckpointService),自动提交工作区状态,使用户能回滚 agent 所做的更改——这是可逆性机制,不是预防机制。利用core.worktreegit 配置技巧(shadowGitConfigWorktree)让独立的.git指向真实工作树,同时不干扰用户自己的 git 仓库。
与模型的协同设计
- 仅原生 function-calling——系统提示词显式排除文本工具目录(
toolsCatalog = "",system.ts:82-83,已在源码核实),因为工具 schema 经各 provider 的原生 function-calling API 字段传递,不再内联为 XML/文本——这是硬性架构承诺,非逐请求判断。 - 按 provider 定制请求体:
src/api/providers/anthropic.ts展示了深度 Anthropic 特化处理:- Prompt caching:对系统提示词和倒数第二条 user 消息应用
cache_control: { type: "ephemeral" }(标准 Anthropic 多轮缓存模式),门控条件是检查模型是否 “supports prompt caching”,并推送"prompt-caching-2024-07-31"beta header。 - Extended thinking:透传
reasoning/thinking参数,把reasoning_delta/thinking_delta流事件映射为"reasoning"类型的 ApiStream chunk。 - 模型 ID 处理:
claude-3-7-sonnet-20250219:thinking后缀在发送前被剥离(映射回claude-3-7-sonnet-20250219),但会触发betas: ["output-128k-2025-02-19"]——即 Roo 自己模型列表里的一个虚拟/伪模型 ID,映射到真实模型 ID + 一个 beta 功能开关。 - Beta header
fine-grained-tool-streaming-2025-05-14是默认始终请求的 beta。 - 代码注释引用了一个公开来源解释该缓存模式:
https://x.com/alexalbert__/status/1823751995901272068。
- Prompt caching:对系统提示词和倒数第二条 user 消息应用
- 跨 provider 推理内容往返:
ApiMessage(见”记忆与上下文管理”)持久化各 provider 特有的推理产物(OpenAI 加密的summary/encrypted_content、OpenRouter/Gemini-3 的reasoning_details数组、DeepSeek/Z.ai 的reasoning_content字符串),使交错思考(interleaved thinking)模型在多轮工具调用序列中保持思维链有效,即便 Roo 内部的对话格式本身是 provider 无关的。 isStealthModel标志被传入系统提示词设置——意味着至少有一条代码路径会为匿名化/隐身模型(例如经 OpenRouter stealth-model 项目提供的模型)渲染不同/精简版提示词,但本轮未追踪具体差异内容。- 按 Mode 记忆上次用模型:依文档确认(本轮未在代码层验证)——“Each mode remembers your last-used model… Roo automatically selects that model”,切换 Mode 时自动选用。
轨迹利用(session/trajectory 是否反哺训练/评测)
- 轨迹(每任务两个 JSON 文件,见”记忆与上下文管理”/“可观测性”)仅用于:(a) IDE 重载后恢复/重建任务(
resumeTaskFromHistory(),Task.ts:1956);(b) 渲染 webview 历史列表(taskMetadata()计算大小/费用/时间戳);(c) 检查点/回滚功能(影子 git 仓库,与这两个 JSON 文件是分开的机制)。 - 未发现任何轨迹被反馈进模型训练、微调或离线 eval harness 的证据。 在遍历过的目录(
src/、apps/、packages/)中未发现evals/、benchmarks/目录或数据集导出工具。这与 Roo Code 作为面向产品的 IDE 扩展、而非研究/训练 harness 的定位一致。 - 鉴于”可观测性”一节中”未发现遥测客户端”的观察以及项目已关停的事实,若曾经存在轨迹反哺训练的管线,很可能存在于一个私有/已移除的 package 中,在这份最终公开快照里缺席——按任务的诚实性要求,此处标注为**“未找到”,而非”确认不存在”**。
与同类 harness 的关键差异(1-3 条)
概述性判断,留待后续 synthesis 阶段做跨 harness 系统对比:
- Orchestrator/Boomerang 模式的子任务隔离是严格单向、无自动上下文继承的(仅初始消息下传、仅完成总结上传),比一些同类 harness 更彻底地把”编排者”限制为空工具组的纯调度角色,刻意避免编排者上下文被文件读取污染。
- 压缩机制是非破坏性标记式(
condenseId/truncationId标记而非删除),原始历史始终完整落盘,这与直接截断/丢弃历史的实现思路不同。 - 安全模型完全基于应用层审批门 + 命令黑白名单 + 受保护文件模式,没有任何操作系统级沙箱/容器隔离,回滚安全网依赖 git 影子仓库而非执行前阻断——这使其安全边界弱于有沙箱/容器隔离的 harness。
原始源码定位
- repo: https://github.com/RooCodeInc/Roo-Code
- commit/version analyzed:
b867ec9145750d0ae1ff7f02d35406e9bf2a0b16(2026-05-15,仓库最后一次提交,与官方关停日期吻合) - 关键文件列表(相对路径):
src/core/task/Task.ts(4619 行,任务生命周期核心:对话历史、ask/say、流式处理、重试、工具结果、检查点钩子、系统提示词组装、上下文窗口超限处理、限流)src/core/assistant-message/presentAssistantMessage.ts(967 行,逐工具调用的分发器/switch 与askApproval接线)src/core/task/build-tools.ts(原生工具数组构建:Mode 过滤、MCP 工具、自定义工具)src/core/prompts/system.ts(系统提示词组装入口SYSTEM_PROMPT)src/core/prompts/tools/filter-tools-for-mode.ts(456 行,按 Mode 的工具允许/拒绝 + 别名解析)src/core/tools/ExecuteCommandTool.ts(shell 执行工具实现)src/core/tools/NewTaskTool.ts(子任务/委派工具实现)src/core/auto-approval/AutoApprovalHandler.ts(请求数/费用上限自动审批门)src/core/auto-approval/commands.ts(命令字符串允许/拒绝列表匹配、危险替换检测)src/core/protect/RooProtectedController.ts(Roo 自身配置文件写保护)src/core/ignore/RooIgnoreController.ts(.rooignore读取/访问门控)src/core/condense/index.ts(694 行,LLM 驱动的上下文摘要/“condense”)src/core/condense/foldedFileContext.ts(tree-sitter 签名折叠文件上下文)src/core/checkpoints/index.ts、src/services/checkpoints/ShadowCheckpointService.ts、RepoPerTaskCheckpointService.ts(git 影子仓库检查点/回滚系统)src/core/task-persistence/apiMessages.ts、taskMetadata.ts(磁盘会话/轨迹 JSON 持久化)src/shared/globalFileNames.ts(api_conversation_history.json、ui_messages.json两个规范文件名)src/services/skills/SkillsManager.ts(719 行)、skillInvocation.ts(Claude-Code 风格 Skills 系统)src/services/mcp/McpHub.ts(约 67KB,MCP 服务器注册/连接/工具列表,逐工具alwaysAllow配置)packages/types/src/events.ts(RooCodeEventName枚举 + Zod schema,事件/可观测性契约)src/api/providers/anthropic.ts(Anthropic 专用请求构建:prompt caching、extended thinking、beta header、:thinking模型 ID 处理)- 仅目录列表未深读:
src/integrations/terminal/*(Terminal.ts、TerminalProcess.ts、ExecaTerminal.ts、ExecaTerminalProcess.ts、TerminalRegistry.ts)、apps/cli/src/agent/*(无头 CLI agent 循环 shim)
一手源存档(sources/)
/Users/zhao/projects/self-wiki/ai-research/sources/harness/roo-code/ 下:
NOTES.md(阶段一调研笔记,含 provenance、逐维度发现原文)key-files/(21 个源文件,约 480KB,从上述关键文件裁剪保存,已核实与仓库实际路径的对应关系):Task.ts、presentAssistantMessage.ts、build-tools.ts(存为build-tools.ts)、filter-tools-for-mode.ts、ExecuteCommandTool.ts、NewTaskTool.ts、AutoApprovalHandler.ts、auto-approval-commands.ts(=commands.ts)、RooProtectedController.ts、RooIgnoreController.ts、condense-index.ts(=condense/index.ts)、foldedFileContext.ts、checkpoints-index.ts(=checkpoints/index.ts)、ShadowCheckpointService.ts、apiMessages.ts、taskMetadata.ts、globalFileNames.ts、SkillsManager.ts、skillInvocation.ts、McpHub.ts、events.ts、prompts-system.ts(=src/core/prompts/system.ts)。