온톨로지와 메모리 시스템 (2/13) — 멀티 에이전트 온톨로지 실전 구현

다수의 에이전트가 실제로 협업하는 구조를 만드는 법


핵심 요약

  • 에이전트 간 통신에는 가벼운 인사이트 전달과 확인이 필요한 작업 요청, 두 경로가 필요하다
  • 컨텍스트 격리(1 에이전트 = 1 역할 = 최소 컨텍스트)가 시스템 품질을 유지하는 열쇠
  • 글로벌 CLAUDE.md → 프로젝트 CLAUDE.md → 세션 메모리, 3계층 구조로 지식을 관리한다

배경

1편에서 온톨로지의 개념과 필요성을 다뤘습니다. 에이전트 간 관계를 정의하는 것이 왜 중요한지, CLAUDE.md와 메모리가 어떤 역할을 하는지.

이번 2편에서는 실제 구현을 다룹니다. 에이전트끼리 어떻게 데이터를 주고받는지, 왜 컨텍스트를 격리해야 하는지, 메모리를 어떻게 계층화하는지.


본문

1. 메시지 허브 — 에이전트 간 통신 설계

온톨로지에 관계를 정의했으면, 실제로 데이터가 오갈 통로가 필요합니다.

에이전트 간 통신은 두 가지로 나뉩니다. 성격이 완전히 다릅니다.

① 인사이트 전달 (fire-and-forget)

POST /api/webhooks
{"content": "...", "tags": ["분석"], "source": "에이전트명"}

"이런 발견이 있었다" 수준의 가벼운 알림입니다. 보내고 끝. 상대방이 받았는지, 처리했는지 확인하지 않습니다.

사용 예시: - 오픈클로 에이전트가 분석 인사이트를 대시보드에 전달 - 주식 에이전트가 시그널 변동을 로그로 기록

② 작업 요청 (ACK 필요)

POST /api/agent-messages
{
  "fromAgent": "홈서버 관리자",
  "toAgent": "글 작성 디렉터",
  "messageType": "task_request",
  "intent": "blog_material",
  "body": {"text": "이 소재로 블로그 글 작성해주세요"}
}

확인 응답(ACK)이 필요한 요청입니다. 재시도, 스레드 추적, 상태 관리가 됩니다.

수신 에이전트는 받은 메시지를 확인하고 응답합니다:

POST /api/agent-messages/{messageId}/ack
{"status": "acked", "response": {"text": "수신 완료, 작성 시작"}}

이 두 경로를 나누는 이유는 명확합니다. 모든 통신에 ACK를 요구하면 시스템이 느려지고, 모든 통신을 fire-and-forget으로 하면 중요한 작업이 빠집니다. 정보 알림은 가볍게, 작업 요청은 확실하게.

실제 사례: 홈서버 관리자가 글 작성 디렉터에게 블로그 소재를 task_request로 전달하면, 글 작성 디렉터가 ACK 후 작업을 시작합니다. 사람이 중계하지 않아도 에이전트끼리 일을 넘기는 구조입니다.


2. 컨텍스트 격리 — 왜 에이전트를 나누는가

"하나의 강력한 에이전트에 모든 역할을 넣으면 안 되나?"

실제로 해봤습니다. 안 됩니다. 이유는 세 가지입니다.

① 컨텍스트 오염

주식 분석 맥락과 Flutter UI 코드가 같은 대화에 있으면, AI가 맥락을 혼동합니다. "이 함수의 리턴값을 분석해줘"라고 했을 때, 주식 데이터 분석인지 코드 분석인지 모호해지는 상황이 실제로 발생합니다.

② CLAUDE.md 충돌

여러 프로젝트의 규칙을 하나의 CLAUDE.md에 넣으면, 지시가 서로 모순됩니다. "간결하게 써라" (콘텐츠)와 "모든 엣지케이스를 명시해라" (코드)가 공존할 수 없습니다.

③ 프롬프트 길이와 성능 저하

AI는 프롬프트가 길어질수록 앞부분 지침을 덜 따르는 경향이 있습니다. 필요 없는 맥락을 줄이는 것 자체가 성능 최적화입니다.

격리 원칙: - 1 에이전트 = 1 역할 = 최소 컨텍스트 - 서브 에이전트에게 작업을 넘길 때, 전체 세션 히스토리를 전달하지 않음 - 에이전트가 알아야 할 것만 전달하고, 나머지는 격리

이 원칙이 에이전트 수가 늘어나도 품질이 유지되는 비결입니다.


3. 메모리 3계층 구조

지식을 어디에, 어떤 수준으로 저장할지가 중요합니다. 3계층으로 나눠 관리합니다.

Layer 1: 글로벌 CLAUDE.md — 모든 에이전트가 아는 것

~/.claude/CLAUDE.md (심링크로 전 에이전트 공유)

여기에 들어가는 것: - 전체 에이전트 목록과 관계 (온톨로지) - 사용자의 판단 기준과 가치관 - 에이전트 간 통신 규약 - 크로스 프로젝트 규칙

