Skip to main content
에이전트는 언어 모델과 도구를 결합하여 작업에 대해 추론하고, 사용할 도구를 결정하며, 반복적으로 솔루션을 향해 작업하는 시스템을 만듭니다. createAgent()는 프로덕션에 바로 사용할 수 있는 에이전트 구현을 제공합니다. LLM 에이전트는 목표를 달성하기 위해 루프 내에서 도구를 실행합니다. 에이전트는 중지 조건이 충족될 때까지 실행됩니다. 즉, 모델이 최종 출력을 내보내거나 반복 제한에 도달할 때까지 실행됩니다.
createAgent()LangGraph를 사용하여 그래프 기반 에이전트 런타임을 구축합니다. 그래프는 에이전트가 정보를 처리하는 방법을 정의하는 노드(단계)와 엣지(연결)로 구성됩니다. 에이전트는 이 그래프를 통해 이동하며, 모델 노드(모델을 호출), 도구 노드(도구를 실행) 또는 미들웨어와 같은 노드를 실행합니다.Graph API에 대해 자세히 알아보세요.

핵심 구성 요소

모델

모델은 에이전트의 추론 엔진입니다. 정적 및 동적 모델 선택을 모두 지원하며 여러 방법으로 지정할 수 있습니다.

정적 모델

정적 모델은 에이전트를 생성할 때 한 번 구성되며 실행 전체에서 변경되지 않습니다. 이것이 가장 일반적이고 간단한 접근 방식입니다. 에서 정적 모델을 초기화하려면:
import { createAgent } from "langchain";

const agent = createAgent({
  model: "openai:gpt-5",
  tools: []
});
모델 식별자 문자열은 provider:model 형식을 사용합니다(예: "openai:gpt-5"). 모델 구성을 더 세밀하게 제어하려는 경우 공급자 패키지를 사용하여 모델 인스턴스를 직접 초기화할 수 있습니다:
import { createAgent } from "langchain";
import { ChatOpenAI } from "@langchain/openai";

const model = new ChatOpenAI({
  model: "gpt-4o",
  temperature: 0.1,
  maxTokens: 1000,
  timeout: 30
});

const agent = createAgent({
  model,
  tools: []
});
모델 인스턴스를 사용하면 구성을 완전히 제어할 수 있습니다. temperature, max_tokens, timeouts와 같은 특정 매개변수를 설정하거나 API 키, base_url 및 기타 공급자별 설정을 구성해야 할 때 사용하세요. 모델에서 사용 가능한 매개변수와 메서드를 보려면 API 참조를 참조하세요.

동적 모델

동적 모델은 현재 와 컨텍스트를 기반으로 에 선택됩니다. 이를 통해 정교한 라우팅 로직과 비용 최적화가 가능합니다. 동적 모델을 사용하려면 요청에서 모델을 수정하는 wrapModelCall을 사용하여 미들웨어를 생성하세요:
import { ChatOpenAI } from "@langchain/openai";
import { createAgent, createMiddleware } from "langchain";

const basicModel = new ChatOpenAI({ model: "gpt-4o-mini" });
const advancedModel = new ChatOpenAI({ model: "gpt-4o" });

const dynamicModelSelection = createMiddleware({
  name: "DynamicModelSelection",
  wrapModelCall: (request, handler) => {
    // 대화 복잡도에 따라 모델 선택
    const messageCount = request.messages.length;

    return handler({
        ...request,
        model: messageCount > 10 ? advancedModel : basicModel,
    });
  },
});

const agent = createAgent({
  model: "gpt-4o-mini", // 기본 모델 (messageCount ≤ 10일 때 사용)
  tools,
  middleware: [dynamicModelSelection] as const,
});
미들웨어 및 고급 패턴에 대한 자세한 내용은 미들웨어 문서를 참조하세요.
모델 구성 세부 정보는 모델을 참조하세요. 동적 모델 선택 패턴은 미들웨어의 동적 모델을 참조하세요.

도구

도구는 에이전트에게 작업을 수행할 수 있는 능력을 제공합니다. 에이전트는 다음을 용이하게 함으로써 단순한 모델 전용 도구 바인딩을 넘어섭니다:
  • 순차적인 여러 도구 호출(단일 프롬프트에 의해 트리거됨)
  • 적절한 경우 병렬 도구 호출
  • 이전 결과를 기반으로 한 동적 도구 선택
  • 도구 재시도 로직 및 오류 처리
  • 도구 호출 간 상태 지속성
자세한 내용은 도구를 참조하세요.

도구 정의

에이전트에 도구 목록을 전달하세요.
import * as z from "zod";
import { createAgent, tool } from "langchain";

const search = tool(
  ({ query }) => `Results for: ${query}`,
  {
    name: "search",
    description: "Search for information",
    schema: z.object({
      query: z.string().describe("The query to search for"),
    }),
  }
);

