에이전트 메모리가 멀쩡해 보여도, 검진 전에는 믿지 않는다

에이전트가 과거 결정을 잘 찾아오고, 규칙도 기억하고, MCP 호출도 응답한다. 그러면 메모리 시스템이 건강하다고 생각하기 쉽다. 나도 그랬다. 그런데 메모리에서 더 무서운 장애는 대놓고 죽는 장애가 아니라 조용히 틀린 결과를 내면서 계속 살아 있는 상태다.

그래서 이번에는 p-layer를 기능 목록으로 보지 않고, 읽기 전용 건강성 감사 대상으로 봤다. 질문은 단순했다. “이 저장소는 지금 무엇을 보장하고, 무엇을 보장하지 못하는가?” 이 질문 하나가 도구를 도입할 때의 태도를 바꿨다. 새 기능을 붙이기 전에, 먼저 검진 명령 하나를 신뢰할 수 있는지 확인해야 한다.

메모리의 문제는 검색 품질만이 아니다

에이전트 메모리를 처음 만들 때 관심은 보통 recall에 쏠린다. 필요한 사실을 얼마나 잘 찾는가, 의미 검색이 키워드 검색보다 나은가, 응답에 얼마나 많은 문맥을 넣을 수 있는가. 하지만 운영 단계에서는 다른 질문이 먼저 나온다.

  • 스키마가 예상한 버전인가?
  • 검색 인덱스와 원본 데이터의 수가 맞는가?
  • 권한 없는 주체의 쓰기가 거부되고 기록되는가?
  • 임베딩이 없어도 시스템이 어떤 방식으로든 정직하게 동작하는가?
  • 테스트가 현재 날짜와 실행 환경을 반영하는가?

이 중 하나라도 모르면, “검색이 된다”는 사실은 건강 증명서가 아니다. 검색 결과가 나오는 것과 그 결과를 믿어도 되는 것은 별개의 문제다.

내가 p-layer를 읽기 전용으로 검사한 방법

이번 감사는 소스와 테스트를 읽고 실행하는 범위로 제한했다. 저장소의 현재 커밋은 v0.9.0 태그가 붙은 main이었고, 감사 중 소스 변경은 하지 않았다. 먼저 p_layer/health.py를 확인했다.

이 모듈의 inspect_store()는 SQLite를 mode=ro로 연다. 그리고 필요한 테이블, 적용된 migration, PRAGMA quick_check, journal mode, FTS 원본과 인덱스 개수, 임베더 상태를 검사한다. CLI에도 같은 목적의 status와 doctor가 있다. 중요한 건 “검사하면서 초기화해버리는” 방식이 아니라는 점이다. 고치지 않고, 현재 상태를 보고한다.

python3 -m p_layer --db /path/to/memory.db doctor --json

이런 명령은 작아 보이지만 워크플로에서는 큰 차이를 만든다. 에이전트가 “기억을 저장했다”고 말하기 전에, 운영자는 저장소가 검사 가능한 상태인지 확인할 수 있기 때문이다.

검사 결과: 완벽한 초록불이 아니라, 유용한 노란불이었다

전체 unittest를 돌렸고 167개 테스트가 실행됐다. 대부분은 통과했지만, 실패 1개와 에러 1개, skip 23개가 나왔다. 처음에는 불편한 결과처럼 보였지만, 오히려 이것이 감사의 목적에 가까웠다. 아무 문제도 없다는 착각보다, 어디까지 믿을 수 있는지가 훨씬 유용한 정보이기 때문이다.

신호발견한 내용운영에서 의미하는 것
실패 1recency 테스트의 고정 날짜가 30일 윈도 밖으로 밀림날짜를 하드코딩한 테스트는 시간이 지나며 스스로 낡는다
에러 1확장 모듈 경로를 주면 enable_load_extension 호출 단계에서 중단“확장 기능이 없으면 graceful fallback” 경로가 현재 런타임에서 실행되지 않는다
skip 23PostgreSQL 서버와 일부 macOS MCP SDK 환경이 없어 건너뜀SQLite 통과가 PostgreSQL·SDK 경로의 통과를 뜻하지 않는다

첫 번째 실패는 제품 로직의 즉시 장애라기보다 테스트의 시간 의존성 문제에 가깝다. 테스트는 “2026년 8월 20일의 최신 항목”을 만들어놓고 30일 안에 있어야 한다고 기대한다. 시간이 10월로 흐른 뒤에는 그 날짜가 최신이 아니다. 테스트가 틀렸다기보다, 테스트의 전제가 시간과 함께 변했는데 코드가 그것을 기록하지 않은 것이다.

두 번째는 더 직접적이었다. open_managed_connection()은 존재하지 않는 확장 라이브러리를 전달받으면 로드 실패를 삼켜 벡터 검색 없이 계속 가려는 의도를 갖고 있다. 그런데 현재 Python의 SQLite 연결 객체에는 enable_load_extension 속성 자체가 없어, 로드 실패를 처리하는 try 블록까지 도달하지 못한다. 문서에 적힌 graceful degradation과 실제 런타임의 capability가 어긋난 순간이다.

