거버넌스 시즌: MCP 및 다중 에이전트 메모리 오픈 소스 회고
요약
본 글은 다중 에이전트 시스템에서 발생하는 '거버넌스 시즌'의 위험성을 경고합니다. MCP 기반 에이전트 스택과 공유 장기 메모리 등 오픈 소스 인프라가 검증되지 않은 상태로 작동하며 사고 발생 지점이 될 수 있음을 지적합니다. 핵심은 모델 품질보다 경계(boundary)와 출처(provenance) 관리의 중요성입니다.
핵심 포인트
- 에이전트 시스템의 실패는 모델 자체보다는 '경계면'에서 주로 발생한다.
- 출처가 기록되지 않은 도구 출력이나 메모리 공유는 심각한 위험을 초래할 수 있다.
- 단순히 움직임(PR, 릴리스)을 측정하는 것이 아니라, 통제(Control)를 로그로 확인해야 한다.
- MCP 서버에는 기능과 권한에 대한 명확한 서명된 파일이 필수적이다.
저는 그 줄을 항상 고정해 둡니다. 그것에서 비상사태처럼 보이는 것은 아무것도 없습니다. 이 작업은 몇 달 동안 6시간마다 실행되었습니다. rsync가 개발 박스(dev box)에서 워킹 트리로 모듈들을 가져왔고, --delete 옵션이 활성화되어 있었으며, 제외 목록(exclusion list)이 어떤 것이 통과할지 결정했습니다. 그러다 누군가가 그 제외 목록을 재구축했고, 몇 개의 항목이 편집 과정에서 빠졌습니다. 망가진 것이 아니라 아예 없었습니다. rsync는 경로가 목록에 없는 이유를 묻지 않습니다. 제외되지 않았고 소스(source)로부터 도착하지 않은 대상(target)에 있는 모든 것은 제거되었습니다. 한 번의 실행으로 70여 개의 사설 모듈이 사라졌습니다.
그것들을 되찾는 작업은 수작업이었습니다. 복사본을 추적하고, 트리 간 차이점(diffing trees)을 비교하며, 파일들을 제자리에 다시 밀어 넣어야 했습니다. 아무도 지지 기반이라고 생각하지 않았던 워킹 디렉토리 주변에 사람들이 모여 2시간가량의 시간이 걸렸습니다. 그 작업을 둘러싼 가드레일(guardrails) 재구축은 복구 작업보다 훨씬 오래 걸렸고, 여러 개의 변경 사항을 거쳐 조각조각으로 이루어졌으며, 어느 것도 처음부터 제대로 된 것은 없었습니다.
제가 에이전트 스택(agent stacks)을 읽는 방식에 실제로 변화를 준 것은 이것이었습니다. 실패의 모든 부분이 올바르게 작동하고 있었다는 것입니다. rsync는 rsync가 하는 일을 정확히 했습니다. 목록은 내부적으로 일관성이 있었습니다. 소스 트리는 건드리지 않았습니다. 경로상에 고장 난 노드는 아무데도 없었습니다. 오직 아무도 끝까지 검증하지 않은 세상의 그림(picture of the world)을 기반으로 행동하는 여러 개의 노드 세트가 있었고, 삭제는 그 불일치가 눈에 보이게 된 첫 순간이었습니다.
이것은 제가 MCP 기반 다중 에이전트 시스템에서 계속 발견하는 형태이며, 이것이 바로 누군가 원하든 아니든 오픈 소스 에이전트 인프라가 거버넌스 시즌에 있는 이유입니다. 범위가 지정되지 않은(Unscoped) MCP 서버와 공유 장기 메모리는 조용히 사고 발생 지점(incident surfaces)으로 변모했습니다. 출처를 밝힐 것이 아무것도 없이 메모리에 기록된 단 하나의 오염된 도구 응답은, 모든 다운스트림 에이전트가 선의로 따르게 될 믿음이 됩니다. 체인의 어떤 에이전트도 잘못하는 것은 없습니다. 그것이 문제입니다.
파손(breakage)은 항상 경계면에서 발생한다
제가 이번 분기에 검토한 거의 모든 사고는 모델 품질보다는 경계(boundary)와 관련되어 있었습니다:
- 아무도 범위를 지정하지 않은 도구를 배포하는 MCP 서버들, 여기에는 환경 비밀 정보에 접근할 수 있는 몇 가지 도구도 포함됩니다.
- 출처(provenance)가 기록되지 않은 도구 출력을 장기 메모리에 직접 쓰는 에이전트들.
- 플래너(Planner)와 실행기(executor) 에이전트들이 동일한 잘못된 검색 결과를 주고받다가, 반복되는 것이 마치 합의처럼 보이게 만드는 경우.
- 릴리스 이후 포크되어 두 개의 네임스페이스를 남기는 메모리 스키마들. 이 두 네임스페이스는 각각 권위 있어 보이지만 서로 조율되지 않습니다.
만약 귀하의 회고가 머지된 PR(Pull Request) 수나 릴리스 횟수를 세는 것이라면, 당신은 움직임을 측정하는 것입니다. 통제(Control)는 다른 숫자이며, 로그에 존재합니다.
이 도구에 누가 서명하는가
우리가 가장 먼저 시도한 것은 문서화였습니다. 모든 MCP 서버는 README에 해당 도구가 무엇을 하는지, 그리고 무엇을 건드릴 수 있는지 설명하는 단락을 추가했습니다. 하지만 아무도 그것들을 읽지 않았고, 설명서에는 읽기만 한다고 되어 있던 두 개의 도구가 파일 시스템으로 쓰기 경로를 가지고 있었습니다. 단락은 경계가 아닙니다.
무엇으로 대체되었는가: 모든 서버는 서명된 기능 파일(capability file)을 전송합니다. 이 파일에는 도구 이름, 입력 및 출력 스키마, 주장하는 범위(scope), 그리고 소유자 키가 포함됩니다. 빌드 파이프라인은 서명되지 않은 파일을 아예 거부하며, 소유자가 지정되지 않은 fs.write 또는 net.egress를 요청하는 도구는 모두 거부합니다. 이 서명 단계에서 '소유권'은 단순한 분위기(vibe)가 아닙니다. 만약 아무도 도구에 키를 붙이려 하지 않는다면, 당신은 스키마보다 더 유용한 것을 배운 것입니다.
그 비용은 현실적입니다. 새로운 서버를 온보딩하는 데 걸리는 시간이 몇 분에서 몇 시간으로 늘어났고, 자동 업데이트가 작동하지 않습니다. 버전 번호만 올라도 무언가를 전송하기 전에 사람이 다시 서명해야 합니다. 프로덕션 스웜(production swarm)의 경우, 저는 그 비용을 지불할 용의가 있습니다. 새벽 3시에 전화할 수 있는 이름이 필요하고, 그것은 저장소(repository)가 아닌 사람이어야 합니다.
되찾을 수 있는 메모리
공유 장기 메모리에 쓰이는 모든 기록에는 이제 agent_id, tool_call_id, source_hash, timestamp, 그리고 신뢰도 값(confidence value)이 포함됩니다. 휘발성 메모리는 스스로 만료되며 아무도 걱정하지 않습니다. 장기적인 쓰기는 제안-커밋(propose-then-commit) 방식입니다. 두 번째 에이전트가 소스 해시를 재계산하고, 그 후에야 기록이 저장됩니다.
저희의 첫 버전은 순수한 로깅이었습니다. 저희는 모든 것을 아름답게 기록했지만, 그것을 활용할 방법이 없었습니다. 나중에 오염된 응답(poisoned response)이 나타났을 때, 복구 계획은 여전히 '네임스페이스를 정리하고 처음부터 다시 구축'하는 것이었으며, 이는 그 안에 무엇이 들어있는지 모른다는 인정이나 다름없습니다.
이제 해시가 인덱스입니다. source_hash로 롤백하여 하나의 도구 호출에 연결되는 기록만 가져오고 나머지는 그대로 둘 수 있습니다. 장기 쓰기가 발생할 때마다 추가적인 왕복(round trip) 비용이 들며, 이전에 '마지막으로 작성한 것이 승리한다(last-write-wins)'는 방식으로 무마되던 충돌들이 이제 표면화되어 논쟁을 통해 해결해야 합니다. 당신이 구매하는 것은 저장소를 불태우는 대신 믿음(belief)을 외과적으로 제거할 수 있는 능력입니다.
두 에이전트가 의견이 다를 때
상충되는 주장들은 작은 위원회로 회부됩니다. 여기에는 유지 관리자 자리 하나와 서로 다른 역할을 가진 두 에이전트가 참여합니다. 이 위원회는 단일 기록을 생성하며, 반대 의견은 그 안에 남게 됩니다.
첫 시도는 가장 큰 모델이 중재하는 것이었습니다. 이 모델은 가장 긴 정당성을 작성한 편을 들었는데, 이는 가장 목소리가 큰 사람을 찾아내는 매우 비싼 방식입니다. 배운 교훈은 패배한 주장을 보이게 유지하는 것이라는 점이었는데, 보통 초기 경고가 그곳에 놓여있기 때문입니다.
결정 과정이 느려졌습니다. 누군가가 의자에 앉아 의견 불일치를 읽어줘야 했지, 스스로 해결되도록 내버려 둘 수 없었습니다. 이 의자가 바로 메커니즘입니다. 이것이 없다면, 가장 자신감 있는 에이전트가 그룹을 덮어쓰고 그룹은 결코 알아차리지 못합니다.
이는 달력에 존재한다
오픈 소스에서의 거버넌스는 문서가 아니라 일정(schedule)입니다. 분기별로 네 가지 아티팩트를 갖춰야 합니다:
- 소유자 및 모든 항목에 대한 롤백 경로가 첨부된 인시던트 원장(incident ledger).
- 메모리 스키마 변경을 위한 RFC(Request for Comments)와 72시간의 댓글 기간 — 스키마를 작성한 사람에게도 예외는 없습니다.
- MCP 레지스트리의 키를 보유하는 사람이 순환하도록 하여, 단일 유지 관리자가 영구적인 '예'가 되는 것을 막습니다.
- 네임스페이스 경계를 넘은 모든 메모리 오염(memory poisoning)에 대한 공개 사후 분석 보고서(public postmortem).
우리는 처음에 이의 소프트 버전을 시도했습니다. 서명을 장려하고, 경고만 주는 방식이었습니다. 한 릴리스 주기가 지난 후, 모두가 경고를 무시하는 법을 배웠습니다. 엄격한 버전은 지금까지 유지되고 있으며, 솔직히 말하자면 아직 실제 위기를 겪어보지 못했기 때문에 — 속도 비용(velocity cost)은 오늘날 명확하지만, 보호는 그렇지 않을 때까지 이론적입니다.
그 로그 라인으로 돌아가서
동기화 인시던트에서 나온 수정 사항은 제외 목록과는 아무 관련이 없었습니다. 이제 모든 실행은 먼저 건식 통과(dry pass)를 수행합니다: 동일한 rsync 호출에 --dry-run 플래그, 동일한 경로를 사용합니다. 미리보기가 대상에 존재하는 파일을 삭제하는 것을 보여주면, 실행은 멈추고 작업은 차단된 것으로 표시됩니다. 인간이 무언가가 사라지기 전에 이를 확인합니다. 이것이 전체 메커니즘입니다. 제외 목록을 올바르게 만드는 것이 아닙니다. 잘못된 제외 목록을 여전히 복구 가능한 상태일 때 크게 알리는 것입니다.
분기별 패스를 항상 같은 방식으로 실행하세요. 어떤 내용이 공유 장기 메모리에 기록되기 전에, 건식 실행(dry run)을 수행해야 합니다. 무엇이 기록될지, 그것이 어떤 도구 호출(tool call)으로 추적되는지, 그리고 그 도구가 손상되었다고 가정했을 때 수동으로 제거할 항목들이 무엇인지 확인하는 것입니다. 제가 강조하고 싶은 부분은 바로 이 지점이며, 저는 이전에도 이러한 것들의 타이밍에 대해 잘못 알고 있었습니다. 에이전트 스택(agent stack)에서 소유자(owner)를 갖거나 그렇지 않은 두 가지 영역이 바로 도구 계층(tool layer)과 메모리 계층(memory layer)이며, 나머지 모든 것은 이들 이후의 하위 시스템입니다.
'누가 이 메모리를 작성했는지, 어떤 도구를 통해 작성했는지, 그리고 어떻게 되돌릴 수 있는지'를 grep 할 수 있는 로그에서 답할 수 없다면, 당신은 거버넌스(governance)를 하는 것이 아닙니다. 그저 희망하는 것일 뿐입니다. MCP 도구들은 서명된 기능(signed capabilities)입니다. 다중 에이전트 메모리는 명시적인 소유자가 있는 자산입니다. rsync --delete는 적어도 무엇을 삭제할지 알려주지만, 당신의 에이전트 스택은 그렇지 않습니다. 만약 그것이 말하도록 만드는 시스템을 구축하지 않는 한 말이죠.
#maref #ai #opensource #machinelearning
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기