작성일: 2026-07-15 (#03) 목적: "개발 채널에 외부 provider holographic 설정" 요청에서 출발해, 실제 컨테이너를 실측하며 holographic의 실동작·저장 타이밍·numpy 함정을 규명하고 dev 프로필에 활성화한 뒤, "memory provider는 채널 전체 대화를 저장하지 않는다" 는 근본 사실에 도달한 전 과정 기록. 성격: 학습/의사결정/실행 기록. 앞선 RAG 설계 논의는 Hermes RAG 논의 — 옵션 비교와 초기 결정, 실행계획서는 Hermes 문서 RAG 파이프라인 — 실행계획서. 관련 프로젝트 메모리:
hermes-dev-holographic-provider,hermes-multi-profile-channel-agents.
0. 요약 (TL;DR)
- holographic = 메모리(RAG) provider (LLM 모델 provider 아님). 설치된 8개 플러그인 중 하나. 로컬 SQLite + FTS5 + HRR, API키·벡터DB 불필요.
- dev 프로필에 활성화 완료. 저장 경로
/opt/data/profiles/dev/memory_store.db, 저장 방식 = 실시간fact_store도구(SOUL.md에 지침 추가), auto_extract=false. - ⚠️ HRR(의미검색)은 이 이미지에 numpy가 없어 런타임에서 비활성 → 실동작은 "FTS5 어휘검색 + Jaccard + trust"뿐. numpy 설치 전까지 의미검색 안 됨. → (c) FTS5-only로 먼저 켜고 HRR은 나중에 승격 결정.
- provider "동시 1개" 제약은 프로필 단위 → 채널별로 다른 provider 가능.
- 핵심 반전: memory provider(holographic 포함)는 멘션/DM으로 봇이 참여한 대화만 저장한다. 멘션 없는 채널 전체 대화는 어떤 provider를 켜도 저장되지 않는다 — 멘션 게이트(
require_mention=true)가 에이전트보다 위에 있기 때문. 이는 Mattermost·Slack 등 전 플랫폼 공통. "채널 전체 저장"은 provider가 아니라 별도 인제스트 파이프라인의 영역.
1. 논의 흐름 (질문 → 결론)
| 순번 | 사용자 질문/요청 | 도달한 결론 |
|---|---|---|
| Q1 | 개발 채널에 외부 provider holographic 설정하자 | holographic=메모리 provider. dev 프로필에 활성화하는 작은 설정 변경(RAG 파이프라인 구축과 별개) |
| Q2 | (auto_extract 선택 중) 세션 종료의 기준이 뭐야? | on_session_end은 매 메시지 아님. idle 만료/압축/재시작/reset 때만. 기본 mode=none이라 idle로는 세션이 안 끝남 |
| Q3 | 대화를 실시간으로 저장하는 방법은? 옳지 않은 방법이야? | 오히려 정석. fact_store 도구로 대화 중 즉시 저장(holographic sync_turn은 no-op=도구 경로가 설계 의도). 세션종료 타이밍 함정을 우회 |
| Q4 | 채널별로 다른 provider 설정 가능? | 가능. memory.provider가 프로필별 config.yaml 문자열 1개 → "동시 1개"는 프로필 단위 |
| Q5 | FTS5+HRR은 기본 설정이야? | FTS5는 항상. HRR은 코드상 기본이나 numpy 없어 런타임 비활성(FTS5 폴백) |
| Q6 | 1.numpy 설치해 HRR 살리자 2.numpy가 뭐야 3.데이터 위치는? | numpy=수치계산 라이브러리(HRR 벡터연산 필수). 데이터=memory_store.db 한 파일(FTS5=가상테이블, HRR=BLOB 컬럼). 설치는 컨테이너 안에서만 유효 |
| Q7 | numpy 설치 때문에 이런 제안? 다른 방법은? 로컬 설치는? | 그렇다. 호스트(Mac) 설치는 무용(컨테이너 격리+wheel 불일치). → (c) FTS5로 먼저 켜고 나중에 HRR 승격 선택 |
| Q8 | 순서대로 진행 | dev에 holographic 활성화 실행 완료(2~7단계) |
| Q9 | 봇 멘션 안 걸어도 대화가 저장돼야 하는 것 아냐? | 아니오. 기본 require_mention=true → 멘션 없는 메시지는 에이전트 전에 drop → 저장 대상 없음 |
| Q10 | holographic 목적이 채널 전체 저장 아니었어? 멘션 저장은 활성화 없이도 됐잖아? | 둘 다 맞음. memory provider는 채널 전체를 저장 못 함(설계상). 내장 메모리로 멘션 대화 기억은 원래 가능. holographic이 준 건 "구조화·검색"뿐 |
| Q11 | Slack도 마찬가지야? Mattermost만? | 전 플랫폼 공통. Slack도 require_mention=true 기본 + Events API가 platform 단에서 app_mention만 전송 |
2. holographic의 정체 규명
hermes memoryCLI 하위:setup/status/off/reset. provider 관리는memory setup [provider](arg 주면 picker 없이 비대화형).- 설치된 memory provider 플러그인 8개: byterover, hindsight, holographic, honcho, mem0, openviking, retaindb, supermemory. 제약 문구: "Only one external provider can be active at a time."
- holographic만 완전 무료·로컬(API키 0). 나머지는 클라우드/유료(mem0/honcho/retaindb/supermemory 등).
- 소스(
plugins/memory/holographic/):__init__.py,store.py,retrieval.py,holographic.py,README.md,plugin.yaml. - 저장 경로:
$HERMES_HOME/memory_store.db. 테이블facts,entities,fact_entities,memory_banks+ FTS5facts_fts. - 도구 2종:
fact_store(add/search/probe/related/reason/contradict/update/remove/list),fact_feedback(신뢰점수 학습). - 설정 기본값(
__init__.py):auto_extract=false,default_trust=0.5,hrr_dim=1024,db_path=$HERMES_HOME/memory_store.db.
3. 저장 타이밍 규명 — "세션 종료"란 무엇인가
holographic의 자동추출(auto_extract)은 on_session_end(messages) 훅에서만 발화한다. 이 훅은 매 메시지가 아니라 세션이 finalize되는 순간에만 호출된다.
run_agent.py의 shutdown_memory_provider docstring: "call at actual session boundaries... NOT called per-turn — only at CLI exit, /reset, gateway session expiry, etc."
발화 지점(5):
| 트리거 | 근거 | 기본 상태 |
|---|---|---|
| ① 유휴 만료(idle) | gateway/session.py:1590 updated_at + idle_minutes |
idle_minutes=1440(24h)이나 mode="none"이라 미작동 |
| ② 일일 경계(daily) | at_hour=4 |
mode="none"이라 미작동 |
| ③ 컨텍스트 압축/session_id 회전 | run_agent.py commit_memory_session |
대화가 길어져 압축 시 발화 |
| ④ 게이트웨이 종료·재시작 | run_agent.py shutdown_memory_provider |
재시작 시 발화 |
⑤ 명시적 /reset |
동일 | 수동 |
핵심: gateway/config.py의 SessionResetPolicy.mode 기본값이 "none"(2026-07 변경, "사용자가 대화 유지를 기대해서 놀란다"는 이유). → 기본 설정에선 유휴/일일로 세션이 안 끝나므로, auto_extract만 켜도 ③압축/④재시작/⑤리셋 때만 flush됨(주기적 축적 안 됨).
4. 실시간 저장 vs 배치 (기억을 언제 담나)
holographic이 대화 내용을 저장하는 3가지 경로:
| 방식 | 시점 | 판단 주체 | 근거 |
|---|---|---|---|
| A. fact_store 도구 | 대화 중 즉시 | 봇(LLM) | get_tool_schemas → FACT_STORE_SCHEMA, handle_tool_call |
| B. built-in 메모리 미러 | 봇이 MEMORY.md/USER.md 쓰는 즉시 | 봇 | on_memory_write — add를 fact로 미러 |
| C. auto_extract 배치 | 세션 종료 시 일괄 | 자동(LLM 추출) | on_session_end(위 3절 함정) |
- holographic의
sync_turn(매 턴 훅)은 의도적으로 no-op: "Holographic memory stores explicit facts via tools, not auto-sync." → 즉 holographic은 처음부터 도구 기반 실시간 저장(A) 을 1급 경로로 설계(auto_extract=false 기본인 이유). - 채택: A(실시간 fact_store). 세션종료 타이밍 함정을 우회, 크래시/재시작에 강함, 저장 품질 정밀. 단 봇이 도구를 부르도록 SOUL.md 지침이 필요 → dev SOUL.md에 추가함(8절).
- "봇 판단 없이 100% 자동+실시간"은 holographic엔 없음(그건
sync_turn을 구현한 byterover 영역).
5. 채널별 다른 provider (프로필 단위)
memory.provider는 각 프로필 자신의 config.yaml에 저장(_save_memory_provider→ 활성 프로필 홈)._get_current_memory_provider가load_config()로 프로필 홈에서 읽음.- 각 채널 봇 = 독립 게이트웨이 프로세스 + 독립 MemoryManager → 자기 프로필 provider만 로드.
memory_store.db도 프로필 홈에 격리. - "동시 1개" 제약 = 프로필 안에서 1개. dev=holographic, sales=mem0 처럼 채널별 상이 가능. 단 dev 하나에 holographic+mem0 동시는 불가.
- 주의: 무료·로컬은 holographic뿐. 클라우드 provider를 채널마다 붙이면 키/비용·메모리(게이트웨이당 ~110MB) 부담. default 프로필은 미변경.
6. FTS5 + HRR 실측 — numpy 함정 (핵심 발견)
| 레이어 | 기본 여부 | 이 컨테이너 실측 |
|---|---|---|
| SQLite 저장 | 항상 | ✅ |
| FTS5 어휘검색(BM25) | 항상 생성·검색 1단계 | ✅ |
| Jaccard 재랭크 + trust 가중 | 항상 | ✅ |
| HRR 의미검색(1024차원) | 코드상 기본(hrr_dim=1024) |
❌ 비활성 (numpy 없음) |
근거:
holographic.py:28-31:try: import numpy … except ImportError: _HAS_NUMPY=False. 이 컨테이너 numpy 미설치(ModuleNotFoundError).store.py _compute_hrr_vector: "No-op if numpy unavailable" →if not self._hrr_available: return. 저장 시 HRR 벡터 계산조차 안 함(facts.hrr_vectorNULL).retrieval.py:38-39:if hrr_weight > 0 and not hrr._HAS_NUMPY:→ HRR 가중치를 0으로 재분배. search/probe/related 전부if not hrr._HAS_NUMPY:로 FTS5 폴백.holographic.py encode_atom: SHA-256 결정론적 위상벡터 → 외부 임베딩 모델·GPU 불필요. 유일한 실질 의존성이 numpy 하나였고 그게 이미지에서 빠져 있던 것.
결론: dev에 holographic을 켜도 실동작 = "FTS5 어휘검색 + Jaccard + trust" 수준. "car"↔"automobile" 의미검색은 numpy 설치 전까진 안 됨. (앞 01-rag-design-discussion 문서의 "holographic=외부 임베딩 없이 의미검색, 인프라 0" 서술은 numpy 전제가 빠진 것.)
7. numpy 설치·영속화 논의
- numpy = 파이썬 수치계산 라이브러리(N차원 배열+벡터/행렬 연산). HRR의 벡터 합성·코사인 유사도 계산에 필수. 임베딩 "모델"이 아니라 순수 수학 라이브러리.
- 호스트(Mac) 설치는 무용: ① 컨테이너는 호스트 파이썬 패키지를 못 봄(격리) ② numpy는 C 확장이라 macOS(arm64) wheel과 컨테이너(linux arm64) wheel 비호환. 설치는 반드시 컨테이너 안에서.
- 실측 제약: venv(
/opt/hermes/.venv)는 hermes 유저 쓰기 불가(root 소유) + 이미지 레이어(볼륨 아님). venv에 pip 없음.uv는/usr/local/bin/uv에 있음. 컨테이너 인터넷 OK./opt/data는 grpcfuse 볼륨(영속). - 영속화 방식:
방식 실체 영속성 exec 설치 docker exec -u root … uv pip install numpydocker restart생존 / recreate·재빌드 시 소멸커스텀 이미지 Dockerfile FROM …:latest+RUN uv pip install numpy, compose build모두 생존(정석) 볼륨+PYTHONPATH /opt/data아래 설치 + PYTHONPATH볼륨으로 영속(리빌드 없음). "로컬 설치"에 가장 근접 - 결정: (c) 지금은 numpy·영속화 보류, FTS5-only로 dev 먼저 활성화. 의미검색이 아쉬운 순간에 (b)볼륨+PYTHONPATH로 HRR 승격.
8. 실제 적용 (실행 로그 + 검증)
대상: dev 프로필(@dev-bot, 채널 b15acwum5bfg9gbhzrfuhh8nee). default·기타 프로필·session_reset 미변경. 전부 -u hermes 실행.
| 단계 | 명령/작업 | 결과 |
|---|---|---|
| 1 사전확인 | hermes -p dev memory status, gateway list |
provider none, dev gateway PID 866 running |
| 2 활성화 | hermes -p dev memory setup holographic |
memory.provider: holographic 기록(비대화형, 기본값) |
| 3 상태 | hermes -p dev memory status |
Provider: holographic, plugin installed ✓ available ✓ |
| 4 SOUL.md | dev SOUL.md에 fact_store 실시간 저장 지침 추가 | 추가됨(사용자 명시 승인 후 — auto-mode 분류기가 페르소나 수정 차단) |
| 5 재기동 | dev python PID kill → s6 자동 부활 | PID 866 → 2275, 로그 에러/트레이스백 없음 |
| 6 검증 | 임시 DB로 store 직접 구동 | _HAS_NUMPY=False, FTS5 한국어 저장/검색 ✓, hrr_vector NULL ✓, facts_fts 존재 ✓ |
| 7 기록 | 프로젝트 메모리 + 이 글 | — |
config.yaml 기록 확인: dev memory: 섹션에 provider: holographic (auto_extract 등은 미기재=기본 false).
데이터 위치(dev 기준):
| 무엇 | 경로 | 형태 |
|---|---|---|
| holographic 전체 | /opt/data/profiles/dev/memory_store.db |
단일 SQLite (활성화·첫 저장 시 생성) |
| ├ FTS5 | 위 파일 내부 | facts_fts 가상테이블 |
| └ HRR | 위 파일 내부 | facts.hrr_vector BLOB + memory_banks.vector |
| 내장 메모리(별개) | /opt/data/profiles/dev/memories/MEMORY.md·USER.md |
마크다운 |
| (호스트에선) | ~/.hermes/profiles/dev/memory_store.db |
/opt/data=~/.hermes 볼륨 |
SOUL.md에 추가한 지침(승인본):
## 메모리 사용 지침 (holographic fact_store)
이 개발 채널에서는 대화 중 아래를 발견하면 즉시 `fact_store`(action=add)로 저장하라:
- 확정된 결정·설정값·환경/버전·엔드포인트·규칙
- 반복될 문제의 원인과 해결책(에러 → 해법)
- 팀·프로젝트 고유 용어와 그 정의
답변 전, 질문과 관련된 과거 사실이 있을 법하면 `fact_store`(action=search 또는 probe)로 먼저 조회해 근거로 삼아라.
저장은 간결한 단일 사실 단위로. 비밀번호·토큰·개인정보 등 민감정보는 저장하지 마라.
9. 근본 재점검 — memory provider ≠ 채널 전체 저장 (반전)
사용자 목적이 "멘션 여부와 무관하게 채널의 모든 대화 저장"임이 드러났고, 이는 memory provider로 달성 불가함을 확인.
- memory provider 훅(
sync_turn,on_session_end,on_memory_write,fact_store)은 에이전트의 턴 안에서만 동작. - 그런데 멘션 게이트가 에이전트보다 위에 있음.
mattermost/adapter.py:MATTERMOST_REQUIRE_MENTION기본 "true"(833행).- 849행
if require_mention and not is_free_channel and not has_mention: return→ 멘션 없는 채널 메시지는 에이전트 실행 전에 drop. allowed_channels(화이트리스트),free_response_channels(멘션 없이 응답할 채널 ID) 노브 존재.
- 따라서 어떤 provider를 켜도 멘션 없는 메시지는 물리적으로 못 봄 → 저장 불가. provider 활성화는 수신 범위를 넓히지 않음.
3개 관문(앞 01-rag-design-discussion 5절 재확인): ①수신(멘션/DM만) ②저장(fact_store/auto_extract) ③파일(별도 색인). 첫 관문에서 대부분 걸림.
사용자의 두 지적, 둘 다 정확:
- "멘션 대화 저장은 활성화 없이도 가능" → 맞음. 내장 메모리(MEMORY.md/USER.md)는 항상 활성. holographic이 준 건 저장의 구조화·검색뿐, 범위는 내장과 동일(멘션/DM).
- "채널 전체 저장이 목적" → 그거라면 holographic은 도구가 아님. memory provider = 봇의 기억(참여한 대화), 채널의 로그가 아님.
"멘션 없이 저장" 억지 방법과 함정: MATTERMOST_FREE_RESPONSE_CHANNELS에 채널 추가(또는 require_mention=false) → 봇이 모든 메시지에 응답하게 됨. "조용히 관찰만 저장(observe-only)" 모드는 없음 → 공유 채널에서 봇이 잡담마다 끼어듦(비실용).
진짜 경로: "채널 전체 대화 저장"은 문서/메시지 RAG 인제스트 파이프라인(Hermes 문서 RAG 파이프라인 — 실행계획서) 영역. 플랫폼 API로 채널 히스토리를 봇 응답과 무관하게 수집→색인. 봇이 수다스러워지지 않고 멘션 게이트도 안 거침. 대신 별도 서비스 구축 필요.
10. 플랫폼 무관성 — Slack도 동일
멘션 게이트는 Mattermost 특성이 아니라 Hermes 전 플랫폼 공통 설계.
| 멘션 게이트 기본 | free_response 노브 | 비고 | |
|---|---|---|---|
| Mattermost | require_mention=true |
MATTERMOST_FREE_RESPONSE_CHANNELS |
allowed_channels 화이트리스트 |
| Slack | require_mention=true(adapter.py:4168) |
SLACK_FREE_RESPONSE_CHANNELS |
strict_mention 모드 추가; Events API가 platform 단에서도 app_mention만 전송(1098행) → 한 겹 더 게이트 |
| Telegram/Discord/Teams 등 | require_mention 브리지 존재 |
플랫폼별 동일 | plugins/platforms/에 22개 어댑터 공통 관례 |
- Slack 로직(
adapter.py:2844-2849): free_response면 응답 /require_mention=false면 응답 / elsereturn # Strict mode: ignore until @-mentioned again. - 핵심은 플랫폼 무관: 멘션 게이트가 에이전트 위에 있어, provider가 채널 전체를 저장하는 건 어느 플랫폼에서도 불가. 인제스트 파이프라인은 플랫폼별 수집 커넥터만 교체하면 되는 공통 설계라, Mattermost로 만들면 Slack 확장이 쉬움.
11. 결론 & 다음 방향
- 현재 dev 구성: holographic 활성(FTS5 실동작, HRR 보류), 실시간 fact_store 저장, 멘션/DM 대화 범위. 무료·로컬.
- holographic 처리 선택지:
- (a) 유지 — 채널 전체 저장엔 기여 못 하나, 멘션/DM 대화 기억을 구조화·검색 가능하게 하는 이득은 실재. 나중에 인제스트 저장소로도 재활용 가능.
- (b) 비활성(
hermes -p dev memory off+ config/SOUL 롤백) 후 인제스트 파이프라인으로 방향 전환.
- 권장: (a)로 두되(해 없음), 진짜 목적인 "채널 전체 대화 저장" 인제스트 파이프라인을 별도 브레인스토밍. 요구사항 재정의 필요: 저장 범위/제외, 저장만 vs 검색까지, 규모, 플랫폼(Mattermost/Slack), 실시간성.
- 미완료(사용자 확인 필요): 실채널 왕복 테스트(멘션 저장→회수)는 미검증. HRR 승격(numpy)은 보류.
12. 실측 근거 인덱스 (파일:라인)
plugins/memory/holographic/__init__.py: sync_turn no-op(222), on_session_end(237), on_memory_write(244), 설정 기본값 auto_extract/trust/hrr_dim(152-155)plugins/memory/holographic/store.py: 스키마 facts/hrr_vector BLOB(17-27), facts_fts FTS5(48), add_fact→_compute_hrr_vector(227-228), _compute_hrr_vector no-op guardplugins/memory/holographic/holographic.py: _HAS_NUMPY(28-31), encode_atom SHA-256(43)plugins/memory/holographic/retrieval.py: 하이브리드 search FTS5→Jaccard→HRR(55,91), numpy 폴백(128,206,277), hrr_weight 재분배(38-39)run_agent.py: shutdown_memory_provider(3305), commit_memory_session(회전/압축 flush)gateway/config.py: SessionResetPolicy mode 기본 "none", idle_minutes=1440(369 부근)gateway/session.py: idle_deadline updated_at+idle_minutes(1590)plugins/platforms/mattermost/adapter.py: require_mention 기본 true(833), free_response(836), skip non-mention(849-851), allowed_channels 화이트리스트plugins/platforms/slack/adapter.py: _slack_require_mention 기본 true(4168), strict_mention(4185), free_response(4192), app_mention 이벤트(1098), 게이팅 분기(2844-2849)- 환경 실측: numpy 미설치(ModuleNotFoundError), venv pip 없음, uv=/usr/local/bin/uv, /opt/data=grpcfuse 볼륨, venv hermes 쓰기불가(root)
부록. 현재 dev 프로필 상태 (2026-07-15 기준)
Provider: holographic(plugin installed ✓ available ✓)- gateway: running, PID 2275
- config:
/opt/data/profiles/dev/config.yaml→memory.provider: holographic - SOUL.md: fact_store 실시간 저장 지침 추가됨
- 미변경: default·sales·finance·qna provider(none/각자), session_reset(mode=none)