Deep Agents 커스터마이징

Deep Agents 커스터마이징

시스템 프롬프트, 도구, 서브에이전트 등으로 Deep Agents를 커스터마이징하는 방법을 알아봐요.

목표에 맞춰 하네스(harness)를 구성하세요. create_deep_agent는 프로덕션 준비가 된 기반을 제공합니다: 데이터에 연결하고, 동작을 형성하고, 사용 사례에 필요한 역량을 추가하세요.

createDeepAgent는 미리 조립된 하네스와 함께 제공됩니다: 파일시스템, 요약, 서브에이전트, 프롬프트 캐싱이 기본으로 포함됩니다. 아래 매개변수를 사용하면 에이전트의 페르소나를 정의하고 데이터·도구에 연결하며 Deep Agents 스택에 추가 미들웨어로 확장할 수 있어요.

// 예: Google 제공자 (다른 탭은 model 문자열만 다름)
import { createDeepAgent } from "deepagents";

const agent = await createDeepAgent({
  model: "google-genai:gemini-3.6-flash",
  systemPrompt: "You are a helpful assistant.",
  tools: [search, fetchUrl],
  memory: ["./AGENTS.md"],
  skills: ["./skills/"],
});

다른 제공자 탭의 model 값: OpenAI openai:gpt-5.5, Anthropic anthropic:claude-sonnet-5, OpenRouter openrouter:z-ai/glm-5.2, Fireworks fireworks:accounts/fireworks/models/glm-5p2, Baseten baseten:zai-org/GLM-5.2, Ollama ollama:north-mini-code-1.0.

매개변수 하는 일
model 사용할 모델
systemPrompt 에이전트를 위한 커스텀 지침
tools 에이전트가 호출할 수 있는 도메인 도구
memory 시작 시 로드되는 AGENTS.md 파일
skills 온디맨드 지식을 위한 스킬 디렉토리
backend 파일시스템 백엔드(기본값 StateBackend)
permissions 파일시스템을 위한 경로 수준 접근 제어
subagents 위임된 작업을 위한 커스텀 서브에이전트
middleware Deep Agents 스택에 추가되는 미들웨어
interruptOn 인간 승인을 위해 도구 호출 전 일시 중지
responseFormat 구조화 출력 스키마
contextSchema 실행별 런타임 컨텍스트 스키마(사용자 ID, API 키, 기능 플래그)

전체 매개변수 목록은 createDeepAgent API 참조를 보세요. 완전한 커스텀 하네스를 처음부터 구성하려면 하네스 구성을 참조하세요.

: 도구, 서브에이전트, 백엔드를 추가하면서 LangSmith로 각 조각이 어떻게 함께 동작하는지 트레이스하세요. 설정은 observability 퀵스타트를 따르고, LangSmith 배포는 프로덕션으로 이동을 참고하세요. 트레이스를 모니터링하고 문제를 감지·수정을 제안하는 LangSmith Engine도 설정하는 것을 권장합니다.

출처: 문서

본문

모델

provider:model 형식의 model 문자열이나 초기화된 모델 인스턴스를 전달하세요. 모든 제공자는 지원 모델, 테스트된 권장 사항은 추천 모델을 보세요.

: provider:model 형식(예: openai:gpt-5.5)을 사용하면 모델을 빠르게 전환할 수 있어요.