const getWeather = tool(
  ({ location }) => `Weather in ${location}: Sunny, 72°F`,
  {
    name: "get_weather",
    description: "Get weather information for a location",
    schema: z.object({
      location: z.string().describe("The location to get weather for"),
    }),
  }
);

const agent = createAgent({
  model: "openai:gpt-4o",
  tools: [search, getWeather],
});
빈 도구 목록이 제공되면 에이전트는 도구 호출 기능 없이 단일 LLM 노드로 구성됩니다.

도구 오류 처리

도구 오류 처리 방식을 사용자 정의하려면 사용자 정의 미들웨어에서 wrapToolCall 후크를 사용하세요:
import { createAgent, createMiddleware, ToolMessage } from "langchain";

const handleToolErrors = createMiddleware({
  name: "HandleToolErrors",
  wrapToolCall: (request, handler) => {
    try {
      return handler(request);
    } catch (error) {
      // 모델에 사용자 정의 오류 메시지를 반환합니다
      return new ToolMessage({
        content: `Tool error: Please check your input and try again. (${error})`,
        tool_call_id: request.toolCall.id!,
      });
    }
  },
});

const agent = createAgent({
  model: "openai:gpt-4o",
  tools: [
    /* ... */
  ],
  middleware: [handleToolErrors] as const,
});
도구가 실패하면 에이전트는 사용자 정의 오류 메시지와 함께 @[ToolMessage]를 반환합니다.

ReAct 루프에서의 도구 사용

에이전트는 ReAct(“추론 + 행동”) 패턴을 따르며, 간단한 추론 단계와 목표 지향적인 도구 호출을 번갈아 수행하고, 결과 관찰을 후속 결정에 반영하여 최종 답변을 제공할 수 있을 때까지 반복합니다.
프롬프트: 현재 가장 인기 있는 무선 헤드폰을 식별하고 재고를 확인하세요.
================================ Human Message =================================

Find the most popular wireless headphones right now and check if they're in stock
  • 추론: “인기는 시간에 민감하므로 제공된 검색 도구를 사용해야 합니다.”
  • 행동: search_products("wireless headphones") 호출
================================== Ai Message ==================================
Tool Calls:
  search_products (call_abc123)
 Call ID: call_abc123
  Args:
    query: wireless headphones
================================= Tool Message =================================

Found 5 products matching "wireless headphones". Top 5 results: WH-1000XM5, ...
  • 추론: “답변하기 전에 상위 항목의 재고를 확인해야 합니다.”
  • 행동: check_inventory("WH-1000XM5") 호출
================================== Ai Message ==================================
Tool Calls:
  check_inventory (call_def456)
 Call ID: call_def456
  Args:
    product_id: WH-1000XM5
================================= Tool Message =================================

Product WH-1000XM5: 10 units in stock
  • 추론: “가장 인기 있는 모델과 재고 상태를 확인했습니다. 이제 사용자의 질문에 답변할 수 있습니다.”
  • 행동: 최종 답변 생성
================================== Ai Message ==================================

I found wireless headphones (model WH-1000XM5) with 10 units in stock...
도구에 대해 자세히 알아보려면 도구를 참조하세요.

시스템 프롬프트

프롬프트를 제공하여 에이전트가 작업에 접근하는 방식을 형성할 수 있습니다. @[system_prompt] 매개변수는 문자열로 제공할 수 있습니다:
const agent = createAgent({
  model,
  tools,
  systemPrompt: "You are a helpful assistant. Be concise and accurate.",
});
@[system_prompt]가 제공되지 않으면 에이전트는 메시지에서 직접 작업을 추론합니다.

동적 시스템 프롬프트

런타임 컨텍스트나 에이전트 상태에 따라 시스템 프롬프트를 수정해야 하는 고급 사용 사례의 경우 미들웨어를 사용할 수 있습니다.
import * as z from "zod";
import { createAgent, dynamicSystemPromptMiddleware } from "langchain";

const contextSchema = z.object({
  userRole: z.enum(["expert", "beginner"]),
});

const agent = createAgent({
  model: "openai:gpt-4o",
  tools: [/* ... */],
  contextSchema,
  middleware: [
    dynamicSystemPromptMiddleware<z.infer<typeof contextSchema>>((state, runtime) => {
      const userRole = runtime.context.userRole || "user";
      const basePrompt = "You are a helpful assistant.";

      if (userRole === "expert") {
        return `${basePrompt} Provide detailed technical responses.`;
      } else if (userRole === "beginner") {
        return `${basePrompt} Explain concepts simply and avoid jargon.`;
      }
      return basePrompt;
    }),
  ],
});

// 시스템 프롬프트는 컨텍스트에 따라 동적으로 설정됩니다
const result = await agent.invoke(
  { messages: [{ role: "user", content: "Explain machine learning" }] },
  { context: { userRole: "expert" } }
);
메시지 유형 및 형식에 대한 자세한 내용은 메시지를 참조하세요. 포괄적인 미들웨어 문서는 미들웨어를 참조하세요.

