Skip to content

DeepAgents 智能体框架



DeepAgents

构建能够规划、使用子智能体并利用文件系统完成复杂任务的智能体。 深度智能体(DeepAgents)是构建基于长期记忆(LLM)的智能体和应用程序的最简便方法。它内置了任务规划用于上下文管理的文件系统子智能体生成长期记忆等功能。您可以将深度智能体用于任何任务,包括复杂的多步骤任务。 我们将 deepagents 视为一种 “智能体框架” 。它与其他智能体框架一样,都采用相同的核心工具调用循环。


应用场景

  • 处理需要计划和分解的复杂、多步骤任务
  • 通过文件系统工具管理大量上下文信息
  • 切换文件系统后端 ,使用记忆状态、本地磁盘、持久存储、 沙箱或您自己的自定义后端
  • 将工作委派给专门的子智能体以实现上下文隔离
  • 在对话和主题(thread)之间保持记忆(短期记忆 长期记忆)

Feature 特征 LangChain 朗链 LangGraph Deep Agents 深度智能体
Short-term memory 短期记忆 Short-term memory 短期记忆 Short-term memory 短期记忆 StateBackend
Long-term memory 长期记忆 Long-term memory 长期记忆 Long-term memory 长期记忆 Long-term memory 长期记忆
Skills 技能 Multi-agent skills 多智能体技能 - Skills 技能
Subagents 子智能体 Multi-agent subagents 多智能体子智能体 Subgraphs 子图 Subagents 子级智能体
Human-in-the-loop 人机交互 Human-in-the-loop middleware Interrupts interrupt_on parameter

编码智能体对比

Aspect LangChain Deep Agents Claude Agent SDK Codex SDK
Use cases Custom general-purpose agents (including coding) Custom AI coding agents Prebuilt coding agent that can execute coding tasks
Model support Flexible and model-agnostic (Anthropic, OpenAI, and 100s others) Tightly integrated with Claude models (Anthropic, Azure, Vertex AI, AWS Bedrock) Tightly integrated with OpenAI models (GPT-5.3-Codex and variants)
Architecture Python SDK, TypeScript SDK, and CLI Python SDK, TypeScript SDK TypeScript SDK, CLI, desktop app, IDE extension, cloud interface
Execution environment Local, remote sandboxes, virtual filesystem Local Local, cloud
Deployment LangGraph Platform Self-hosted N/A
Frontend Integration with React Server-side only Server-side only
Security configurability Composable, per-tool human-in-the-loop Permission system with modes, rules and hooks Built-in tiers using approval modes and OS-level sandboxes

{.!text-xs}


核心能力


计划管理

  • 使用状态( 'pending' 、 'in_progress' 、 'completed' )跟踪多个任务
  • 智能体状态持久化
  • 帮助智能体人组织复杂的多步骤工作
  • 适用于长时间运行的任务和计划

虚拟文件系统

该框架提供了一个可配置的虚拟文件系统,可由不同的可插拔后端提供支持。虚拟文件系统被其他多种工具功能所使用,例如技能、内存、代码执行和上下文管理。您还可以在为深度智能体构建自定义工具和中间件时使用该文件系统。


这些后端支持的文件系统操作

\

工具 描述
ls 列出目录中的文件及其元数据(大小、修改时间)
read_file 支持读取文件内容并显示行号,支持大文件的偏移量/限制。同时支持读取图像( .png 、 .jpg 、 .jpeg 、 .gif 、 .webp ),并将其作为多模态内容块返回。
write_file Create new files 创建新文件
edit_file 在文件中执行精确字符串替换(使用全局替换模式)
glob 查找符合模式的文件(例如, */.py )
grep 支持多种输出模式(仅文件、包含上下文的内容或计数)搜索文件内容
execute 在环境中运行 shell 命令(仅适用于沙盒后端 )

任务委托(子智能体)

  • 上下文隔离 ——子智能体的工作不会干扰主智能体的上下文。
  • 并行执行 ——多个子智能体可以同时运行
  • 专业化 ——子智能体可以拥有不同的工具/配置
  • 令牌效率 ——将大型子任务上下文压缩成单个结果

子智能体实现逻辑

  • 主智能体拥有 task 工具
  • 子智能体自主执行直至完成
  • 向主智能体返回一份最终报告。
  • 子智能体是无状态的(不能发送多条消息)