모델은 세 가지 방식으로 지정할 수 있습니다(설치 패키지는 npm/pnpm/yarn/bun 모두 지원):

  • OpenAInpm install @langchain/openai deepagents:
    // default parameters 방식: 지정한 모델에 대해 initChatModel을 기본 매개변수로 호출
    import { createDeepAgent } from "deepagents";
    process.env.OPENAI_API_KEY = "your-api-key";
    const agent = createDeepAgent({ model: "gpt-5.5" });
    
    // initChatModel 방식: 특정 모델 매개변수를 사용하려면 initChatModel 직접 사용
    import { initChatModel } from "langchain";
    import { createDeepAgent } from "deepagents";
    process.env.OPENAI_API_KEY = "your-api-key";
    const model = await initChatModel("gpt-5.5");
    const agent = createDeepAgent({ model, temperature: 0 });
    
    // Model Class 방식
    import { ChatOpenAI } from "@langchain/openai";
    import { createDeepAgent } from "deepagents";
    const agent = createDeepAgent({
      model: new ChatOpenAI({ model: "gpt-5.5", apiKey: ***, temperature: 0 }),
    });
    
  • Anthropicnpm install @langchain/anthropic deepagents:
    import { initChatModel } from "langchain";
    import { createDeepAgent } from "deepagents";
    process.env.ANTHROPIC_API_KEY = "your-api-key";
    const model = await initChatModel("claude-sonnet-4-6");
    const agent = createDeepAgent({ model, temperature: 0 });
    
    import { ChatAnthropic } from "@langchain/anthropic";
    import { createDeepAgent } from "deepagents";
    const agent = createDeepAgent({
      model: new ChatAnthropic({ model: "claude-sonnet-4-6", apiKey: ***, temperature: 0 }),
    });
    
  • Azurenpm install @langchain/azure deepagents (+ AZURE_OPENAI_API_KEY, AZURE_OPENAI_ENDPOINT, OPENAI_API_VERSION):
    import { initChatModel } from "langchain";
    import { createDeepAgent } from "deepagents";
    process.env.AZURE_OPENAI_API_KEY = "your-api-key";
    process.env.AZURE_OPENAI_ENDPOINT = "your-endpoint";
    process.env.OPENAI_API_VERSION = "your-api-version";
    const model = await initChatModel("azure_openai:gpt-5.5");
    const agent = createDeepAgent({ model, temperature: 0 });
    
  • Google Gemininpm install @langchain/google-genai deepagents (+ GOOGLE_API_KEY):
    import { initChatModel } from "langchain";
    import { createDeepAgent } from "deepagents";
    process.env.GOOGLE_API_KEY = "your-api-key";
    const model = await initChatModel("google-genai:gemini-3.1-pro-preview");
    const agent = createDeepAgent({ model, temperature: 0 });
    
  • Bedrock Conversenpm install @langchain/aws deepagents (자격 증명 설정은 AWS Bedrock 시작 가이드 참조):
    import { ChatBedrockConverse } from "@langchain/aws";
    import { createDeepAgent } from "deepagents";
    const agent = createDeepAgent({
      model: new ChatBedrockConverse({ model: "anthropic.claude-sonnet-4-6", region: "us-east-2", temperature: 0 }),
    });
    
  • 기타 — 어떤 지원 모델 문자열이나 초기화된 모델 인스턴스든 전달하세요:
    import { initChatModel } from "langchain";
    import { createDeepAgent } from "deepagents";
    const model = await initChatModel("provider:model-name");
    const agent = createDeepAgent({ model });
    

: 채팅 모델은 일시적인 API 실패를 자동 재시도합니다(지수 백오프). max_retries/timeout 튜닝의 기본값·한도·코드 샘플은 LangChain Models 페이지에 있습니다.

도구

파일 관리와 서브에이전트 생성을 위한 내장 도구 외에 커스텀 도구를 제공할 수 있어요:

// 예: Google 제공자 (다른 탭은 model 문자열만 다름)
import { tool } from "langchain";
import { TavilySearch } from "@langchain/tavily";
import { createDeepAgent } from "deepagents";
import { z } from "zod";

const internetSearch = tool(
  async ({
    query,
    maxResults = 5,
    topic = "general",
    includeRawContent = false,
  }: {
    query: string;
    maxResults?: number;
    topic?: "general" | "news" | "finance";
    includeRawContent?: boolean;
  }) => {
    const tavilySearch = new TavilySearch({
      maxResults,
      tavilyApiKey: proces...KEY,
      includeRawContent,
      topic,
    });
    return await tavilySearch._call({ query });
  },
  {
    name: "internet_search",
    description: "Run a web search",
    schema: z.object({
      query: z.string().describe("The search query"),
      maxResults: z.number().optional().default(5),
      topic: z
        .enum(["general", "news", "finance"])
        .optional()
        .default("general"),
      includeRawContent: z.boolean().optional().default(false),
    }),
  },
);

const agent = createDeepAgent({
  model: "google-genai:gemini-3.6-flash",
  tools: [internetSearch],
});

다른 제공자 탭의 model 값: OpenAI openai:gpt-5.5, Anthropic anthropic:claude-sonnet-5, OpenRouter openrouter:z-ai/glm-5.2, Fireworks fireworks:accounts/fireworks/models/glm-5p2, Baseten baseten:zai-org/GLM-5.2, Ollama ollama:north-mini-code-1.0.

MCP 도구

: Deep Agents는 Model Context Protocol (MCP) 도구를 완전히 지원합니다. 데이터베이스, API, 파일시스템 등 어떤 MCP 서버에서든 도구를 로드해 create_deep_agent에 직접 전달할 수 있어요.

MCP 서버에 연결하려면 @langchain/mcp-adapters를 설치하세요:

npm install @langchain/mcp-adapters
// 예: Google 제공자 (다른 탭은 model 문자열만 다름)
import { createDeepAgent } from "deepagents";

const { MultiServerMCPClient } = await import("@langchain/mcp-adapters");

const client = new MultiServerMCPClient({
    my_server: {
        transport: "http",
        url: "http://localhost:8000/mcp",
    },
});

