A2A · PATTERNS
실무 패턴 & 안티패턴
실무에서 검증된 A2A 설계 패턴과 흔히 빠지는 안티패턴을 정리합니다. 프로덕션 배포 전 체크리스트로 완성합니다.
핵심 설계 패턴
PATTERN 1
단일 책임 Agent
각 Agent는 하나의 명확한 역할만 담당합니다. Search Agent는 검색만, Code Agent는 코드 실행만. Skill 개수는 3개 이하로 제한합니다.
json단일 책임 Agent Card
{
"name": "PDF Parser Agent",
"description": "PDF 파일 파싱과 텍스트 추출 전문",
"skills": [
{"id": "parse-pdf", "name": "PDF 파싱"},
{"id": "extract-tables", "name": "표 추출"}
]
// ← Skill 2개: 명확하고 집중
}
PATTERN 2
멱등성 Task 설계
같은 Task를 여러 번 실행해도 같은 결과가 나오도록 설계합니다. Task ID를 幂等성 키로 활용해 재시도 시 중복 처리를 방지합니다.
python멱등성 처리
task_results: dict[str, dict] = {}
async def run_task(params: dict) -> dict:
task_id = params["id"]
# 이미 처리된 Task면 캐시 반환
if task_id in task_results:
return task_results[task_id]
result = await process(params)
task_results[task_id] = result
return result
PATTERN 3
Graceful Degradation
일부 Sub-Agent 실패 시 부분 결과로 응답합니다. 전체 실패보다 부분 성공이 사용자에게 더 유용합니다. Artifact에 오류 정보를 포함해 투명성을 유지합니다.
python부분 성공 응답
results = await asyncio.gather(
call_search(query),
call_analysis(query),
return_exceptions=True
)
artifacts = []
for i, r in enumerate(results):
if isinstance(r, Exception):
artifacts.append({
"name": f"agent-{i}-error",
"parts": [{"type": "text",
"text": f"[실패] {str(r)}"}]
})
else:
artifacts.append(r)
PATTERN 4
Progress Notification
장시간 작업에서 SSE 스트림으로 진행률을 보고합니다. 사용자가 연결이 끊겼는지, 작업 중인지 구분할 수 있어 UX가 개선됩니다.
python진행률 스트리밍
async def stream_with_progress(params, rpc_id):
steps = ["검색", "분석", "요약"]
for i, step in enumerate(steps, 1):
yield emit({...,
"result": {
"status": {
"state": "working",
"message": {"parts": [{
"type": "text",
"text": f"[{i}/{len(steps)}] {step} 중..."
}]}
},
"final": False
}
})
await do_step(step)
피해야 할 안티패턴
ANTI-PATTERN 1
모노리식 Orchestrator Agent
Orchestrator가 직접 검색, 코드 실행, 데이터 분석까지 모두 처리합니다. 확장성이 없고, 단일 장애점이 됩니다. Orchestrator는 위임과 통합만 담당해야 합니다.
ANTI-PATTERN 2
Task ID 미사용
매 요청마다 새 Task를 만들고 ID를 저장하지 않습니다. 재연결 시
tasks/resubscribe를 쓸 수 없고, 중복 처리 방지도 불가능합니다. 항상 클라이언트가 Task ID를 생성하고 관리하세요.ANTI-PATTERN 3
SSE 연결 무한 대기
tasks/sendSubscribe에 타임아웃 없이 연결합니다. 네트워크 오류 시 클라이언트가 무한 대기 상태에 빠집니다. 타임아웃을 설정하고 tasks/resubscribe로 재연결 로직을 구현하세요.ANTI-PATTERN 4
Agent Card 과잉 설계
모든 Agent에 10개 이상의 Skill을 등록하고, 각 Skill에 20개의 예시를 작성합니다. LLM이 오히려 혼란스러워집니다. Skill당 예시는 2~5개, Skill 총 개수는 5개 이하가 최적입니다.
Agent Card 품질 기준
| 항목 | 권장 | 피해야 할 것 |
|---|---|---|
| name | 역할을 즉시 알 수 있는 이름 "PDF Parser Agent" | 범용적인 이름 "Agent 1", "My Agent" |
| description | 입력-출력을 명시 "URL 또는 PDF를 받아 구조화된 텍스트로 추출" | 모호한 설명 "다양한 기능을 제공하는 에이전트" |
| skills.examples | 실제 사용 사례 2~5개 | 예시 없음 또는 20개 이상 |
| skills 개수 | 1~3개 | 10개 이상 |
| version | semver: 1.2.3 | 없음 또는 "latest" |
에러 코드 레퍼런스
| 코드 | 이름 | 원인 | 대처 |
|---|---|---|---|
| -32700 | Parse Error | 잘못된 JSON 형식 | 요청 페이로드 검증 |
| -32600 | Invalid Request | jsonrpc/method/id 필드 누락 | JSON-RPC 2.0 형식 확인 |
| -32601 | Method Not Found | 존재하지 않는 메서드 호출 | Agent Card의 capabilities 확인 |
| -32602 | Invalid Params | 파라미터 타입/구조 오류 | tasks/send params 스펙 확인 |
| -32000 | Task Not Found | 존재하지 않는 Task ID | tasks/send로 새 Task 생성 |
| -32001 | Task Not Cancelable | 이미 완료된 Task 취소 시도 | Task 상태 먼저 확인 |
| -32002 | Push Notification Not Supported | capabilities.pushNotifications=false인 Agent에 Webhook 등록 | Agent Card 확인 후 Polling으로 대체 |
| -32003 | Unsupported Operation | Agent가 지원하지 않는 작업 요청 | Skill 목록 및 inputModes 확인 |
프로덕션 배포 체크리스트
A2A 프로덕션 체크리스트
Agent Card
- name, url, version, description 모두 설정
- capabilities.streaming 실제 지원 여부와 일치
- authentication.schemes 정확히 명시
- 각 Skill에 examples 2개 이상 포함
- Cache-Control 헤더 설정 (max-age=3600 권장)
Task 처리
- tasks/send 및 tasks/sendSubscribe 둘 다 구현
- Task ID 저장 및 멱등성 처리 구현
- 모든 Task에 submitted → working → completed 전환 이벤트 발행
- input-required 상태 핸들링 구현 (멀티턴 필요 시)
- Task 상태 저장소에 TTL 설정 (메모리 누수 방지)
신뢰성
- 모든 A2A 호출에 타임아웃 설정 (tasks/send: 60s, sendSubscribe: 300s)
- 재시도 로직 구현 (지수 백오프, 최대 3회)
- Circuit Breaker로 연쇄 장애 방지
- asyncio.gather(return_exceptions=True)로 부분 실패 처리
- 레지스트리 헬스체크 주기 설정 (30초 권장)
관찰 가능성
- 각 Task에 고유 ID + 추적 가능한 로그 구조 적용
- Task 상태 전환마다 타임스탬프 기록
- Orchestrator → Sub-Agent 호출 지연 시간 메트릭 수집
- 실패 Task 비율 알림 설정 (임계값: 5% 이상)
보안
- 인증 없이 접근 가능한 Agent Card 경로만 공개 노출
- tasks/send 엔드포인트에 인증 미들웨어 적용
- Agent 간 통신에 mTLS 또는 내부 Bearer Token 사용
- Task 파라미터 크기 제한 설정 (기본 10MB)
- Agent Card의 url 필드를 서버 측에서 검증 (SSRF 방지)
🚀 A2A 트랙 완료
A2A 프로토콜 스펙부터 LangGraph 통합, 레지스트리 설계, 프로덕션 패턴까지 전 과정을 학습했습니다. 다음은 AI Agent 아키텍처 트랙에서 ReAct, Planning, Memory 등 핵심 설계 패턴을 심화 학습하세요.