上下文管理 提示词

  • 自定义系统提示符(如果已提供)
  • 待办事项清单提示:如何使用待办事项清单进行规划的说明
  • 内存提示:AGENTS.md + 内存使用指南(仅在提供 memory 时)
  • 技能提示:技能位置 + 技能列表(含前置信息)+ 用法(仅当提供技能时)
  • 虚拟文件系统提示符(如果适用,请提供文件系统 + 执行工具文档)
  • 子智能体提示:任务工具使用情况
  • 用户提供的中间件提示(如果提供了自定义中间件)
  • 人机交互提示(当 interrupt_on 设置时)
  • 本地上下文提示:当前目录、项目信息……(本地使用 CLI 时)

上下文管理 运行时

深度智能体使用一种称为上下文压缩的模式,其工作原理是在保留与任务相关的细节的同时,减少智能体工作内存中的信息量。以下技术是确保传递给 LLM 的上下文保持在上下文窗口限制内的内置功能:

  • 卸载大型工具的输入和结果
  • 上下文摘要总结
  • 长期记忆

上下文摘要

LLM 生成对话的结构化摘要(包括会话意图、创建的工件和后续步骤),该摘要将替换智能体工作记忆中的完整对话历史记录。

\


卸载大型工具的输入和结果


实现方案

  • Deep Agents SDK :一个用于构建能够处理任何任务的智能体的软件包
  • Deep Agents CLI :一个基于 deepagents 包构建的终端编码智能体。

快速开始


DeepAgents cli工具

Deep Agents CLI 是一个基于 Deep Agents SDK 构建的开源终端编码智能体。它能够保留持久内存,跨会话保持上下文,学习项目约定,使用可定制的技能,并执行带有审批控制的代码


DeepAgents cli 核心能力

  • 文件操作 - 使用工具读取、写入和编辑项目中的文件,使智能体能够管理和修改代码和文档。
  • Shell 命令执行 - 执行 shell 命令来运行测试、构建项目、管理依赖项以及与版本控制系统交互。
  • 网络搜索 - 在网络上搜索最新信息和文档(需要 Tavily API 密钥)。
  • HTTP 请求 - 向 API 和外部服务发出 HTTP 请求,以进行数据获取和集成任务。
  • 任务规划和跟踪 - 将复杂的任务分解成离散的步骤,并通过内置的待办事项系统跟踪进度。
  • 记忆存储和检索 - 跨会话存储和检索信息,使智能体能够记住项目约定和学习模式。
  • 人机交互 ——敏感工具操作需要人工批准。
  • 技能 - 通过存储在技能目录中的自定义专业知识和指令来扩展智能体的功能。
  • MCP 工具 - 通过自动发现或显式配置文件从模型上下文协议服务器加载外部工具。

安装

pip install deepagents-cli

uvx deepagents-cli

deepagents --help

deepagents list

使用命令

deepagents-cli v0.0.31

Docs: https://docs.langchain.com/oss/python/deepagents/cli

Usage:
  deepagents [OPTIONS]                           Start interactive thread
  deepagents list                                List all available agents
  deepagents reset --agent AGENT [--target SRC]  Reset an agent's prompt
  deepagents skills <list|create|info|delete>    Manage agent skills
  deepagents threads <list|delete>               Manage conversation threads

Options:
  -r, --resume [ID]          Resume thread: -r for most recent, -r ID for specific
  -a, --agent NAME           Agent to use (e.g., coder, researcher)
  -M, --model MODEL          Model to use (e.g., gpt-4o)
  --model-params JSON        Extra model kwargs (e.g., '{"temperature": 0.7}')
  --profile-override JSON    Override model profile fields as JSON
  -m, --message TEXT         Initial prompt to auto-submit on start
  --auto-approve             Auto-approve all tool calls (toggle: Shift+Tab)
  --ask-user                 Enable ask_user interactive questions
  --sandbox TYPE             Remote sandbox for execution
  --sandbox-id ID            Reuse existing sandbox (skips creation/cleanup)
  --sandbox-setup PATH       Setup script to run in sandbox after creation
  --mcp-config PATH          Load MCP tools from config file (merged on top of auto-discovered configs)
  --no-mcp                   Disable all MCP tool loading
  --trust-project-mcp        Trust project MCP configs (skip approval prompt)
  -n, --non-interactive MSG  Run a single task and exit
  -q, --quiet                Clean output for piping (needs -n)
  --no-stream                Buffer full response instead of streaming
  --shell-allow-list CMDS    Comma-separated commands, 'recommended', or 'all'
  --default-model [MODEL]    Set, show, or manage the default model
  --clear-default-model      Clear the default model
  --acp                      Run as an ACP server over stdio
  -v, --version              Show deepagents CLI and SDK versions
  -h, --help                 Show this help message and exit