const tools = await client.getTools();

const agent = await createDeepAgent({
    model: "google-genai:gemini-3.6-flash",
    tools,
});

const result = await agent.invoke({
    messages: [{ role: "user", content: "Use the MCP server to help me." }],
});

표준입력(stdin) 서버, OAuth 인증, 도구 필터링, 상태 유지 세션을 포함한 자세한 구성 옵션은 MCP 가이드를 참고하세요.

시스템 프롬프트

system_prompt=에 에이전트용 지침을 전달하세요:

// 예: Google 제공자 (다른 탭은 model 문자열만 다름)
import { createDeepAgent } from "deepagents";

const researchInstructions =
  `You are an expert researcher. ` +
  `Your job is to conduct thorough research, and then ` +
  `write a polished report.`;

const agent = createDeepAgent({
  model: "google-genai:gemini-3.6-flash",
  systemPrompt: researchInstructions,
});

참고: 문자열 외에도 메인 에이전트는 구조화된 콘텐츠 블록이 있는 SystemMessage을 받아들입니다. Deep Agents는 그 블록을 보존합니다(서브에이전트 사전 스펙은 문자열로 유지).

  • 서브에이전트 프롬프트: 선언적 서브에이전트는 프로파일 오버레이를 자체 모델에 대해 해석한 뒤, 해석된 프로파일의 base_system_prompt/system_prompt_suffix를 서브에이전트가 작성한 system_prompt에 적용합니다. system_prompt_suffix만 제공하는 프로파일(내장 Anthropic/OpenAI 프로파일의 일반적인 경우)은 작성된 프롬프트에 추가하고, base_system_prompt를 설정하는 프로파일은 그것을 통째로 교체합니다.
  • 범용 서브에이전트 프롬프트: 자동 추가되는 범용 서브에이전트는 기본 프롬프트를 general_purpose_subagent.system_prompt(설정 시) → HarnessProfile.base_system_prompt(설정 시) → SDK 범용 기본값 순으로 해석하며, 프로파일 접미사를 그 위에 겹칩니다. 두 override 필드가 모두 설정되면 범용 전용 필드가 우선해, 호출자가 두 필드를 모두 튜닝해도 GP override가 조용히 버려지지 않습니다.

미들웨어

Deep Agents는 아래 나열된 내장 미들웨어, LangChain의 사전 빌드 미들웨어, 제공자별 미들웨어, 직접 작성한 커스텀 미들웨어를 포함한 모든 미들웨어를 지원합니다.

미들웨어를 createDeepAgentmiddleware 인자에 전달하세요. 커스텀 미들웨어는 Deep Agents 스택에서 PatchToolCallsMiddleware 뒤에 추가됩니다.

Deep Agents 스택

createDeepAgent는 미들웨어를 고정된 순서로 만듭니다. 베어 스택은 모델만 있을 때 얻는 것이고, 전체 스택은 선택적 인자를 전달하거나 해석된 하네스 프로파일이 기여할 때만 나타나는 슬롯까지 포함한 완전한 조립 순서입니다.

베어 스택

model만 있는 경우(다른 선택적 인자 없음) 메인 에이전트에는 일반적으로 다음이 포함됩니다:

  1. FilesystemMiddleware
  2. SubAgentMiddleware(하네스 프로파일이 비활성화하지 않는 한 범용 서브에이전트가 자동 추가되므로)
  3. SummarizationMiddleware
  4. PatchToolCallsMiddleware
  5. 프롬프트 캐싱 미들웨어(지원 제공자에서 추가됨, 그 외에는 no-op)
  6. 하네스 프로파일 확장제외 도구 필터링(해석된 모델 프로파일이 정의하는 경우)

전체 스택