모든 에이전트가 세션 시작 시 읽으므로, 여기 있는 정보는 시스템 전체에 공유됩니다.

Layer 2: 프로젝트 CLAUDE.md — 이 에이전트만 아는 것

{프로젝트 루트}/CLAUDE.md

여기에 들어가는 것: - 프로젝트 목적과 구조 - 해당 프로젝트만의 규칙과 워크플로우 - 스킬 트리거, 에이전트 역할 분리 - 기술 스택, API 설정

프로젝트 고유 지식이 다른 에이전트를 오염시키지 않도록 격리합니다.

Layer 3: 세션 메모리 — 대화에서 축적되는 것

{프로젝트}/.claude/projects/{id}/memory/

여기에 들어가는 것: - 사용자 피드백 ("이렇게 하지 마", "이건 좋았어") - 프로젝트 상태 변화 - 작업 중 학습한 패턴

세션을 넘어 유지되며, 해당 프로젝트의 에이전트가 점점 더 사용자에게 맞춰갑니다.

계층 간 흐름:

세션에서 반복되는 피드백
  → 프로젝트 CLAUDE.md에 규칙으로 승격
    → 여러 프로젝트에 공통이면 글로벌 CLAUDE.md로 승격

아래에서 위로 올라가는 구조입니다. 한 에이전트에서 검증된 원칙이 전체 시스템으로 퍼져나갑니다.


4. 온톨로지 관리 실전 팁

운영하면서 정리된 팁들입니다.

① 관계 테이블을 CLAUDE.md에 유지한다

## Relationships
- 오픈클로 → 홈서버: 인사이트 → 대시보드 표시 [data]
- 콰이어트 ↔ 성장 일지: Flutter 패턴 공유 [tech]
- 나의 삶 정리 → 글 작성 디렉터: 경험 → 콘텐츠 소재 [content]

태그([data], [tech], [content])로 관계 유형을 표시합니다. 한눈에 파악됩니다.

② 새 에이전트 추가 시 체크리스트

  • 온톨로지에 역할 추가
  • 기존 에이전트와의 관계 정의 (최소 1개)
  • 관계가 없으면 → 정말 필요한 에이전트인지 재검토
  • 글로벌 CLAUDE.md 업데이트

③ 주기적으로 관계를 검증한다

정의된 관계가 실제로 작동하고 있는지 확인합니다. 온톨로지에는 "A → B 데이터 전달"이라고 적혀있는데, 실제로는 한 번도 전달된 적 없다면 그 관계는 삭제하거나 구현해야 합니다.

④ 글로벌 CLAUDE.md는 간결하게 유지한다

온톨로지 정보, 사용자 성향, 통신 규약 정도만. 상세 구현은 프로젝트 CLAUDE.md에. AI가 매 세션 읽는 파일이므로, 짧을수록 잘 따릅니다.


주의사항 및 설계 고려사항

  • 메시지 허브 없이 시작해도 됩니다. 초기에는 사람이 중계해도 충분합니다. "이 에이전트 결과를 저 에이전트에 넣어줘" 하는 식으로. 빈도가 잦아지면 그때 자동화합니다.

  • 격리와 공유의 균형이 중요합니다. 너무 격리하면 에이전트가 섬이 되고, 너무 공유하면 컨텍스트가 오염됩니다. 공유는 글로벌 CLAUDE.md로, 격리는 프로젝트 CLAUDE.md로. 이 경계를 의식적으로 관리해야 합니다.

  • 온톨로지는 살아있는 문서입니다. 에이전트가 추가/삭제되고, 관계가 바뀌고, 역할이 변합니다. 한 번 만들고 끝이 아니라 계속 업데이트해야 합니다.

  • 에이전트 교체는 단계적으로. 안정적으로 운영 중인 에이전트를 교체할 때는 병행 운영(Strangler Fig 패턴)으로 검증 단계를 거쳐야 합니다. 새 에이전트가 토큰 폭주나 예상치 못한 동작을 보이면, 즉시 원래 에이전트로 회귀할 수 있는 구조가 필요합니다.


마무리

에이전트 하나는 도구입니다. 에이전트가 많아지고 온톨로지가 없으면 혼란입니다. 에이전트가 많아지고 온톨로지가 있으면 시스템입니다.

차이를 만드는 건 에이전트 수가 아니라, 관계 설계와 지식 계층화입니다. CLAUDE.md를 공유하고, 메시지 허브로 통신하고, 컨텍스트를 격리하고, 메모리를 계층화하면 — 에이전트가 늘어나도 품질이 유지되는 구조가 만들어집니다.

에이전트를 하나씩 늘려가고 있다면, 지금이 온톨로지를 정리할 타이밍입니다.

시리즈 전체 안내: 시리즈 목차

댓글

이 블로그의 인기 게시물

"LLM 핵심 학습 (1/6) — 기본: 토큰화·임베딩·어텐션·위치 인코딩"

"LLM 핵심 학습 (2/6) — 파인튜닝: LoRA·QLoRA·증류·Adapter"

"ML 기초 학습 (1/9) — 머신러닝과 sklearn: 학습의 좌표계"