호출

에이전트의 State에 업데이트를 전달하여 에이전트를 호출할 수 있습니다. 모든 에이전트는 상태에 메시지 시퀀스를 포함합니다. 에이전트를 호출하려면 새 메시지를 전달하세요:
await agent.invoke({
  messages: [{ role: "user", content: "What's the weather in San Francisco?" }],
})
에이전트에서 단계 및/또는 토큰을 스트리밍하려면 스트리밍 가이드를 참조하세요. 그 외의 경우 에이전트는 LangGraph Graph API를 따르며 모든 관련 메서드를 지원합니다.

고급 개념

구조화된 출력

경우에 따라 에이전트가 특정 형식으로 출력을 반환하도록 할 수 있습니다. LangChain은 responseFormat 매개변수를 사용하여 이를 수행하는 간단하고 범용적인 방법을 제공합니다.
import * as z from "zod";
import { createAgent } from "langchain";

const ContactInfo = z.object({
  name: z.string(),
  email: z.string(),
  phone: z.string(),
});

const agent = createAgent({
  model: "openai:gpt-4o",
  responseFormat: ContactInfo,
});

const result = await agent.invoke({
  messages: [
    {
      role: "user",
      content: "Extract contact info from: John Doe, [email protected], (555) 123-4567",
    },
  ],
});

console.log(result.structuredResponse);
// {
//   name: 'John Doe',
//   email: '[email protected]',
//   phone: '(555) 123-4567'
// }
구조화된 출력에 대해 자세히 알아보려면 구조화된 출력을 참조하세요.

메모리

에이전트는 메시지 상태를 통해 대화 기록을 자동으로 유지합니다. 대화 중에 추가 정보를 기억하도록 사용자 정의 상태 스키마를 사용하도록 에이전트를 구성할 수도 있습니다. 상태에 저장된 정보는 에이전트의 단기 메모리로 생각할 수 있습니다:
import * as z from "zod";
import { MessagesZodState } from "@langchain/langgraph";
import { createAgent, type BaseMessage } from "langchain";

const customAgentState = z.object({
  messages: MessagesZodState.shape.messages,
  userPreferences: z.record(z.string(), z.string()),
});

const CustomAgentState = createAgent({
  model: "openai:gpt-4o",
  tools: [],
  stateSchema: customAgentState,
});
메모리에 대해 자세히 알아보려면 메모리를 참조하세요. 세션 간에 지속되는 장기 메모리 구현에 대한 정보는 장기 메모리를 참조하세요.

스트리밍

invoke로 에이전트를 호출하여 최종 응답을 받는 방법을 살펴보았습니다. 에이전트가 여러 단계를 실행하는 경우 시간이 걸릴 수 있습니다. 중간 진행 상황을 표시하려면 메시지가 발생할 때 스트리밍할 수 있습니다.
const stream = await agent.stream(
  {
    messages: [{
      role: "user",
      content: "Search for AI news and summarize the findings"
    }],
  },
  { streamMode: "values" }
);

for await (const chunk of stream) {
  // 각 청크는 해당 시점의 전체 상태를 포함합니다
  const latestMessage = chunk.messages.at(-1);
  if (latestMessage?.content) {
    console.log(`Agent: ${latestMessage.content}`);
  } else if (latestMessage?.tool_calls) {
    const toolCallNames = latestMessage.tool_calls.map((tc) => tc.name);
    console.log(`Calling tools: ${toolCallNames.join(", ")}`);
  }
}
스트리밍에 대한 자세한 내용은 스트리밍을 참조하세요.

미들웨어

미들웨어는 실행의 여러 단계에서 에이전트 동작을 사용자 정의하기 위한 강력한 확장성을 제공합니다. 미들웨어를 사용하여 다음을 수행할 수 있습니다:
  • 모델이 호출되기 전에 상태 처리(예: 메시지 자르기, 컨텍스트 주입)
  • 모델의 응답 수정 또는 검증(예: 가드레일, 콘텐츠 필터링)
  • 사용자 정의 로직으로 도구 실행 오류 처리
  • 상태 또는 컨텍스트에 따른 동적 모델 선택 구현
  • 사용자 정의 로깅, 모니터링 또는 분석 추가
미들웨어는 에이전트의 실행 그래프에 원활하게 통합되어 핵심 에이전트 로직을 변경하지 않고도 주요 지점에서 데이터 흐름을 가로채고 수정할 수 있습니다.
beforeModel, afterModelwrapToolCall과 같은 후크를 포함한 포괄적인 미들웨어 문서는 미들웨어를 참조하세요.

Connect these docs programmatically to Claude, VSCode, and more via MCP for real-time answers.
I