처음부터 끝까지:

  1. SkillsMiddleware: skills를 전달할 때만. 파일 도구가 실행되기 전에 스킬 메타데이터가 있도록 파일시스템 미들웨어 앞에 주입됩니다.

  2. FilesystemMiddleware: 읽기·쓰기·디렉토리 탐색 같은 파일시스템 작업을 처리. permissions를 전달하면 에이전트가 호출할 수 있는 모든 도구를 평가하도록 여기에 파일시스템 권한 적용이 포함됩니다.

  3. SubAgentMiddleware: 동기 서브에이전트가 하나 이상 있을 때만. 작업 위임을 위해 서브에이전트를 생성·조정. 범용 서브에이전트가 기본으로 자동 추가되므로 베어 스택에 포함됩니다. 그 서브에이전트를 비활성화하고 동기 subagents를 전달하지 않으면 생략됩니다(서브에이전트 없이 실행 참조).

  4. SummarizationMiddleware: 대화가 길어질 때 컨텍스트 한도 내에 머무르도록 메시지 히스토리를 축약(createSummarizationMiddleware 경유).

  5. PatchToolCallsMiddleware: 실행이 인터럽트 후 재개되거나 잘못된 도구 호출 인자를 받았을 때 메시지 히스토리의 매달린 도구 호출을 복구. Anthropic 프롬프트 캐싱과 아래 꼬리 스택 앞에 실행.

  6. AsyncSubAgentMiddleware: 비동기 서브에이전트를 구성한 경우에만.

  7. 당신의 middleware 인자: middleware 인자로 전달하는 선택적 미들웨어가 여기 추가됨(Patch 뒤, 꼬리 스택 앞).

  8. 하네스 프로파일 확장: 해석된 모델 프로파일의 제공자별 미들웨어(있는 경우).

  9. 제외 도구 필터링: 하네스 프로파일이 제외 도구를 나열하면 미들웨어가 그 도구들을 에이전트에서 제거.

  10. 프롬프트 캐싱(AnthropicPromptCachingMiddlewareBedrockPromptCachingMiddleware): 각각 Anthropic 모델과 Amazon Bedrock Converse 모델에 자동 추가. 둘 다 Patch와 당신의 미들웨어 뒤에 실행되어 캐시된 접두사가 실제로 모델에 전송되는 것과 일치하도록 함.

  11. MemoryMiddleware: memory를 전달할 때만.

    참고: MemoryMiddleware는 프로파일 확장과 프롬프트 캐싱 미들웨어 뒤에 배치되어 주입된 메모리 업데이트가 캐시 접두사를 무효화할 가능성을 낮춥니다. 이 순서 우려는 createDeepAgent 구현 주석에도 언급되어 있습니다.

  12. HumanInTheLoopMiddleware: interruptOn을 전달할 때만. 구성된 도구 호출에서 인간 승인 또는 입력을 위해 일시 중지.

동기 서브에이전트 스택

내장 범용 서브에이전트와 각 선언적 동기 SubAgent 그래프는 createDeepAgent가 코드로 만드는 스택을 사용합니다. 주요 에이전트와 대체로 모양이 같지만(파일시스템, 요약, Patch, 프로파일 확장, Anthropic·Bedrock 캐싱, 선택적 권한) 두 가지가 다릅니다:

  • 스킬이 PatchToolCallsMiddleware 뒤에 실행됩니다(주요 에이전트에서는 skills가 설정되면 스킬이 파일시스템 미들웨어 앞에 실행).
  • 서브에이전트 그래프 안에는 SubAgentMiddleware없습니다(부모 에이전트만 task 도구를 노출).

선언적 서브에이전트가 interruptOn을 설정하면 그 값이 서브에이전트의 createAgent로 전달되어 구성된 도구 호출에 대한 human-in-the-loop 처리를 연결합니다.

사전 빌드 미들웨어

LangChain은 재시도, 폴백, PII 감지 같은 기능을 추가할 수 있는 추가 사전 빌드 미들웨어를 제공합니다. 자세한 내용은 사전 빌드 미들웨어를 참조하세요.

deepagents 패키지는 같은 워크플로를 위한 createSummarizationMiddleware도 노출합니다. 자세한 내용은 요약을 참조하세요.

제공자별 미들웨어

특정 LLM 제공자에 최적화된 제공자별 미들웨어는 미들웨어 통합을 참고하세요.

커스텀 미들웨어

기능을 확장하거나, 도구를 추가하거나, 커스텀 훅을 구현하는 추가 미들웨어를 제공할 수 있어요:

// 예: Google 제공자 (다른 탭은 model 문자열만 다름)
import { tool, createMiddleware } from "langchain";
import { createDeepAgent } from "deepagents";
import * as z from "zod";

const getWeather = tool(
  ({ city }: { city: string }) => {
    return `The weather in ${city} is sunny.`;
  },
  {
    name: "get_weather",
    description: "Get the weather in a city.",
    schema: z.object({
      city: z.string(),
    }),
  },
);

let callCount = 0;

const logToolCallsMiddleware = createMiddleware({
  name: "LogToolCallsMiddleware",
  wrapToolCall: async (request, handler) => {
    // Intercept and log every tool call - demonstrates cross-cutting concern
    callCount += 1;
    const toolName = request.toolCall.name;

    console.log(`[Middleware] Tool call #${callCount}: ${toolName}`);
    console.log(
      `[Middleware] Arguments: ${JSON.stringify(request.toolCall.args)}`,
    );

    // Execute the tool call
    const result = await handler(request);

    // Log the result
    console.log(`[Middleware] Tool call #${callCount} completed`);

    return result;
  },
});