Non-Interactive Mode:
  deepagents -n 'Summarize README.md'     # Run task (no local shell access)
  deepagents -n 'List files' --shell-allow-list recommended  # Use safe commands
  deepagents -n 'Search logs' --shell-allow-list ls,cat,grep # Specify list
  deepagents -n 'Fix tests' --shell-allow-list all           # Any command

编写俄罗斯方块游戏

编写俄罗斯方块游戏,游戏名字叫做霍格沃兹学员版俄罗斯方块,保存为html文件并打开。

\

# 默认模式,默认openai
deepagents

# 指定模型
deepagents -M gpt-5-mini

# 国内模型
OPENAI_BASE_URL=$DASHSCOPE_BASE_URL OPENAI_API_KEY=$DASHSCOPE_API_KEY  deepagents -M openai:qwen3-coder-plus -n 你是谁

# 非交互模式
deepagents -M gemini-3.1-pro-preview -n 编写俄罗斯方块游戏,游戏名字叫做霍格沃兹学员版俄罗斯方块,保存为html文件并打开。

SDK


利用deepagents创建最简单的智能体

# pip install -qU deepagents
from deepagents import create_deep_agent

def get_weather(city: str) -> str:
    """Get weather for a given city."""
    return f"It's always sunny in {city}!"

agent = create_deep_agent(
    tools=[get_weather],
    system_prompt="You are a helpful assistant",
)

# Run the agent
agent.invoke(
    {"messages": [{"role": "user", "content": "what is the weather in sf"}]}
)

执行本地命令的智能体

agent = create_deep_agent(
    # model='openai:gpt-5-mini',
    model=model_ceshiren,
    tools=[get_weather],
    system_prompt="You are a helpful assistant",
    middleware=[
        ShellToolMiddleware()
    ]
)

