游乐游手机版
首页/AI热点日报/热点详情

LangChain的DeepAgents工具体系全面解析:MCP、Skills与沙箱安全配合机制

类型:热点整理2026-05-31
行业里有个常见困惑:明明用的是同一个底层模型,为什么有的Agent干起活来像刚入职的实习生,有的却像个经验丰富的主力干将? 答案往往不在模型本身——真去拆解一下就会发现,差距主要出在工具上。更准确地说,是“工具怎么被设计出来”的,这决定了Agent能力的上限。 评估过不少开源Agent框架后,发现一

行业里有个常见困惑:明明用的是同一个底层模型,为什么有的Agent干起活来像刚入职的实习生,有的却像个经验丰富的主力干将?

答案往往不在模型本身——真去拆解一下就会发现,差距主要出在工具上。更准确地说,是“工具怎么被设计出来”的,这决定了Agent能力的上限。

评估过不少开源Agent框架后,发现一个很有意思的现象:有的框架把工具当成简单的函数调用,能跑就行;有的稍微多想了一步,会琢磨工具描述怎么写模型才能懂;但真正做得好的,是直接把工具当成“接口设计”问题来通盘考虑的——工具怎么组织、怎么被发现、怎么安全地执行,每一步都有讲究。

DeepAgents在工具这块投入不小。它不是简单塞几个内置工具就完事,而是试图搭建一个完整的工具生态:Skills负责复用工作流,MCP接外部服务,沙箱模型把执行边界收住。顺着这个思路,今天就来拆解一下。

内置工具不是摆设

先说基础的。DeepAgents默认提供的工具,每一个都有明确的使用意图,不是凑数的。

write_todos看着像个简单的待办清单,但它的提示词里有讲究:

Use this tool to track multi-step tasks. Break down complex objectives into concrete, actionable items.
Mark items as complete when done. Update the list as requirements change.

说白了,它是在引导Agent养成“规划-执行-检查”的工作习惯。背后藏着的是任务管理的思维方式。

文件操作工具族的设计也值得一说。read_file支持指定行范围,edit_file支持字符串替换,globgrep支持批量搜索——这套组合拳打下来,刚好覆盖代码分析的完整工作流:先搜索定位,再细读内容,再修改保存。

特别想拎出来说的是edit_file。它不是简单的“覆盖写入”,而是支持类似sed的替换操作:

edit_file(
path="/path/to/file.py",
old_string="def old_function():",
new_string="def new_function():"
)

为什么选替换而不是直接写?因为替换天然带一点“验证”的意味。如果old_string在文件里找不到,工具会报错,而不是盲目写入把文件搞坏。这种防御性设计,在生产环境里能实实在在避免很多低级事故。

当然,这些只是基础。真正的扩展能力来自Skills和MCP。

Skills:可复用的工作流

Skills是DeepAgents里很巧妙的设计。它解决了一个特别实际的问题:怎么把某个领域里已经被验证过的最佳实践,变成Agent能直接用的东西?

举个例子。假设你有个内部流程:每次代码审查都要检查安全漏洞、性能隐患、是否符合编码规范。把这个流程写成文档给Agent看当然可以,但那是静态的。Skills的价值在于,它能把这套流程变成可复用的模块。

Skill的结构

一个Skill就是一个目录,里面必须有个SKILL.md文件:

/skills/code-review/
├── SKILL.md # 核心定义
└── helper.py # 可选的辅助代码

SKILL.md的格式是YAML frontmatter加Markdown内容:

---
name: code-review
description: Perform comprehensive code review focusing on security, performance, and maintainability
license: MIT
---

# Code Review Skill

## When to Use

Use this skill when:
- User asks you to review code
- Pull request needs analysis
- Security audit is required

## Review Checklist

### Security
- [ ] Check for SQL injection vulnerabilities
- [ ] Validate input sanitization
- [ ] Review authentication logic

### Performance
- [ ] Identify N+1 queries
- [ ] Check for unnecessary loops
- [ ] Review memory usage patterns

### Maintainability
- [ ] Verify code follows project conventions
- [ ] Check documentation completeness
- [ ] Assess test coverage

## Output Format

Provide findings in this structure:

**Critical Issues** (must fix)
- ...

**Warnings** (should fix)
- ...

**Suggestions** (nice to ha ve)
- ...

Skills系统会解析这个文件,提取元数据(name, description, license),然后把Markdown内容注入到Agent的系统提示里。

渐进式披露

Skills系统里还有个很精妙的设计叫“渐进式披露”(Progressive Disclosure)。

第一次加载Skill时,系统只读取YAML frontmatter——也就几十个token,知道有这么个Skill、大概干什么的。只有当Agent真正决定用这个Skill时,才把完整的Markdown内容加载进来。

skills.py里的实现:

class SkillMetadata(TypedDict):
path: str
name: str
description: str
# ... 其他元数据

class SkillsMiddleware(AgentMiddleware):
def __init__(self, backend, sources):
# 启动时只加载元数据
self._skills_metadata = self._load_metadata(sources)