const agent = await createDeepAgent({
  model: "google-genai:gemini-3.6-flash",
  tools: [getWeather] as any,
  middleware: [logToolCallsMiddleware] as any,
});

다른 제공자 탭의 model 값: OpenAI openai:gpt-5.5, Anthropic anthropic:claude-sonnet-5, OpenRouter openrouter:z-ai/glm-5.2, Fireworks fireworks:accounts/fireworks/models/glm-5p2, Baseten baseten:zai-org/GLM-5.2, Ollama ollama:north-mini-code-1.0.

경고: 초기화 후 속성을 변경하지 마세요

훅 호출 간에 값을 추적해야 하면(예: 카운터나 누적 데이터) 그래프 상태를 사용하세요. 그래프 상태는 설계상 스레드 범위로 지정되어 동시성 하에서 안전하게 업데이트됩니다.

이렇게 하세요:

const customMiddleware = createMiddleware({
  name: "CustomMiddleware",
  beforeAgent: async (state) => {
    return { x: (state.x ?? 0) + 1 }; // Update graph state instead
  },
});

이렇게 하지 마세요:

let x = 1;

const customMiddlewareBad = createMiddleware({
  name: "CustomMiddleware",
  beforeAgent: async () => {
    x += 1; // Mutation causes race conditions
  },
});

beforeAgent에서 state.x를 수정하거나, beforeAgent에서 공유 변수를 변경하거나, 훅에서 다른 공유 값을 바꾸는 등 제자리 변경은 많은 작업이 동시에 실행되므로(서브에이전트, 병렬 도구, 다른 스레드의 병렬 호출) 미묘한 버그와 경쟁 조건을 일으킬 수 있습니다. 커스텀 미들웨어에서 변경을 꼭 써야 한다면 서브에이전트·병렬 도구·동시 에이전트 호출이 동시에 실행될 때 어떤 일이 생기는지 고려하세요.

기본 미들웨어 인스턴스 재정의

인터프리터

인터프리터를 사용해 범위가 지정된 QuickJS 런타임에서 JavaScript를 실행하는 eval 도구를 추가하세요. 인터프리터는 에이전트가 도구를 프로그래매틱하게 구성하거나, 작업을 배치하거나, 코드에서 오류를 처리하거나, 전체 셸 환경 없이 구조화된 데이터를 변환해야 할 때 유용합니다.

// 예: Google 제공자 (다른 탭은 model 문자열만 다름)
import { createDeepAgent } from "deepagents";
import { createCodeInterpreterMiddleware } from "@langchain/quickjs";

const agent = createDeepAgent({
  model: "google-genai:gemini-3.6-flash",
  middleware: [createCodeInterpreterMiddleware()],
});

설정, 프로그래매틱 도구 호출, 서브에이전트 오케스트레이션, 한도는 인터프리터를 참고하세요.

서브에이전트

상세 작업을 격리하고 컨텍스트 비대화를 피하려면 서브에이전트를 사용하세요:

// 예: Google 제공자 (다른 탭은 model 문자열만 다름)
import { tool } from "langchain";
import { TavilySearch } from "@langchain/tavily";
import { createDeepAgent, type SubAgent } from "deepagents";
import { z } from "zod";

const internetSearch = tool(
  async ({
    query,
    maxResults = 5,
    topic = "general",
    includeRawContent = false,
  }: {
    query: string;
    maxResults?: number;
    topic?: "general" | "news" | "finance";
    includeRawContent?: boolean;
  }) => {
    const tavilySearch = new TavilySearch({
      maxResults,
      tavilyApiKey: proces...KEY,
      includeRawContent,
      topic,
    });
    return await tavilySearch._call({ query });
  },
  {
    name: "internet_search",
    description: "Run a web search",
    schema: z.object({
      query: z.string().describe("The search query"),
      maxResults: z.number().optional().default(5),
      topic: z
        .enum(["general", "news", "finance"])
        .optional()
        .default("general"),
      includeRawContent: z.boolean().optional().default(false),
    }),
  },
);

const researchSubagent: SubAgent = {
  name: "research-agent",
  description: "Used to research more in depth questions",
  systemPrompt: "You are a great researcher",
  tools: [internetSearch],
  model: "google-genai:gemini-3.6-flash", // Optional override, defaults to main agent model
};
const subagents = [researchSubagent];

const agent = createDeepAgent({
  model: "google_genai:gemini-3.6-flash",
  subagents,
});

서브에이전트에 대한 자세한 내용은 서브에이전트를 참고하세요.

백엔드

딥 에이전트의 도구는 가상 파일 시스템을 사용해 파일을 저장·접근·편집할 수 있습니다. 기본적으로 딥 에이전트는 StateBackend을 사용합니다.

