[AI] Multi-Agent System을 Production에 올려보자! 설계부터 코드·보안·평가·운영까지 A→Z
Multi-Agent System을
Production에 올려보자
여러 개의 확률적인 LLM을 어떻게 하나의 예측 가능한 시스템으로 묶을 것인가가 주제다.
Multi-Agent Demo를 만드는 건 의외로 쉽다. Researcher Agent, Coder Agent, Reviewer Agent를 만들고 서로 대화시키면 꽤 그럴듯한 결과가 나온다. 화면에는 Agent들이 열심히 메시지를 주고받고, 마지막에는 멋진 보고서까지 만들어진다.
그런데 그 시스템에 진짜 고객 데이터와 사내 API를 붙이는 순간 이야기가 달라진다.
Customer Agent는 Policy Agent에게 규정을 물었다.
Policy Agent가 Action Agent에게 “처리 가능”이라고 전달했다.
Action Agent가 API를 호출했는데 timeout이 발생했다.
Planner는 실패했다고 생각하고 다시 Action Agent를 호출했다.
그런데 첫 번째 API 요청은 실제로 성공해 있었다.
결과는? 동일한 업무가 두 번 실행됐다.
여기서 문제가 된 것은 LLM의 지능이 아니다. Distributed System 설계가 없었던 것이다.
그래서 Production Multi-Agent를 이해할 때 가장 먼저 버려야 할 생각이 있다.
“LLM 여러 명의 단체 채팅방”이 아니다.
1. 그런데 Multi-Agent는 왜 필요한가?
먼저 불편한 질문을 하나 해보자.
답부터 말하면 Agent 수가 많다는 것 자체에는 아무런 가치가 없다. 현재 LangChain의 Multi-Agent 문서도 복잡한 문제라고 해서 반드시 Multi-Agent가 필요한 것은 아니며, 적절한 Tool과 Prompt를 가진 Single Agent로 충분한 경우가 많다고 명시한다. Microsoft Agent Framework 역시 함수로 확실하게 구현할 수 있다면 Agent 대신 함수를 사용하라고 권장한다.
실제 연구 결과도 비슷하다. 2025년 공개된 Why Do Multi-Agent LLM Systems Fail?은 5개 Multi-Agent framework와 150개 이상의 task를 분석해 specification/system design, inter-agent misalignment, verification/termination 등 3개 범주의 14개 실패 모드를 정리했다. 즉 Agent가 늘어나면 capability뿐 아니라 coordination failure surface도 같이 늘어난다.
2025년 말 공개된 Towards a Science of Scaling Agent Systems도 흥미롭다. 실험 범위 안에서 parallelizable task에는 중앙집중형 Multi-Agent가 도움이 됐지만, sequential reasoning task에서는 여러 Multi-Agent 구조가 오히려 성능을 떨어뜨렸다. “Agent를 더 붙이면 좋아진다”가 아니라 Task의 구조와 Coordination topology가 맞아야 한다는 뜻이다.
그럼 언제 나누는가?
| 이유 | 왜 Agent 분리가 유리한가 | 예시 |
|---|---|---|
| Context Isolation | Agent마다 필요한 정보만 전달 | 법규 Agent에 고객 상담 전체 history를 보내지 않음 |
| Privilege Isolation | 읽기/쓰기 권한을 Agent별 분리 | Research Agent는 DB Write 권한 없음 |
| Parallelism | 독립 작업을 병렬 수행 | 법규·상품·고객 정보를 동시에 검색 |
| Different Models | 업무별 모델 최적화 | Router는 작은 모델, 복잡한 reasoning은 큰 모델 |
| Independent Ownership | 팀별 독립 개발·배포 | Compliance Agent는 준법팀 플랫폼에서 운영 |
2. 2026년의 방향: Agent를 더 자유롭게가 아니라 Workflow를 더 명확하게
초기 Multi-Agent 논문은 Agent끼리 대화시키는 데 집중했다. CAMEL은 role-playing agent interaction을 탐구했고, AutoGen은 여러 conversable agent의 대화를 application programming primitive로 만들었다. MetaGPT는 여기에 SOP(Standard Operating Procedure)를 넣어 software engineering workflow를 구조화했다.
그런데 Production tooling의 최근 방향은 조금 다르다.
- Google ADK 2.0은 infinite loop, hallucinated routing, business logic bypass 때문에 deterministic graph/workflow control을 강조한다.
- CrewAI 역시 Production에서는 먼저 Flow를 만들고 그 안에 Crew를 배치하는 Flow-first 방식을 권장한다.
- Microsoft Agent Framework 1.0은 AutoGen과 Semantic Kernel의 후속으로, explicit workflow·state management·middleware·telemetry를 전면에 놓았다. 1.0은 2026년 4월 GA됐다.
- OpenAI Agents SDK도 LLM-driven orchestration과 code-driven orchestration을 명확히 구분하고 두 방식을 섞을 수 있도록 설계한다.
“다음에 어떤 전문가가 필요한가?”처럼 열린 판단은 Agent가 할 수 있다.
“잔액이 0보다 큰가?”, “권한이 존재하는가?”, “오늘 이미 실행했는가?”는 코드가 해야 한다.
3. 우리가 만들 시스템: 금융 업무 Multi-Agent
예제로 다음 업무를 생각해보자.
가능하다면 변경 요청을 등록한 뒤 결과를 알려줘.”
단순 질문처럼 보이지만 실제로는 여러 문제가 섞여 있다.
계약·고객 상태 조회
상품/업무 규정 검색
규제·예외 검토
변경 요청 실행
여기서 Side Effect라는 용어가 나온다. 외부 시스템 상태를 바꾸는 작업을 뜻한다. DB UPDATE, 송금, 이메일 발송, 주문 취소, 계정 잠금 같은 행위다.
“이 Agent에게 고객 정보를 수정하지 말라고 Prompt에 적어두었다”는 것은 보안 통제가 아니다.
수정 권한 자체가 없는 Credential을 주거나, Tool Gateway가 Authorization을 거부해야 한다.
4. Agent들은 어떤 방식으로 협업해야 할까?
Multi-Agent Architecture라고 하면 흔히 Swarm을 떠올리지만 실제로는 여러 topology가 있다.
OpenAI Agents SDK는 크게 Manager가 specialist를 tool처럼 호출하는 방식과 specialist가 대화의 control을 가져가는 Handoff를 구분한다. LangChain 역시 Subagent, Handoff, Router, Skills, Custom Workflow 같은 패턴을 별도로 설명한다.
| 패턴 | 강점 | 약점 | 추천 상황 |
|---|---|---|---|
| Router | 싸고 단순 | 복잡한 재계획 약함 | 업무 분류 |
| Supervisor | 통제·관찰 쉬움 | Manager 병목 | Enterprise 기본값 |
| Graph | 예측 가능·복구 쉬움 | 설계 필요 | 규제/업무 Process |
| Handoff | 대화 UX 자연스러움 | Context 관리 난도 | 상담 Agent |
| Swarm | 탐색 자유도 | 비용·loop·검증 난도 | 연구/개방형 탐색 |
금융/Enterprise 업무라면 Graph + Supervisor부터 시작하는 편이 현실적이다. 고정된 business invariant는 Graph가 보장하고, 어느 전문 Agent를 사용할지 애매한 구간에만 Supervisor의 판단을 허용한다.
5. Persona보다 중요한 것: Agent Contract
Demo에서는 이렇게 만든다.
You are an expert compliance officer.
Be careful and check every regulation.
Production에서는 부족하다. Agent에게 필요한 것은 멋진 Persona가 아니라 명확한 계약이다.
agent:
name: policy_agent
purpose: "적용 가능한 상품/업무 규정을 찾고 근거를 반환"
input_schema: PolicyQuery
output_schema: PolicyEvidence
tools:
- policy_search
permissions:
- policy:read
state:
read:
- product_code
- effective_date
write:
- policy_evidence
limits:
max_steps: 3
timeout_ms: 12000
max_output_tokens: 1800
memory: none
on_failure:
action: escalate
forbidden:
- customer_write
- execute_business_action
이 계약 덕분에 “Policy Agent가 갑자기 고객 계좌를 수정했다” 같은 상황 자체를 구조적으로 어렵게 만들 수 있다.
6. 코드로 내려가 보자: State부터 만든다
Multi-Agent에서 가장 중요한 객체는 사실 Agent가 아니라 State다.
State는 현재 Workflow가 어디까지 진행됐고 무엇을 알고 있는지를 담는 구조화 데이터다. Agent끼리 자유로운 자연어를 계속 전달하는 대신, 중요한 값은 typed state에 저장한다.
from typing import TypedDict, Literal
from pydantic import BaseModel
class PolicyEvidence(BaseModel):
policy_id: str
effective_from: str
decision_hint: Literal["eligible", "ineligible", "review"]
citations: list[str]
class ProposedAction(BaseModel):
action_type: Literal["RATE_CHANGE_REQUEST"]
customer_id: str
contract_id: str
parameters: dict
class WorkflowState(TypedDict, total=False):
request_id: str
user_id: str
tenant_id: str
customer_id: str
contract_id: str
customer_context: dict
policy_evidence: list[PolicyEvidence]
proposed_action: ProposedAction
authorization_result: Literal[
"allow", "deny", "human_review"
]
execution_result: dict
error: str
step_count: int
여기서 중요한 차이를 하나 보자.
“Customer Agent가 이런 말을 했고 Policy Agent가 저런 말을 했으니 적절히 판단해.”
authorization_result = "human_review"처럼 machine-readable state로 넘긴다.
Natural Language는 reasoning interface로 사용하되, 시스템의 truth를 저장하는 포맷으로 쓰지 않는 것이 포인트다.
LangGraph로 최소 Orchestrator 만들기
예제는 구현을 구체화하기 위해 LangGraph를 사용하되 구조 자체는 framework-neutral하다. 현재 LangGraph는 state checkpointing과 fault-tolerant execution을 핵심 기능으로 제공하고, persistent checkpointer를 이용해 중단 후 재개할 수 있다.
from langgraph.graph import StateGraph, START, END
from langgraph.checkpoint.postgres.aio import AsyncPostgresSaver
async def load_customer(state: WorkflowState):
# READ-ONLY API
customer = await customer_api.get_contract(
user_id=state["user_id"],
customer_id=state["customer_id"],
contract_id=state["contract_id"],
)
return {"customer_context": customer}
async def retrieve_policy(state: WorkflowState):
evidence = await policy_agent(
customer_context=state["customer_context"]
)
return {"policy_evidence": evidence}
async def propose_action(state: WorkflowState):
action = await action_planner_agent(
customer_context=state["customer_context"],
policy_evidence=state["policy_evidence"],
)
return {"proposed_action": action}
async def authorize(state: WorkflowState):
# LLM이 아니라 deterministic policy engine
result = policy_engine.evaluate(
user_id=state["user_id"],
tenant_id=state["tenant_id"],
action=state["proposed_action"].model_dump(),
)
return {"authorization_result": result}
def route_after_authorization(state: WorkflowState):
match state["authorization_result"]:
case "allow":
return "execute"
case "human_review":
return "approval"
case _:
return "deny"
graph = StateGraph(WorkflowState)
graph.add_node("customer", load_customer)
graph.add_node("policy", retrieve_policy)
graph.add_node("propose", propose_action)
graph.add_node("authorize", authorize)
graph.add_edge(START, "customer")
graph.add_edge("customer", "policy")
graph.add_edge("policy", "propose")
graph.add_edge("propose", "authorize")
graph.add_conditional_edges(
"authorize",
route_after_authorization,
{
"execute": "execute",
"approval": "approval",
"deny": "deny",
},
)
graph.add_edge("execute", END)
graph.add_edge("approval", END)
graph.add_edge("deny", END)
여기서 일부러 authorize()를 Agent로 만들지 않았다. 이런 구분이 Production 설계의 핵심이다.
7. MCP와 A2A는 어디에 들어가는가?
2026년 Agent Architecture를 보면 MCP와 A2A가 자주 등장한다. 그런데 둘은 해결하는 문제가 다르다.
MCP(Model Context Protocol)는 Agent가 Tool과 Resource를 사용하는 interface에 가깝다. 2026년 7월 28일 사양에서는 protocol core가 stateless하게 재설계됐고, Multi Round-Trip Requests, authorization hardening, extension framework 등이 추가됐다.
반면 A2A(Agent2Agent)는 독립 Agent service 사이의 interoperability를 위한 protocol이다. 현재 공식 specification의 최신 released version은 1.0.0이며, 서로 내부 memory나 tool 구현을 공개하지 않아도 capability discovery와 task/message 교환을 할 수 있도록 설계된다.
MCP: “너 어떤 Tool 쓸 수 있어?”
A2A: “너라는 Agent에게 이 일을 맡길 수 있어?”
다만 둘 다 Workflow Engine은 아니다. 메시지를 주고받을 수 있다는 것과 올바르게 협업한다는 것은 전혀 다른 문제다.
8. 보안: Agent가 둘이 되면 공격 경로도 둘이 된다
2026 OWASP Top 10 for Agentic Applications에는 Agent Goal Hijack, Tool Misuse, Identity & Privilege Abuse, Agentic Supply Chain, Unexpected Code Execution, Memory & Context Poisoning, Insecure Inter-Agent Communication, Cascading Failures, Human-Agent Trust Exploitation, Rogue Agents가 포함된다.
① User Identity와 Agent Identity를 구분한다
사용자가 가진 Token을 Agent들이 무작정 서로 전달하면 안 된다. Agent Runtime 자체의 Workload Identity와 사용자를 대신해 수행하는 Delegated Identity를 구분해야 한다.
특히 최신 MCP Authorization 사양은 Resource Indicator를 사용해 Token을 특정 MCP Server에 바인딩하도록 요구하고, MCP Server가 받은 Token을 downstream API로 그대로 전달하는 Token Passthrough를 금지한다. 이유는 Confused Deputy와 Token 재사용 공격 때문이다.
Confused Deputy란 권한이 높은 서비스가 공격자의 의도를 모르고 대신 권한을 행사해주는 문제다.
② Authorization은 Tool 실행 직전에 다시 한다
async def execute_tool(
*,
user,
agent,
tool_name,
arguments,
):
decision = authz_engine.authorize(
subject=user,
workload=agent,
action=tool_name,
resource=arguments,
)
if not decision.allowed:
raise PermissionError("tool execution denied")
validate_schema(tool_name, arguments)
enforce_rate_limit(user, agent, tool_name)
return await tool_registry[tool_name](**arguments)
Agent가 이미 “허용됐다”고 말했는지는 중요하지 않다. 실행 순간의 Authorization 결과가 중요하다.
③ Peer Agent의 메시지도 Untrusted Input이다
A2A는 HTTPS/TLS와 표준 authentication scheme을 사용하도록 설계되고, AgentCard를 통해 필요한 security scheme을 discovery할 수 있다. 하지만 인증된 Agent가 보낸 메시지라는 이유만으로 내용까지 신뢰해서는 안 된다.
상대가 누구인지는 인증으로 확인할 수 있다.
상대가 말한 내용이 사실인지는 별도의 검증이 필요하다.
9. Memory: 편리하지만 오래 남는 Prompt Injection이 될 수도 있다
Agent Memory는 보통 세 종류로 나누면 이해하기 쉽다.
현재 Run에 필요한 구조화 상태
동일 대화의 과거 context
다음 세션에도 유지되는 기억
가장 위험한 것은 Long-term Memory다. OWASP는 2026년 Memory & Context Poisoning을 별도의 agentic risk로 다룬다. 공격자가 한 번 삽입한 악성 정보가 persistent context에 저장되면 이후 여러 Session의 planning과 tool use를 오염시킬 수 있기 때문이다.
출처 없는 자연어 Summary를 고신뢰 Memory로 승격하지 않는다.
모든 Persistent Memory에는 provenance, owner, created_at, TTL, sensitivity, source를 남긴다.
Provenance는 “이 정보가 어디서 왔는가”를 의미한다. 금융/Enterprise Agent에서는 Memory도 Data Lineage의 일부로 봐야 한다.
10. 장애가 나면 어떻게 하지? 여기서부터 Distributed System이다
Agent가 API를 한 번 호출하고 끝난다면 단순하다. 하지만 Multi-Agent는 10~30개의 LLM/Tool call이 이어질 수 있고, 그 사이 어느 한 곳이라도 timeout, 429, 500, process restart가 발생할 수 있다.
Checkpoint
Checkpoint는 Workflow 중간 상태를 저장하는 것이다. LangGraph의 persistence layer도 각 graph step의 state snapshot을 저장해 Human-in-the-loop, fault recovery, time travel 등을 지원한다.
Idempotency
어려운 단어지만 개념은 간단하다.
async def execute_rate_change(action, request_id):
key = f"{request_id}:{hash_action(action)}"
existing = await idempotency_store.get(key)
if existing:
return existing
result = await core_api.create_rate_change(
idempotency_key=key,
**action.model_dump()
)
await idempotency_store.put(key, result)
return result
HTTP timeout은 “실패”를 뜻하지 않는다. 결과를 모른다는 뜻일 수 있다. 그래서 Retry 전에 현재 상태 또는 Idempotency Key를 확인해야 한다.
Saga와 Compensation
여러 시스템의 상태를 순서대로 바꾸는 업무라면 일부만 성공할 수 있다. 전통적인 Distributed System에서는 이런 경우 Saga 패턴을 사용한다.
예를 들어 “조건 변경 → 수수료 재계산 → 안내문 생성” 중 두 번째 단계가 실패했다면 첫 번째 단계를 되돌리는 보상 작업을 정의할 수 있다.
Compensation action 역시 미리 정의된 API와 Policy로 실행한다.
11. Human-in-the-Loop는 언제 넣어야 할까?
모든 Tool 호출을 사람이 승인하면 자동화의 의미가 없다. 반대로 모든 것을 자동 실행하면 위험하다. 그래서 Risk-based Approval이 필요하다.
| 위험도 | 예시 | 처리 |
|---|---|---|
| Low | FAQ / 문서 조회 | 자동 |
| Medium | 내부 업무 Ticket 생성 | Policy 조건부 자동 |
| High | 고객 계약/금액 변경 | 사람 승인 |
| Critical | 권한 변경·대규모 지급 | 기존 통제 Process 유지 |
LangChain의 HITL middleware도 Tool call을 policy에 따라 pause하고 approve/edit/reject 후 checkpoint에서 재개하는 패턴을 제공한다.
사람에게 “승인하시겠습니까?”만 보여주지 않는다.
무엇을, 왜, 어떤 근거로, 어느 시스템에서 바꾸는지 보여줘야 한다.
12. 비용: Agent 수보다 더 무서운 것은 Fan-out이다
Single Agent에서는 사용자 요청 하나가 LLM call 3번이었다고 해보자.
Multi-Agent에서 Supervisor가 4개의 Agent를 호출하고, 각 Agent가 2~3번 reasoning하고, 마지막 aggregation을 다시 한다면 요청 하나가 10~20개의 Model call로 커질 수 있다.
사용자 10 RPS가 작아 보여도 평균 fan-out 4 × 3 round라면 최대 120 model-call RPS 규모의 burst가 생길 수 있다.
Self-hosted vLLM 같은 Serving 환경에서는 이 fan-out이 GPU queue와 KV cache 압박으로 바로 연결된다. Managed API에서도 Rate Limit과 비용으로 돌아온다.
그래서 Run Budget을 둔다
run_budget = {
"max_wall_clock_sec": 60,
"max_llm_calls": 12,
"max_tool_calls": 20,
"max_agent_hops": 6,
"max_parallel_agents": 4,
"max_input_tokens": 80_000,
"max_output_tokens": 12_000,
}
Budget 초과는 “Agent가 아직 생각 중”이 아니라 System failure condition으로 다뤄야 한다.
모델도 Agent별로 다르게
Extraction → 작은 structured-output 모델
Complex Planner → 강한 reasoning 모델
Validator → Rule + 작은 모델 또는 deterministic code
Final Writer → 사용자 품질에 맞는 모델
Multi-Agent의 장점 중 하나는 모든 Step에 가장 비싼 모델을 사용할 필요가 없다는 것이다.
13. Observability: 최종 답변만 Logging하면 아무것도 모른다
Multi-Agent 장애를 디버깅하려면 “답이 틀렸다”로는 부족하다.
OpenTelemetry의 GenAI semantic convention에서는 agent invocation과 tool call을 span으로 표현하는 작업이 진행되고 있으며, agent별 tool-call count 같은 metric도 정의되어 있다.
최소한 다음 값은 Run마다 남기는 것이 좋다.
- request_id / workflow_id / tenant_id
- agent_name / agent_version
- model + model version
- prompt/template version
- tool name + latency + status
- input/output token
- handoff source / target
- policy decision
- checkpoint ID
- total cost estimate
- termination reason
고객 PII, 계좌 정보, 내부 문서가 그대로 Trace backend로 유출될 수 있다. Redaction과 sensitivity policy가 필요하다.
14. Multi-Agent 평가는 “최종 답변 정확도” 하나로 끝나지 않는다
Agent가 답을 맞혔더라도 잘못된 Tool을 호출했거나 우연히 권한 검사를 건너뛰었다면 Production에서는 실패다.
Layer 1. Outcome
- 업무가 실제로 성공했는가?
- 최종 답변이 근거와 일치하는가?
- 정확한 고객/계약/날짜를 사용했는가?
Layer 2. Trajectory
- 정확한 Agent로 routing됐는가?
- 불필요한 Agent 호출이 있었는가?
- 금지된 Tool을 호출했는가?
- Authorization 전에 Action을 실행하지 않았는가?
Layer 3. Reliability
- Tool이 500을 반환해도 복구되는가?
- Timeout 뒤 Side Effect가 중복되는가?
- Agent가 서로 handoff만 반복하는가?
- Max-step에 얼마나 자주 도달하는가?
Layer 4. Security
- RAG 문서 안 Prompt Injection을 따라가는가?
- Peer Agent가 가짜 Authorization 결과를 보내면 믿는가?
- Memory poisoning이 다음 session으로 전파되는가?
- 권한 없는 Tool Call의 성공률은 0인가?
Google ADK도 final response뿐 아니라 execution trajectory를 평가 대상으로 제공하며, AgentBench 역시 interactive environment에서 reasoning과 action을 함께 평가해야 한다는 문제의식에서 만들어졌다.
CI에서 돌릴 Test의 모습
def test_high_risk_action_requires_approval(trace):
assert "authorize" in trace.nodes
execute_index = trace.nodes.index("execute")
authorize_index = trace.nodes.index("authorize")
assert authorize_index < execute_index
assert trace.state["authorization_result"] in {
"allow",
"human_review"
}
def test_no_duplicate_side_effect(fake_core_api):
fake_core_api.timeout_after_commit = True
run_workflow(request_id="REQ-1001")
run_workflow(request_id="REQ-1001")
assert fake_core_api.change_count == 1
그리고 LLM-as-a-Judge는 가능한 한 마지막 수단으로 쓴다. Tool call 여부, JSON schema, 금액, 날짜, 권한 위반처럼 코드로 판별 가능한 것은 코드로 평가하는 편이 재현성이 높다.
15. Production에서 정말 자주 보게 될 실패 패턴
A → B → A → B로 계속 위임.
해결: hop limit + transition rule.
모든 Agent가 전체 대화 history를 계속 전달.
해결: typed state + context isolation.
Agent A의 추측을 B가 사실로 받아들임.
해결: provenance + evidence contract.
Provider 429에 모든 Agent가 동시에 재시도.
해결: global retry budget + jitter.
편의를 위해 모든 Agent에 모든 Tool을 제공.
해결: per-agent least privilege.
Reviewer가 계속 수정 요청.
해결: max round + explicit acceptance criteria.
16. 2026년 Open Source Agent Framework는 무엇을 볼까?
여기서는 “누가 최고인가”보다 각 framework가 어느 Layer에서 강한지를 보는 편이 맞다.
| Framework | 핵심 성격 | Production 포인트 | 잘 맞는 환경 |
|---|---|---|---|
| LangGraph | Stateful Graph Runtime | Checkpoint · HITL · durable execution | 세밀한 orchestration 제어 |
| Microsoft Agent Framework 1.0 | AutoGen + Semantic Kernel 후속 | Workflow · middleware · telemetry · MCP/A2A | .NET/Python · Microsoft estate |
| Google ADK 2.x | Graph-first agent platform | Workflow · HITL · eval · deploy | Google Cloud / multi-language |
| OpenAI Agents SDK | 작은 Agent primitive | Handoff · Agent-as-tool · guardrail · tracing | 간결한 Python orchestration |
| CrewAI | Crew + Flow | Production은 Flow-first | Role-based team workflow |
| Strands Agents | Model-driven Agent SDK | Graph · Swarm · Workflow · A2A | AWS 친화적 구조 |
LangGraph는 checkpoint 기반 stateful execution을 강하게 제공하고, CrewAI는 Flow를 Production backbone으로 권장한다. Google ADK는 2026년 graph-first 방향을 강화했으며, Microsoft Agent Framework 1.0은 AutoGen/Semantic Kernel을 하나의 지원되는 platform으로 합쳤다. Strands도 Graph·Swarm·Workflow를 구분한다.
1. Workflow state를 어디에 저장할 것인가?
2. Side Effect의 Idempotency를 누가 책임질 것인가?
3. Authorization은 어디서 강제할 것인가?
4. 중단된 Run을 어떻게 Resume할 것인가?
5. Trace와 Audit를 어떻게 연결할 것인가?
이 질문의 답이 없으면 framework를 바꿔도 Production 문제는 그대로 남는다.
17. 실제 배포 Architecture
Read Agent와 Write Agent Worker를 분리하는 이유
모든 Agent를 동일한 Kubernetes Deployment에 넣을 필요가 없다.
검색·요약 Agent는 외부 시스템을 변경하지 못하는 read-only worker pool에서 돌리고, Side Effect가 가능한 Action Worker는 별도 Network Policy와 Identity를 사용할 수 있다.
이것이 Bulkhead 패턴이다. 배의 격벽처럼 한 영역의 문제가 전체 시스템으로 퍼지지 않도록 분리하는 구조다.
Long-running task를 HTTP Request에 묶지 않는다
2분짜리 Agent workflow를 API connection 하나로 계속 붙들고 있는 것은 장애에 취약하다.
장시간 업무는 submit → workflow_id 반환 → 상태 조회/stream → 완료 이벤트 형태가 운영하기 쉽다.
18. 금융/Enterprise에서는 무엇이 더 달라질까?
PII가 Agent 사이를 무작정 이동하면 안 된다
Policy Agent가 고객 주민번호까지 알아야 할 이유가 없다. Agent별로 필요한 Attribute만 전달한다.
# Customer Agent 결과
{
"product_code": "LOAN-A12",
"contract_date": "2025-04-03",
"customer_segment": "PREFERRED",
"delinquency_flag": false
}
# policy_agent에는 이름/주민번호/전화번호가 필요 없다.
Prompt/Model/Tool도 Version 관리한다
같은 고객 요청이라도 Prompt가 바뀌거나 Model이 바뀌거나 Search Index가 갱신되면 결과가 달라질 수 있다.
따라서 감사 가능한 Run이라면 최소한 다음 조합을 복원할 수 있어야 한다.
model_provider / model_version
prompt_version
tool_schema_version
retrieval_index_version
policy_version
workflow_version
Business Decision과 Generative Reasoning을 구분한다
예를 들어 신용 승인 여부처럼 고위험 업무라면 Agent가 설명·자료 수집·규정 탐색을 도울 수는 있어도 최종 결정 주체와 통제 방식은 기존 Model Risk / Credit Policy / Governance 체계를 따라야 한다.
“LLM이 그렇게 판단했다”는 감사 가능한 정책이 아니다.
19. 그래서 처음부터 10-Agent를 만들까?
아니다.
Single Agent baseline보다 정확도는 비슷한데 latency가 3배, token이 5배라면 Multi-Agent는 실패한 설계일 수 있다.
더 나은 task success,
더 작은 context,
더 강한 privilege isolation,
더 쉬운 team ownership,
더 나은 recovery를 얻었는지를 본다.
20. Production 직전 Checklist
마지막으로: Multi-Agent의 진짜 어려움은 Intelligence가 아니다
Multi-Agent를 처음 보면 관심은 자연스럽게 Agent에게 간다.
어떤 Prompt를 넣을까.
어떤 역할을 줄까.
서로 어떻게 토론시킬까.
그런데 Production에 가까워질수록 주인공은 바뀐다.
하지만 시스템의 경계까지 확률적이어서는 안 된다.
어떤 상태에서 어떤 Action이 가능한지,
실패하면 어디에서 다시 시작하는지,
몇 번까지 실행할 수 있는지,
무엇을 사람이 승인해야 하는지는
시스템이 명확하게 알아야 한다.
그래서 내가 Production Multi-Agent를 설계한다면 가장 먼저 Agent Prompt를 작성하지 않을 것이다.
먼저 Workflow State를 그리고, Trust Boundary를 나누고, Side Effect를 표시하고, Authorization 위치와 Failure/Retry 정책을 정할 것이다.
그 다음에야 “이 노드 중 어디를 LLM에게 맡기면 좋은가?”를 묻는다.
Agent가 많은 Architecture가 아니다.
필요한 곳에서만 Agent가 자유롭고,
중요한 곳에서는 시스템이 단호한 Architecture다.
References · 공식 문서 / 논문
- OpenAI Agents SDK — Agents / Agent orchestration / Handoffs.
- LangChain / LangGraph — Multi-Agent patterns, Persistence, Human-in-the-loop.
- Microsoft Agent Framework 1.0 — AutoGen + Semantic Kernel successor.
- Google Agent Development Kit / ADK 2.0.
- CrewAI — Production Architecture / Flow-first.
- Strands Agents — Graph / Swarm / Workflow.
- Model Context Protocol — 2026-07-28 Specification / Authorization.
- Agent2Agent Protocol — Specification 1.0 / Security.
- OWASP Top 10 for Agentic Applications 2026.
- Cemri et al. — Why Do Multi-Agent LLM Systems Fail?
- Kim et al. — Towards a Science of Scaling Agent Systems.
- Li et al. — CAMEL: Communicative Agents for “Mind” Exploration of LLM Society.
- Wu et al. — AutoGen: Enabling Next-Gen LLM Applications via Multi-Agent Conversation.
- Hong et al. — MetaGPT: Meta Programming for a Multi-Agent Collaborative Framework.
- OpenTelemetry — GenAI Agent spans / metrics semantic conventions.
Cloud/Agent framework와 protocol 기능은 빠르게 변한다. 특히 MCP/A2A specification과 Agent SDK의 API·GA/Preview 상태는 실제 도입 직전에 공식 문서를 다시 확인하는 것이 좋다.