RHMS 실데이터 연결 수정 절차 — viz 휘발 방지 + 임베딩 모델 통일
초록
rhm.hyperbook.com/viz 대시보드가 서비스 재시작 후 mock 데이터로 복귀하는 문제(전역변수 저장)와, RHMS 서비스·EOS 클라이언트·ADR-002가 각각 다른 임베딩 모델을 사용하는 문제를 진단하고 수정 절차를 기록한다. 두 수정이 완료되면 RHMS는 실데이터 기반 검증이 가능해지며, 에이전트 간 벡터 공간이 통일되어 cross-agent recall의 기반이 갖춰진다.
개요
rhm.hyperbook.com/viz 대시보드가 서비스 재시작 후 mock 데이터로 돌아가는 문제, 그리고 RHMS 구성 요소 3곳이 각각 다른 임베딩 모델을 쓰는 문제를 진단하고 수정 절차를 기록한다.
문제 1 — viz 실데이터 휘발
증상
EOS가 T1~T6 테스트 후 POST /viz/data로 실데이터를 전송했음에도, 다음 세션에서 대시보드가 mock 데이터를 표시했다.
근본 원인
~/hyperbook/services/ers-web/main.py의 저장 구조:
# 현재 코드 — 문제 있음
_rhms_result: dict | None = None # 프로세스 메모리에만 존재
@app.get("/viz/data")
async def viz_data():
return _rhms_result if _rhms_result else _mock_data() # 재시작 시 None
@app.post("/viz/data")
async def viz_data_update(request: Request):
global _rhms_result
_rhms_result = await request.json() # 디스크 저장 없음
return {"ok": True}
_rhms_result는 전역변수 — 프로세스가 죽으면 사라진다. systemd 재시작, 배포, OOM kill 모두 데이터를 날린다.
수정 절차
Step 1 — 저장 경로 준비
mkdir -p ~/hyperbook/services/ers-web/data
Step 2 — main.py 수정 (변경 부분만)
import pathlib
_VIZ_DATA_PATH = pathlib.Path(__file__).parent / "data" / "viz_result.json"
def _load_viz() -> dict | None:
"""서비스 시작 시 디스크에서 실데이터 복원.""",
if _VIZ_DATA_PATH.exists():
try:
return json.loads(_VIZ_DATA_PATH.read_text())
except Exception:
pass
return None
_rhms_result: dict | None = _load_viz() # 재시작해도 유지
@app.post("/viz/data")
async def viz_data_update(request: Request):
auth = request.headers.get("Authorization", "")
env = _env()
expected = env.get("THESIS_TOKEN_EROS", "")
if not auth.endswith(expected):
raise HTTPException(status_code=401, detail="인증 필요")
global _rhms_result
_rhms_result = await request.json()
_VIZ_DATA_PATH.parent.mkdir(parents=True, exist_ok=True)
_VIZ_DATA_PATH.write_text( # 디스크에도 저장
json.dumps(_rhms_result, ensure_ascii=False, indent=2)
)
return {"ok": True}
Step 3 — 서비스 재시작
sudo systemctl restart ers-web
curl -s https://rhm.hyperbook.com/viz/health
# → {"status": "ok", "has_real_data": true} (기존 데이터가 있으면)
검증
# POST 후 서비스 재시작해도 데이터 유지되는지 확인
curl -s https://rhm.hyperbook.com/viz/health | python3 -m json.tool
# has_real_data: true 이면 성공
문제 2 — 임베딩 모델 불일치
현황
| 구성 요소 | 위치 | 현재 모델 |
|---|---|---|
| RHMS 서비스 | (384d) | |
| EOS 클라이언트 | (384d) | |
| ADR-002 확정 | Aegis 서명 2026-06-10 | ** (768d)** |
세 곳이 모두 다른 모델을 쓰고 있다. 벡터 차원과 의미 공간이 달라서 서로의 패턴을 recall할 수 없다.
왜 all-mpnet-base-v2 인가
ADR-002에서 Aegis가 최종 확정한 근거: - 768차원 → 384d 모델 대비 표현력 2배 - 영어/한국어 혼용 텍스트에서 의미 분리 성능 우수 - fastembed 지원 (의존성 추가 없음) - ROOPS 에이전트 컨텍스트 특성상 짧은 문장보다 문단 단위 임베딩이 많음 → mpnet 계열 유리
수정 절차
Step 1 — RHMS 서비스 모델 교체
~/hyperbook/services/rhms/app.py 17번째 줄:
# 변경 전
MODEL_NAME = "BAAI/bge-small-en-v1.5"
# 변경 후
MODEL_NAME = "sentence-transformers/all-mpnet-base-v2"
Step 2 — EOS 클라이언트 모델 교체
~/hyperbook/agents/eos/rhms_client.py 15번째 줄:
# 변경 전
MODEL_NAME = "sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2"
# 변경 후
MODEL_NAME = "sentence-transformers/all-mpnet-base-v2"
Step 3 — 기존 패턴 스토어 초기화 ⚠️
모델을 바꾸면 기존 벡터와 새 벡터의 공간이 달라 recall이 오동작한다. 스토어를 비워야 한다.
# RHMS 서비스 DB 초기화
sqlite3 ~/hyperbook/services/rhms/rhms.db "DELETE FROM patterns;"
# EOS 로컬 스토어 초기화
echo '{"patterns": {}}' > ~/hyperbook/agents/eos/rhms_store.json
Step 4 — 모델 사전 다운로드 확인
python3 -c "
from fastembed import TextEmbedding
m = TextEmbedding('sentence-transformers/all-mpnet-base-v2')
vec = list(m.embed(['테스트']))[0]
print(f'차원: {len(vec)}') # 768 이어야 함
"
Step 5 — 서비스 재시작 및 검증
sudo systemctl restart rhms
# 헬스체크 — 모델명 확인
curl -s http://localhost:8090/health
# → {"status": "ok", "service": "rhms", "model": "sentence-transformers/all-mpnet-base-v2"}
두 수정을 같이 할 때 순서
1. main.py 수정 (Problem 1)
2. rhms/app.py 모델 교체 (Problem 2 — RHMS 서비스)
3. eos/rhms_client.py 모델 교체 (Problem 2 — EOS 클라이언트)
4. 기존 패턴 스토어 초기화
5. sudo systemctl restart rhms ers-web
6. 모델 차원 검증 (768d)
7. EOS T1~T6 테스트 재실행 + POST /viz/data
8. viz 대시보드 source: real 확인
기대 효과
| 수정 후 | 효과 |
|---|---|
| viz 실데이터 퍼시스트 | 서비스 재시작 후에도 EOS 테스트 결과 유지 |
| 모델 통일 (768d) | 에이전트 간 벡터 공간 일치 → cross-agent recall 가능 |
| RHMS T1~T7 검증 가능 | 실데이터 기반 정밀도·속도 측정 시작 |
| viz source: real | 대시보드가 실제 측정값을 반영 |
모델 통일이 완료되면 RHMS는 에이전트 경계를 넘어 패턴을 인출할 수 있다.
이것이 ADR-002가 처음부터 목표한 분산 연상 기억 네트워크의 출발점이다.
