<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>LangChain on 麻辣香郭的精神家园</title><link>https://malaxg.top/tags/langchain/</link><description>Recent content in LangChain on 麻辣香郭的精神家园</description><generator>Hugo</generator><language>zh-CN</language><lastBuildDate>Sat, 25 Jul 2026 21:30:00 +0800</lastBuildDate><atom:link href="https://malaxg.top/tags/langchain/index.xml" rel="self" type="application/rss+xml"/><item><title>Deep Agents 学习文档</title><link>https://malaxg.top/posts/deepagents-learning-guide/</link><pubDate>Sat, 25 Jul 2026 21:30:00 +0800</pubDate><guid>https://malaxg.top/posts/deepagents-learning-guide/</guid><description>&lt;p&gt;更新日期：2026-07-31&lt;br&gt;
适用对象：已经了解 Python、LLM API、基础 Agent/工具调用，想系统学习 LangChain &lt;code&gt;deepagents&lt;/code&gt; 框架的人。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;说明：&lt;code&gt;deepagents&lt;/code&gt; 仍在快速演进（部分能力需要 &lt;code&gt;deepagents&amp;gt;=0.7&lt;/code&gt;）。本文按当前官方文档与 GitHub 仓库整理，写项目时应以官方文档和 API reference 为准。本次更新补充了 &lt;strong&gt;中间件机制、shell/沙箱、解释器、MCP 集成、上下文压缩内部机制、内置工具完整清单、生态与多语言版本&lt;/strong&gt;，并新增了三张可读的 SVG 图解。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="deepagents-hero" id="deepagents-start"&gt;
&lt;div class="deepagents-hero__copy"&gt;
&lt;span class="deepagents-kicker"&gt;DEEP AGENTS / FIELD GUIDE&lt;/span&gt;
&lt;p class="deepagents-hero__title"&gt;把复杂任务交给一个会规划、会协作、会记笔记的 Agent。&lt;/p&gt;
&lt;p class="deepagents-hero__lede"&gt;这不是 API 目录，而是一条从“跑通第一个 agent”到“设计生产系统”的学习路径。先看 SVG 图，再读代码，最后用一个博客选题研究 Agent 把知识串起来。&lt;/p&gt;
&lt;div class="deepagents-hero__actions"&gt;
&lt;a href="#deepagents-roadmap"&gt;查看学习路线 &lt;span aria-hidden="true"&gt;&amp;rarr;&lt;/span&gt;&lt;/a&gt;
&lt;a class="deepagents-hero__action--quiet" href="#deepagents-architecture"&gt;先看架构图&lt;/a&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="deepagents-hero__signal" aria-label="Deep Agents 核心执行闭环"&gt;
&lt;span class="deepagents-kicker"&gt;THE CORE LOOP&lt;/span&gt;
&lt;svg class="deepagents-hero__loop" viewBox="0 0 200 200" aria-hidden="true"&gt;
&lt;defs&gt;
&lt;marker id="loopArrow" markerWidth="8" markerHeight="8" refX="4" refY="4" orient="auto"&gt;&lt;path d="M0 0 L8 4 L0 8 z" fill="currentColor"/&gt;&lt;/marker&gt;
&lt;/defs&gt;
&lt;circle cx="100" cy="100" r="72" fill="none" stroke="currentColor" stroke-width="1.4" stroke-dasharray="4 6" opacity="0.5"/&gt;
&lt;path d="M100 34 A66 66 0 0 1 157 133" fill="none" stroke="currentColor" stroke-width="2.4" marker-end="url(#loopArrow)"/&gt;
&lt;path d="M150 145 A66 66 0 0 1 43 145" fill="none" stroke="currentColor" stroke-width="2.4" marker-end="url(#loopArrow)"/&gt;
&lt;path d="M43 133 A66 66 0 0 1 100 34" fill="none" stroke="currentColor" stroke-width="2.4" opacity="0.85"/&gt;
&lt;g class="deepagents-hero__loop-dot"&gt;&lt;circle cx="100" cy="28" r="7"/&gt;&lt;circle cx="158" cy="128" r="7"/&gt;&lt;circle cx="100" cy="168" r="7"/&gt;&lt;circle cx="42" cy="128" r="7"/&gt;&lt;/g&gt;
&lt;text x="100" y="16" text-anchor="middle"&gt;Plan&lt;/text&gt;
&lt;text x="182" y="132" text-anchor="middle"&gt;Work&lt;/text&gt;
&lt;text x="100" y="190" text-anchor="middle"&gt;Delegate&lt;/text&gt;
&lt;text x="20" y="132" text-anchor="middle"&gt;Review&lt;/text&gt;
&lt;/svg&gt;
&lt;strong&gt;Plan &amp;rarr; Work &amp;rarr; Delegate &amp;rarr; Review&lt;/strong&gt;
&lt;div class="deepagents-hero__steps"&gt;
&lt;span&gt;&lt;b&gt;01&lt;/b&gt;规划&lt;/span&gt;
&lt;span&gt;&lt;b&gt;02&lt;/b&gt;执行&lt;/span&gt;
&lt;span&gt;&lt;b&gt;03&lt;/b&gt;委派&lt;/span&gt;
&lt;span&gt;&lt;b&gt;04&lt;/b&gt;验收&lt;/span&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="deepagents-roadmap" id="deepagents-roadmap"&gt;
&lt;div class="deepagents-roadmap__head"&gt;
&lt;div&gt;
&lt;span class="deepagents-kicker"&gt;LEARNING MAP / 07 DAYS&lt;/span&gt;
&lt;p class="deepagents-roadmap__title"&gt;从一个工具调用，走到一套可控的 Agent 系统&lt;/p&gt;</description><content:encoded><![CDATA[<p>更新日期：2026-07-31<br>
适用对象：已经了解 Python、LLM API、基础 Agent/工具调用，想系统学习 LangChain <code>deepagents</code> 框架的人。</p>
<blockquote>
<p>说明：<code>deepagents</code> 仍在快速演进（部分能力需要 <code>deepagents&gt;=0.7</code>）。本文按当前官方文档与 GitHub 仓库整理，写项目时应以官方文档和 API reference 为准。本次更新补充了 <strong>中间件机制、shell/沙箱、解释器、MCP 集成、上下文压缩内部机制、内置工具完整清单、生态与多语言版本</strong>，并新增了三张可读的 SVG 图解。</p>
</blockquote>
<div class="deepagents-hero" id="deepagents-start">
  <div class="deepagents-hero__copy">
    <span class="deepagents-kicker">DEEP AGENTS / FIELD GUIDE</span>
    <p class="deepagents-hero__title">把复杂任务交给一个会规划、会协作、会记笔记的 Agent。</p>
    <p class="deepagents-hero__lede">这不是 API 目录，而是一条从“跑通第一个 agent”到“设计生产系统”的学习路径。先看 SVG 图，再读代码，最后用一个博客选题研究 Agent 把知识串起来。</p>
    <div class="deepagents-hero__actions">
      <a href="#deepagents-roadmap">查看学习路线 <span aria-hidden="true">&rarr;</span></a>
      <a class="deepagents-hero__action--quiet" href="#deepagents-architecture">先看架构图</a>
    </div>
  </div>
  <div class="deepagents-hero__signal" aria-label="Deep Agents 核心执行闭环">
    <span class="deepagents-kicker">THE CORE LOOP</span>
    <svg class="deepagents-hero__loop" viewBox="0 0 200 200" aria-hidden="true">
      <defs>
        <marker id="loopArrow" markerWidth="8" markerHeight="8" refX="4" refY="4" orient="auto"><path d="M0 0 L8 4 L0 8 z" fill="currentColor"/></marker>
      </defs>
      <circle cx="100" cy="100" r="72" fill="none" stroke="currentColor" stroke-width="1.4" stroke-dasharray="4 6" opacity="0.5"/>
      <path d="M100 34 A66 66 0 0 1 157 133" fill="none" stroke="currentColor" stroke-width="2.4" marker-end="url(#loopArrow)"/>
      <path d="M150 145 A66 66 0 0 1 43 145" fill="none" stroke="currentColor" stroke-width="2.4" marker-end="url(#loopArrow)"/>
      <path d="M43 133 A66 66 0 0 1 100 34" fill="none" stroke="currentColor" stroke-width="2.4" opacity="0.85"/>
      <g class="deepagents-hero__loop-dot"><circle cx="100" cy="28" r="7"/><circle cx="158" cy="128" r="7"/><circle cx="100" cy="168" r="7"/><circle cx="42" cy="128" r="7"/></g>
      <text x="100" y="16" text-anchor="middle">Plan</text>
      <text x="182" y="132" text-anchor="middle">Work</text>
      <text x="100" y="190" text-anchor="middle">Delegate</text>
      <text x="20" y="132" text-anchor="middle">Review</text>
    </svg>
    <strong>Plan &rarr; Work &rarr; Delegate &rarr; Review</strong>
    <div class="deepagents-hero__steps">
      <span><b>01</b>规划</span>
      <span><b>02</b>执行</span>
      <span><b>03</b>委派</span>
      <span><b>04</b>验收</span>
    </div>
  </div>
</div>
<div class="deepagents-roadmap" id="deepagents-roadmap">
  <div class="deepagents-roadmap__head">
    <div>
      <span class="deepagents-kicker">LEARNING MAP / 07 DAYS</span>
      <p class="deepagents-roadmap__title">从一个工具调用，走到一套可控的 Agent 系统</p>
    </div>
    <span class="deepagents-roadmap__status">建议顺序：上到下</span>
  </div>
  <ol class="deepagents-roadmap__list">
    <li><span>01</span><strong>基础</strong><small>安装、模型、最小 agent</small></li>
    <li><span>02</span><strong>工具</strong><small>让模型知道何时调用</small></li>
    <li><span>03</span><strong>上下文</strong><small>文件、backend、权限</small></li>
    <li><span>04</span><strong>协作</strong><small>subagents 与 task</small></li>
    <li><span>05</span><strong>长期化</strong><small>skills、memory、HITL</small></li>
    <li><span>06</span><strong>进阶</strong><small>middleware、sandbox、压缩</small></li>
    <li><span>07</span><strong>评测</strong><small>streaming、tracing、验收</small></li>
  </ol>
</div>
<div class="deepagents-visual" id="deepagents-architecture" aria-label="Deep Agents 分层架构图">
  <div class="deepagents-visual__head">
    <span class="deepagents-kicker">FIGURE 01 / ARCHITECTURE</span>
    <span class="deepagents-visual__hint">先记住：Deep Agents 是上层 harness</span>
  </div>
  <div class="deepagents-stack">
    <div class="deepagents-stack__layer deepagents-stack__layer--product"><span>你的业务层</span><strong>Tools &middot; Skills &middot; Memory</strong><small>把领域知识、权限和业务动作接入 agent</small></div>
    <div class="deepagents-stack__connector" aria-hidden="true">&darr;</div>
    <div class="deepagents-stack__layer deepagents-stack__layer--deep"><span>Deep Agents</span><strong>Planning &middot; Filesystem &middot; Subagents</strong><small>复杂任务默认需要的工作台和护栏</small></div>
    <div class="deepagents-stack__connector" aria-hidden="true">&darr;</div>
    <div class="deepagents-stack__layer deepagents-stack__layer--runtime"><span>LangChain + LangGraph</span><strong>Agent loop &middot; State &middot; Runtime</strong><small>模型、工具调用、状态和执行图</small></div>
    <div class="deepagents-stack__connector" aria-hidden="true">&darr;</div>
    <div class="deepagents-stack__layer deepagents-stack__layer--model"><span>模型与基础设施</span><strong>LLM &middot; Checkpointer &middot; Store</strong><small>推理能力、会话恢复和持久化</small></div>
  </div>
  <p class="deepagents-visual__caption">把它理解成“积木 + 运行时 + 工程脚手架”：你仍然拥有 LangChain/LangGraph 的控制力，但不用每次从零拼出复杂 agent 的基础能力。</p>
</div>
<div class="deepagents-visual deepagents-visual--flow" aria-label="Deep Agents 任务执行流程图">
  <div class="deepagents-visual__head">
    <span class="deepagents-kicker">FIGURE 02 / EXECUTION LOOP</span>
    <span class="deepagents-visual__hint">大任务的中间产物要离开对话窗口</span>
  </div>
  <div class="deepagents-flow">
    <div class="deepagents-flow__node deepagents-flow__node--input"><span>01</span><strong>目标</strong><small>用户提出一个复杂问题</small></div>
    <span class="deepagents-flow__arrow" aria-hidden="true">&rarr;</span>
    <div class="deepagents-flow__node deepagents-flow__node--plan"><span>02</span><strong>计划</strong><small><code>write_todos</code> 拆解步骤</small></div>
    <span class="deepagents-flow__arrow" aria-hidden="true">&rarr;</span>
    <div class="deepagents-flow__node deepagents-flow__node--work"><span>03</span><strong>工作区</strong><small>笔记与结果写入文件</small></div>
    <span class="deepagents-flow__arrow" aria-hidden="true">&rarr;</span>
    <div class="deepagents-flow__node deepagents-flow__node--delegate"><span>04</span><strong>委派</strong><small><code>task</code> 调用 subagent</small></div>
    <span class="deepagents-flow__arrow" aria-hidden="true">&rarr;</span>
    <div class="deepagents-flow__node deepagents-flow__node--review"><span>05</span><strong>交付</strong><small>主 agent 汇总并验收</small></div>
  </div>
</div>
<div class="deepagents-capability-map" aria-label="Deep Agents 能力地图">
  <div class="deepagents-capability-map__intro">
    <span class="deepagents-kicker">CAPABILITY MAP</span>
    <p>学习时可以把每个概念放回这八个问题里。</p>
  </div>
  <div class="deepagents-capability-map__grid">
    <div><span>PLAN</span><strong>怎么拆任务？</strong><small><code>write_todos</code></small></div>
    <div><span>CONTEXT</span><strong>信息放在哪里？</strong><small>filesystem / backend</small></div>
    <div><span>DELEGATE</span><strong>谁来做子任务？</strong><small>subagents / <code>task</code></small></div>
    <div><span>EXECUTE</span><strong>怎么跑命令？</strong><small>sandbox / <code>execute</code></small></div>
    <div><span>EXTEND</span><strong>怎么接外部系统？</strong><small>tools / MCP</small></div>
    <div><span>REUSE</span><strong>什么值得长期记住？</strong><small>skills / memory</small></div>
    <div><span>CONTROL</span><strong>危险动作谁批准？</strong><small>permissions / HITL</small></div>
    <div><span>ASSEMBLE</span><strong>默认行为怎么改？</strong><small>middleware</small></div>
  </div>
</div>
<div class="deepagents-metrics" aria-label="Deep Agents 关键默认参数速览">
  <div class="deepagents-metrics__head">
    <span class="deepagents-kicker">KEY DEFAULTS / 记住这几个阈值</span>
    <p>这些数字直接决定 agent 在长任务里的行为，调优前先记住默认值。</p>
  </div>
  <div class="deepagents-metrics__grid">
    <div class="deepagents-metric">
      <svg viewBox="0 0 24 24" aria-hidden="true" width="26" height="26"><path d="M4 4h16v4H4zM4 10h16v4H4zM4 16h10v4H4z" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linejoin="round"/></svg>
      <strong>20K</strong>
      <span>token</span>
      <small>单次工具输入/输出超过约 2 万 token 就卸载到文件。</small>
    </div>
    <div class="deepagents-metric">
      <svg viewBox="0 0 36 36" aria-hidden="true" width="26" height="26"><circle cx="18" cy="18" r="15" fill="none" stroke="currentColor" stroke-width="3" opacity="0.25"/><circle cx="18" cy="18" r="15" fill="none" stroke="currentColor" stroke-width="3" stroke-dasharray="80 94" stroke-linecap="round" transform="rotate(-90 18 18)"/></svg>
      <strong>85%</strong>
      <span>上下文</span>
      <small>越过模型窗口约 85% 且无可卸载内容时触发摘要。</small>
    </div>
    <div class="deepagents-metric">
      <svg viewBox="0 0 24 24" aria-hidden="true" width="26" height="26"><path d="M4 6h16M4 12h10M4 18h13" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/></svg>
      <strong>10</strong>
      <span>行预览</span>
      <small>卸载后对话里只留路径指针 + 文件前 10 行预览。</small>
    </div>
    <div class="deepagents-metric">
      <svg viewBox="0 0 24 24" aria-hidden="true" width="26" height="26"><path d="M12 3l3 3-3 3-3-3zM12 15l3 3-3 3-3-3zM3 12l3-3 3 3-3 3zM15 12l3-3 3 3-3 3z" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linejoin="round"/></svg>
      <strong>0.7+</strong>
      <span>版本</span>
      <small>替换中间件、<code>delete</code>、文件工具白名单等需要此版本。</small>
    </div>
  </div>
</div>
<h2 id="svg-图解把-agent-过程变成可检查的图">SVG 图解：把 Agent 过程变成可检查的图</h2>
<p>SVG 不只是网页上的一张配图，它是一种可以被阅读、修改和版本控制的文本格式。对 Deep Agents 来说，SVG 最适合表达三件事：<strong>谁在做事、信息流向哪里、哪个动作需要人确认</strong>。</p>
<div class="deepagents-svg-lesson" id="deepagents-svg">
  <div class="deepagents-svg-lesson__intro">
    <span class="deepagents-kicker">SVG STUDY / READ THE SYSTEM</span>
    <p class="deepagents-svg-lesson__title">先读拓扑，再读 API，最后才写代码。</p>
    <p>下面这张图把一个“研究并交付报告”的任务拆成主 agent、文件工作区、subagents、HITL 和最终输出。你可以沿着箭头复述整个执行过程，而不是只记住一串参数名。</p>
  </div>
  <figure class="deepagents-svg-figure">
    <img src="/deepagents-learning/deepagents-execution-map.svg" alt="Deep Agents 执行拓扑图：用户目标经过主 Agent、文件工作区、子代理和人工批准后生成交付物" loading="lazy">
    <figcaption>图 03：一个可控的 Deep Agents 任务，把对话变成有边界、有中间产物、有验收点的工作流。</figcaption>
  </figure>
</div>
<h3 id="为什么用-svg而不是截图">为什么用 SVG，而不是截图</h3>
<ul>
<li><strong>可解释</strong>：节点、连线、标签都能对应到代码和运行时事件。</li>
<li><strong>可维护</strong>：SVG 是纯文本，可以和文章、代码一起进入 Git diff。</li>
<li><strong>可复用</strong>：同一张图可以嵌入博客、课程笔记、README 或演示页面。</li>
<li><strong>可访问</strong>：<code>title</code>、<code>desc</code>、<code>text</code> 和 <code>alt</code> 可以帮助读屏和搜索理解图的语义。</li>
</ul>
<figure class="deepagents-svg-figure deepagents-svg-figure--anatomy">
  <img src="/deepagents-learning/svg-anatomy.svg" alt="SVG 三个基本元素：rect 表示节点，path 表示关系，text 表示解释" loading="lazy">
  <figcaption>图 04：一张学习图通常可以先拆成 `rect`、`path`、`text` 三类 SVG 基元。</figcaption>
</figure>
<table>
	<thead>
			<tr>
					<th>SVG 部件</th>
					<th>图上表达什么</th>
					<th>Deep Agents 对应什么</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td><code>&lt;rect&gt;</code></td>
					<td>一个稳定的对象或边界</td>
					<td>主 agent、文件区、subagent、审批节点</td>
			</tr>
			<tr>
					<td><code>&lt;path&gt;</code></td>
					<td>有方向的关系或数据流</td>
					<td><code>write_todos</code>、<code>task</code>、工具调用、结果回传</td>
			</tr>
			<tr>
					<td><code>&lt;text&gt;</code></td>
					<td>让读者知道节点的语义</td>
					<td>工具名、路径、角色、交付物类型</td>
			</tr>
			<tr>
					<td><code>marker</code></td>
					<td>箭头的方向</td>
					<td>谁调用谁、谁等待谁、结果回到哪里</td>
			</tr>
	</tbody>
</table>
<h3 id="从一行-svg-回到一个-agent-概念">从一行 SVG 回到一个 Agent 概念</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span><span style="color:#f92672">&lt;path</span> <span style="color:#a6e22e">class=</span><span style="color:#e6db74">&#34;edge&#34;</span> <span style="color:#a6e22e">d=</span><span style="color:#e6db74">&#34;M 270 236 H 355&#34;</span> <span style="color:#f92672">/&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">&lt;rect</span> <span style="color:#a6e22e">class=</span><span style="color:#e6db74">&#34;process&#34;</span> <span style="color:#a6e22e">x=</span><span style="color:#e6db74">&#34;355&#34;</span> <span style="color:#a6e22e">y=</span><span style="color:#e6db74">&#34;160&#34;</span> <span style="color:#a6e22e">width=</span><span style="color:#e6db74">&#34;330&#34;</span> <span style="color:#a6e22e">height=</span><span style="color:#e6db74">&#34;168&#34;</span> <span style="color:#a6e22e">rx=</span><span style="color:#e6db74">&#34;10&#34;</span> <span style="color:#f92672">/&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">&lt;text</span> <span style="color:#a6e22e">x=</span><span style="color:#e6db74">&#34;381&#34;</span> <span style="color:#a6e22e">y=</span><span style="color:#e6db74">&#34;230&#34;</span><span style="color:#f92672">&gt;</span>主 Agent<span style="color:#f92672">&lt;/text&gt;</span>
</span></span></code></pre></div><p>把它翻译成人话：<strong>一条 path 表示“目标进入主 agent”的关系，rect 表示主 agent 这个执行节点，text 给节点补上可读的解释</strong>。如果你把 <code>path</code> 画反了，图就会误导读者；如果没有 <code>text</code>，图就只有形状，没有知识。</p>
<div class="deepagents-svg-practice">
  <span class="deepagents-kicker">SVG PRACTICE / 15 MIN</span>
  <strong>把一个真实任务画成 5 个节点</strong>
  <ol>
    <li>写下用户目标，标成 input。</li>
    <li>画出主 agent，并在旁边写出它会调用的工具。</li>
    <li>把大段研究资料放进 `/notes/`，把最终结果放进 `/outputs/`。</li>
    <li>用一个 subagent 节点表示独立研究或审查。</li>
    <li>给写入、发送、删除等副作用动作加一个 HITL 节点。</li>
  </ol>
</div>
<h2 id="1-一句话理解">1. 一句话理解</h2>
<p><code>deepagents</code> 是 LangChain 生态里的一个 Agent harness：它不是替代 LangChain/LangGraph 的底层框架，而是在 LangChain agent 与 LangGraph runtime 之上，把复杂任务常用能力预装好。</p>
<p>它默认帮你处理这些事：</p>
<ul>
<li>规划：内置 <code>write_todos</code>，让 agent 把复杂任务拆成步骤。</li>
<li>文件系统：内置 <code>ls</code>、<code>read_file</code>、<code>write_file</code>、<code>edit_file</code>、<code>glob</code>、<code>grep</code>、<code>delete</code>，让 agent 把大上下文写到文件里再检索。</li>
<li>子代理：内置 <code>task</code> 工具，可把复杂子任务交给隔离上下文的 subagent，也支持异步子代理。</li>
<li>上下文工程：大输入/大输出可 offload 到文件系统，长对话可自动总结（summarization）。</li>
<li>持久记忆：用文件形式保存长期 memory。</li>
<li>Skills：把专门工作流、领域知识、模板、脚本按需加载。</li>
<li>Shell 访问：配合 sandbox 后端提供 <code>execute</code>，在隔离环境里跑命令；也可用 QuickJS 解释器跑受限 JS。</li>
<li>工具生态：接入任意自定义函数或任意 MCP server。</li>
<li>Human-in-the-loop：对危险工具调用暂停并等待人类批准。</li>
<li>Streaming：基于 LangGraph streaming 查看主 agent 和 subagent 的执行过程。</li>
</ul>
<p>它由一整套 LangChain <strong>中间件（middleware）</strong> 组装而成，这是理解 Deep Agents 的关键：几乎每个内置能力都对应栈里的一个中间件，你可以替换、扩展或裁剪它们（见第 11 节）。</p>
<p>更简单地说：LangChain 给你积木，LangGraph 给你运行时，Deep Agents 给你一套“复杂任务 agent 默认应该有的脚手架”。它的设计取向是 opinionated（有主张）、extensible（可扩展不用 fork）、model-agnostic（任意支持 tool calling 的模型）、production-ready（基于 LangGraph 的流式、持久化、checkpoint，配合 LangSmith 追踪与评测）。</p>
<h2 id="2-什么时候该用-deep-agents">2. 什么时候该用 Deep Agents</h2>
<p>适合：</p>
<ul>
<li>研究报告、竞品分析、资料搜集、写作辅助这类多步骤任务。</li>
<li>编码助手、测试修复、文档维护这类需要读写文件和运行命令的任务。</li>
<li>需要把任务分给多个角色的系统，比如 researcher、critic、data-analyzer。</li>
<li>需要长期记住用户偏好、项目约定、历史经验的 agent。</li>
<li>需要审计、审批、权限控制的生产 agent。</li>
</ul>
<p>不一定适合：</p>
<ul>
<li>单轮聊天。</li>
<li>一个模型加一两个工具的简单问答。</li>
<li>你需要完全自定义状态机、严格控制每个节点和边的流程。这时直接用 LangGraph 往往更清楚。</li>
</ul>
<p>选择原则：</p>
<ul>
<li>简单工具调用：优先 <code>langchain.create_agent</code>。</li>
<li>强流程编排：优先 LangGraph。</li>
<li>长任务、多文件、多子任务、需要 memory/skills/HITL：优先 Deep Agents。</li>
</ul>
<h2 id="3-安装与环境">3. 安装与环境</h2>
<p>最小安装：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>pip install -U deepagents
</span></span></code></pre></div><p>如果使用 OpenAI：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>pip install -U deepagents langchain-openai
</span></span></code></pre></div><p>如果使用 Anthropic：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>pip install -U deepagents langchain-anthropic
</span></span></code></pre></div><p>如果使用 Google Gemini：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>pip install -U deepagents langchain-google-genai
</span></span></code></pre></div><p>Windows PowerShell 设置环境变量示例：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-powershell" data-lang="powershell"><span style="display:flex;"><span>$env:OPENAI_API_KEY=<span style="color:#e6db74">&#34;你的 API key&#34;</span>
</span></span><span style="display:flex;"><span>$env:DEEPAGENTS_MODEL=<span style="color:#e6db74">&#34;openai:gpt-5&#34;</span>
</span></span></code></pre></div><p>macOS/Linux 示例：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>export OPENAI_API_KEY<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;你的 API key&#34;</span>
</span></span><span style="display:flex;"><span>export DEEPAGENTS_MODEL<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;openai:gpt-5&#34;</span>
</span></span></code></pre></div><p>注意：</p>
<ul>
<li>模型必须支持 tool calling。</li>
<li><code>model</code> 可以传 <code>&quot;provider:model-name&quot;</code> 字符串，也可以传已经初始化好的 LangChain chat model。</li>
<li>官方默认模型和推荐模型会更新，项目里建议通过环境变量配置模型名。</li>
</ul>
<h2 id="4-最小可运行-agent">4. 最小可运行 Agent</h2>
<p>创建 <code>hello_deepagents.py</code>：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#f92672">import</span> os
</span></span><span style="display:flex;"><span><span style="color:#f92672">from</span> deepagents <span style="color:#f92672">import</span> create_deep_agent
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">get_weather</span>(city: str) <span style="color:#f92672">-&gt;</span> str:
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;&#34;&#34;Get mock weather for a city.&#34;&#34;&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> <span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;It is sunny in </span><span style="color:#e6db74">{</span>city<span style="color:#e6db74">}</span><span style="color:#e6db74">.&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>agent <span style="color:#f92672">=</span> create_deep_agent(
</span></span><span style="display:flex;"><span>    model<span style="color:#f92672">=</span>os<span style="color:#f92672">.</span>getenv(<span style="color:#e6db74">&#34;DEEPAGENTS_MODEL&#34;</span>, <span style="color:#e6db74">&#34;openai:gpt-5&#34;</span>),
</span></span><span style="display:flex;"><span>    tools<span style="color:#f92672">=</span>[get_weather],
</span></span><span style="display:flex;"><span>    system_prompt<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;You are a helpful assistant. Use tools when they are useful.&#34;</span>,
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>result <span style="color:#f92672">=</span> agent<span style="color:#f92672">.</span>invoke(
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#34;messages&#34;</span>: [
</span></span><span style="display:flex;"><span>            {<span style="color:#e6db74">&#34;role&#34;</span>: <span style="color:#e6db74">&#34;user&#34;</span>, <span style="color:#e6db74">&#34;content&#34;</span>: <span style="color:#e6db74">&#34;What is the weather in Chongqing?&#34;</span>}
</span></span><span style="display:flex;"><span>        ]
</span></span><span style="display:flex;"><span>    },
</span></span><span style="display:flex;"><span>    config<span style="color:#f92672">=</span>{<span style="color:#e6db74">&#34;configurable&#34;</span>: {<span style="color:#e6db74">&#34;thread_id&#34;</span>: <span style="color:#e6db74">&#34;demo-hello&#34;</span>}},
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(result[<span style="color:#e6db74">&#34;messages&#34;</span>][<span style="color:#f92672">-</span><span style="color:#ae81ff">1</span>]<span style="color:#f92672">.</span>content)
</span></span></code></pre></div><p>运行：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>python hello_deepagents.py
</span></span></code></pre></div><p>你要观察的不是天气结果，而是这几个点：</p>
<ul>
<li>函数 <code>get_weather</code> 被当作工具暴露给模型。</li>
<li>函数参数类型和 docstring 会影响模型是否正确调用工具。</li>
<li><code>create_deep_agent(...)</code> 返回的是一个可 invoke/stream 的 LangGraph compiled graph。</li>
<li><code>thread_id</code> 用来把同一个会话的状态串起来。</li>
</ul>
<h2 id="5-核心-apicreate_deep_agent">5. 核心 API：<code>create_deep_agent</code></h2>
<p>常用参数：</p>
<ul>
<li><code>model</code>：模型字符串或模型实例。</li>
<li><code>tools</code>：你提供给 agent 的业务工具。</li>
<li><code>system_prompt</code>：你的业务角色和任务要求。它会和 Deep Agents 的内置提示一起工作。</li>
<li><code>middleware</code>：扩展或拦截 agent 行为。</li>
<li><code>subagents</code>：定义自定义子代理。</li>
<li><code>backend</code>：文件系统后端，比如内存、磁盘、Store、sandbox。</li>
<li><code>skills</code>：skills 目录路径。</li>
<li><code>memory</code>：启动时加载到系统提示里的 memory 文件路径。</li>
<li><code>response_format</code>：结构化输出 schema。</li>
<li><code>interrupt_on</code>：为指定工具启用 human-in-the-loop。</li>
<li><code>checkpointer</code>：让线程状态可持久化；HITL 场景必需。</li>
</ul>
<p>Deep Agents 默认会挂载多类 middleware，包括 todo、filesystem、subagent、summarization 等。你通常先用默认值起步，只有遇到明确需求时再扩展 middleware。</p>
<h2 id="6-system-prompt-怎么写">6. System Prompt 怎么写</h2>
<p>Deep Agents 已经有一套内置系统提示，教模型如何规划、读写文件、调用子代理。你的 <code>system_prompt</code> 应该补充“业务身份”和“质量标准”，不要重复解释框架工具。</p>
<p>推荐结构：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>You are a research assistant for technical writing.
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Goals:
</span></span><span style="display:flex;"><span>- Produce accurate, sourced, concise reports.
</span></span><span style="display:flex;"><span>- Separate facts, assumptions, and recommendations.
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Workflow:
</span></span><span style="display:flex;"><span>- First clarify the task if necessary.
</span></span><span style="display:flex;"><span>- Use search tools for current or external facts.
</span></span><span style="display:flex;"><span>- Write large notes to files before synthesizing.
</span></span><span style="display:flex;"><span>- Use subagents for independent research branches.
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Output:
</span></span><span style="display:flex;"><span>- Start with the conclusion.
</span></span><span style="display:flex;"><span>- Include source links.
</span></span><span style="display:flex;"><span>- Mention uncertainty clearly.
</span></span></code></pre></div><p>常见错误：</p>
<ul>
<li>把 prompt 写成很长的操作手册，挤占上下文。</li>
<li>没有说明输出标准，导致结果散。</li>
<li>没有说明何时使用工具，模型会乱查或完全不查。</li>
<li>把用户每次变化的信息写进静态 <code>system_prompt</code>；动态偏好更适合 memory 或 runtime context。</li>
</ul>
<h2 id="7-工具设计">7. 工具设计</h2>
<p>Deep Agents 可以接收普通 callable、LangChain <code>@tool</code>、BaseTool 或 dict 工具。</p>
<p>一个好工具应该：</p>
<ul>
<li>名字明确，避免泛化成 <code>do_task</code>。</li>
<li>参数有类型标注。</li>
<li>docstring 写清楚何时使用、输入约束、返回内容。</li>
<li>返回结构化、紧凑、可被模型消费的数据。</li>
<li>对错误给出可读信息，不要只抛异常。</li>
</ul>
<p>示例：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#f92672">from</span> typing <span style="color:#f92672">import</span> Literal
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">search_articles</span>(
</span></span><span style="display:flex;"><span>    query: str,
</span></span><span style="display:flex;"><span>    max_results: int <span style="color:#f92672">=</span> <span style="color:#ae81ff">5</span>,
</span></span><span style="display:flex;"><span>    topic: Literal[<span style="color:#e6db74">&#34;general&#34;</span>, <span style="color:#e6db74">&#34;news&#34;</span>, <span style="color:#e6db74">&#34;technical&#34;</span>] <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;general&#34;</span>,
</span></span><span style="display:flex;"><span>) <span style="color:#f92672">-&gt;</span> dict:
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;&#34;&#34;Search article references for a query.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    Use this when the user asks for external or current information.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    Returns a dict with title, url, snippet, and published_at when available.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    &#34;&#34;&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> {
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#34;query&#34;</span>: query,
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#34;results&#34;</span>: [
</span></span><span style="display:flex;"><span>            {
</span></span><span style="display:flex;"><span>                <span style="color:#e6db74">&#34;title&#34;</span>: <span style="color:#e6db74">&#34;Example result&#34;</span>,
</span></span><span style="display:flex;"><span>                <span style="color:#e6db74">&#34;url&#34;</span>: <span style="color:#e6db74">&#34;https://example.com&#34;</span>,
</span></span><span style="display:flex;"><span>                <span style="color:#e6db74">&#34;snippet&#34;</span>: <span style="color:#e6db74">&#34;Short summary...&#34;</span>,
</span></span><span style="display:flex;"><span>                <span style="color:#e6db74">&#34;published_at&#34;</span>: <span style="color:#66d9ef">None</span>,
</span></span><span style="display:flex;"><span>            }
</span></span><span style="display:flex;"><span>        ],
</span></span><span style="display:flex;"><span>    }
</span></span></code></pre></div><p>工具设计的关键不是“能不能调用”，而是“模型能不能判断什么时候调用、怎么传参、如何解释返回”。</p>
<h2 id="8-内置文件系统能力">8. 内置文件系统能力</h2>
<p>Deep Agents 的一个核心思路是：不要把所有东西塞进上下文窗口，把中间资料、搜索结果、草稿、结构化产物写进文件系统。</p>
<p>常见内置文件工具：</p>
<ul>
<li><code>ls</code>：列目录，带大小和修改时间等元数据。</li>
<li><code>read_file</code>：读文件，带行号，支持 <code>offset</code>/<code>limit</code> 处理大文件；对图片、视频、音频、PDF/PPT 等可返回多模态内容块。</li>
<li><code>write_file</code>：写新文件或覆盖文件。</li>
<li><code>edit_file</code>：局部精确字符串替换，支持全局替换。</li>
<li><code>delete</code>：删除文件，或递归删除目录（需要 <code>deepagents&gt;=0.7</code>；不支持删除的后端会自动隐藏它）。</li>
<li><code>glob</code>：按 pattern 找文件，比如 <code>**/*.py</code>。</li>
<li><code>grep</code>：全文搜索，支持“仅文件名 / 带上下文 / 计数”等输出模式。</li>
<li><code>execute</code>：在环境里运行 shell 命令，<strong>仅 sandbox 后端可用</strong>（见第 10 节）。</li>
</ul>
<p><code>read_file</code> 支持的多模态扩展名大致包括：</p>
<ul>
<li>图片：<code>.png</code> <code>.jpg</code> <code>.jpeg</code> <code>.gif</code> <code>.webp</code> <code>.heic</code> <code>.heif</code></li>
<li>视频：<code>.mp4</code> <code>.mov</code> <code>.webm</code> <code>.avi</code> 等</li>
<li>音频：<code>.wav</code> <code>.mp3</code> <code>.flac</code> <code>.aac</code> <code>.ogg</code> 等</li>
<li>文档：<code>.pdf</code> <code>.ppt</code> <code>.pptx</code></li>
</ul>
<p>使用文件系统的价值：</p>
<ul>
<li>大工具返回结果可以先落盘，再摘要。</li>
<li>多轮任务可以复用中间产物。</li>
<li>subagent 可以把结果写成文件，主 agent 再读取。</li>
<li>memory 和 skills 都可以建立在文件抽象之上。</li>
</ul>
<p>实践建议：</p>
<ul>
<li>要求 agent 把大型研究资料写到 <code>/notes/</code> 或 <code>/workspace/</code>。</li>
<li>要求最终产物写成 <code>/outputs/report.md</code>。</li>
<li>对代码项目，只让 agent 操作工作区内路径。</li>
<li>对生产服务，避免直接暴露真实磁盘。</li>
</ul>
<h2 id="9-backends文件系统后端">9. Backends：文件系统后端</h2>
<p>Deep Agents 的文件工具不是只能操作真实磁盘。它们通过 backend 抽象读写不同存储。</p>
<figure class="deepagents-svg-figure">
  <img src="/deepagents-learning/backends-map.svg" alt="Deep Agents 后端选型地图：同一套文件工具通过 CompositeBackend 路由到 StateBackend、FilesystemBackend、StoreBackend 或 Sandbox 后端" loading="lazy">
  <figcaption>图 05：一套文件工具，四种存储位置。先按“数据活多久、给谁看、能不能执行命令”选后端，再用 CompositeBackend 按路径组合。</figcaption>
</figure>
<h3 id="91-statebackend">9.1 <code>StateBackend</code></h3>
<p>默认后端。文件存储在 LangGraph state 中，适合临时草稿和单线程会话。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#f92672">from</span> deepagents <span style="color:#f92672">import</span> create_deep_agent
</span></span><span style="display:flex;"><span><span style="color:#f92672">from</span> deepagents.backends <span style="color:#f92672">import</span> StateBackend
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>agent <span style="color:#f92672">=</span> create_deep_agent(
</span></span><span style="display:flex;"><span>    model<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;openai:gpt-5&#34;</span>,
</span></span><span style="display:flex;"><span>    backend<span style="color:#f92672">=</span>StateBackend(),
</span></span><span style="display:flex;"><span>)
</span></span></code></pre></div><p>适合：</p>
<ul>
<li>demo。</li>
<li>临时 scratchpad。</li>
<li>不希望 agent 碰真实文件系统的场景。</li>
</ul>
<h3 id="92-filesystembackend">9.2 <code>FilesystemBackend</code></h3>
<p>读写本地磁盘。适合本地开发和受控 CI，不建议直接放到 Web API 生产服务里。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#f92672">from</span> deepagents <span style="color:#f92672">import</span> create_deep_agent
</span></span><span style="display:flex;"><span><span style="color:#f92672">from</span> deepagents.backends <span style="color:#f92672">import</span> FilesystemBackend
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>agent <span style="color:#f92672">=</span> create_deep_agent(
</span></span><span style="display:flex;"><span>    model<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;openai:gpt-5&#34;</span>,
</span></span><span style="display:flex;"><span>    backend<span style="color:#f92672">=</span>FilesystemBackend(root_dir<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;.&#34;</span>, virtual_mode<span style="color:#f92672">=</span><span style="color:#66d9ef">True</span>),
</span></span><span style="display:flex;"><span>)
</span></span></code></pre></div><p>重点：</p>
<ul>
<li><code>root_dir</code> 限定根目录。</li>
<li><code>virtual_mode=True</code> 才能更好地把路径限制在 root 下。</li>
<li>本地磁盘读写有安全风险，尤其是 <code>.env</code>、密钥、私有代码。</li>
</ul>
<h3 id="93-storebackend">9.3 <code>StoreBackend</code></h3>
<p>把文件存进 LangGraph store，适合跨 thread 的长期数据。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#f92672">from</span> deepagents <span style="color:#f92672">import</span> create_deep_agent
</span></span><span style="display:flex;"><span><span style="color:#f92672">from</span> deepagents.backends <span style="color:#f92672">import</span> StoreBackend
</span></span><span style="display:flex;"><span><span style="color:#f92672">from</span> langgraph.store.memory <span style="color:#f92672">import</span> InMemoryStore
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>store <span style="color:#f92672">=</span> InMemoryStore()
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>agent <span style="color:#f92672">=</span> create_deep_agent(
</span></span><span style="display:flex;"><span>    model<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;openai:gpt-5&#34;</span>,
</span></span><span style="display:flex;"><span>    backend<span style="color:#f92672">=</span>StoreBackend(namespace<span style="color:#f92672">=</span><span style="color:#66d9ef">lambda</span> ctx: (<span style="color:#e6db74">&#34;demo-user&#34;</span>,)),
</span></span><span style="display:flex;"><span>    store<span style="color:#f92672">=</span>store,
</span></span><span style="display:flex;"><span>)
</span></span></code></pre></div><p>生产里要认真设计 namespace：</p>
<ul>
<li>用户级：<code>(user_id,)</code></li>
<li>租户级：<code>(tenant_id,)</code></li>
<li>agent 级：<code>(assistant_id,)</code></li>
</ul>
<p>不要让不同用户共享同一个 memory namespace，除非这就是你的产品设计。</p>
<h3 id="94-compositebackend">9.4 <code>CompositeBackend</code></h3>
<p>把不同路径路由到不同后端。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#f92672">from</span> deepagents <span style="color:#f92672">import</span> create_deep_agent
</span></span><span style="display:flex;"><span><span style="color:#f92672">from</span> deepagents.backends <span style="color:#f92672">import</span> CompositeBackend, StateBackend, StoreBackend
</span></span><span style="display:flex;"><span><span style="color:#f92672">from</span> langgraph.store.memory <span style="color:#f92672">import</span> InMemoryStore
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>store <span style="color:#f92672">=</span> InMemoryStore()
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>agent <span style="color:#f92672">=</span> create_deep_agent(
</span></span><span style="display:flex;"><span>    model<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;openai:gpt-5&#34;</span>,
</span></span><span style="display:flex;"><span>    backend<span style="color:#f92672">=</span>CompositeBackend(
</span></span><span style="display:flex;"><span>        default<span style="color:#f92672">=</span>StateBackend(),
</span></span><span style="display:flex;"><span>        routes<span style="color:#f92672">=</span>{
</span></span><span style="display:flex;"><span>            <span style="color:#e6db74">&#34;/memories/&#34;</span>: StoreBackend(namespace<span style="color:#f92672">=</span><span style="color:#66d9ef">lambda</span> ctx: (<span style="color:#e6db74">&#34;demo-user&#34;</span>,)),
</span></span><span style="display:flex;"><span>        },
</span></span><span style="display:flex;"><span>    ),
</span></span><span style="display:flex;"><span>    store<span style="color:#f92672">=</span>store,
</span></span><span style="display:flex;"><span>)
</span></span></code></pre></div><p>常见组合：</p>
<ul>
<li><code>/workspace/</code>：临时 StateBackend。</li>
<li><code>/memories/</code>：持久 StoreBackend。</li>
<li><code>/docs/</code>：只读自定义 backend。</li>
<li><code>/outputs/</code>：本地磁盘或对象存储。</li>
</ul>
<h2 id="10-permissions路径权限">10. Permissions：路径权限</h2>
<p>如果 agent 能读写文件，必须考虑权限。</p>
<p>基础示例：只允许访问 <code>/workspace/</code>，其他全部拒绝。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#f92672">from</span> deepagents <span style="color:#f92672">import</span> FilesystemPermission, create_deep_agent
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>agent <span style="color:#f92672">=</span> create_deep_agent(
</span></span><span style="display:flex;"><span>    model<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;openai:gpt-5&#34;</span>,
</span></span><span style="display:flex;"><span>    backend<span style="color:#f92672">=</span>backend,
</span></span><span style="display:flex;"><span>    permissions<span style="color:#f92672">=</span>[
</span></span><span style="display:flex;"><span>        FilesystemPermission(
</span></span><span style="display:flex;"><span>            operations<span style="color:#f92672">=</span>[<span style="color:#e6db74">&#34;read&#34;</span>, <span style="color:#e6db74">&#34;write&#34;</span>],
</span></span><span style="display:flex;"><span>            paths<span style="color:#f92672">=</span>[<span style="color:#e6db74">&#34;/workspace/**&#34;</span>],
</span></span><span style="display:flex;"><span>            mode<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;allow&#34;</span>,
</span></span><span style="display:flex;"><span>        ),
</span></span><span style="display:flex;"><span>        FilesystemPermission(
</span></span><span style="display:flex;"><span>            operations<span style="color:#f92672">=</span>[<span style="color:#e6db74">&#34;read&#34;</span>, <span style="color:#e6db74">&#34;write&#34;</span>],
</span></span><span style="display:flex;"><span>            paths<span style="color:#f92672">=</span>[<span style="color:#e6db74">&#34;/**&#34;</span>],
</span></span><span style="display:flex;"><span>            mode<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;deny&#34;</span>,
</span></span><span style="display:flex;"><span>        ),
</span></span><span style="display:flex;"><span>    ],
</span></span><span style="display:flex;"><span>)
</span></span></code></pre></div><p>要点：</p>
<ul>
<li><code>operations=[&quot;read&quot;]</code> 覆盖 <code>ls</code>、<code>read_file</code>、<code>glob</code>、<code>grep</code>。</li>
<li><code>operations=[&quot;write&quot;]</code> 覆盖 <code>write_file</code>、<code>edit_file</code>。</li>
<li>规则按顺序匹配，first match wins。</li>
<li>如果没有任何规则匹配，默认允许。</li>
<li>permissions 只管内置文件系统工具，不管自定义工具、MCP 工具，也不管 sandbox 里的任意 shell 命令。</li>
</ul>
<p>生产建议：</p>
<ul>
<li>先 deny，再精确 allow，或者显式 allow 工作区后 deny 全部。</li>
<li>secrets、配置、凭据目录默认不可读。</li>
<li>写操作配合 HITL。</li>
<li>对自定义工具单独做权限校验。</li>
</ul>
<h2 id="11-middlewaredeep-agents-的装配层">11. Middleware：Deep Agents 的装配层</h2>
<p>Deep Agents 并不是一个黑盒。<code>create_deep_agent</code> 实际上是把一整套 LangChain <strong>中间件</strong>按固定顺序组装成一条流水线。理解这条流水线，你就能精确地替换、扩展或裁剪它的默认行为。</p>
<figure class="deepagents-svg-figure">
  <img src="/deepagents-learning/middleware-stack.svg" alt="Deep Agents 默认中间件栈：请求依次穿过 Skills、Filesystem、SubAgent、Summarization、PatchToolCalls、PromptCaching、Memory、HumanInTheLoop 等中间件" loading="lazy">
  <figcaption>图 06：一次请求穿过默认中间件栈。蓝色始终启用，黄色按参数启用，绿色是核心支架。</figcaption>
</figure>
<p>主 agent 的默认栈大致顺序：</p>
<ol>
<li><code>SkillsMiddleware</code>：传入 <code>skills</code> 时启用，注入在文件系统中间件<strong>之前</strong>，先拿到 skill 元数据。</li>
<li><code>FilesystemMiddleware</code>：处理读写与目录操作，传入 <code>permissions</code> 时权限校验在此执行。它是必需支架，不能被移除。</li>
<li><code>SubAgentMiddleware</code>：生成并协调子代理，只有主 agent 暴露 <code>task</code> 工具。</li>
<li><code>SummarizationMiddleware</code>：对话过长时压缩历史。</li>
<li><code>PatchToolCallsMiddleware</code>：修复中断恢复后遗留的悬空工具调用。</li>
<li><code>AsyncSubAgentMiddleware</code>：配置了异步子代理时启用。</li>
<li><strong>你传入的中间件</strong>：在 Patch 之后合并。</li>
<li>Harness profile 附带的供应商专用中间件、排除工具过滤。</li>
<li>Prompt caching（Anthropic / Bedrock）：始终注册，对不支持的模型 no-op。</li>
<li><code>MemoryMiddleware</code>：传入 <code>memory</code> 时启用，放在缓存之后减少缓存前缀失效。</li>
<li><code>HumanInTheLoopMiddleware</code>：传入 <code>interrupt_on</code> 时启用。</li>
</ol>
<h3 id="111-替换默认中间件">11.1 替换默认中间件</h3>
<p>传入的中间件按 <code>.name</code> 与默认栈匹配：<strong>名字相同则原地替换，名字不同则插入到 <code>PatchToolCallsMiddleware</code> 之后</strong>。替换需要 <code>deepagents&gt;=0.7</code>。</p>
<p>注意：替换是<strong>完全覆盖，不是合并</strong>，替换实例必须自己配置好所有参数。尤其覆盖 <code>FilesystemMiddleware</code> 时，必须直接把 <code>backend</code>（和 <code>permissions</code>）传给它，它不会从 <code>create_deep_agent()</code> 继承。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#f92672">from</span> deepagents <span style="color:#f92672">import</span> create_deep_agent
</span></span><span style="display:flex;"><span><span style="color:#f92672">from</span> deepagents.backends <span style="color:#f92672">import</span> StateBackend
</span></span><span style="display:flex;"><span><span style="color:#f92672">from</span> deepagents.middleware <span style="color:#f92672">import</span> SummarizationMiddleware
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>backend <span style="color:#f92672">=</span> StateBackend()
</span></span><span style="display:flex;"><span>model <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;openai:gpt-5.5&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>custom_summarization <span style="color:#f92672">=</span> SummarizationMiddleware(
</span></span><span style="display:flex;"><span>    model<span style="color:#f92672">=</span>model,
</span></span><span style="display:flex;"><span>    backend<span style="color:#f92672">=</span>backend,
</span></span><span style="display:flex;"><span>    trigger<span style="color:#f92672">=</span>(<span style="color:#e6db74">&#34;tokens&#34;</span>, <span style="color:#ae81ff">100000</span>),  <span style="color:#75715e"># 超过 10 万 token 才压缩</span>
</span></span><span style="display:flex;"><span>    keep<span style="color:#f92672">=</span>(<span style="color:#e6db74">&#34;messages&#34;</span>, <span style="color:#ae81ff">20</span>),       <span style="color:#75715e"># 保留最近 20 条消息</span>
</span></span><span style="display:flex;"><span>    summary_prompt<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;Your custom summary prompt here.&#34;</span>,
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>agent <span style="color:#f92672">=</span> create_deep_agent(
</span></span><span style="display:flex;"><span>    model<span style="color:#f92672">=</span>model,
</span></span><span style="display:flex;"><span>    middleware<span style="color:#f92672">=</span>[custom_summarization],  <span style="color:#75715e"># 按 name 替换默认 SummarizationMiddleware</span>
</span></span><span style="display:flex;"><span>)
</span></span></code></pre></div><h3 id="112-添加自定义中间件">11.2 添加自定义中间件</h3>
<p>想在每次工具调用前后做日志、埋点、限流，可以用 <code>wrap_tool_call</code>：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#f92672">from</span> langchain.agents.middleware <span style="color:#f92672">import</span> wrap_tool_call
</span></span><span style="display:flex;"><span><span style="color:#f92672">from</span> deepagents <span style="color:#f92672">import</span> create_deep_agent
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">@wrap_tool_call</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">log_tool_calls</span>(request, handler):
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;&#34;&#34;拦截并记录每次工具调用。&#34;&#34;&#34;</span>
</span></span><span style="display:flex;"><span>    result <span style="color:#f92672">=</span> handler(request)
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> result
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>agent <span style="color:#f92672">=</span> create_deep_agent(
</span></span><span style="display:flex;"><span>    model<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;openai:gpt-5.5&#34;</span>,
</span></span><span style="display:flex;"><span>    tools<span style="color:#f92672">=</span>[get_weather],
</span></span><span style="display:flex;"><span>    middleware<span style="color:#f92672">=</span>[log_tool_calls],
</span></span><span style="display:flex;"><span>)
</span></span></code></pre></div><h3 id="113-只读-agent裁剪文件工具">11.3 只读 agent：裁剪文件工具</h3>
<p><code>FilesystemMiddleware</code> 支持用 <code>tools</code> 白名单限制暴露哪些文件工具（需 <code>deepagents&gt;=0.7</code>）。<code>read_file</code> 必须包含，否则报 <code>ValueError</code>；后端不支持时 <code>execute</code>、<code>delete</code> 会自动移除。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#f92672">from</span> deepagents <span style="color:#f92672">import</span> create_deep_agent
</span></span><span style="display:flex;"><span><span style="color:#f92672">from</span> deepagents.middleware <span style="color:#f92672">import</span> FilesystemMiddleware
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># 只读 agent：write_file、edit_file、delete、execute 永远不出现</span>
</span></span><span style="display:flex;"><span>agent <span style="color:#f92672">=</span> create_deep_agent(
</span></span><span style="display:flex;"><span>    model<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;anthropic:claude-sonnet-4-6&#34;</span>,
</span></span><span style="display:flex;"><span>    backend<span style="color:#f92672">=</span>backend,
</span></span><span style="display:flex;"><span>    middleware<span style="color:#f92672">=</span>[
</span></span><span style="display:flex;"><span>        FilesystemMiddleware(backend<span style="color:#f92672">=</span>backend, tools<span style="color:#f92672">=</span>[<span style="color:#e6db74">&#34;read_file&#34;</span>, <span style="color:#e6db74">&#34;ls&#34;</span>, <span style="color:#e6db74">&#34;glob&#34;</span>, <span style="color:#e6db74">&#34;grep&#34;</span>]),
</span></span><span style="display:flex;"><span>    ],
</span></span><span style="display:flex;"><span>)
</span></span></code></pre></div><h3 id="114-中间件状态管理的坑">11.4 中间件状态管理的坑</h3>
<p><strong>不要在初始化后就地修改实例属性</strong>来跨调用追踪值——那会在并发下引发竞态。需要计数器一类的跨 hook 状态时，写进图状态（按线程隔离，并发安全）。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#f92672">from</span> langchain.agents.middleware <span style="color:#f92672">import</span> AgentMiddleware
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">CountMiddleware</span>(AgentMiddleware):
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">def</span> <span style="color:#a6e22e">before_agent</span>(self, state, runtime):
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> {<span style="color:#e6db74">&#34;x&#34;</span>: state<span style="color:#f92672">.</span>get(<span style="color:#e6db74">&#34;x&#34;</span>, <span style="color:#ae81ff">0</span>) <span style="color:#f92672">+</span> <span style="color:#ae81ff">1</span>}  <span style="color:#75715e"># 更新图状态，正确</span>
</span></span></code></pre></div><p>子代理的中间件继承规则也要注意：</p>
<ul>
<li>general-purpose 子代理会继承主 agent 对默认中间件的<strong>覆盖</strong>，但不携带主 agent 专属中间件；它的 skills 运行在 <code>PatchToolCallsMiddleware</code> 之后。</li>
<li>通过 <code>subagents=</code> 声明的子代理<strong>不继承</strong>主 agent 的中间件自定义，需要在它自己的 <code>middleware</code> 字段里单独传。</li>
</ul>
<h2 id="12-shell沙箱与解释器">12. Shell、沙箱与解释器</h2>
<p>普通后端（State/Filesystem/Store）只暴露文件操作。当你需要 agent 真正<strong>运行命令</strong>——装依赖、跑测试、调 CLI、做系统级文件操作——就需要 sandbox 后端或解释器。</p>
<h3 id="121-sandbox-后端与-execute">12.1 Sandbox 后端与 <code>execute</code></h3>
<p>沙箱本身就是一种 backend。配置后 agent 会额外获得 <code>execute</code> 工具，可在隔离环境里运行任意 shell 命令。框架每次模型调用会检查后端是否实现沙箱协议，没实现就把 <code>execute</code> 过滤掉，agent 根本看不到它。</p>
<p>可用提供商（各自独立安装包）：</p>
<table>
	<thead>
			<tr>
					<th>提供商</th>
					<th>安装包</th>
					<th>后端类</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>LangSmith</td>
					<td><code>langsmith[sandbox]</code></td>
					<td><code>LangSmithSandbox</code></td>
			</tr>
			<tr>
					<td>Daytona</td>
					<td><code>langchain-daytona</code></td>
					<td><code>DaytonaSandbox</code></td>
			</tr>
			<tr>
					<td>E2B</td>
					<td><code>langchain-e2b</code></td>
					<td><code>E2BSandbox</code></td>
			</tr>
			<tr>
					<td>Modal</td>
					<td><code>langchain-modal</code></td>
					<td><code>ModalSandbox</code></td>
			</tr>
			<tr>
					<td>Runloop</td>
					<td><code>langchain-runloop</code></td>
					<td><code>RunloopSandbox</code></td>
			</tr>
			<tr>
					<td>Vercel</td>
					<td><code>langchain-vercel-sandbox</code></td>
					<td><code>VercelSandbox</code></td>
			</tr>
			<tr>
					<td>AgentCore</td>
					<td><code>langchain-agentcore-codeinterpreter</code></td>
					<td><code>AgentCoreSandbox</code></td>
			</tr>
	</tbody>
</table>
<p>沙箱后端唯一必须实现的方法是 <code>execute()</code>，其他文件操作都由基类基于它构建。<code>execute()</code> 返回合并的 stdout/stderr、退出码，输出过大时自动落盘并提示用 <code>read_file</code> 增量读取。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#f92672">from</span> deepagents.backends.langsmith <span style="color:#f92672">import</span> LangSmithSandbox
</span></span><span style="display:flex;"><span><span style="color:#f92672">from</span> langsmith.sandbox <span style="color:#f92672">import</span> SandboxClient
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>client <span style="color:#f92672">=</span> SandboxClient()
</span></span><span style="display:flex;"><span>backend <span style="color:#f92672">=</span> LangSmithSandbox(sandbox<span style="color:#f92672">=</span>client<span style="color:#f92672">.</span>create_sandbox())
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>result <span style="color:#f92672">=</span> backend<span style="color:#f92672">.</span>execute(<span style="color:#e6db74">&#34;python --version&#34;</span>)
</span></span><span style="display:flex;"><span>print(result<span style="color:#f92672">.</span>output)
</span></span></code></pre></div><p>两种集成模式：</p>
<ul>
<li><strong>Sandbox-as-tool（推荐，也是默认）</strong>：agent 跑在你的机器上，需要时调用沙箱。密钥留在沙箱外、代码可即时更新，代价是每次调用有网络延迟。</li>
<li><strong>Agent-in-sandbox</strong>：agent 整个跑在沙箱里，更贴近本地开发，但密钥必须放进沙箱、更新要重建镜像。</li>
</ul>
<p>生命周期：默认线程级（每个会话一个沙箱，建议配 <code>idle_ttl_seconds</code> 自动清理），也可助手级共享。沙箱持续计费，用完记得关。</p>
<blockquote>
<p><strong>安全铁律</strong>：沙箱能隔离宿主，但挡不住上下文注入和网络泄露。<strong>绝不要把 API key、令牌、数据库凭证放进沙箱</strong>——被注入的 agent 会读走并外泄。正确做法是把密钥留在沙箱外的工具里，agent 只按名字调用工具、永远看不到凭证；必要时阻断沙箱网络、对所有工具调用开 HITL。把沙箱产出的一切当作不可信输入处理。</p>
</blockquote>
<h3 id="122-解释器interpreters">12.2 解释器（Interpreters）</h3>
<p>如果你只需要让 agent 跑一点确定性的数据变换、循环、批处理，而不想给它整个 shell，可以用解释器：它添加一个 <code>eval</code> 工具，在受限的 QuickJS 运行时里跑 JavaScript。它<strong>不提供</strong> shell、包安装、文件系统或网络访问，因此比沙箱安全得多，适合“程序化地调用工具 / 转换结构化数据”。</p>
<p>选择原则：</p>
<ul>
<li>只做数据变换、聚合、循环 → 解释器。</li>
<li>需要装依赖、跑测试、调系统命令 → 沙箱。</li>
<li>都不需要 → 普通 State/Filesystem/Store 后端就够。</li>
</ul>
<h2 id="13-mcp-与自定义工具生态">13. MCP 与自定义工具生态</h2>
<p>Deep Agents 的 <code>tools=</code> 参数同时接受三类东西：普通 Python 函数、LangChain 工具，以及<strong>任意 MCP server 暴露的工具</strong>。这让它可以直接接入数据库、外部 API、公司内部系统。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#f92672">from</span> deepagents <span style="color:#f92672">import</span> create_deep_agent
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># search / fetch_page / run_query 可以来自本地函数，</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># 也可以来自 MCP server（通过 LangChain MCP 适配器加载后传进来）</span>
</span></span><span style="display:flex;"><span>agent <span style="color:#f92672">=</span> create_deep_agent(
</span></span><span style="display:flex;"><span>    model<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;anthropic:claude-sonnet-4-6&#34;</span>,
</span></span><span style="display:flex;"><span>    tools<span style="color:#f92672">=</span>[search, fetch_page, run_query],
</span></span><span style="display:flex;"><span>)
</span></span></code></pre></div><p>要点：</p>
<ul>
<li>通过 <code>tools=</code> 加进来的自定义/MCP 工具<strong>不受</strong>文件系统白名单限制，也不受 <code>permissions</code> 约束——它们的安全边界要你自己在工具内部把控。</li>
<li>MCP 工具的加载走 LangChain 的 MCP 集成，把 MCP server 的工具转成 LangChain 工具后再传入。</li>
<li>想彻底隐藏某些内置文件工具，可以注册 harness profile 用 <code>excluded_tools</code>；但 <code>FilesystemMiddleware</code> 本身是必需支架，不能被 <code>excluded_middleware</code> 移除。</li>
</ul>
<h2 id="14-subagents子代理">14. Subagents：子代理</h2>
<p>Subagent 的核心价值是上下文隔离。主 agent 把一个子任务交出去，subagent 自己搜索、读写、推理，最后只把摘要结果交还主 agent。</p>
<p>基础示例：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#f92672">from</span> deepagents <span style="color:#f92672">import</span> create_deep_agent
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">web_search</span>(query: str) <span style="color:#f92672">-&gt;</span> dict:
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;&#34;&#34;Search the web for a query.&#34;&#34;&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> {<span style="color:#e6db74">&#34;query&#34;</span>: query, <span style="color:#e6db74">&#34;results&#34;</span>: []}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>research_subagent <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;name&#34;</span>: <span style="color:#e6db74">&#34;researcher&#34;</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;description&#34;</span>: <span style="color:#e6db74">&#34;Use for deep research on a specific technical topic.&#34;</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;system_prompt&#34;</span>: <span style="color:#e6db74">&#34;You are a careful technical researcher. Cite sources.&#34;</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;tools&#34;</span>: [web_search],
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;model&#34;</span>: <span style="color:#e6db74">&#34;openai:gpt-5&#34;</span>,
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>agent <span style="color:#f92672">=</span> create_deep_agent(
</span></span><span style="display:flex;"><span>    model<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;openai:gpt-5&#34;</span>,
</span></span><span style="display:flex;"><span>    subagents<span style="color:#f92672">=</span>[research_subagent],
</span></span><span style="display:flex;"><span>    system_prompt<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;You coordinate research and produce final answers.&#34;</span>,
</span></span><span style="display:flex;"><span>)
</span></span></code></pre></div><p>何时使用 subagent：</p>
<ul>
<li>并行研究多个方向。</li>
<li>让 critic/reviewer 独立检查结果。</li>
<li>数据分析、代码审查、事实核查等角色明显不同。</li>
<li>某个子任务会产生大量中间上下文，不想污染主对话。</li>
</ul>
<p>不要滥用：</p>
<ul>
<li>每个 subagent 都会增加成本、延迟和调试复杂度。</li>
<li>子任务边界不清时，subagent 输出会空泛。</li>
<li>主 agent 仍要负责整合、判断和验收。</li>
</ul>
<p>内置 <code>general-purpose</code> subagent：</p>
<ul>
<li>每个 deep agent 默认都有一个 general-purpose subagent。</li>
<li>它默认继承主 agent 的模型、工具和 system prompt。</li>
<li>配置了 skills 时，general-purpose subagent 会继承主 agent skills。</li>
<li>自定义 subagent 默认不继承主 agent skills，需要单独传 <code>skills</code>。</li>
</ul>
<h2 id="15-structured-output">15. Structured Output</h2>
<p>如果你希望 agent 返回可解析 JSON，而不是自由文本，可以用 <code>response_format</code>。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#f92672">from</span> pydantic <span style="color:#f92672">import</span> BaseModel, Field
</span></span><span style="display:flex;"><span><span style="color:#f92672">from</span> deepagents <span style="color:#f92672">import</span> create_deep_agent
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">ResearchReport</span>(BaseModel):
</span></span><span style="display:flex;"><span>    title: str <span style="color:#f92672">=</span> Field(description<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;Report title&#34;</span>)
</span></span><span style="display:flex;"><span>    summary: str <span style="color:#f92672">=</span> Field(description<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;Short executive summary&#34;</span>)
</span></span><span style="display:flex;"><span>    key_points: list[str] <span style="color:#f92672">=</span> Field(description<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;Important findings&#34;</span>)
</span></span><span style="display:flex;"><span>    sources: list[str] <span style="color:#f92672">=</span> Field(description<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;Source URLs&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>agent <span style="color:#f92672">=</span> create_deep_agent(
</span></span><span style="display:flex;"><span>    model<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;openai:gpt-5&#34;</span>,
</span></span><span style="display:flex;"><span>    tools<span style="color:#f92672">=</span>[web_search],
</span></span><span style="display:flex;"><span>    system_prompt<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;Produce accurate research reports.&#34;</span>,
</span></span><span style="display:flex;"><span>    response_format<span style="color:#f92672">=</span>ResearchReport,
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>result <span style="color:#f92672">=</span> agent<span style="color:#f92672">.</span>invoke(
</span></span><span style="display:flex;"><span>    {<span style="color:#e6db74">&#34;messages&#34;</span>: [{<span style="color:#e6db74">&#34;role&#34;</span>: <span style="color:#e6db74">&#34;user&#34;</span>, <span style="color:#e6db74">&#34;content&#34;</span>: <span style="color:#e6db74">&#34;Research Deep Agents.&#34;</span>}]}
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(result[<span style="color:#e6db74">&#34;structured_response&#34;</span>])
</span></span></code></pre></div><p>适合：</p>
<ul>
<li>API 返回给前端。</li>
<li>后续程序要消费 agent 输出。</li>
<li>评测和自动化验收。</li>
</ul>
<h2 id="16-memory长期记忆">16. Memory：长期记忆</h2>
<p>Deep Agents 的 memory 是文件形式的长期上下文。创建 agent 时传入 memory 文件路径，agent 启动会读取这些文件并注入系统提示；会话过程中也可以通过文件编辑更新 memory。</p>
<p>用户级 memory 示例：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#f92672">from</span> deepagents <span style="color:#f92672">import</span> create_deep_agent
</span></span><span style="display:flex;"><span><span style="color:#f92672">from</span> deepagents.backends <span style="color:#f92672">import</span> CompositeBackend, StateBackend, StoreBackend
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>agent <span style="color:#f92672">=</span> create_deep_agent(
</span></span><span style="display:flex;"><span>    model<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;openai:gpt-5&#34;</span>,
</span></span><span style="display:flex;"><span>    memory<span style="color:#f92672">=</span>[<span style="color:#e6db74">&#34;/memories/preferences.md&#34;</span>],
</span></span><span style="display:flex;"><span>    backend<span style="color:#f92672">=</span>CompositeBackend(
</span></span><span style="display:flex;"><span>        default<span style="color:#f92672">=</span>StateBackend(),
</span></span><span style="display:flex;"><span>        routes<span style="color:#f92672">=</span>{
</span></span><span style="display:flex;"><span>            <span style="color:#e6db74">&#34;/memories/&#34;</span>: StoreBackend(
</span></span><span style="display:flex;"><span>                namespace<span style="color:#f92672">=</span><span style="color:#66d9ef">lambda</span> ctx: (ctx<span style="color:#f92672">.</span>runtime<span style="color:#f92672">.</span>context<span style="color:#f92672">.</span>user_id,),
</span></span><span style="display:flex;"><span>            ),
</span></span><span style="display:flex;"><span>        },
</span></span><span style="display:flex;"><span>    ),
</span></span><span style="display:flex;"><span>)
</span></span></code></pre></div><p>设计 memory 时先分三类：</p>
<ul>
<li>用户偏好：语言、格式、禁忌、长期目标。</li>
<li>项目知识：架构、约定、目录、测试方式。</li>
<li>经验总结：过去成功/失败的工作方法。</li>
</ul>
<p>建议：</p>
<ul>
<li>memory 文件保持短而可维护。</li>
<li>让 agent 写 memory 前尽量经过确认。</li>
<li>不要把短期任务细节都写进长期 memory。</li>
<li>不要保存敏感信息，除非你已经设计好加密、隔离和删除机制。</li>
</ul>
<h2 id="17-skills按需加载的能力包">17. Skills：按需加载的能力包</h2>
<p>Skill 是一个目录，里面必须有 <code>SKILL.md</code>，可以附带脚本、模板、参考资料、资产文件。</p>
<p>典型目录：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>skills/
</span></span><span style="display:flex;"><span>  langgraph-docs/
</span></span><span style="display:flex;"><span>    SKILL.md
</span></span><span style="display:flex;"><span>    references/
</span></span><span style="display:flex;"><span>      api-notes.md
</span></span><span style="display:flex;"><span>  code-review/
</span></span><span style="display:flex;"><span>    SKILL.md
</span></span><span style="display:flex;"><span>    review_checklist.md
</span></span></code></pre></div><p><code>SKILL.md</code> 示例：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-markdown" data-lang="markdown"><span style="display:flex;"><span>---
</span></span><span style="display:flex;"><span><span style="color:#f92672">name</span>: <span style="color:#ae81ff">code-review</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">description</span>: <span style="color:#ae81ff">Use this skill when reviewing code changes for bugs, regressions, security issues, and missing tests.</span>
</span></span><span style="display:flex;"><span>---
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span># Code Review
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">## Instructions
</span></span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">1.</span> Inspect the diff and surrounding code.
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">2.</span> Prioritize correctness, security, and user-visible regressions.
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">3.</span> Report findings with file and line references.
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">4.</span> Keep summaries brief.
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">## References
</span></span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">-</span> Read <span style="color:#e6db74">`review_checklist.md`</span> when the review touches authentication, billing, or permissions.
</span></span></code></pre></div><p>在 SDK 中使用：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#f92672">from</span> deepagents <span style="color:#f92672">import</span> create_deep_agent
</span></span><span style="display:flex;"><span><span style="color:#f92672">from</span> deepagents.backends <span style="color:#f92672">import</span> FilesystemBackend
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>agent <span style="color:#f92672">=</span> create_deep_agent(
</span></span><span style="display:flex;"><span>    model<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;openai:gpt-5&#34;</span>,
</span></span><span style="display:flex;"><span>    backend<span style="color:#f92672">=</span>FilesystemBackend(root_dir<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;.&#34;</span>, virtual_mode<span style="color:#f92672">=</span><span style="color:#66d9ef">True</span>),
</span></span><span style="display:flex;"><span>    skills<span style="color:#f92672">=</span>[<span style="color:#e6db74">&#34;/skills/&#34;</span>],
</span></span><span style="display:flex;"><span>)
</span></span></code></pre></div><p>Skill 的心智模型：</p>
<ul>
<li>tools 是“低层能力”：搜索、读文件、发请求、查数据库。</li>
<li>skills 是“工作方法”：怎么研究、怎么审查、怎么写报告、怎么用某套内部规范。</li>
<li>memory 是“长期背景”：这个用户/项目一直相关的事实。</li>
</ul>
<p>Progressive disclosure：</p>
<ul>
<li>启动时 agent 只读 skill 的 frontmatter。</li>
<li>当任务匹配 skill description 时，才读取完整 <code>SKILL.md</code>。</li>
<li><code>SKILL.md</code> 再指向额外参考资料或脚本。</li>
</ul>
<p>写 skill 的关键是 description。模型主要靠 description 判断是否使用这个 skill。</p>
<h2 id="18-human-in-the-loop">18. Human-in-the-loop</h2>
<p>对删除、发邮件、写数据库、执行 shell、修改文件这类敏感动作，应加人工审批。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#f92672">from</span> langchain.tools <span style="color:#f92672">import</span> tool
</span></span><span style="display:flex;"><span><span style="color:#f92672">from</span> langgraph.checkpoint.memory <span style="color:#f92672">import</span> MemorySaver
</span></span><span style="display:flex;"><span><span style="color:#f92672">from</span> deepagents <span style="color:#f92672">import</span> create_deep_agent
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">@tool</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">send_email</span>(to: str, subject: str, body: str) <span style="color:#f92672">-&gt;</span> str:
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;&#34;&#34;Send an email.&#34;&#34;&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> <span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;Sent email to </span><span style="color:#e6db74">{</span>to<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>checkpointer <span style="color:#f92672">=</span> MemorySaver()
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>agent <span style="color:#f92672">=</span> create_deep_agent(
</span></span><span style="display:flex;"><span>    model<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;openai:gpt-5&#34;</span>,
</span></span><span style="display:flex;"><span>    tools<span style="color:#f92672">=</span>[send_email],
</span></span><span style="display:flex;"><span>    interrupt_on<span style="color:#f92672">=</span>{
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#34;send_email&#34;</span>: {<span style="color:#e6db74">&#34;allowed_decisions&#34;</span>: [<span style="color:#e6db74">&#34;approve&#34;</span>, <span style="color:#e6db74">&#34;reject&#34;</span>]},
</span></span><span style="display:flex;"><span>    },
</span></span><span style="display:flex;"><span>    checkpointer<span style="color:#f92672">=</span>checkpointer,
</span></span><span style="display:flex;"><span>)
</span></span></code></pre></div><p>常见 decision：</p>
<ul>
<li><code>approve</code>：按原参数执行。</li>
<li><code>edit</code>：修改参数后执行。</li>
<li><code>reject</code>：拒绝执行，并可给 agent 反馈。</li>
</ul>
<p>要点：</p>
<ul>
<li>HITL 需要 checkpointer，否则暂停后无法可靠恢复。</li>
<li>审批策略应按工具风险分级。</li>
<li>读操作不一定要审批，写操作、外部副作用、不可逆操作优先审批。</li>
</ul>
<h2 id="19-streaming-与调试">19. Streaming 与调试</h2>
<p>Streaming 让你实时看到 agent 进展、工具调用、subagent 执行。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#66d9ef">for</span> chunk <span style="color:#f92672">in</span> agent<span style="color:#f92672">.</span>stream(
</span></span><span style="display:flex;"><span>    {<span style="color:#e6db74">&#34;messages&#34;</span>: [{<span style="color:#e6db74">&#34;role&#34;</span>: <span style="color:#e6db74">&#34;user&#34;</span>, <span style="color:#e6db74">&#34;content&#34;</span>: <span style="color:#e6db74">&#34;Research LangGraph and summarize.&#34;</span>}]},
</span></span><span style="display:flex;"><span>    stream_mode<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;updates&#34;</span>,
</span></span><span style="display:flex;"><span>    subgraphs<span style="color:#f92672">=</span><span style="color:#66d9ef">True</span>,
</span></span><span style="display:flex;"><span>    version<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;v2&#34;</span>,
</span></span><span style="display:flex;"><span>):
</span></span><span style="display:flex;"><span>    print(chunk[<span style="color:#e6db74">&#34;type&#34;</span>], chunk[<span style="color:#e6db74">&#34;ns&#34;</span>], chunk[<span style="color:#e6db74">&#34;data&#34;</span>])
</span></span></code></pre></div><p>你可以观察：</p>
<ul>
<li>主 agent 当前在哪一步。</li>
<li>是否调用了 <code>write_todos</code>。</li>
<li>是否把资料写入文件。</li>
<li>是否创建 subagent。</li>
<li>subagent 是否在并行执行。</li>
<li>工具参数是否合理。</li>
</ul>
<p>调试建议：</p>
<ul>
<li>打开 LangSmith tracing。</li>
<li>先用假工具或小数据跑通流程。</li>
<li>对工具调用记录输入输出。</li>
<li>对最终输出做自动评测，比如是否包含 source、是否是合法 JSON、是否覆盖所有问题。</li>
</ul>
<h2 id="20-context-engineering">20. Context Engineering</h2>
<p>Deep Agents 的上下文工程默认围绕四件事：</p>
<ul>
<li>System prompt：角色、目标、规则、输出标准。</li>
<li>Tool prompts：工具描述和工具使用说明（filesystem、subagents、可选 planning 等中间件会自动追加各自的工具说明）。</li>
<li>Filesystem offloading：把大内容写入文件，再按需读取。</li>
<li>Summarization：上下文接近限制时压缩旧消息。</li>
</ul>
<h3 id="201-压缩生命周期先卸载再摘要">20.1 压缩生命周期：先卸载，再摘要</h3>
<p>这套机制不是玄学，它有明确的阈值和顺序：</p>
<figure class="deepagents-svg-figure">
  <img src="/deepagents-learning/context-lifecycle.svg" alt="Deep Agents 上下文压缩生命周期：对话增长后先把超过 2 万 token 的工具输入输出卸载到文件，越过 85% 时触发摘要" loading="lazy">
  <figcaption>图 07：上下文快满时的两级处理。先卸载大工具输入/输出到文件，再在 85% 阈值触发摘要。</figcaption>
</figure>
<ul>
<li><strong>Offloading（卸载）</strong>：单次工具的输入或输出超过约 <strong>20,000 token</strong> 时，Deep Agents 把内容写到 backend，对话里只留下<strong>文件路径指针 + 前 10 行预览</strong>，agent 后续可用 <code>read_file</code>/<code>grep</code> 按需拉回。当会话超过模型窗口约 <strong>85%</strong> 时，旧的冗余工具调用也会被截断成指针。</li>
<li><strong>Summarization（摘要）</strong>：越过 85% 且没有更多可卸载内容时，<code>SummarizationMiddleware</code> 触发。它做两件事——生成一份<strong>结构化的上下文内摘要</strong>（会话意图、已产出、下一步），替代工作内存里的完整历史；同时把<strong>原始对话消息写入文件系统</strong>作为规范记录。若模型 profile 不可用，回退为 17 万 token 触发 / 保留 6 条消息。</li>
<li><strong>主动压缩</strong>：<code>create_summarization_tool_middleware</code> 会给 agent 一个 <code>compact_conversation</code> 工具，让它在任务之间<strong>主动</strong>触发压缩，而不必等到 85%。这不会关掉自动摘要，二者共享同一引擎。</li>
</ul>
<p>流式时，可以按 <code>metadata.lc_source == &quot;summarization&quot;</code> 把摘要产生的 token 过滤掉，避免污染前端输出。</p>
<h3 id="202-实践模式">20.2 实践模式</h3>
<ol>
<li>让 agent 先写 todo。</li>
<li>搜索或读取资料后写入 <code>/notes/</code>。</li>
<li>中途产物写入 <code>/drafts/</code>。</li>
<li>最终产物写入 <code>/outputs/</code>。</li>
<li>对重要结论要求附证据来源。</li>
<li>内存保持精简，只放始终相关的约定；任务专用能力交给聚焦的 skills。</li>
<li>把繁重、输出量大的多步任务交给子代理，保持主 agent 上下文干净。</li>
</ol>
<p>一个高质量任务提示：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>Research Deep Agents and write a technical learning note.
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Requirements:
</span></span><span style="display:flex;"><span>- Create a short plan first.
</span></span><span style="display:flex;"><span>- Save raw notes to /notes/deepagents.md.
</span></span><span style="display:flex;"><span>- Compare Deep Agents with LangChain create_agent and LangGraph.
</span></span><span style="display:flex;"><span>- Produce final output as /outputs/deepagents-learning-note.md.
</span></span><span style="display:flex;"><span>- Include links to official docs.
</span></span></code></pre></div><p>这个提示比“介绍一下 Deep Agents”更容易激活框架的优势。</p>
<h2 id="21-推荐学习路线">21. 推荐学习路线</h2>
<h3 id="第-1-天跑通最小-agent">第 1 天：跑通最小 agent</h3>
<p>目标：</p>
<ul>
<li>安装 <code>deepagents</code>。</li>
<li>配置一个支持 tool calling 的模型。</li>
<li>跑通 <code>create_deep_agent</code>。</li>
<li>理解 <code>invoke</code> 输入输出格式。</li>
</ul>
<p>练习：</p>
<ul>
<li>写一个 mock weather tool。</li>
<li>问 agent 三个问题：不需要工具、需要工具、需要多步推理。</li>
</ul>
<h3 id="第-2-天掌握工具设计">第 2 天：掌握工具设计</h3>
<p>目标：</p>
<ul>
<li>学会给工具写类型和 docstring。</li>
<li>观察模型如何选择工具。</li>
<li>处理工具错误和空结果。</li>
</ul>
<p>练习：</p>
<ul>
<li>写 <code>search_articles</code>、<code>read_document_summary</code> 两个工具。</li>
<li>故意传模糊问题，看 agent 是否会问清楚或调用搜索。</li>
</ul>
<h3 id="第-3-天文件系统与-backend">第 3 天：文件系统与 backend</h3>
<p>目标：</p>
<ul>
<li>理解 StateBackend、FilesystemBackend、StoreBackend。</li>
<li>学会让 agent 把中间结果写文件。</li>
<li>学会权限限制。</li>
</ul>
<p>练习：</p>
<ul>
<li>要求 agent 把研究笔记写到 <code>/notes/</code>。</li>
<li>设置只允许 <code>/workspace/**</code> 读写。</li>
<li>测试 agent 访问被禁止路径时的行为。</li>
</ul>
<h3 id="第-4-天subagents">第 4 天：subagents</h3>
<p>目标：</p>
<ul>
<li>理解上下文隔离。</li>
<li>定义 researcher、critic 两个子代理。</li>
<li>观察主 agent 如何合并子代理结果。</li>
</ul>
<p>练习：</p>
<ul>
<li>researcher 查资料。</li>
<li>critic 检查事实和遗漏。</li>
<li>主 agent 输出最终报告。</li>
</ul>
<h3 id="第-5-天skills">第 5 天：skills</h3>
<p>目标：</p>
<ul>
<li>写一个自己的 <code>SKILL.md</code>。</li>
<li>理解 progressive disclosure。</li>
<li>区分 tools、skills、memory。</li>
</ul>
<p>练习：</p>
<ul>
<li>写 <code>technical-blog-writing</code> skill。</li>
<li>让 agent 按你的博客风格生成文章大纲。</li>
</ul>
<h3 id="第-6-天memory">第 6 天：memory</h3>
<p>目标：</p>
<ul>
<li>配置用户级 memory。</li>
<li>设计 memory 文件结构。</li>
<li>避免污染长期记忆。</li>
</ul>
<p>练习：</p>
<ul>
<li>写 <code>/memories/preferences.md</code>。</li>
<li>让 agent 记住你的输出偏好。</li>
<li>换一个 <code>thread_id</code> 验证是否能读取 memory。</li>
</ul>
<h3 id="第-7-天hitlstreaming评测">第 7 天：HITL、streaming、评测</h3>
<p>目标：</p>
<ul>
<li>对敏感工具加审批。</li>
<li>用 streaming 观察执行。</li>
<li>建立简单验收脚本或人工 checklist。</li>
</ul>
<p>练习：</p>
<ul>
<li>给 <code>write_file</code>、<code>send_email</code> 或真实副作用工具加 interrupt。</li>
<li>记录一次完整 trace。</li>
<li>对输出做结构化校验。</li>
</ul>
<h2 id="22-小项目博客选题研究-agent">22. 小项目：博客选题研究 Agent</h2>
<p>这个项目适合放在你的博客工作流里练习。</p>
<p>目标：</p>
<p>用户输入一个方向，比如“agent context engineering”，agent 自动完成：</p>
<ol>
<li>拆解研究计划。</li>
<li>搜索官方资料和高质量文章。</li>
<li>把原始笔记写到 <code>/notes/topic.md</code>。</li>
<li>让 critic subagent 检查遗漏、过时信息和不可靠来源。</li>
<li>输出博客大纲、核心论点、参考链接。</li>
<li>可选：把最终 Markdown 写到 <code>/outputs/draft.md</code>。</li>
</ol>
<p>建议角色：</p>
<ul>
<li>main agent：项目经理和最终写作者。</li>
<li>researcher subagent：搜资料、摘录、整理事实。</li>
<li>critic subagent：挑错、检查引用、标出不确定性。</li>
<li>style skill：你的博客风格、标题习惯、段落节奏。</li>
</ul>
<p>建议文件结构：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>agent_workspace/
</span></span><span style="display:flex;"><span>  skills/
</span></span><span style="display:flex;"><span>    blog-style/
</span></span><span style="display:flex;"><span>      SKILL.md
</span></span><span style="display:flex;"><span>  notes/
</span></span><span style="display:flex;"><span>  drafts/
</span></span><span style="display:flex;"><span>  outputs/
</span></span><span style="display:flex;"><span>  memories/
</span></span><span style="display:flex;"><span>    preferences.md
</span></span></code></pre></div><p>验收标准：</p>
<ul>
<li>是否有明确选题角度。</li>
<li>是否引用官方或一手来源。</li>
<li>是否区分事实和观点。</li>
<li>是否有可写成文章的结构。</li>
<li>是否避免把搜索片段直接拼贴成正文。</li>
</ul>
<h2 id="23-常见坑">23. 常见坑</h2>
<ul>
<li>模型不支持工具调用：agent 看起来会“思考”，但不会可靠调用工具。</li>
<li>工具 docstring 太弱：模型不知道何时调用，也不知道参数怎么填。</li>
<li>返回大段原始内容：上下文迅速膨胀，应写文件再摘要。</li>
<li>滥用 subagent：任务变慢、成本变高、结果更难调试。</li>
<li><code>FilesystemBackend</code> 直接暴露真实项目目录：容易误读 secrets 或改坏文件。</li>
<li>忘记 <code>virtual_mode=True</code>：<code>root_dir</code> 本身不等于完整安全边界。</li>
<li>permissions 以为能管住所有东西：它只管内置文件工具，不管自定义工具和 sandbox shell。</li>
<li>HITL 没有 checkpointer：暂停和恢复会出问题。</li>
<li>memory 写太多：长期记忆变成垃圾堆，反而降低质量。</li>
<li>skills description 不清楚：agent 根本不会触发 skill。</li>
<li>替换默认中间件时以为是“合并”：其实是完全覆盖，覆盖 <code>FilesystemMiddleware</code> 忘了重新传 <code>backend</code>/<code>permissions</code> 会出错。</li>
<li>在中间件里就地改实例属性来计数：并发下会竞态，应写图状态。</li>
<li>把密钥放进 sandbox：被上下文注入的 agent 能读走并外泄，密钥要留在沙箱外的工具里。</li>
<li>该用解释器却上了 sandbox：只做数据变换却开放整个 shell，放大了攻击面。</li>
</ul>
<h2 id="24-生产化-checklist">24. 生产化 checklist</h2>
<p>上线前至少确认：</p>
<ul>
<li>模型：支持 tool calling，延迟和成本可接受。</li>
<li>工具：参数 schema 清晰，错误可恢复，有超时。</li>
<li>权限：文件读写路径受限，secrets 不可读。</li>
<li>副作用：写文件、发请求、发邮件、执行命令等有 HITL 或策略保护。</li>
<li>状态：thread_id、checkpointer、store namespace 设计清楚。</li>
<li>Memory：用户隔离，敏感信息策略明确。</li>
<li>Skills：版本化，description 清楚，引用文件完整。</li>
<li>Observability：LangSmith tracing 或等价日志可用。</li>
<li>Evaluation：有样例任务、预期输出、回归检查。</li>
<li>成本控制：subagent 数量、搜索次数、工具返回大小有限制。</li>
</ul>
<h2 id="25-官方资料入口">25. 官方资料入口</h2>
<ul>
<li>Deep Agents overview: <a href="https://docs.langchain.com/oss/python/deepagents/overview">https://docs.langchain.com/oss/python/deepagents/overview</a></li>
<li>Quickstart: <a href="https://docs.langchain.com/oss/python/deepagents/quickstart">https://docs.langchain.com/oss/python/deepagents/quickstart</a></li>
<li>Customization（中间件）: <a href="https://docs.langchain.com/oss/python/deepagents/customization">https://docs.langchain.com/oss/python/deepagents/customization</a></li>
<li>Context engineering: <a href="https://docs.langchain.com/oss/python/deepagents/context-engineering">https://docs.langchain.com/oss/python/deepagents/context-engineering</a></li>
<li>Backends: <a href="https://docs.langchain.com/oss/python/deepagents/backends">https://docs.langchain.com/oss/python/deepagents/backends</a></li>
<li>Sandboxes: <a href="https://docs.langchain.com/oss/python/deepagents/sandboxes">https://docs.langchain.com/oss/python/deepagents/sandboxes</a></li>
<li>Interpreters: <a href="https://docs.langchain.com/oss/python/deepagents/interpreters">https://docs.langchain.com/oss/python/deepagents/interpreters</a></li>
<li>Tools（含 MCP）: <a href="https://docs.langchain.com/oss/python/deepagents/tools">https://docs.langchain.com/oss/python/deepagents/tools</a></li>
<li>Permissions: <a href="https://docs.langchain.com/oss/python/deepagents/permissions">https://docs.langchain.com/oss/python/deepagents/permissions</a></li>
<li>Subagents: <a href="https://docs.langchain.com/oss/python/deepagents/subagents">https://docs.langchain.com/oss/python/deepagents/subagents</a></li>
<li>Memory: <a href="https://docs.langchain.com/oss/python/deepagents/memory">https://docs.langchain.com/oss/python/deepagents/memory</a></li>
<li>Skills: <a href="https://docs.langchain.com/oss/python/deepagents/skills">https://docs.langchain.com/oss/python/deepagents/skills</a></li>
<li>Streaming: <a href="https://docs.langchain.com/oss/python/deepagents/streaming">https://docs.langchain.com/oss/python/deepagents/streaming</a></li>
<li>Human-in-the-loop: <a href="https://docs.langchain.com/oss/python/deepagents/human-in-the-loop">https://docs.langchain.com/oss/python/deepagents/human-in-the-loop</a></li>
<li>API Reference: <a href="https://reference.langchain.com/python/deepagents/">https://reference.langchain.com/python/deepagents/</a></li>
<li>Deep Agents GitHub: <a href="https://github.com/langchain-ai/deepagents">https://github.com/langchain-ai/deepagents</a></li>
<li>官方示例: <a href="https://github.com/langchain-ai/deepagents/tree/main/examples">https://github.com/langchain-ai/deepagents/tree/main/examples</a></li>
</ul>
<h2 id="26-生态与多语言版本">26. 生态与多语言版本</h2>
<p>Deep Agents 不只有 Python SDK，围绕它还有一套生态，写生产系统前值得知道：</p>
<ul>
<li><strong>JavaScript / TypeScript 版本</strong>：<code>deepagentsjs</code>（https://github.com/langchain-ai/deepagentsjs），API 与 Python 版对齐，前端 / Node 全栈项目可直接用。</li>
<li><strong>Deep Agents Code</strong>：官方预构建的终端编码 agent，定位类似 Claude Code / Cursor，可由任意 LLM 驱动。可用 <code>curl -LsSf https://langch.in/dcode | bash</code> 安装——注意这是从远程 URL 下载脚本直接执行，建议先下载审查脚本内容再决定是否运行。</li>
<li><strong>分层可组合</strong>：任何 LangGraph <code>CompiledStateGraph</code> 都能当作子代理传给 Deep Agent，你可以把已有的 LangGraph 工作流原样嵌进来。</li>
<li><strong>模型无关</strong>：支持前沿 API（OpenAI、Anthropic、Google、OpenRouter）、托管开源模型（Baseten、Fireworks）以及自托管（Ollama、vLLM、llama.cpp），只要支持 tool calling 即可。</li>
<li><strong>配套工程</strong>：基于 LangGraph 的流式、持久化、checkpoint，加上 LangSmith 的追踪、评估与部署，构成一条从原型到生产的链路。</li>
</ul>
<blockquote>
<p>安全提醒：Deep Agents 采用“信任 LLM”模型——agent 能执行其工具允许的任何操作。真正的边界应该在<strong>工具 / 沙箱层面</strong>强制实施，而不是指望模型自我约束。</p>
</blockquote>
<h2 id="27-最短复习版">27. 最短复习版</h2>
<p>记住这张表：</p>
<table>
	<thead>
			<tr>
					<th>你要解决的问题</th>
					<th>Deep Agents 里的东西</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>复杂任务怎么拆</td>
					<td><code>write_todos</code></td>
			</tr>
			<tr>
					<td>大上下文怎么放</td>
					<td>filesystem tools + offloading</td>
			</tr>
			<tr>
					<td>上下文快满了怎么办</td>
					<td>卸载到文件 + <code>SummarizationMiddleware</code></td>
			</tr>
			<tr>
					<td>多角色怎么做</td>
					<td><code>subagents</code> / <code>task</code></td>
			</tr>
			<tr>
					<td>中间产物放哪</td>
					<td>backend</td>
			</tr>
			<tr>
					<td>要跑命令 / 装依赖</td>
					<td>sandbox 后端 + <code>execute</code></td>
			</tr>
			<tr>
					<td>只做数据变换</td>
					<td>interpreter + <code>eval</code></td>
			</tr>
			<tr>
					<td>长期偏好怎么记</td>
					<td><code>memory</code></td>
			</tr>
			<tr>
					<td>专门工作流怎么注入</td>
					<td><code>skills</code></td>
			</tr>
			<tr>
					<td>接外部系统</td>
					<td>自定义工具 / MCP</td>
			</tr>
			<tr>
					<td>危险操作怎么拦</td>
					<td><code>interrupt_on</code> + checkpointer</td>
			</tr>
			<tr>
					<td>想改默认行为</td>
					<td><code>middleware</code>（按 <code>.name</code> 替换）</td>
			</tr>
			<tr>
					<td>执行过程怎么看</td>
					<td><code>stream(...)</code> + LangSmith</td>
			</tr>
			<tr>
					<td>输出怎么给程序消费</td>
					<td><code>response_format</code></td>
			</tr>
	</tbody>
</table>
<p>学习顺序：</p>
<ol>
<li>先跑通最小 agent。</li>
<li>再写两个好工具。</li>
<li>接着学文件系统和 backend。</li>
<li>然后加 subagent。</li>
<li>补 memory、skills、HITL、streaming、评测。</li>
<li>最后深入 middleware、sandbox 与上下文压缩，把它当作可拆装的系统而非黑盒。</li>
</ol>
<p>Deep Agents 的真正难点不是 API，而是产品和工程判断：哪些上下文该进 prompt，哪些该进文件，哪些该变成 skill，哪些该变成 memory，哪些操作必须让人批准，哪些能力该由中间件裁剪。</p>
]]></content:encoded></item></channel></rss>