스킬이나 메모리를 사용한다면 에이전트를 만들기 전에 기대하는 스킬·메모리 파일을 백엔드에 추가해야 합니다.

  • StateBackendlanggraph 상태에 저장되는 스레드 범위 파일시스템 백엔드. 파일은 스레드 내에서 턴 간에 유지(체크포인터 경유)되며 스레드 간에 공유되지 않습니다.
    import { createDeepAgent, StateBackend } from "deepagents";
    // 기본 제공
    const agent = createDeepAgent();
    // 내부적으로는
    const agent2 = createDeepAgent({ backend: new StateBackend() });
    
  • FilesystemBackend — 로컬 머신의 파일시스템.

    경고: 이 백엔드는 에이전트에게 직접적인 파일시스템 읽기/쓰기 접근을 부여합니다. 주의해서 적절한 환경에서만 사용하세요. 자세한 내용은 FilesystemBackend 참조.

    // 예: Google 제공자
    import { createDeepAgent, FilesystemBackend } from "deepagents";
    const agent = createDeepAgent({
      model: "google-genai:gemini-3.6-flash",
      backend: new FilesystemBackend({ rootDir: ".", virtualMode: true }),
    });
    

    : 내부 에이전트 데이터(오프로드된 도구 결과, 대화 기록)가 프로젝트 파일과 함께 디스크에 쓰이지 않도록 FilesystemBackendCompositeBackend로 감싸세요. 권장 패턴 참조.

  • LocalShellBackend — 호스트에서 직접 셸 실행이 가능한 파일시스템. 파일시스템 도구에 더해 명령 실행용 execute 도구를 제공합니다.

    경고: 이 백엔드는 에이전트에게 직접적인 파일시스템 읽기/쓰기 접근 호스트에서 제한 없는 셸 실행을 부여합니다. 극도로 주의해서 적절한 환경에서만 사용하세요. 자세한 내용은 LocalShellBackend 참조.

    // 예: Google 제공자
    import { createDeepAgent, LocalShellBackend } from "deepagents";
    const backend = new LocalShellBackend({ workingDirectory: "." });
    const agent = createDeepAgent({ model: "google-genai:gemini-3.6-flash", backend });
    
  • StoreBackend스레드 간에 유지되는 장기 저장을 제공하는 파일시스템. namespace 매개변수가 데이터 격리를 제어합니다. 멀티 사용자 배포에서는 사용자·테넌트별로 데이터를 격리하도록 항상 namespace 팩토리를 설정하세요.
    // 예: Google 제공자
    import { createDeepAgent, StoreBackend } from "deepagents";
    import { InMemoryStore } from "@langchain/langgraph";
    const store = new InMemoryStore(); // Good for local dev; omit for LangSmith Deployment
    const agent = createDeepAgent({
      model: "google-genai:gemini-3.6-flash",
      backend: new StoreBackend({ namespace: (rt) => [rt.serverInfo.user.identity] }),
      store,
    });
    

    참고: LangSmith Deployment에 배포할 때는 store 매개변수를 생략하세요. 플랫폼이 에이전트용 스토어를 자동 프로비저닝합니다.

  • ContextHubBackend — LangSmith Hub 저장소의 영속 파일시스템 저장. 자세한 내용은 ContextHubBackend 참조.
  • CompositeBackend — 파일시스템의 다른 라우트가 다른 백엔드를 가리키도록 지정할 수 있는 유연한 백엔드.
    // 예: Google 제공자
    import { createDeepAgent, CompositeBackend, StateBackend, StoreBackend } from "deepagents";
    import { InMemoryStore } from "@langchain/langgraph";
    const store = new InMemoryStore();
    const agent = createDeepAgent({
      model: "google-genai:gemini-3.6-flash",
      backend: new CompositeBackend(new StateBackend(), {
        "/memories/": new StoreBackend({ namespace: () => ["memories"] }),
      }),
      store,
    });
    

자세한 내용은 백엔드를 참고하세요.

샌드박스

샌드박스는 에이전트 코드를 자체 파일시스템과 셸 명령용 execute 도구를 갖춘 격리된 환경에서 실행하는 특수한 백엔드입니다. 로컬 머신을 전혀 변경하지 않고 에이전트가 파일을 쓰고, 의존성을 설치하고, 명령을 실행하게 하려면 샌드박스 백엔드를 사용하세요.

샌드박스는 딥 에이전트 생성 시 backend에 샌드박스 백엔드를 전달해 구성합니다:

import { createDeepAgent, LangSmithSandbox } from "deepagents";
import { ChatAnthropic } from "@langchain/anthropic";
import { SandboxClient } from "langsmith/sandbox";

const client = new SandboxClient();
const lsSandbox = await client.createSandbox();

