체인은 길을 따라가고, 에이전트는 길을 고릅니다
지금까지 우리는 LangChain을 이용해 여러 종류의 체인을 만들어 왔습니다. 프롬프트를 만들고, 모델을 호출하고, 출력 파서를 붙이고, 검색기를 연결했습니다. RAG 파이프라인에서는 사용자의 질문을 받아 관련 문서를 찾고, 그 문서를 컨텍스트로 넣어 답변을 생성했습니다. 도구 호출 장에서는 모델이 외부 함수를 호출하도록 만드는 방법도 살펴보았습니다.
그런데 실제 업무는 언제나 그렇게 예쁘게 흐르지 않습니다. 사용자가 이렇게 말한다고 생각해 보겠습니다.
"우리 제품 문서에서 환불 정책을 찾아보고, 이번 달 주문 데이터와 비교해서 예외 처리 대상 고객을 정리한 다음, 초안 메일을 만들어줘. 단, 실제 발송은 하지 마."
이 요청은 단순한 한 줄 체인으로 표현하기 어렵습니다. 먼저 문서를 검색해야 할지, 주문 데이터베이스를 조회해야 할지, 고객별 조건을 계산해야 할지, 혹은 사용자의 의도를 더 물어봐야 할지 실행 중에 결정해야 합니다. 어떤 단계는 한 번으로 끝나지 않을 수도 있습니다. 검색 결과가 부족하면 다시 검색해야 하고, 계산 결과가 이상하면 다른 도구를 써서 확인해야 합니다.
체인은 정해진 레일 위를 달리는 기차에 가깝습니다. 입력 → 검색 → 프롬프트 → 모델 → 파서처럼 개발자가 실행 순서를 미리 정해 둡니다. 반면 에이전트는 목적지를 알고 움직이는 운전자에 가깝습니다. 도로 상황을 보고, 어느 길로 갈지 고르고, 막히면 우회합니다. LangChain 공식 문서에서도 에이전트를 "작업을 추론하고, 어떤 도구를 사용할지 결정하며, 해결책을 향해 반복적으로 작업하는 시스템"으로 설명합니다.1
중요한 차이는 실행 흐름입니다. 체인은 고정된 실행 흐름을 가집니다. 에이전트는 동적 의사결정 루프를 가집니다. 이 차이 때문에 에이전트는 더 유연하지만, 동시에 더 예측하기 어렵습니다. 그래서 이번 장의 목표는 단순히 "에이전트를 실행해 보자"가 아닙니다. 에이전트가 어떻게 생각하고 행동하는지, 어디까지 맡기고 어디서 통제해야 하는지, 비용과 안전성을 어떻게 관리해야 하는지까지 함께 익히는 것입니다.

