Skip to content

中间件系统:扩展代理能力

DeepAgents 的编排器(Harness)由多种能力组合而成,使构建长时间运行的智能体变得更加容易。本文将深入探讨这些内置能力的工作原理,以及如何通过中间件模式扩展代理功能。

编排器核心能力

DeepAgents 编排器提供六大核心能力:

能力描述
规划能力通过 write_todos 工具维护结构化任务列表
虚拟文件系统可配置的文件系统抽象,支持多种后端
任务委派创建子代理执行隔离的多步骤任务
上下文管理自动处理长对话的上下文压缩和管理
代码执行在沙箱环境中安全执行代码
人机协作在关键操作处暂停等待人工审批

编排器六大核心能力总览

规划能力:write_todos 工具

编排器提供 write_todos 工具,让代理能够维护结构化的任务列表:

typescript
const todos = [
  { id: "1", content: "分析项目结构", status: "completed" },
  { id: "2", content: "重构核心模块", status: "in_progress" },
  { id: "3", content: "编写测试用例", status: "pending" },
  { id: "4", content: "更新文档", status: "pending" },
];

特性:

  • 使用三种状态追踪任务:pendingin_progresscompleted
  • 持久化存储于代理状态中
  • 帮助代理组织复杂的多步骤工作
  • 适用于长时间运行的任务与规划

虚拟文件系统工具

编排器提供完整的文件系统工具集:

工具描述
ls列出目录下的文件及元数据(大小、修改时间)
read_file读取文件内容,支持大文件分页,也支持读取图片
write_file创建新文件
edit_file对文件执行精确字符串替换
glob查找匹配模式的文件(如 **/*.py
grep在文件内容中搜索,支持多种输出模式
execute在沙箱中运行 Shell 命令

这些工具由后端(Backend)提供支持,可以是内存存储、本地文件系统或远程沙箱。

上下文管理机制

DeepAgents 使用多种技术管理长时间运行任务的上下文:

1. 大型工具输入/结果卸载

当工具调用的输入或结果超过 20,000 个 Token 时,会自动卸载:

typescript
// 配置卸载阈值
const agent = createDeepAgent({
  model: "claude-sonnet-4-20250514",
  // 默认 20000 tokens
  tool_token_limit_before_evict: 20000,
});

输入卸载流程:

  1. 检测到大型工具输入
  2. 将完整内容保存到文件系统
  3. 用文件路径引用替换原始内容
  4. 代理需要时可重新读取

结果卸载流程:

  1. 检测到大型工具结果
  2. 将结果保存到配置的后端
  3. 用文件路径引用和前 10 行预览替换
  4. 代理可按需重新读取或搜索

上下文卸载机制双路径流程

2. 上下文总结

当上下文超过模型窗口的 85% 时,自动触发总结:

触发条件:上下文达到 max_input_tokens 的 85%
保留:最近 10% 的 Token 作为近期上下文
回退:若模型配置不可用,则 170,000 Token 触发,保留 6 条消息

总结过程:

  1. 上下文内总结:LLM 生成结构化总结,包括:

    • 会话意图
    • 已创建的产物
    • 下一步计划
  2. 文件系统保全:完整对话消息写入文件系统,作为权威记录

typescript
// 总结后的消息示例
const summarizedMessage = {
  role: "system",
  content: `
## 会话总结

### 意图
用户请求重构项目中的认证模块

### 已完成
- 分析了现有认证逻辑
- 设计了新的 JWT 方案
- 创建了 auth/jwt.ts 文件

### 下一步
- 实现 token 刷新逻辑
- 编写单元测试

完整对话历史已保存至: /context/history_001.md
`,
};

上下文总结机制与85%阈值触发

任务委派:子代理系统

编排器允许主代理创建子代理执行隔离任务:

typescript
// 主代理调用 task 工具
const taskResult = await taskTool.invoke({
  task: "搜索项目中所有使用 deprecated API 的代码",
  context: "项目使用 React 18 和 TypeScript",
});

子代理特点:

  • 上下文隔离:子代理的工作不污染主代理上下文
  • 并行执行:多个子代理可并发运行
  • 专门化:子代理可拥有不同的工具配置
  • Token 效率:子任务上下文压缩为单个结果返回
  • 无状态:子代理完成后只返回最终报告

子代理任务委派与上下文隔离

代码执行能力

使用沙箱后端时,编排器会暴露 execute 工具:

typescript
// 在沙箱中执行命令
const result = await executeTool.invoke({
  command: "npm test -- --coverage",
  timeout: 60000,
});

// 返回结果
{
  stdout: "PASS src/auth.test.ts\n...",
  stderr: "",
  exitCode: 0,
  truncated: false
}

安全性保障:

  • 代码在隔离环境中运行
  • 保护宿主系统免受代理操作影响
  • 支持资源限制和超时控制
  • 大型输出自动截断并保存到文件

人机协作机制

通过 interrupt_on 配置关键操作的审批点:

typescript
const agent = createDeepAgent({
  model: "claude-sonnet-4-20250514",
  tools: [writeFileTool, deleteFileTool, shellTool],
  interruptOn: {
    delete_file: true,           // 所有删除操作需审批
    shell: true,                 // 所有 shell 命令需审批
    write_file: {                // 条件审批
      condition: (args) => args.path.includes("config"),
    },
  },
});

审批流程:

  1. 代理调用需要审批的工具
  2. 执行暂停,等待人工决策
  3. 人工可以:批准、修改参数后批准、拒绝
  4. 代理根据决策继续执行

人机协作审批决策流程

技能系统的渐进式披露

技能使用渐进式披露模式,减少不必要的 Token 消耗:

启动时:仅读取每个 SKILL.md 的 frontmatter(名称、描述、触发条件)
运行时:当任务匹配技能描述时,才加载完整技能内容
typescript
// 技能的 frontmatter
const skillMeta = {
  name: "code-review",
  description: "执行代码审查,检查代码质量和安全性",
  trigger: "当用户请求代码审查或 PR 审查时",
};

// 只有匹配时才加载完整内容
if (taskMatchesSkill(userRequest, skillMeta)) {
  const fullSkillContent = await loadSkill("code-review");
  // 将完整技能内容加入上下文
}

技能渐进式加载机制

记忆系统

记忆文件在会话启动时自动加载:

typescript
const agent = createDeepAgent({
  model: "claude-sonnet-4-20250514",
  memory: [
    "~/.deepagents/agent/AGENTS.md",      // 全局记忆
    ".deepagents/AGENTS.md",               // 项目记忆
  ],
});

记忆 vs 技能对比:

特性记忆 (Memory)技能 (Skills)
加载时机启动时始终加载按需渐进式加载
内容类型偏好、约定、指南专门工作流、领域知识
更新方式代理可主动更新通常人工编写

提示词组装流程

最终的代理提示词由多个部分组装而成:

1. 自定义 system_prompt(若提供)
2. 基础代理提示词
3. Todo 列表提示词:如何用待办列表进行规划
4. 记忆提示词:AGENTS.md + 使用指南(若提供 memory)
5. 技能提示词:技能位置 + 列表 + 使用方式(若提供 skills)
6. 虚拟文件系统提示词(文件系统 + execute 工具文档)
7. 子代理提示词:Task 工具用法
8. 用户中间件提示词(若提供自定义中间件)
9. 人机协作提示词(若设置 interrupt_on)
10. 本地上下文提示词:当前目录、项目信息(CLI 使用时)

提示词组装管道10层结构

自定义中间件开发

你可以开发自定义中间件扩展代理能力:

typescript
import { BaseMiddleware } from "@langchain/langgraph-agents/middleware";

class LoggingMiddleware extends BaseMiddleware {
  name = "logging";
  
  // 添加到系统提示词的内容
  getPromptAddition(): string {
    return `
## 日志记录
- 在执行重要操作前后记录日志
- 使用 log_action 工具记录操作
- 日志格式:[时间] [级别] 消息
`;
  }
  
  // 提供的工具
  getTools() {
    return [
      tool(
        async (input: { level: string; message: string }) => {
          const timestamp = new Date().toISOString();
          console.log(`[${timestamp}] [${input.level}] ${input.message}`);
          return `已记录: ${input.message}`;
        },
        {
          name: "log_action",
          description: "记录代理操作日志",
          schema: z.object({
            level: z.enum(["info", "warn", "error"]),
            message: z.string(),
          }),
        }
      ),
    ];
  }
}

// 使用自定义中间件
const agent = createDeepAgent({
  model: "claude-sonnet-4-20250514",
  middleware: [new LoggingMiddleware()],
});

自定义中间件扩展模式

小结

本文介绍了 DeepAgents 编排器的核心能力:

  1. 规划能力write_todos 工具维护结构化任务列表
  2. 虚拟文件系统:7 个文件操作工具,支持多种后端
  3. 上下文管理:自动卸载大型内容,智能总结长对话
  4. 任务委派:子代理系统实现上下文隔离和并行执行
  5. 代码执行:沙箱环境中的安全命令执行
  6. 人机协作:关键操作的审批机制
  7. 渐进式技能:按需加载专业能力
  8. 记忆系统:持久化上下文和偏好

下一篇文章,我们将深入学习如何配置自定义模型提供商,让 DeepAgents 支持任意 LLM。

读文档、看源码、写代码,理解 AI Agent 本质 🤖