学习笔记 · Obsidian
Deep Agents Code:MCP、子代理、记忆、技能、插件与 Hooks
扩展面与信任面
| 扩展 | 加入什么 | 风险等级 |
|---|---|---|
| Memory | 启动常驻指令与持久经验 | 可形成持久提示注入 |
| Skill | 按需工作流、脚本、参考和资产 | 指令注入;脚本可执行 |
| Subagent | 专门角色与模型 | 继承主工具,扩大调用面 |
| MCP | 外部工具/API/本地子进程 | 本机命令、SSRF、环境变量外传 |
| Plugin | 打包 skills、MCP、hooks | 一次启用多种可执行能力 |
| Hook | 生命周期上的外部命令与决策 | 直接以用户权限执行代码 |
安装、启用或信任这些内容等于授权代码或指令进入 Agent 执行链。仓库内容、插件市场和 MCP URL 都要按可执行供应链处理。
MCP 配置与合并
.mcp.json 自动发现顺序从低到高:
~/.deepagents/.mcp.json<project>/.deepagents/.mcp.json<project>/.mcp.json- 显式
--mcp-config(最高)
以 server name 合并;同名时高优先级的整个 server object 替换旧对象,不做深合并。项目根 .mcp.json 兼容 Claude Code。--no-mcp 与 --mcp-config 互斥。
传输类型:
- stdio:
command、args、env,作为子进程常驻。 - SSE / HTTP:
url、headers,可选auth: "oauth"。 - Header 的
${VAR}在 server 激活时从父 shell 解析;一个变量缺失只使该 server 失败。
Server name 只能匹配 [A-Za-z0-9_-]+,避免名称进入 OAuth 文件名时产生路径或 shell 注入。
工具收窄
每个 server 可设置 allowedTools 或 disabledTools,二者互斥且不能是空列表。条目支持 literal 与 fnmatch glob,同时匹配裸工具名和 server-prefixed 名称。
Auto 模式只在以下条件全部满足时把 MCP 工具当作只读:readOnlyHint === true、destructiveHint 非真、所有标准 hints 都是 Boolean/null。该 annotation 是 MCP server 自我声明,dcode 不验证实际副作用,因此不能当成强安全证明。
OAuth 与状态
HTTP/SSE 可用 auth: "oauth",与 Authorization header 互斥。dcode mcp login <server> 支持标准 PKCE、Slack 特例和 GitHub device flow。Token 目录权限为 0700,文件 0600,以 URL hash 区分同名 dev/prod server,并用临时文件 + rename 原子写入。
Server 状态为 ok、unauthenticated 或 error;单个失败不会阻断整个 Agent,/mcp 可查看原因和工具列表。刷新 token 失败时 server 进入 unauthenticated,重新 login 后可恢复当前会话。
项目 MCP 默认拒绝
项目 MCP 既可能启动本地命令,也可能向任意 URL 发请求并把 ${VAR} 放进 headers。因此:
- 交互模式首次逐 server 显示 command / URL,支持只允许本次或保存 approval。
- 保存项绑定 resolved project root、server name 与整个定义的 SHA-256 fingerprint;定义变更必须重新批准。
- headless 未批准项静默跳过,除非当前 run 显式
--trust-project-mcp。 - deny policy 胜过 saved approval 与 trust flag。
- 用户级 MCP 始终信任,等同信任自己的全局 config。
- OAuth login 同样遵守项目 trust,防止恶意 header 在登录阶段拉取 secrets。
按名称全局预批准的 DEEPAGENTS_CODE_DANGEROUSLY_ENABLE_PROJECT_MCP_SERVERS 是逃生口:不同项目或定义变更只要同名仍会命中。优先保存带 fingerprint 的 approval。
Subagents
自定义同步子代理放在:
- 用户:
~/.deepagents/{agent}/agents/<name>/AGENTS.md - 项目:
.deepagents/agents/<name>/AGENTS.md
项目同名覆盖用户。YAML frontmatter 必填 name、description,可选 model;Markdown 正文成为 system prompt。文件方式不能配置 tools、middleware、interrupt_on 或 skills,自定义 subagent 继承主 Agent tools;需要完整控制时使用 SDK。
dcode 当前不向最终用户暴露 async subagents。同步 task 与动态 subagents 可用:内置 JavaScript interpreter 让 Agent 在 eval 内用 task() 扇出。提示中使用“workflow”会倾向启动这类编排,TUI 按 phase 展示动态子代理。
可用较便宜模型覆盖 general-purpose 子代理,降低简单调查成本。安全上要注意:Auto 的父级审批不覆盖子代理内部动作,且文件式 subagent 无法单独收窄工具。
Memory
dcode 会在 ~/.deepagents/<agent>/memories/ 按主题保存 Markdown,流程是任务前检索、执行不确定时再查、完成后学习。/remember [context] 可显式要求从当前对话更新 memory 与 skills。
常驻指令来源包括用户 AGENTS.md、项目 .deepagents/AGENTS.md 与项目根 AGENTS.md,依次拼接。额外项目知识文件不会自动加载,需从 AGENTS.md 引用。
使用边界:
- 全局 memory:个人风格、通用编码偏好、跨项目方法。
- 项目 memory:架构、约束、测试和发布规则。
- 详细任务流程:放 Skill,不常驻。
- 自动学习内容要可审计;不要让不可信仓库文本自动写入跨项目 memory。
memory-and-skills 页只列 .deepagents/AGENTS.md,而 configuration 页明确根 AGENTS.md 也会加载;实际数据位置与拼接顺序以配置诊断和 configuration 页为准。
Skills
Skill 按 Agent Skills 规范组织,启动只读 name/description,命中时读完整 SKILL.md。/reload 重新发现。
目录优先级从低到高:
- 用户 dcode skills
- 用户
.agents/skills - 项目
.deepagents/skills - 项目
.agents/skills
同名整体覆盖。Symlink 解析必须留在标准 skill roots;确有共享资产时用 extra allowlist,但它只扩大 containment,不增加 discovery 目录。
Skills 可用:
dcode skills create/info/list/delete/skill:<name> [args]会话内直接注入--skill启动时调用- 外部 Agent Skills CLI 安装 community skills
项目级安装适用于任意 Agent;全局 community install 默认只进 ~/.deepagents/agent/skills/,自定义 named agent 需显式链接或用项目安装。
Plugins 与 marketplaces
Plugin 可同时贡献 skills、MCP server 与 hooks,支持 .claude-plugin/plugin.json 和 .codex-plugin/plugin.json。Manifest 可省略;默认发现根 SKILL.md/skills/、.mcp.json、hooks/hooks.json。
路径必须以 ./ 开头、留在 plugin root 且不能含 ..。Plugin skills 使用 plugin@marketplace namespace,避免与项目和用户 skills 冲突。MCP 与 hooks 可引用 plugin root、writable data dir 与 project dir。
Marketplace 可来自 GitHub repo、HTTPS Git、HTTPS JSON 或本地目录/文件。远端只允许 HTTPS;直接 JSON catalog 不能引用未下载的本地相对 plugin 目录。
启用 plugin 是其 hooks 的唯一 consent gate;project workspace trust 不会再次拦 plugin hooks。安装后先审查 manifest、MCP commands/URLs 和 hook events,再启用并 /reload。
Hooks
Hooks 把 lifecycle event 作为 JSON 写入外部命令 stdin,并根据 exit code/stdout 汇总 allow、deny、context 或 continue。配置位置:用户 ~/.deepagents/hooks.json、项目 .deepagents/hooks.json、plugin hooks。
优先级为项目 → 用户 → plugin。所有匹配 handler 并发执行;高优先级只决定冲突结果,不阻止低优先级 handler 已产生副作用。因此不能把“高优先级 deny”当作低优先级 hook 不运行。
项目 hooks 需要 workspace trust;headless 必须显式 trust flag。Plugin hooks 由 plugin enable 授权。
Handler 安全
command走 shell,支持管道/重定向;优先使用argv跳过 shell 解释。- Payload 始终走 stdin,不插值到参数。
- 默认超时 600 秒,
UserPromptSubmit默认 30 秒。 - 环境会剥离名称含 KEY/TOKEN/SECRET/PASSWORD/APIKEY 的变量;需要认证时从 secret manager 或受控文件读取。
- 配置在启动时快照,只有
/reload/ 新会话生效。
事件
客户端事件:SessionStart、UserPromptSubmit、SessionEnd、PermissionRequest、Notification。服务端事件:PreToolUse、PostToolUse、PreCompact、Stop、SubagentStart、SubagentStop。
PreToolUse 在权限 prompt 与执行前发生,是主要治理点;多个结果按 deny > ask > allow。PermissionRequest 可代表用户回答审批。PostToolUse 只能追加反馈,无法撤销已发生动作。
Stop 可阻止结束并把反馈送回 Agent,但要检查 stop_hook_active 防止循环;系统硬限制连续继续 8 次。SessionStart、UserPromptSubmit、SubagentStart 可注入上下文;SubagentStop 只能给主 Agent 加上下文,不能恢复已结束子代理。
Exit code 语义:0 解析 JSON;2 走该事件的阻断/反馈路径;其他非零只诊断并继续。JSON 必须是 stdout 唯一内容。单个 stdout/stderr 最多保留 100,000 bytes。
不支持的兼容字段
当前不应用 updatedInput、updatedToolOutput、defer、updatedPermissions、sessionTitle、watchPaths 等字段,只诊断并回退。不要从 Claude/Codex 兼容格式推断 dcode 会修改工具参数或保存权限规则。
安全基线
- 不可信项目:拒绝 project MCP 与 hooks,使用 remote sandbox。
- MCP:先 allowlist tools,再审 command、URL、headers 和 OAuth scope。
- Plugin:把 enable 视为同时批准指令、网络、子进程与 lifecycle code。
- Hooks:用
argv、固定可执行文件、最小输入与超时;记住所有 handler 都会跑。 - Memory:区分用户级与项目级,避免不可信内容写入跨项目长期记忆。
- Skills:校验 symlink containment,项目 override 视作仓库代码审查的一部分。