에이전트의 기본 구조: 모델, 도구, 지시문
LangChain의 현대적인 에이전트 구성은 create_agent를 중심으로 이해하면 쉽습니다. create_agent는 모델, 도구, 시스템 프롬프트를 결합해 에이전트 실행 그래프를 만들어 줍니다. LangChain v1 계열에서는 여러 종류의 오래된 에이전트 타입을 직접 고르는 방식보다, create_agent를 사용해 핵심 구성요소를 조립하는 방식이 중심이 되었습니다.2
가장 작은 에이전트는 다음 세 가지를 가집니다.
첫째, 모델은 에이전트의 판단 엔진입니다. 사용자의 요청을 읽고, 지금 어떤 정보가 부족한지 판단하고, 어떤 도구를 호출할지 결정합니다.
둘째, 도구는 에이전트의 손과 발입니다. 검색, 계산, 데이터베이스 조회, 파일 읽기, API 호출, 이메일 초안 생성 같은 실제 행동을 수행합니다.
셋째, 시스템 프롬프트는 에이전트의 업무 규칙입니다. 어떤 역할을 맡는지, 어떤 도구를 언제 써야 하는지, 위험한 행동은 어떻게 처리해야 하는지 알려 줍니다.
다음 예제에서는 외부 API 없이 실행 흐름을 이해할 수 있도록 가짜 검색 도구와 계산 도구를 만듭니다.
from langchain.agents import create_agent
from langchain.tools import tool
from langchain_openai import ChatOpenAI
@tool
def search_info(query: str) -> str:
"""Search for simple factual information.
Use this tool when the user asks for information that may need lookup.
The input should be a concise search query.
"""
mock_data = {
"tokyo population": "Tokyo metropolitan area population is about 37.4 million.",
"japan population": "Japan population is about 124.8 million.",
}
return mock_data.get(query.lower(), f"No mock result for: {query}")
@tool
def calculator(expression: str) -> str:
"""Calculate a basic arithmetic expression.
Use this tool when arithmetic is required.
Only numbers and basic operators are allowed.
"""
allowed = set("0123456789+-*/(). %")
if not set(expression) <= allowed:
return "Error: unsupported characters in expression."
try:
# 학습용 예제입니다. 운영에서는 eval 대신 안전한 계산 파서나
# 미리 정의한 계산 함수를 사용하는 편이 좋습니다.
return str(eval(expression, {"__builtins__": {}}, {}))
except Exception as e:
return f"Error: {e}"
model = ChatOpenAI(model="gpt-4o-mini", temperature=0)
tools = [search_info, calculator]
agent = create_agent(
model=model,
tools=tools,
system_prompt=(
"You are a careful data assistant. "
"Use tools when you need lookup or calculation. "
"Do not guess numbers. "
"Explain the final answer in Korean."
),
)
result = agent.invoke(
{
"messages": [
{
"role": "user",
"content": "도쿄권 인구는 일본 전체 인구의 몇 퍼센트인지 계산해줘.",
}
]
}
)
print(result["messages"][-1].content)이 코드를 보면 일반 체인과 비슷해 보일 수 있습니다. 하지만 내부 동작은 다릅니다. 체인에서는 개발자가 "먼저 도쿄 인구를 검색하고, 다음 일본 인구를 검색하고, 마지막에 계산한다"라고 순서를 정해야 합니다. 에이전트에서는 모델이 현재 질문을 보고 필요한 행동을 선택합니다.
도구 정의에서 특히 중요한 부분은 함수 이름, 타입 힌트, docstring입니다. 에이전트는 도구의 내부 코드를 읽고 이해하는 것이 아니라, 도구 이름과 설명, 입력 스키마를 보고 언제 사용할지 판단합니다. 도구 설명이 모호하면 에이전트도 모호하게 행동합니다. helper, process, run 같은 이름보다 search_customer_orders, calculate_refund_amount, read_policy_document처럼 목적이 드러나는 이름이 훨씬 좋습니다.
ReAct: 생각하고, 행동하고, 관찰하고, 다시 판단하기
에이전트의 대표적인 실행 패턴은 ReAct입니다. ReAct는 Reason과 Act를 합친 말입니다. 모델이 문제를 해석하고, 필요한 행동을 선택하고, 행동 결과를 관찰한 뒤, 다음 행동을 다시 결정하는 구조입니다. LangGraph 문서에서도 에이전트는 도구를 사용하는 LLM이 지속적인 피드백 루프 안에서 동작하는 형태이며, 예측하기 어려운 문제와 해결 경로에 적합하다고 설명합니다.3
방금 예제를 사람이 볼 수 있는 실행 흐름으로 풀어 쓰면 다음과 같습니다.
사용자 요청: "도쿄권 인구는 일본 전체 인구의 몇 퍼센트인지 계산해줘."
모델 판단: 도쿄권 인구와 일본 전체 인구라는 두 개의 사실값이 필요합니다.
행동:
search_info("tokyo population")호출.관찰: "Tokyo metropolitan area population is about 37.4 million."
모델 판단: 분모가 될 일본 전체 인구가 아직 필요합니다.
행동:
search_info("japan population")호출.관찰: "Japan population is about 124.8 million."
모델 판단: 이제 비율 계산이 필요합니다.
행동:
calculator("37.4 / 124.8 * 100")호출.관찰:
29.967948717948715.최종 답변: 도쿄권 인구는 일본 전체 인구의 약 30.0%라고 설명합니다.
핵심은 "한 번의 모델 호출로 답을 끝내지 않는다"는 점입니다. 에이전트는 도구 결과를 다시 모델에게 전달하고, 모델은 그 관찰 결과를 바탕으로 다음 행동을 정합니다. 그래서 에이전트는 검색과 계산, 데이터 조회와 문서 요약처럼 서로 다른 능력을 엮어 복합적인 일을 처리할 수 있습니다.
다만 개발할 때는 모델의 숨겨진 내부 추론을 그대로 노출하려고 하기보다, 관찰 가능한 실행 단계에 집중하는 편이 좋습니다. 어떤 도구가 호출되었는지, 어떤 입력이 들어갔는지, 어떤 결과가 돌아왔는지, 최종 답변이 그 결과에 근거하는지 확인하면 됩니다. 운영 환경에서는 이 정보가 곧 디버깅과 감사의 핵심 자료가 됩니다.
검색 도구와 계산 도구를 함께 쓰는 에이전트
이번에는 조금 더 현실적인 형태로 검색 도구와 계산 도구를 분리해 보겠습니다. 실제 서비스에서는 검색 도구가 웹 검색 API, 사내 문서 검색기, SQL 쿼리 도구, 벡터스토어 retriever 중 하나일 수 있습니다. 계산 도구는 단순 계산기일 수도 있고, 가격 정책 계산기나 세금 계산기처럼 업무 규칙이 담긴 함수일 수도 있습니다.
from langchain.agents import create_agent
from langchain.tools import tool
from langchain_openai import ChatOpenAI
@tool
def product_policy_search(query: str) -> str:
"""Search internal product policy documents.
Use this tool for refund, warranty, shipping, and subscription policy questions.
"""
if "refund" in query.lower() or "환불" in query:
return (
"Refund policy: Customers can request a full refund within 14 days "
"if the product has not been used. Digital subscriptions are prorated."
)
return "No relevant policy found."
@tool
def prorated_refund(monthly_price: float, used_days: int, total_days: int = 30) -> str:
"""Calculate prorated refund for a monthly subscription.
Args:
monthly_price: Monthly subscription price.
used_days: Number of days already used.
total_days: Number of days in the billing period. Default is 30.
"""
if used_days < 0 or total_days <= 0 or used_days > total_days:
return "Error: invalid day values."
unused_days = total_days - used_days
refund = monthly_price * unused_days / total_days
return f"Refund amount: {refund:.2f}"
agent = create_agent(
model=ChatOpenAI(model="gpt-4o-mini", temperature=0),
tools=[product_policy_search, prorated_refund],
system_prompt="""
You are a customer support assistant.
Use the policy search tool before answering policy questions.
Use the refund calculator for prorated subscription refunds.
If the user asks you to actually issue a refund, do not execute it. Ask for human approval.
Answer in Korean.
""",
)
response = agent.invoke(
{
"messages": [
{
"role": "user",
"content": "월 30000원 구독을 10일 사용한 고객이 환불을 요청했어. 정책상 얼마를 환불해야 해?",
}
]
}
)
print(response["messages"][-1].content)여기서 시스템 프롬프트는 에이전트의 행동 경계를 정합니다. "정책 질문에는 정책 검색 도구를 먼저 써라", "비례 환불 계산에는 계산 도구를 써라", "실제 환불 실행은 하지 말고 사람의 승인을 받아라"라는 규칙이 들어 있습니다.
이런 규칙은 단순한 친절 문구가 아닙니다. 에이전트가 실무 시스템과 연결될수록 프롬프트는 업무 절차서에 가까워집니다. 특히 돈, 개인정보, 권한 변경, 외부 발송처럼 되돌리기 어려운 행동은 반드시 별도의 승인 단계를 두어야 합니다. 지난 장에서 도구 호출을 다루며 강조했던 "쓰기 도구 실행 전 승인" 원칙은 에이전트에서도 그대로 이어집니다.
정적 모델과 동적 모델 선택
에이전트를 만들 때 가장 간단한 방식은 모델을 하나 정해 고정하는 것입니다. 이를 정적 모델 구성이라고 볼 수 있습니다.
agent = create_agent(
model="openai:gpt-4o-mini",
tools=tools,
system_prompt="Answer accurately and concisely.",
)정적 모델은 이해하기 쉽고 운영하기도 편합니다. 대부분의 MVP와 내부 도구는 이 방식으로 시작해도 충분합니다. 문제는 모든 요청이 같은 난이도를 갖지 않는다는 점입니다. "오늘 날씨 알려줘"와 "지난 6개월 매출 데이터를 분석해서 이탈 원인을 추정해줘"를 같은 모델로 처리하면 비용 또는 품질 중 하나가 손해를 볼 수 있습니다.
이때 동적 모델 선택이 유용합니다. LangChain의 에이전트 미들웨어를 사용하면 실행 중 상태나 대화 길이, 사용자 등급, 작업 복잡도에 따라 다른 모델을 선택할 수 있습니다. 공식 문서에서는 wrap_model_call을 이용해 현재 요청을 가로채고 모델을 바꾸는 패턴을 제시합니다.4
from langchain.agents import create_agent
from langchain.agents.middleware import wrap_model_call, ModelRequest, ModelResponse
from langchain_openai import ChatOpenAI
basic_model = ChatOpenAI(model="gpt-4o-mini", temperature=0)
advanced_model = ChatOpenAI(model="gpt-4o", temperature=0)
@wrap_model_call
def select_model_by_complexity(request: ModelRequest, handler) -> ModelResponse:
"""대화가 길거나 복잡하면 더 강한 모델을 사용합니다."""
messages = request.state["messages"]
message_count = len(messages)
if message_count > 10:
return handler(request.override(model=advanced_model))
return handler(request.override(model=basic_model))
agent = create_agent(
model=basic_model,
tools=tools,
system_prompt="You are a practical assistant.",
middleware=[select_model_by_complexity],
)실무에서는 단순히 메시지 개수만 볼 필요는 없습니다. 의도 분류 결과, 예상 도구 호출 수, 사용자의 요금제, 업무 위험도, 응답 지연 허용 시간 등을 함께 고려할 수 있습니다. 예를 들어 고객센터 FAQ는 저렴하고 빠른 모델로 처리하고, 법무 검토 초안이나 복잡한 데이터 분석은 더 강한 모델로 라우팅할 수 있습니다.
동적 모델 선택의 핵심은 "항상 가장 좋은 모델"이 아니라 "상황에 맞는 모델"입니다. 에이전트는 반복 호출을 할 수 있으므로 작은 비용 차이도 누적되면 커집니다. 반대로 너무 약한 모델을 쓰면 도구 선택 오류가 늘어나고, 재시도 때문에 오히려 총비용이 올라갈 수 있습니다.
정적 도구와 권한 기반 동적 도구 필터링
모델만 동적으로 고르는 것이 아닙니다. 도구도 상황에 따라 다르게 보여 줄 수 있습니다.
정적 도구 구성은 에이전트를 만들 때 도구 목록을 고정하는 방식입니다.
agent = create_agent(
model=model,
tools=[product_policy_search, prorated_refund],
system_prompt="You are a support assistant.",
)이 방식은 간단하고 명확합니다. 하지만 실제 서비스에서는 사용자마다 허용되는 도구가 다릅니다. 일반 사용자는 읽기 도구만 사용할 수 있고, 상담원은 환불 초안 생성 도구를 사용할 수 있으며, 관리자는 승인된 환불 실행 도구까지 사용할 수 있습니다. 모든 사용자에게 모든 도구를 노출하면 모델이 실수로 위험한 도구를 고를 가능성이 생깁니다.
LangChain 문서에서는 미들웨어를 이용해 런타임 컨텍스트, 인증 상태, 사용자 권한, 기능 플래그에 따라 사용 가능한 도구를 필터링하는 패턴을 소개합니다.5
from dataclasses import dataclass
from typing import Callable
from langchain.agents import create_agent
from langchain.agents.middleware import wrap_model_call, ModelRequest, ModelResponse
@dataclass
class UserContext:
user_role: str
@wrap_model_call
def filter_tools_by_role(
request: ModelRequest,
handler: Callable[[ModelRequest], ModelResponse],
) -> ModelResponse:
"""사용자 역할에 따라 에이전트에게 노출되는 도구를 제한합니다."""
context = request.runtime.context if request.runtime else None
role = getattr(context, "user_role", "viewer")
if role == "admin":
return handler(request)
if role == "support_agent":
allowed_tools = [
tool for tool in request.tools
if tool.name in {"product_policy_search", "prorated_refund"}
]
return handler(request.override(tools=allowed_tools))
allowed_tools = [
tool for tool in request.tools
if tool.name.startswith("read_") or tool.name == "product_policy_search"
]
return handler(request.override(tools=allowed_tools))
agent = create_agent(
model=model,
tools=[
product_policy_search,
prorated_refund,
# issue_refund, # 실제 환불 실행 도구라고 가정
# delete_customer_data # 매우 위험한 도구라고 가정
],
system_prompt="Follow user permissions strictly.",
middleware=[filter_tools_by_role],
context_schema=UserContext,
)이 구조의 장점은 안전성입니다. 프롬프트에 "삭제하지 마"라고 쓰는 것보다, 애초에 삭제 도구를 모델에게 보여 주지 않는 편이 훨씬 안전합니다. 에이전트 보안의 첫 번째 원칙은 선한 의도를 기대하는 것이 아니라, 가능한 행동의 범위를 줄이는 것입니다.
도구가 많을수록 에이전트는 더 똑똑해지는 것이 아니라 더 헷갈릴 수 있습니다. 비슷한 이름의 도구가 많으면 잘못된 도구를 고를 가능성이 올라갑니다. 따라서 처음에는 1~3개의 핵심 도구로 시작하고, 로그를 보며 실제로 필요한 도구를 추가하는 편이 좋습니다.
에이전트의 예측 불가능성 관리하기
에이전트는 유연합니다. 바로 그 이유 때문에 위험합니다. 체인은 개발자가 정한 경로를 벗어나기 어렵지만, 에이전트는 매 단계마다 선택합니다. 검색을 한 번만 해도 될 일을 세 번 할 수도 있고, 계산 도구에 잘못된 인자를 넣을 수도 있으며, 도구 오류를 오해하고 이상한 결론을 낼 수도 있습니다.
그래서 좋은 에이전트 개발은 "더 자유롭게 만들기"가 아니라 "필요한 만큼만 자유롭게 만들기"에 가깝습니다.
반복 한도 설정
에이전트는 목표를 달성할 때까지 도구 호출과 모델 호출을 반복합니다. 하지만 목표가 모호하거나 도구 결과가 계속 실패하면 루프가 길어질 수 있습니다. LangChain 공식 Agents 문서에서도 에이전트는 최종 출력이 나오거나 반복 한도에 도달할 때까지 실행된다고 설명합니다.6
현대적인 create_agent 기반 실행에서는 LangGraph 실행 설정을 통해 재귀 또는 반복 깊이를 제한하는 식으로 안전장치를 둘 수 있습니다.
result = agent.invoke(
{
"messages": [
{"role": "user", "content": "이 문제를 조사해서 답해줘."}
]
},
config={"recursion_limit": 8},
)반복 한도는 너무 낮으면 복합 작업을 끝내지 못하고, 너무 높으면 비용과 지연 시간이 커집니다. 검색 한두 번과 계산 한 번이면 충분한 업무라면 낮게 잡고, 조사형 업무라면 조금 더 높게 잡습니다. 중요한 것은 무한히 돌도록 두지 않는 것입니다.
중간 단계 로깅
에이전트 디버깅에서 가장 중요한 질문은 이것입니다.
"왜 이런 답을 했지?"
이 질문에 답하려면 최종 답변만 저장해서는 부족합니다. 어떤 도구를 호출했는지, 입력은 무엇이었는지, 도구 결과는 무엇이었는지, 오류가 있었는지 기록해야 합니다. 개발 중에는 콘솔 출력만으로도 충분하지만, 운영 환경에서는 LangSmith 같은 관측 도구나 자체 로그 시스템에 trace를 남기는 것이 좋습니다.
{
"request_id": "req_20260509_001",
"user_id": "user_123",
"tool_calls": [
{
"tool": "product_policy_search",
"input": {"query": "subscription refund policy"},
"output_preview": "Refund policy: Customers can request...",
"latency_ms": 230,
},
{
"tool": "prorated_refund",
"input": {"monthly_price": 30000, "used_days": 10, "total_days": 30},
"output_preview": "Refund amount: 20000.00",
"latency_ms": 5,
},
],
"final_answer_preview": "정책상 비례 환불 금액은 20,000원입니다...",
}로그에는 민감정보를 그대로 남기지 않도록 주의해야 합니다. 고객 이름, 이메일, 결제 정보, 액세스 토큰은 마스킹하거나 저장하지 않는 편이 안전합니다. 에이전트는 외부 시스템과 연결되기 때문에 일반 챗봇보다 감사 로그의 중요성이 훨씬 큽니다.
파싱 오류 처리와 handle_parsing_errors
LangChain의 오래된 AgentExecutor 기반 에이전트를 사용하거나 기존 코드를 유지보수하다 보면 handle_parsing_errors 설정을 만날 수 있습니다. 이는 모델 출력이 에이전트가 기대한 액션 형식으로 파싱되지 않았을 때, 즉시 예외를 던질지 아니면 오류 내용을 다시 모델에게 전달해 재시도하게 할지 정하는 옵션입니다.
# 레거시 AgentExecutor 기반 코드에서 볼 수 있는 패턴입니다.
# 최신 create_agent 중심 코드와는 구분해서 이해하세요.
from langchain.agents import AgentExecutor
agent_executor = AgentExecutor(
agent=legacy_agent,
tools=tools,
max_iterations=5,
return_intermediate_steps=True,
handle_parsing_errors=True,
verbose=True,
)이 옵션은 편리하지만 만능은 아닙니다. 파싱 오류가 계속 발생한다면 단순히 재시도만 늘릴 것이 아니라 프롬프트, 출력 형식, 도구 설명, 모델 선택을 함께 점검해야 합니다. 최신 도구 호출 기반 모델과 구조화 출력 기능을 사용하면 과거 ReAct 문자열 파싱 방식보다 안정적으로 액션을 표현할 수 있습니다.
에이전트 설계 체크리스트
에이전트를 만들기 전에 스스로에게 질문해야 합니다.
이 작업은 정말 에이전트가 필요한가요? 실행 순서가 거의 고정되어 있다면 LCEL 체인이나 LangGraph workflow가 더 낫습니다. 예를 들어 "문서 검색 후 답변 생성"처럼 흐름이 명확한 기본 RAG는 에이전트보다 체인이 단순하고 안정적입니다.
반대로 다음과 같은 경우에는 에이전트가 잘 맞습니다.
사용자의 요청마다 필요한 도구와 순서가 달라집니다.
중간 결과를 보고 다시 검색하거나 계산해야 합니다.
외부 API, 데이터베이스, 문서 검색, 계산 도구를 조합해야 합니다.
사용자가 목표만 말하고 세부 절차는 시스템이 판단해야 합니다.
그리고 에이전트를 설계할 때는 다음 원칙을 지키는 것이 좋습니다.
도구는 작고 명확하게 만듭니다.
위험한 도구는 권한과 승인 절차 뒤에 둡니다.
반복 한도와 타임아웃을 반드시 설정합니다.
도구 호출 로그와 최종 답변 근거를 남깁니다.
처음부터 많은 도구를 주지 말고 실제 실패 로그를 보며 확장합니다.
비용이 큰 모델은 복잡한 요청에만 사용하도록 라우팅합니다.
에이전트의 품질은 모델 하나로 결정되지 않습니다. 좋은 도구 설명, 적절한 권한 설계, 명확한 시스템 프롬프트, 반복 한도, 로깅, 평가 데이터가 함께 맞물려야 합니다.
언제 LangGraph로 넘어가야 할까요
이번 장에서는 LangChain의 create_agent를 중심으로 에이전트를 만들었습니다. 이 방식은 빠르게 시작하기 좋고, 단일 에이전트가 도구를 선택하며 문제를 해결하는 구조에 잘 맞습니다. 하지만 업무가 더 복잡해지면 더 세밀한 제어가 필요해집니다.
예를 들어 다음과 같은 요구가 생길 수 있습니다.
도구 실행 전 반드시 사람 승인을 받아야 합니다.
검색 실패 시 다른 검색기로 재시도해야 합니다.
계획 수립 에이전트, 조사 에이전트, 작성 에이전트를 분리해야 합니다.
상태를 저장하고 나중에 같은 지점부터 재개해야 합니다.
특정 조건에서만 루프를 돌고, 특정 조건에서는 강제로 종료해야 합니다.
이런 경우에는 LangGraph가 더 적합합니다. LangChain 문서에서도 LangChain의 에이전트 구현은 LangGraph primitive 위에서 동작하며, 더 깊은 커스터마이징이 필요하면 LangGraph로 직접 에이전트를 구현할 수 있다고 설명합니다.7
다음 장에서는 바로 이 지점으로 넘어갑니다. 지금까지는 "모델이 도구를 고르는 에이전트"를 만들었다면, 다음 장에서는 상태를 가진 워크플로와 멀티 에이전트 구조를 직접 설계합니다. 에이전트가 한 명의 똑똑한 조수라면, LangGraph는 여러 조수가 협업하는 사무실의 업무 흐름표입니다.
에이전트는 강력합니다. 하지만 강력한 도구일수록 경계가 필요합니다. 모델에게 목표를 주고, 도구를 쥐여 주고, 반복 루프를 허용하되, 권한과 비용과 로그는 개발자가 책임져야 합니다. 그 균형을 잡을 때 LangChain 에이전트는 단순한 챗봇을 넘어 실제 업무를 처리하는 애플리케이션이 됩니다.
참고
3LangGraph Workflows and agents 문서
4LangChain Agents - Dynamic model
5LangChain Agents - Dynamic tools
이 노트는 보도·비평·교육·연구 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.