def modify_request(self, request):
# 第一次只注入元数据
skills_intro = self._format_skills_intro()
# ...

def _get_skill_full_content(self, skill_name):
# 真正用到时才加载完整内容
return self._backend.read_file(self._skill_paths[skill_name])

这个设计非常实用。试想一下,假如有20个Skill,每个平均5KB,如果全塞进系统提示,上下文一下就被撑起来了,token成本也跟着水涨船高。渐进式披露的好处在于,启动成本主要跟Skill数量有关,而不是跟Skill正文长度成正比。

Skill的层级

Skills可以从多个来源加载,形成层级覆盖:

agent = create_deep_agent(
skills=[
"/skills/base/", # 公司基础规范
"/skills/team/", # 团队特定规则
"/skills/project/", # 项目定制流程
]
)

同名Skill,后面的会覆盖前面的。这种设计让组织可以建立自己的Skill体系:基础层提供通用能力,上层逐级定制。

MCP:打破围墙花园

Skills解决的是“复用”的问题,但还有个更现实的挑战:怎么跟外部世界连接?

你的Agent可能需要查数据库、发Slack消息、操作GitHub PR。这些能力不应该硬编码在Agent里,而是应该通过标准协议动态接入。

这就是MCP(Model Context Protocol)的用武之地。

MCP是什么

简单说,MCP就像AI应用的“USB接口”。它定义了一套标准协议,让任何服务都可以暴露给LLM使用,而Agent侧不需要关心后端到底是什么。

一个MCP Server可以提供:

  • Tools —— 可调用的函数
  • Resources —— 可读取的数据
  • Prompts —— 可复用的提示模板

DeepAgents通过langchain-mcp-adapters集成MCP:

from langchain_mcp_adapters import load_mcp_tools
from deepagents import create_deep_agent

# 连接到一个MCP Server
mcp_tools = load_mcp_tools("https://my-mcp-server.com/sse")

agent = create_deep_agent(
tools=mcp_tools + [my_custom_tool]
)

实战:接入数据库查询

假设你有个内部数据库,想让Agent能查询。传统做法一般是写个query_database工具,把连接字符串和查询逻辑都硬编码进去。但这样耦合太紧了。

MCP的做法是:单独部署一个MCP Server,专门处理数据库访问。

# mcp_server.py
from mcp.server import Server

server = Server("database-server")

@server.tool()
async def query_database(sql: str) -> str:
"""Execute SQL query and return results"""
# 连接数据库、执行查询、返回结果
return results

@server.resource("schema://tables")
async def get_tables() -> str:
"""Return database schema"""
return schema_info

然后在DeepAgents里接入:

from langchain_mcp_adapters import load_mcp_tools

# Agent通过MCP协议使用数据库,不用关心具体实现
db_tools = load_mcp_tools("http://localhost:8000/sse")

agent = create_deep_agent(tools=db_tools)

好处很明显:数据库逻辑独立维护,可以热更新;多个Agent可以共用同一个MCP Server;MCP Server可以自己控制权限、审计、限流;Agent侧代码干净,只关心业务逻辑。

MCP生态

MCP协议由Anthropic发起,但正在形成开放生态。目前已经有官方和社区实现的Server:

  • 文件系统 —— 读写本地文件
  • PostgreSQL —— 数据库查询
  • GitHub —— 操作PR、Issues
  • Slack —— 发送消息
  • Puppeteer —— 浏览器自动化

DeepAgents的思路很清楚:内置工具覆盖通用需求,MCP接住特定场景。这样既保留了开箱即用的体验,又不会把扩展空间封死。

沙箱安全模型

工具能力越强,安全问题就越突出。DeepAgents有个execute工具能执行shell命令,如果滥用就是远程代码执行漏洞。

DeepAgents的安全哲学很直接:Trust the LLM,但把边界enforcement放在工具层。

这不是说“相信模型不会干坏事”,而是说“就算模型想干坏事,工具层也得拦得住”。

Backend的安全层级

DeepAgents的Backend设计体现了这种分层安全的思想。

最底层是BackendProtocol,定义文件操作的基本接口。然后有SandboxBackendProtocol扩展,增加了执行能力:

class BackendProtocol:
"""基础后端:只支持文件操作"""
def read_file(self, path: str) -> ReadResult: ...
def write_file(self, path: str, content: str) -> WriteResult: ...

class SandboxBackendProtocol(BackendProtocol):
"""沙箱后端:额外支持执行"""
def execute(self, command: str) -> ExecuteResult: ...

注意这个继承关系。execute不是基础能力,是额外能力。只有显式使用支持Sandbox的Backend,execute工具才可用。

后端类型对比

StateBackend —— 最安全的选项

from deepagents.backends import StateBackend

agent = create_deep_agent(backend=StateBackend)
  • 文件存在内存里,不对真实文件系统操作
  • 不支持execute,调用会返回错误
  • 适合不需要持久化的场景,或者纯粹的分析任务

FilesystemBackend —— 有持久化需求时用

from deepagents.backends import FilesystemBackend