try {
  const agent = createDeepAgent({
    model: new ChatAnthropic({ model: "claude-opus-4-8" }),
    systemPrompt: "You are a coding assistant with sandbox access.",
    backend: new LangSmithSandbox({ sandbox: lsSandbox }),
  });

  const result = await agent.invoke({
    messages: [
      {
        role: "user",
        content: "Create a hello world Python script and run it",
      },
    ],
  });
} finally {
  await client.deleteSandbox(lsSandbox.name);
}

자세한 내용은 샌드박스를 참고하세요.

Human-in-the-loop

일부 도구 작업은 민감해서 실행 전에 인간 승인이 필요할 수 있습니다. 도구별로 승인을 구성할 수 있어요:

import { tool } from "langchain";
import { createDeepAgent } from "deepagents";
import { MemorySaver } from "@langchain/langgraph";
import { z } from "zod";

const removeFile = tool(
  async ({ path }: { path: string }) => {
    return `Deleted ${path}`;
  },
  {
    name: "remove_file",
    description: "Delete a file from the filesystem.",
    schema: z.object({ path: z.string() }),
  },
);

const fetchFile = tool(
  async ({ path }: { path: string }) => {
    return `Contents of ${path}`;
  },
  {
    name: "fetch_file",
    description: "Read a file from the filesystem.",
    schema: z.object({ path: z.string() }),
  },
);

const notifyEmail = tool(
  async ({ to, subject, body }: { to: string; subject: string; body: string }) => {
    return `Sent email to ${to}`;
  },
  {
    name: "notify_email",
    description: "Send an email.",
    schema: z.object({ to: z.string(), subject: z.string(), body: z.string() }),
  },
);

// Checkpointer is REQUIRED for human-in-the-loop
const checkpointer = new MemorySaver();

const agent = createDeepAgent({
  model: "google_genai:gemini-3.6-flash",
  tools: [removeFile, fetchFile, notifyEmail],
  interruptOn: {
    remove_file: true, // Default: approve, edit, reject, respond
    fetch_file: false, // No interrupts needed
    notify_email: { allowedDecisions: ["approve", "reject"] }, // No editing
  },
  checkpointer, // Required!
});

에이전트와 서브에이전트 모두 도구 호출 시 그리고 도구 호출 내부에서 인터럽트를 구성할 수 있어요. 자세한 내용은 Human-in-the-loop을 참고하세요.

스킬

스킬을 사용해 딥 에이전트에 새로운 역량과 전문 지식을 제공할 수 있어요. 도구가 네이티브 파일시스템 작업 같은 저수준 기능을 다루는 경향이 있는 반면, 스킬은 작업을 완료하는 방법에 대한 상세 지침, 참조 정보, 템플릿 같은 기타 자산을 담을 수 있습니다.

이 파일들은 에이전트가 현재 프롬프트에 스킬이 유용하다고 판단할 때만 로드됩니다. 이러한 점진적 공개는 시작 시 에이전트가 고려해야 하는 토큰과 컨텍스트 양을 줄여줍니다.

예시 스킬은 Deep Agents 예시 스킬을 참고하세요.

딥 에이전트에 스킬을 추가하려면 create_deep_agent의 인자로 전달하세요. 스킬 사용은 StateBackend(invoke시 files로 시드), StoreBackend(스토어에 업로드), FilesystemBackend(디스크/업로드) 중 어떤 백엔드를 쓰느냐에 따라 달라집니다 — 스킬 페이지에서 각각의 전체 예시를 보세요:

// 예: FilesystemBackend (다른 백엔드 예시는 skills 페이지 참조)
import { createDeepAgent, FilesystemBackend } from "deepagents";
import { MemorySaver } from "@langchain/langgraph";

const checkpointer = new MemorySaver();

const skillUrl =
  "https://raw.githubusercontent.com/langchain-ai/deepagentsjs/refs/heads/main/examples/skills/langgraph-docs/SKILL.md";
const response = await fetch(skillUrl);
const skillContent = await response.text();

let backend = new FilesystemBackend({
  rootDir: process.cwd(),
  virtualMode: true,
});
await backend.uploadFiles([
  ["/skills/langgraph-docs/SKILL.md", new TextEncoder().encode(skillContent)],
]);

const agent = await createDeepAgent({
  model: "anthropic:claude-sonnet-4-6",
  backend,
  // IMPORTANT: deepagents skill source paths are virtual (POSIX) paths relative to the backend root.
  skills: ["/skills/"],
  interruptOn: { read_file: true, write_file: true, delete_file: true },
  checkpointer, // Required for filesystem operations!
});

const config = { configurable: { thread_id: `thread-${Date.now()}` } };
const result = await agent.invoke(
  { messages: [{ role: "user", content: "what is langraph?" }] },
  config,
);

메모리

