에이전트
에이전트 (Agents)
에이전트는 주어진 작업이 완료될 때까지 모델이 툴을 호출하는 루프예요.
A harness is everything around that loop: the prompt, the tools, and any middleware that shapes the model's behavior. harness는 루프 주변의 모든 것이에요: 프롬프트, 툴, 그리고 모델의 행동을 형성하는 모든 미들웨어.
create_agent는 매우 구성 가능한 harness예요. 가장 단순하게는 이렇게 만들 수 있어요:
여기에 더해 model=, tools=, system_prompt= 파라미터로 기본 사항을 직접 구성할 수 있어요. 더 고급 기능을 위해 미들웨어로 harness를 확장하세요.
핵심 컴포넌트 (Core components)
모델 (Model)
모델 식별자 문자열("provider:model") 또는 초기화된 모델 인스턴스를 전달해 에이전트의 모델을 선택하세요. 파라미터, 제공자 설정, 동적 모델 선택은 모델을 참고하세요.
툴 (Tools)
에이전트에 툴을 제공하려면 어떤 Python 호출 가능 객체, LangChain 툴, 또는 툴 dict를 전달하세요. 툴 정의, 컨텍스트 접근, 동적 툴 선택은 툴을 참고하세요.
import { tool } from "langchain";
import * as z from "zod";
var search = tool(({ query }) => `Results for: ${query}`, {
name: "search",
description: "Search for information",
schema: z.object({ query: z.string() }),
});
var agent = createAgent({ model: "google-genai:gemini-3.6-flash", tools: [search] });
var agent = createAgent({ model: "openai:gpt-5.5", tools: [search] });
var agent = createAgent({ model: "anthropic:claude-sonnet-5", tools: [search] });
var agent = createAgent({ model: "openrouter:z-ai/glm-5.2", tools: [search] });
var agent = createAgent({ model: "fireworks:accounts/fireworks/models/glm-5p2", tools: [search] });
var agent = createAgent({ model: "baseten:zai-org/GLM-5.2", tools: [search] });
var agent = createAgent({ model: "ollama:north-mini-code-1.0", tools: [search] });
시스템 프롬프트 (System prompt)
에이전트가 작업에 접근하는 방식을 형성해요. 시스템 프롬프트 파라미터는 문자열이나 SystemMessage를 받아요. 런타임의 동적 프롬프트를 위해 미들웨어를 사용하세요.
var agent = createAgent({
model: "google-genai:gemini-3.6-flash",
tools,
systemPrompt: "You are a helpful assistant. Be concise and accurate.",
});
구조화된 출력 (Structured output)
response_format=로 에이전트에서 검증된 스키마를 반환하세요. 전략과 예제는 구조화된 출력을 참고하세요.
const Answer = z.object({ summary: z.string(), confidence: z.number() });
const result = await agent.invoke({
messages: [{ role: "user", content: "Summarize AI trends" }],
responseFormat: Answer,
});
result.structuredResponse; // { summary: ..., confidence: ... }
에이전트 상태 (Agent state)
모든 에이전트는 현재 대화 기록과 툴·미들웨어가 필요로 하는 커스텀 필드를 담는 AgentState 객체로 실행 컨텍스트를 관리해요.
기본 필드:
| 필드 | 타입 | 설명 |
|---|---|---|
messages |
BaseMessage[] |
현재 스레드의 전체 대화 기록. 추가 전용(append-only)이에요: 새 메시지가 추가되며 교체되지 않아요. |
AgentState는 모든 node-style 미들웨어 훅(beforeModel, afterModel 등)에 전달되는 타입이기도 해요. 훅은 현재 상태를 받고 병합할 업데이트 객체를 반환할 수 있어요.
커스텀 필드를 추가하려면 미들웨어에서 stateSchema(StateSchema 또는 Zod 객체)로 상태 스키마를 정의하세요:
import { createAgent, createMiddleware } from "langchain";
import { StateSchema } from "@langchain/langgraph";
const MyState = new StateSchema({
userId: z.string(),
callCount: z.number().default(0),
});
const stateMiddleware = createMiddleware({
name: "StateExtension",
stateSchema: MyState, // [!code highlight]
});
const agent = createAgent({
tools: [],
middleware: [stateMiddleware],
});
전체 세부 사항, 예제, 미들웨어 수준 상태 스키마는 단기 메모리와 커스텀 미들웨어를 참고하세요.
호출 (Invocation)
LangSmith로 이 루프의 각 단계를 추적하고 툴 호출을 디버깅하며 에이전트 출력을 평가하세요. 설정하려면 tracing quickstart를 따르세요. 또한 LangSmith Engine을 설정해 트레이스를 모니터링하고 문제를 감지하며 수정을 제안받는 것을 권장해요.
메시지로 에이전트를 호출할 수 있어요. 내부적으로는 에이전트의 State에 업데이트를 전달해요. 모든 에이전트는 상태에 메시지 시퀀스를 포함하므로, 에이전트를 호출하려면 새 메시지와 함께 thread_id를 전달해 에이전트가 대화 기록을 유지·재개할 수 있게 해요:
import { AIMessage } from "@langchain/core/messages";
import { MemorySaver } from "@langchain/langgraph";
const agent = createAgent({
model: "openai:gpt-5.5",
tools: [...tools],
checkpointer: new MemorySaver(),
});
const config = { configurable: { thread_id: crypto.randomUUID() } };
let result = await agent.invoke(
{
messages: [
{ role: "user", content: "What's the weather in San Francisco?" },
],
},
config,
);
// A follow-up turn on the same conversation: reuse the same thread_id to keep history
result = await agent.invoke(
{ messages: [{ role: "user", content: "What about tomorrow?" }] },
config,
);
thread_id로 대화 기록을 유지하려면 에이전트가 체크포인터로 구성되어야 해요. LangSmith 배포 시 체크포인터가 자동으로 프로비저닝돼요. 로컬에서는 create_agent(..., checkpointer=InMemorySaver())처럼 명시적으로 전달하세요.
툴·미들웨어에 실행별 구성(사용자 ID, API 키, 기능 플래그 등)을 전달해야 한다면 config와 함께 context로 전달하세요. 해당 데이터의 형태를 contextSchema로 정의하고 runtime.context로 접근하세요:
const contextSchema = z.object({
user_id: z.string(),
});
const agent = createAgent({
model: "openai:gpt-5.5",
tools,
contextSchema,
});
const result = await agent.invoke(
{ messages: [{ role: "user", content: "..." }] },
{ configurable: { thread_id: crypto.randomUUID() }, context: { user_id: "user-123" } },
);
thread_id는 대화(메시지 기록, 체크포인트)를 범위로 하고, context는 툴·미들웨어가 호출 시 읽는 실행별 데이터를 전달해요. 둘 다 함께 전달되는 것이 일반적이에요. 더 자세한 내용은 툴 컨텍스트와 Runtime을 참고하세요.
스트리밍 (Streaming)
invoke는 실행 끝에 최종 응답을 반환해요. 에이전트가 여러 툴 호출을 실행하면 사용자는 완료 전에 진행 상황 업데이트가 필요할 때가 많아요. 스트리밍을 사용해 중간 메시지와 툴 활동을 발생 즉시 표시하세요.
const stream = await agent.streamEvents(
{
messages: [
{
role: "user",
content: "Search for AI news and summarize the findings",
},
],
},
{ version: "v3" },
);
for await (const snapshot of stream.values) {
// Each snapshot contains the full state at that point
const latestMessage = snapshot.messages.at(-1);
if (latestMessage?.content) {
if (latestMessage.type === "human") {
console.log(`User: ${latestMessage.content}`);
} else if (latestMessage.type === "ai") {
console.log(`Agent: ${latestMessage.content}`);
}
} else if (latestMessage?.tool_calls?.length) {
const toolCallNames = latestMessage.tool_calls.map((tc) => tc.name);
console.log(`Calling tools: ${toolCallNames.join(", ")}`);
}
}
스트리밍 모드, 이벤트 유형, UI 패턴은 Streaming을 참고하세요.
Harness 구성 (Configure the harness)
create_agent는 매우 확장 가능해요. 미들웨어는 커스터마이징의 기본 요소예요: 각 조각이 하나의 관심사를 처리하고, 올바른 시점에 에이전트 루프에 연결되며, 다른 것과 자유롭게 결합돼요. 사용 사례에 필요한 것만 사용하고 나머지는 건너뛰세요.
일반적인 패턴은 일급(일등) 미들웨어로 사전 구축돼 있어요. 그 외는 커스텀 미들웨어로 만들 수 있어요.
에이전트가 복잡한 작업을 수행함에 따라 몇 가지 핵심 영역에서 지원이 필요해요. 미들웨어 생태계는 다음을 제공해요:
- 실행 환경 (Execution environment) — 툴, 파일시스템, 샌드박스, 코드 실행
- 컨텍스트 관리 (Context management) — 요약, 메모리, 스킬, 프롬프트 캐싱
- 계획·위임 (Planning and delegation) — 병렬·격리 작업을 위한 할 일 목록과 서브에이전트
- 결함 허용 (Fault tolerance) — 재시도, 폴백, 호출 한도
- 가드레일 (Guardrails) — PII 탐지와 콘텐츠 제어
- 스티어링 (Steering) — 영향력 큰 작업 전 사람의 승인 (human-in-the-loop)
create_deep_agent는 장기 실행 코딩·리서치 작업(파일시스템, 요약, 서브에이전트, 프롬프트 캐싱이 기본 포함)을 위해 이 스택을 사전 조립해요. 전체 사전 구축 harness는 Deep Agents를 참고하세요.
실행 환경 (Execution environment)
에이전트는 텍스트를 생성하는 것보다 조치를 취할 수 있을 때 특히 유용해요. 실행 환경은 에이전트에게 작업 공간을 제공해요: 호출 가능한 툴, 턴에 걸쳐 파일을 읽고 쓰는 파일시스템, 스크립트·셸 명령을 실행하는 코드 실행.
import { createFilesystemMiddleware, StateBackend } from "deepagents";
var agent = createAgent({
model: "google-genai:gemini-3.6-flash",
tools: [search],
middleware: [createFilesystemMiddleware({ backend: new StateBackend() })],
});
FilesystemMiddleware, 샌드박스, 인터프리터를 참고하세요.
컨텍스트 관리 (Context management)
모든 모델 호출에는 고정된 컨텍스트 윈도우가 있어요. 에이전트가 실행되면 그 윈도우는 누적된 기록, 툴 결과, 중간 단계로 채워져요. 요약은 오버플로 발생 전에 기록을 압축하고, 메모리는 시작 시 영구적 지침을 로드해 지식을 세션 간 전달하며, 스킬은 모든 것을 미리 로드하는 대신 요구에 따라 도메인 지식을 표시해요.
import {
StateBackend,
createFilesystemMiddleware,
createSkillsMiddleware,
createSummarizationMiddleware,
} from "deepagents";
var backend = new StateBackend();
const model = "google-genai:gemini-3.6-flash";
var agent = createAgent({
model,
tools: [search],
middleware: [
createFilesystemMiddleware({ backend }),
createSummarizationMiddleware({ model, backend }),
createSkillsMiddleware({ backend, sources: ["./skills/"] }),
],
});
SummarizationMiddleware, MemoryMiddleware, 스킬, 컨텍스트 엔지니어링을 참고하세요.
계획과 위임 (Planning and delegation)
복잡한 작업은 하나의 컨텍스트 윈도우가 감당할 수 있는 범위를 초과하는 경우가 많아요. 위임은 메인 에이전트가 작업을 조각으로 나누고 각자 격리된 컨텍스트에서 실행되는 서브에이전트에 맡기고, 실행보다 조정에 집중할 수 있게 해요. 작업은 병렬로 실행될 수 있고, 메인 에이전트의 컨텍스트는 깨끗하게 유지돼요.
import { createAgent, todoListMiddleware, tool } from "langchain";
import { createSubAgentMiddleware } from "deepagents";
var search = tool(({ query }) => `Search results for: ${query}`, {
name: "search",
description: "Search for a query and return a short summary.",
schema: z.object({ query: z.string() }),
});
var agent = createAgent({
model: "openai:gpt-5.5",
tools: [search],
middleware: [
todoListMiddleware(),
createSubAgentMiddleware({
defaultModel: "anthropic:claude-sonnet-4-6",
defaultTools: [],
subagents: [
{
name: "researcher",
description: "Searches and returns a structured summary.",
systemPrompt:
"Use the search tool to research the question and summarize key points.",
tools: [search],
model: "google-genai:gemini-3.6-flash",
middleware: [],
},
],
}),
],
});
서브에이전트를 참고하세요.
에이전트 이름 지정 (Name your agent)
선택적으로 에이전트에 식별자를 사용하세요. 특히 다중 에이전트 시스템에서 에이전트를 서브그래프로 임베드할 때 유용해요.
var agent = createAgent({
model: "openai:gpt-5.5",
tools,
name: "research_assistant",
});
결함 허용 (Fault tolerance)
프로덕션 에이전트는 개발에서 거의 나타나지 않는 실패(레이트 한도, 모델 타임아웃, 일시적 API 오류)를 만나요. 결함 허용 미들웨어는 이를 인프라 수준에서 처리하므로 툴과 비즈니스 로직이 매 호출마다 try/catch를 둘 필요가 없어요.
import {
createAgent,
modelRetryMiddleware,
tool,
toolRetryMiddleware,
} from "langchain";
var agent = createAgent({
model: "openai:gpt-5.5",
tools: [search],
middleware: [
modelRetryMiddleware({ maxRetries: 3 }),
toolRetryMiddleware({ maxRetries: 2 }),
],
});
modelRetryMiddleware, toolRetryMiddleware, 사전 구축 미들웨어를 참고하세요.
가드레일 (Guardrails)
어떤 정책은 프롬프트에 담을 수 없어요 — 모델이 무엇을 하든 결정적으로 시행되어야 해요. 가드레일은 데이터가 에이전트 루프를 통과할 때 가로채, 툴 결과가 모델 컨텍스트에 도달하기 전에 규정 준수 규칙이나 콘텐츠 정책을 적용해요.
import { createAgent, piiMiddleware, tool } from "langchain";
var agent = createAgent({
model: "openai:gpt-5.5",
tools: [search],
middleware: [piiMiddleware("email")],
});
piiMiddleware, 사전 구축 미들웨어를 참고하세요.
스티어링 (Steering)
완전 자율이 항상 적절한 것은 아니에요. 스티어링은 파괴적인 쓰기, 비용이 큰 API 호출, 판단이 필요한 모든 것 앞의 특정 결정 지점에 사람을 배치할 수 있게 해요 — 에이전트를 재구성하지 않고도요. 에이전트가 멈추고 기다리면, 사람이 승인·편집·거부하고, 실행이 계속돼요.
import { createAgent, humanInTheLoopMiddleware, tool } from "langchain";
var agent = createAgent({
model: "openai:gpt-5.5",
tools: [search],
middleware: [humanInTheLoopMiddleware({ interruptOn: { writeFile: true } })],
});
humanInTheLoopMiddleware, Human-in-the-loop을 참고하세요.
미들웨어 리소스 (Middleware resources)
- 미들웨어 개요 — 미들웨어 스택이 어떻게 작동하는지, 훅이 언제 발화하는지
- 사전 구축 미들웨어 — 구성 예제가 있는 전체 레퍼런스
- 커스텀 미들웨어 — 비즈니스 로직, PII 제거 등을 위한 자체 훅 작성
출처: 문서
본문
이 페이지는 LangChain 에이전트 개념을 소개해요. 에이전트는 create_agent로 만드는 모델+harness로, 본문은 호출 루프 주변의 프롬프트·툴·미들웨어를 다뤄요. 핵심 컴포넌트(모델·툴·시스템 프롬프트·구조화된 출력·에이전트 상태), 호출(thread_id·checkpointer·context), 스트리밍, 그리고 harness 구성(실행 환경, 컨텍스트 관리, 계획·위임, 결함 허용, 가드레일, 스티어링, 미들웨어 리소스)을 설명해요.