agent = create_deep_agent(
backend=FilesystemBackend(root_dir="./safe_zone")
)
  • 文件写入真实磁盘,但限制在root_dir
  • 仍然不支持execute
  • 适合需要保存结果,但不需要执行命令的场景

Sandbox Backends —— 需要执行时用

DeepAgents支持多种沙箱后端:

# Modal 沙箱
from deepagents.backends.sandbox import ModalBackend

agent = create_deep_agent(
backend=ModalBackend(
image="python:3.11",
secrets=["MY_API_KEY"]
)
)

# Daytona 沙箱
from deepagents.backends.sandbox import DaytonaBackend

agent = create_deep_agent(
backend=DaytonaBackend(
timeout=300,
language="python"
)
)

这些沙箱后端在隔离环境里执行命令,有资源限制、超时控制、网络隔离。即使Agent执行了恶意代码,也只影响沙箱内部。

最小权限原则

配置Agent时,不妨问自己:这个任务真的需要执行权限吗?真的需要写文件吗?

如果只需要读文件分析,用StateBackend。如果需要保存结果但不需要执行,用FilesystemBackend。只有确实需要运行命令(比如构建项目、运行测试),才上Sandbox。

这种“默认拒绝,显式开启”的设计,很符合安全领域的最小权限原则。

Human-in-the-Loop

沙箱是第一道防线,但有些时候业务需要更细粒度的控制。比如允许Agent读任何文件,但写文件需要人工确认。

DeepAgents的interrupt_on配置就是干这个的:

agent = create_deep_agent(
backend=FilesystemBackend(root_dir="./workspace"),
interrupt_on={
"write_file": True, # 写文件前暂停
"edit_file": True, # 编辑前暂停
"execute": { # 执行命令时根据内容决定
"condition": lambda tool_call: "rm" in tool_call["args"]["command"]
}
}
)

当Agent调用这些工具时,执行会暂停,系统抛出中断,等待人类审批。审批可以修改工具参数,或者直接拒绝。

这在生产环境里特别重要。可以让Agent自动处理常规任务,但在关键操作前——比如写生产代码、删文件、发邮件——再让人来拍板。

自定义Backend开发

如果现有的Backend都不满足需求,可以自己实现。

Backend的核心是实现BackendProtocol

from deepagents.backends.protocol import BackendProtocol, ReadResult, WriteResult, LsResult

class MyCustomBackend(BackendProtocol):
def __init__(self, config):
self.config = config
# 初始化你的存储连接

def read_file(self, path: str) -> ReadResult:
# 实现读取逻辑
content = self._fetch_from_my_storage(path)
return ReadResult(content=content)

def write_file(self, path: str, content: str) -> WriteResult:
# 实现写入逻辑
self._sa ve_to_my_storage(path, content)
return WriteResult(success=True)

def ls(self, path: str) -> LsResult:
# 实现列表逻辑
files = self._list_my_storage(path)
return LsResult(files=files)

然后在创建Agent时使用:

agent = create_deep_agent(
backend=lambda runtime: MyCustomBackend(config)
)

为什么这里要用lambda?因为某些Backend(比如StateBackend)需要运行时context才能初始化。lambda的作用,就是把Backend的创建延迟到真正需要的时候。

实战:S3 Backend

假设你想把文件存在AWS S3而不是本地磁盘:

import boto3
from deepagents.backends.protocol import BackendProtocol, ReadResult, WriteResult

class S3Backend(BackendProtocol):
def __init__(self, bucket: str):
self.s3 = boto3.client('s3')
self.bucket = bucket

def read_file(self, path: str) -> ReadResult:
try:
response = self.s3.get_object(Bucket=self.bucket, Key=path)
content = response['Body'].read().decode('utf-8')
return ReadResult(content=content)
except self.s3.exceptions.NoSuchKey:
return ReadResult(error="file_not_found")

def write_file(self, path: str, content: str) -> WriteResult:
self.s3.put_object(
Bucket=self.bucket,
Key=path,
Body=content.encode('utf-8')
)
return WriteResult(success=True)

# 使用
agent = create_deep_agent(
backend=lambda rt: S3Backend(bucket="my-agent-bucket")
)

这样Agent的所有文件操作都透明地落在S3上,天然支持多实例共享、持久化、备份。

小结

这一篇其实想说明一个核心观点:真正把Agent做强的,往往不是模型参数,而是工具体系是不是成型。

内置工具解决的是最常见的脏活累活,Skills解决的是经验复用,MCP解决的是外部连接,沙箱和Human-in-the-Loop解决的则是边界控制。把这几层拼起来,你得到的就不再是“能调几个函数的Agent”,而是一套能逐步接近生产环境的工作系统。

所以更愿意把DeepAgents理解成“工具生态框架”,而不只是“多塞了几个工具的Agent封装”。这两者看起来差不多,落到实际项目里差别会非常大。

来源:https://www.53ai.com/news/langchain/2026032747320.html

相关热点

继续查看同栏目近期热点。

延伸阅读

补充最近整理过的热点入口。