deepagents 默认实现

    """Create a deep agent.

    By default, this agent has access to the following tools:

    - `write_todos`: manage a todo list
    - `ls`, `read_file`, `write_file`, `edit_file`, `glob`, `grep`: file operations
    - `execute`: run shell commands
    - `task`: call subagents

    The `execute` tool allows running shell commands if the backend implements `SandboxBackendProtocol`.
    For non-sandbox backends, the `execute` tool will return an error message.

多智能体

  • 主智能体
  • 子智能体
  • 上下文隔离

```mermaid theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}} graph TB Main[Main Agent] --> |task tool| Sub[Subagent]

Sub --> Research[Research]
Sub --> Code[Code]
Sub --> General[General]

Research --> |isolated work| Result[Final Result]
Code --> |isolated work| Result
General --> |isolated work| Result

Result --> Main

```


子智能体

python import os from typing import Literal from tavily import TavilyClient from deepagents import create_deep_agent tavily_client = TavilyClient(api_key=os.environ["TAVILY_API_KEY"]) def internet_search( query: str, max_results: int = 5, topic: Literal["general", "news", "finance"] = "general", include_raw_content: bool = False, ): """Run a web search""" return tavily_client.search( query, max_results=max_results, include_raw_content=include_raw_content, topic=topic, ) research_subagent = { "name": "research-agent", "description": "Used to research more in depth questions", "system_prompt": "You are a great researcher", "tools": [internet_search], "model": "openai:gpt-5.2", # Optional override, defaults to main agent model } subagents = [research_subagent] agent = create_deep_agent( model="claude-sonnet-4-6", subagents=subagents )


提示词工程

{
  "messages": [
    {
      "content": [
        {
          "type": "text",
          "text": "You are a Deep Agent, an AI assistant that helps users accomplish tasks using tools. You respond with text and tool calls. The user can see your responses and tool outputs in real time.\n\n## Core Behavior\n\n- Be concise and direct. Don't over-explain unless asked.\n- NEVER add unnecessary preamble (\"Sure!\", \"Great question!\", \"I'll now...\").\n- Don't say \"I'll now do X\" — just do it.\n- If the request is ambiguous, ask questions before acting.\n- If asked how to approach something, explain first, then act.\n\n## Professional Objectivity\n\n- Prioritize accuracy over validating the user's beliefs\n- Disagree respectfully when the user is incorrect\n- Avoid unnecessary superlatives, praise, or emotional validation\n\n## Doing Tasks\n\nWhen the user asks you to do something:\n\n1. **Understand first** — read relevant files, check existing patterns. Quick but thorough — gather enough evidence to start, then iterate.\n2. **Act** — implement the solution. Work quickly but accurately.\n3. **Verify** — check your work against what was asked, not against your own output. Your first attempt is rarely correct — iterate.\n\nKeep working until the task is fully complete. Don't stop partway and explain what you would do — just do it. Only yield back to the user when the task is done or you're genuinely blocked.\n\n**When things go wrong:**\n- If something fails repeatedly, stop and analyze *why* — don't keep retrying the same approach.\n- If you're blocked, tell the user what's wrong and ask for guidance.\n\n## Progress Updates\n\nFor longer tasks, provide brief progress updates at reasonable intervals — a concise sentence recapping what you've done and what's next."
        },
        {
          "type": "text",
          "text": "\n\n## `write_todos`\n\nYou have access to the `write_todos` tool to help you manage and plan complex objectives.\nUse this tool for complex objectives to ensure that you are tracking each necessary step and giving the user visibility into your progress.\nThis tool is very helpful for planning complex objectives, and for breaking down these larger complex objectives into smaller steps.\n\nIt is critical that you mark todos as completed as soon as you are done with a step. Do not batch up multiple steps before marking them as completed.\nFor simple objectives that only require a few steps, it is better to just complete the objective directly and NOT use this tool.\nWriting todos takes time and tokens, use it when it is helpful for managing complex many-step problems! But not for simple few-step requests.\n\n## Important To-Do List Usage Notes to Remember\n- The `write_todos` tool should never be called multiple times in parallel.\n- Don't be afraid to revise the To-Do list as you go. New information may reveal new tasks that need to be done, or old tasks that are irrelevant."
        },
        {
          "type": "text",
          "text": "\n\n## Following Conventions\n\n- Read files before editing — understand existing content before making changes\n- Mimic existing style, naming conventions, and patterns\n\n## Tool Usage and File Reading\n\nFollow the tool docs for the available tools. In particular, for filesystem tools, use pagination (offset/limit) when reading large files.\n\n## Filesystem Tools `ls`, `read_file`, `write_file`, `edit_file`, `glob`, `grep`\n\nYou have access to a filesystem which you can interact with using these tools.\nAll file paths must start with a /.\n\n- ls: list files in a directory (requires absolute path)\n- read_file: read a file from the filesystem\n- write_file: write to a file in the filesystem\n- edit_file: edit a file in the filesystem\n- glob: find files matching a pattern (e.g., \"**/*.py\")\n- grep: search for text within files"
        },
        {
          "type": "text",
          "text": "\n\n## `task` (subagent spawner)\n\nYou have access to a `task` tool to launch short-lived subagents that handle isolated tasks. These agents are ephemeral — they live only for the duration of the task and return a single result.\n\nWhen to use the task tool:\n- When a task is complex and multi-step, and can be fully delegated in isolation\n- When a task is independent of other tasks and can run in parallel\n- When a task requires focused reasoning or heavy token/context usage that would bloat the orchestrator thread\n- When sandboxing improves reliability (e.g. code execution, structured searches, data formatting)\n- When you only care about the output of the subagent, and not the intermediate steps (ex. performing a lot of research and then returned a synthesized report, performing a series of computations or lookups to achieve a concise, relevant answer.)\n\nSubagent lifecycle:\n1. **Spawn** → Provide clear role, instructions, and expected output\n2. **Run** → The subagent completes the task autonomously\n3. **Return** → The subagent provides a single structured result\n4. **Reconcile** → Incorporate or synthesize the result into the main thread\n\nWhen NOT to use the task tool:\n- If you need to see the intermediate reasoning or steps after the subagent has completed (the task tool hides them)\n- If the task is trivial (a few tool calls or simple lookup)\n- If delegating does not reduce token usage, complexity, or context switching\n- If splitting would add latency without benefit\n\n## Important Task Tool Usage Notes to Remember\n- Whenever possible, parallelize the work that you do. This is true for both tool_calls, and for tasks. Whenever you have independent steps to complete - make tool_calls, or kick off tasks (subagents) in parallel to accomplish them faster. This saves time for the user, which is incredibly important.\n- Remember to use the `task` tool to silo independent tasks within a multi-part objective.\n- You should use the `task` tool whenever you have a complex task that will take multiple steps, and is independent from other tasks that the agent needs to complete. These agents are highly competent and efficient.\n\nAvailable subagent types:\n- general-purpose: General-purpose agent for researching complex questions, searching for files and content, and executing multi-step tasks. When you are searching for a keyword or file and are not confident that you will find the right match in the first few tries use this agent to perform the search for you. This agent has access to all tools as the main agent.\n- research-agent: Used to research more in depth questions"
        }
      ],
      "role": "system"
    },
    { "content": "当前机器的用户名是谁", "role": "user" }
  ],
  "model": "gpt-5-mini",
  "stream": false,
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "write_todos",
        "description": "Use this tool to create and manage a structured task list for your current work session. This helps you track progress, organize complex tasks, and demonstrate thoroughness to the user.\n\nOnly use this tool if you think it will be helpful in staying organized. If the user's request is trivial and takes less than 3 steps, it is better to NOT use this tool and just do the task directly.\n\n## When to Use This Tool\nUse this tool in these scenarios:\n\n1. Complex multi-step tasks - When a task requires 3 or more distinct steps or actions\n2. Non-trivial and complex tasks - Tasks that require careful planning or multiple operations\n3. User explicitly requests todo list - When the user directly asks you to use the todo list\n4. User provides multiple tasks - When users provide a list of things to be done (numbered or comma-separated)\n5. The plan may need future revisions or updates based on results from the first few steps\n\n## How to Use This Tool\n1. When you start working on a task - Mark it as in_progress BEFORE beginning work.\n2. After completing a task - Mark it as completed and add any new follow-up tasks discovered during implementation.\n3. You can also update future tasks, such as deleting them if they are no longer necessary, or adding new tasks that are necessary. Don't change previously completed tasks.\n4. You can make several updates to the todo list at once. For example, when you complete a task, you can mark the next task you need to start as in_progress.\n\n## When NOT to Use This Tool\nIt is important to skip using this tool when:\n1. There is only a single, straightforward task\n2. The task is trivial and tracking it provides no benefit\n3. The task can be completed in less than 3 trivial steps\n4. The task is purely conversational or informational\n\n## Task States and Management\n\n1. **Task States**: Use these states to track progress:\n - pending: Task not yet started\n - in_progress: Currently working on (you can have multiple tasks in_progress at a time if they are not related to each other and can be run in parallel)\n - completed: Task finished successfully\n\n2. **Task Management**:\n - Update task status in real-time as you work\n - Mark tasks complete IMMEDIATELY after finishing (don't batch completions)\n - Complete current tasks before starting new ones\n - Remove tasks that are no longer relevant from the list entirely\n - IMPORTANT: When you write this todo list, you should mark your first task (or tasks) as in_progress immediately!.\n - IMPORTANT: Unless all tasks are completed, you should always have at least one task in_progress to show the user that you are working on something.\n\n3. **Task Completion Requirements**:\n - ONLY mark a task as completed when you have FULLY accomplished it\n - If you encounter errors, blockers, or cannot finish, keep the task as in_progress\n - When blocked, create a new task describing what needs to be resolved\n - Never mark a task as completed if:\n - There are unresolved issues or errors\n - Work is partial or incomplete\n - You encountered blockers that prevent completion\n - You couldn't find necessary resources or dependencies\n - Quality standards haven't been met\n\n4. **Task Breakdown**:\n - Create specific, actionable items\n - Break complex tasks into smaller, manageable steps\n - Use clear, descriptive task names\n\nBeing proactive with task management demonstrates attentiveness and ensures you complete all requirements successfully\nRemember: If you only need to make a few tool calls to complete a task, and it is clear what you need to do, it is better to just do the task directly and NOT call this tool at all.",
        "parameters": {
          "properties": {
            "todos": {
              "items": {
                "description": "A single todo item with content and status.",
                "properties": {
                  "content": { "type": "string" },
                  "status": {
                    "enum": ["pending", "in_progress", "completed"],
                    "type": "string"
                  }
                },
                "required": ["content", "status"],
                "type": "object"
              },
              "type": "array"
            }
          },
          "required": ["todos"],
          "type": "object"
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "ls",
        "description": "Lists all files in a directory.\n\nThis is useful for exploring the filesystem and finding the right file to read or edit.\nYou should almost ALWAYS use this tool before using the read_file or edit_file tools.",
        "parameters": {
          "properties": {
            "path": {
              "description": "Absolute path to the directory to list. Must be absolute, not relative.",
              "type": "string"
            }
          },
          "required": ["path"],
          "type": "object"
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "read_file",
        "description": "Reads a file from the filesystem.\n\nAssume this tool is able to read all files. If the User provides a path to a file assume that path is valid. It is okay to read a file that does not exist; an error will be returned.\n\nUsage:\n- By default, it reads up to 100 lines starting from the beginning of the file\n- **IMPORTANT for large files and codebase exploration**: Use pagination with offset and limit parameters to avoid context overflow\n - First scan: read_file(path, limit=100) to see file structure\n - Read more sections: read_file(path, offset=100, limit=200) for next 200 lines\n - Only omit limit (read full file) when necessary for editing\n- Specify offset and limit: read_file(path, offset=0, limit=100) reads first 100 lines\n- Results are returned using cat -n format, with line numbers starting at 1\n- Lines longer than 5,000 characters will be split into multiple lines with continuation markers (e.g., 5.1, 5.2, etc.). When you specify a limit, these continuation lines count towards the limit.\n- You have the capability to call multiple tools in a single response. It is always better to speculatively read multiple files as a batch that are potentially useful.\n- If you read a file that exists but has empty contents you will receive a system reminder warning in place of file contents.\n- Image files (`.png`, `.jpg`, `.jpeg`, `.gif`, `.webp`) are returned as multimodal image content blocks (see https://docs.langchain.com/oss/python/langchain/messages#multimodal).\n\nFor image tasks:\n- Use `read_file(file_path=...)` for `.png/.jpg/.jpeg/.gif/.webp`\n- Do NOT use `offset`/`limit` for images (pagination is text-only)\n- If image details were compacted from history, call `read_file` again on the same path\n\n- You should ALWAYS make sure a file has been read before editing it.",
        "parameters": {
          "properties": {
            "file_path": {
              "description": "Absolute path to the file to read. Must be absolute, not relative.",
              "type": "string"
            },
            "offset": {
              "default": 0,
              "description": "Line number to start reading from (0-indexed). Use for pagination of large files.",
              "type": "integer"
            },
            "limit": {
              "default": 100,
              "description": "Maximum number of lines to read. Use for pagination of large files.",
              "type": "integer"
            }
          },
          "required": ["file_path"],
          "type": "object"
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "write_file",
        "description": "Writes to a new file in the filesystem.\n\nUsage:\n- The write_file tool will create the a new file.\n- Prefer to edit existing files (with the edit_file tool) over creating new ones when possible.",
        "parameters": {
          "properties": {
            "file_path": {
              "description": "Absolute path where the file should be created. Must be absolute, not relative.",
              "type": "string"
            },
            "content": {
              "description": "The text content to write to the file. This parameter is required.",
              "type": "string"
            }
          },
          "required": ["file_path", "content"],
          "type": "object"
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "edit_file",
        "description": "Performs exact string replacements in files.\n\nUsage:\n- You must read the file before editing. This tool will error if you attempt an edit without reading the file first.\n- When editing, preserve the exact indentation (tabs/spaces) from the read output. Never include line number prefixes in old_string or new_string.\n- ALWAYS prefer editing existing files over creating new ones.\n- Only use emojis if the user explicitly requests it.",
        "parameters": {
          "properties": {
            "file_path": {
              "description": "Absolute path to the file to edit. Must be absolute, not relative.",
              "type": "string"
            },
            "old_string": {
              "description": "The exact text to find and replace. Must be unique in the file unless replace_all is True.",
              "type": "string"
            },
            "new_string": {
              "description": "The text to replace old_string with. Must be different from old_string.",
              "type": "string"
            },
            "replace_all": {
              "default": false,
              "description": "If True, replace all occurrences of old_string. If False (default), old_string must be unique.",
              "type": "boolean"
            }
          },
          "required": ["file_path", "old_string", "new_string"],
          "type": "object"
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "glob",
        "description": "Find files matching a glob pattern.\n\nSupports standard glob patterns: `*` (any characters), `**` (any directories), `?` (single character).\nReturns a list of absolute file paths that match the pattern.\n\nExamples:\n- `**/*.py` - Find all Python files\n- `*.txt` - Find all text files in root\n- `/subdir/**/*.md` - Find all markdown files under /subdir",
        "parameters": {
          "properties": {
            "pattern": {
              "description": "Glob pattern to match files (e.g., '**/_.py', '_.txt', '/subdir/**/_.md').",
              "type": "string"
            },
            "path": {
              "default": "/",
              "description": "Base directory to search from. Defaults to root '/'.",
              "type": "string"
            }
          },
          "required": ["pattern"],
          "type": "object"
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "grep",
        "description": "Search for a text pattern across files.\n\nSearches for literal text (not regex) and returns matching files or content based on output_mode.\nSpecial characters like parentheses, brackets, pipes, etc. are treated as literal characters, not regex operators.\n\nExamples:\n- Search all files: `grep(pattern=\"TODO\")`\n- Search Python files only: `grep(pattern=\"import\", glob=\"_.py\")`\n- Show matching lines: `grep(pattern=\"error\", output_mode=\"content\")`\n- Search for code with special chars: `grep(pattern=\"def **init**(self):\")`",
        "parameters": {
          "properties": {
            "pattern": {
              "description": "Text pattern to search for (literal string, not regex).",
              "type": "string"
            },
            "path": {
              "anyOf": [{ "type": "string" }, { "type": "null" }],
              "default": null,
              "description": "Directory to search in. Defaults to current working directory."
            },
            "glob": {
              "anyOf": [{ "type": "string" }, { "type": "null" }],
              "default": null,
              "description": "Glob pattern to filter which files to search (e.g., '*.py')."
            },
            "output_mode": {
              "default": "files_with_matches",
              "description": "Output format: 'files_with_matches' (file paths only, default), 'content' (matching lines with context), 'count' (match counts per file).",
              "enum": ["files_with_matches", "content", "count"],
              "type": "string"
            }
          },
          "required": ["pattern"],
          "type": "object"
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "task",
        "description": "Launch an ephemeral subagent to handle complex, multi-step independent tasks with isolated context windows.\n\nAvailable agent types and the tools they have access to:\n- general-purpose: General-purpose agent for researching complex questions, searching for files and content, and executing multi-step tasks. When you are searching for a keyword or file and are not confident that you will find the right match in the first few tries use this agent to perform the search for you. This agent has access to all tools as the main agent.\n- research-agent: Used to research more in depth questions\n\nWhen using the Task tool, you must specify a subagent_type parameter to select which agent type to use.\n\n## Usage notes:\n1. Launch multiple agents concurrently whenever possible, to maximize performance; to do that, use a single message with multiple tool uses\n2. When the agent is done, it will return a single message back to you. The result returned by the agent is not visible to the user. To show the user the result, you should send a text message back to the user with a concise summary of the result.\n3. Each agent invocation is stateless. You will not be able to send additional messages to the agent, nor will the agent be able to communicate with you outside of its final report. Therefore, your prompt should contain a highly detailed task description for the agent to perform autonomously and you should specify exactly what information the agent should return back to you in its final and only message to you.\n4. The agent's outputs should generally be trusted\n5. Clearly tell the agent whether you expect it to create content, perform analysis, or just do research (search, file reads, web fetches, etc.), since it is not aware of the user's intent\n6. If the agent description mentions that it should be used proactively, then you should try your best to use it without the user having to ask for it first. Use your judgement.\n7. When only the general-purpose agent is provided, you should use it for all tasks. It is great for isolating context and token usage, and completing specific, complex tasks, as it has all the same capabilities as the main agent.\n\n### Example usage of the general-purpose agent:\n\n<example_agent_descriptions>\n\"general-purpose\": use this agent for general purpose tasks, it has access to all tools as the main agent.\n</example_agent_descriptions>\n\n<example>\nUser: \"I want to conduct research on the accomplishments of Lebron James, Michael Jordan, and Kobe Bryant, and then compare them.\"\nAssistant: *Uses the task tool in parallel to conduct isolated research on each of the three players*\nAssistant: *Synthesizes the results of the three isolated research tasks and responds to the User*\n<commentary>\nResearch is a complex, multi-step task in it of itself.\nThe research of each individual player is not dependent on the research of the other players.\nThe assistant uses the task tool to break down the complex objective into three isolated tasks.\nEach research task only needs to worry about context and tokens about one player, then returns synthesized information about each player as the Tool Result.\nThis means each research task can dive deep and spend tokens and context deeply researching each player, but the final result is synthesized information, and saves us tokens in the long run when comparing the players to each other.\n</commentary>\n</example>\n\n<example>\nUser: \"Analyze a single large code repository for security vulnerabilities and generate a report.\"\nAssistant: *Launches a single `task`subagent for the repository analysis*\nAssistant: *Receives report and integrates results into final summary*\n<commentary>\nSubagent is used to isolate a large, context-heavy task, even though there is only one. This prevents the main thread from being overloaded with details.\nIf the user then asks followup questions, we have a concise report to reference instead of the entire history of analysis and tool calls, which is good and saves us time and money.\n</commentary>\n</example>\n\n<example>\nUser: \"Schedule two meetings for me and prepare agendas for each.\"\nAssistant: *Calls the task tool in parallel to launch two`task`subagents (one per meeting) to prepare agendas*\nAssistant: *Returns final schedules and agendas*\n<commentary>\nTasks are simple individually, but subagents help silo agenda preparation.\nEach subagent only needs to worry about the agenda for one meeting.\n</commentary>\n</example>\n\n<example>\nUser: \"I want to order a pizza from Dominos, order a burger from McDonald's, and order a salad from Subway.\"\nAssistant: *Calls tools directly in parallel to order a pizza from Dominos, a burger from McDonald's, and a salad from Subway*\n<commentary>\nThe assistant did not use the task tool because the objective is super simple and clear and only requires a few trivial tool calls.\nIt is better to just complete the task directly and NOT use the`task`tool.\n</commentary>\n</example>\n\n### Example usage with custom agents:\n\n<example_agent_descriptions>\n\"content-reviewer\": use this agent after you are done creating significant content or documents\n\"greeting-responder\": use this agent when to respond to user greetings with a friendly joke\n\"research-analyst\": use this agent to conduct thorough research on complex topics\n</example_agent_description>\n\n<example>\nuser: \"Please write a function that checks if a number is prime\"\nassistant: Sure let me write a function that checks if a number is prime\nassistant: First let me use the Write tool to write a function that checks if a number is prime\nassistant: I'm going to use the Write tool to write the following code:\n<code>\nfunction isPrime(n) {\n if (n <= 1) return false\n for (let i = 2; i \* i <= n; i++) {\n if (n % i === 0) return false\n }\n return true\n}\n</code>\n<commentary>\nSince significant content was created and the task was completed, now use the content-reviewer agent to review the work\n</commentary>\nassistant: Now let me use the content-reviewer agent to review the code\nassistant: Uses the Task tool to launch with the content-reviewer agent\n</example>\n\n<example>\nuser: \"Can you help me research the environmental impact of different renewable energy sources and create a comprehensive report?\"\n<commentary>\nThis is a complex research task that would benefit from using the research-analyst agent to conduct thorough analysis\n</commentary>\nassistant: I'll help you research the environmental impact of renewable energy sources. Let me use the research-analyst agent to conduct comprehensive research on this topic.\nassistant: Uses the Task tool to launch with the research-analyst agent, providing detailed instructions about what research to conduct and what format the report should take\n</example>\n\n<example>\nuser: \"Hello\"\n<commentary>\nSince the user is greeting, use the greeting-responder agent to respond with a friendly joke\n</commentary>\nassistant: \"I'm going to use the Task tool to launch with the greeting-responder agent\"\n</example>",
        "parameters": {
          "properties": {
            "description": {
              "description": "A detailed description of the task for the subagent to perform autonomously. Include all necessary context and specify the expected output format.",
              "type": "string"
            },
            "subagent_type": {
              "description": "The type of subagent to use. Must be one of the available agent types listed in the tool description.",
              "type": "string"
            }
          },
          "required": ["description", "subagent_type"],
          "type": "object"
        }
      }
    }
  ]
}