AGENTS.md 파일을 사용해 딥 에이전트에 추가 컨텍스트를 제공하세요.

: 코딩 에이전트가 AGENTS.md를 통해 발견하는 저장소 위키를 생성하려면 OpenWiki를 참고하세요.

딥 에이전트 생성 시 memory 매개변수에 하나 이상의 파일 경로를 전달할 수 있어요. StateBackend에서는 invokefilesAGENTS.md를 시드하고, StoreBackend에서는 스토어에 /AGENTS.md로 저장하며, FilesystemBackend에서는 경로(예: ["./AGENTS.md", "./.deepagents/AGENTS.md"])를 직접 전달합니다. 다음은 StoreBackend 예시입니다:

// 예: Google 제공자 (파일을 스토어에 저장하는 방식; 다른 백엔드 탭은 memory 페이지 참조)
import { createDeepAgent, StoreBackend, type FileData } from "deepagents";
import { InMemoryStore, MemorySaver } from "@langchain/langgraph";

const AGENTS_MD_URL =
  "https://raw.githubusercontent.com/langchain-ai/deepagents/refs/heads/main/examples/text-to-sql-agent/AGENTS.md";

async function fetchText(url: string): Promise<string> {
  const res = await fetch(url);
  if (!res.ok) {
    throw new Error(`Failed to fetch ${url}: ${res.status} ${res.statusText}`);
  }
  return await res.text();
}

const agentsMd = await fetchText(AGENTS_MD_URL);

function createFileData(content: string): FileData {
  const now = new Date().toISOString();
  return { content, mimeType: "text/plain", created_at: now, modified_at: now };
}

const store = new InMemoryStore();
const fileData = createFileData(agentsMd);
await store.put(["filesystem"], "/AGENTS.md", fileData);

const checkpointer = new MemorySaver();

const agent = await createDeepAgent({
  model: "google-genai:gemini-3.6-flash",
  backend: new StoreBackend({ namespace: () => ["filesystem"] }),
  store: store,
  checkpointer: checkpointer,
  memory: ["/AGENTS.md"],
});

const result = await agent.invoke(
  {
    messages: [
      { role: "user", content: "Please tell me what's in your memory files." },
    ],
  },
  { configurable: { thread_id: "12345" } },
);

메모리에 대한 자세한 내용은 메모리를 참고하세요.

구조화 출력

Deep Agents는 구조화 출력을 지원합니다.

createDeepAgent() 호출에 responseFormat 인자로 원하는 구조화 출력 스키마를 전달할 수 있어요. 모델이 구조화 데이터를 생성하면 캡처·검증되어 에이전트 상태의 structuredResponse 키에 반환됩니다.

import { tool } from "langchain";
import { TavilySearch } from "@langchain/tavily";
import { createDeepAgent } from "deepagents";
import { z } from "zod";

const internetSearch = tool(
  async ({
    query,
    maxResults = 5,
    topic = "general",
    includeRawContent = false,
  }: {
    query: string;
    maxResults?: number;
    topic?: "general" | "news" | "finance";
    includeRawContent?: boolean;
  }) => {
    const tavilySearch = new TavilySearch({
      maxResults,
      tavilyApiKey: proces...KEY,
      includeRawContent,
      topic,
    });
    return await tavilySearch._call({ query });
  },
  {
    name: "internet_search",
    description: "Run a web search",
    schema: z.object({
      query: z.string().describe("The search query"),
      maxResults: z.number().optional().default(5),
      topic: z
        .enum(["general", "news", "finance"])
        .optional()
        .default("general"),
      includeRawContent: z.boolean().optional().default(false),
    }),
  },
);

const weatherReportSchema = z.object({
  location: z.string().describe("The location for this weather report"),
  temperature: z.number().describe("Current temperature in Celsius"),
  condition: z.string().describe("Current weather condition (e.g., sunny, cloudy, rainy)"),
  humidity: z.number().describe("Humidity percentage"),
  windSpeed: z.number().describe("Wind speed in km/h"),
  forecast: z.string().describe("Brief forecast for the next 24 hours"),
});

const agent = await createDeepAgent({
  responseFormat: weatherReportSchema,
  tools: [internetSearch],
});

const result = await agent.invoke({
  messages: [
    { role: "user", content: "What's the weather like in San Francisco?" },
  ],
});

console.log(result.structuredResponse);

이 예시의 공개 LangSmith 실행 보기

자세한 내용과 예시는 response format을 참고하세요.

고급

createDeepAgentcreateAgent 위에 미들웨어 스택을 미리 조립합니다. 포함할 역량을 정확히 선택해 완전히 커스텀 에이전트를 만들려면 하네스 구성을 참조하세요.

더 알아보기 (Learn more)