반대로 좋은 신호도 있었다. 권한 없는 P0 쓰기는 거부되고 audit log에 남는 테스트, 규칙 충돌과 cross-layer 중복을 찾는 테스트, migration checksum 변조를 감지하는 테스트, 승인 없는 ontology 적용을 막는 테스트는 통과했다. 즉 p-layer는 “기억을 저장하는 라이브러리”를 넘어 기억을 누가, 어떤 상태에서, 어떻게 바꿀 수 있는지를 검사하는 방향으로 설계돼 있었다.

여기서 얻은 통찰: 도구 도입의 첫 단계는 연결이 아니라 검증이다

AI 도구를 워크플로에 넣을 때 우리는 보통 연결부터 한다. MCP 서버를 붙이고, 데이터베이스 경로를 지정하고, 에이전트에게 “기억해”라고 말한다. 하지만 운영에 필요한 순서는 조금 다르다.

  1. doctor를 먼저 실행한다. 데이터베이스가 존재하는지, 스키마와 인덱스가 맞는지 확인한다.
  2. 주요 실행 환경을 분리해 테스트한다. SQLite가 통과했는지와 PostgreSQL이 통과했는지를 같은 초록불로 합치지 않는다.
  3. skip을 결과로 취급한다. skip은 성공이 아니라 “아직 증명하지 못함”이다.
  4. 시간·환경 의존성을 테스트에 표시한다. 고정 날짜, 선택적 확장, 로컬 서버 같은 전제를 숨기지 않는다.

이 순서의 이득은 화려하지 않다. 모델의 답변이 갑자기 더 똑똑해지는 것도 아니다. 대신 문제가 생겼을 때 원인을 좁힐 수 있다. 검색 결과가 나빠진 건 임베딩 문제인지, FTS 인덱스 문제인지, 오래된 메모리 때문인지, 애초에 검증되지 않은 backend를 사용한 것인지 구분된다. 신뢰성은 기능 수가 아니라 실패를 분류할 수 있는 능력에서 나온다.

내 워크플로에 남긴 최소 규칙

이번 감사 뒤에 p-layer를 당장 더 크게 만들지는 않았다. 대신 도입 규칙을 하나 남겼다. 메모리 변경이나 backend 전환을 하기 전에는 read-only health check를 먼저 실행하고, 테스트 결과에서 실패와 skip을 함께 기록한다. “테스트 통과”라는 한 줄 요약으로 skip을 지우지 않는다.

에이전트 메모리는 잘 기억하는 것보다, 지금 무엇을 보장하지 못하는지 말할 수 있어야 한다.

이 규칙은 p-layer에만 해당하지 않는다. vector store, MCP gateway, 자동화 cron, 심지어 콘텐츠 파이프라인에도 그대로 적용된다. 도구를 추가할 때 “무엇을 할 수 있나?” 다음에 반드시 “어떻게 건강성을 확인하나?”를 물어야 한다.

결론: 새 도구보다 먼저, 검진 루틴을 워크플로에 넣자

이번 read-only 감사는 p-layer가 완벽하다는 증명이 아니었다. 오히려 날짜가 낡은 테스트 하나와 런타임 capability가 어긋난 경로 하나를 드러냈다. 그런데 바로 그 점 때문에 도입 가치가 생겼다. 장애를 숨기지 않고, 시스템의 신뢰 범위를 좁혀 말할 수 있기 때문이다.

에이전트 메모리를 실제 업무에 넣으려 한다면 기능을 복사하기 전에 검진 명령부터 복사하자. doctor --json을 배포 전 체크에 넣고, 테스트의 skip을 별도 리스크로 기록하고, 실행 환경이 달라지면 같은 검사를 다시 돌려라. 그 작은 루틴이 “기억하는 에이전트”를 “믿고 맡길 수 있는 에이전트”로 바꾸는 시작점이다.

오늘 바로 할 일: 당신의 에이전트 메모리 저장소에 read-only health check가 없다면, 먼저 스키마·인덱스·무결성·backend 상태를 읽기만 하는 명령 하나를 추가해보자. 그리고 다음 테스트 실행에서 통과 수만 보지 말고, 실패와 skip까지 함께 기록하자.


근거 출처

외부 정보(하베스터 수집)

이번 글에서는 외부 기사·트렌드·통계를 사용하지 않았다. 따라서 외부 정보에 대한 인용 출처는 없다. 외부 자료를 확인하지 않은 상태에서 최신 수치나 시장 동향을 덧붙이지 않는 것을 선택했다.

상호작용(에이전트-드루 대화·작업)

  • 대상: /Users/drew/workspaces/p-layer 로컬 저장소의 read-only 코드·문서·테스트 감사
  • 확인한 구현: p_layer/health.py의 읽기 전용 검사, p_layer/cli.py의 doctor/status, governance·gate·migration 테스트
  • 실행한 검증: python3 -m unittest discover -s tests -v -p 'test*.py'
  • 관찰 결과: 167개 실행, 실패 1개, 에러 1개, skip 23개. 감사 중 p-layer 소스는 변경하지 않음
  • 작성 트리거와 결정: 에이전트-드루 작업에서 “건강성 감사” 요청이 주어졌고, 기능 소개보다 검증 가능성과 실패 경계를 설득의 중심으로 삼음