이 검증은 2026년 8월에 실시했습니다. 기사 내용의 동작(순수한 install이 호스트형 서버를 작성함, doctor의 기본 모드가 remote임, CLI 실행이 기본적으로 텔레메트리를 전송함)은 모두 당시의 기본값이며, 이후 LoreKit 측에서 변경되었을 수 있습니다. 공개 시점 기준으로 재확인하지는 않았습니다.
계기가 된 배경
AI 코딩 에이전트를 위한 '영구 메모리'를 제공하는 툴 LoreKit 소개 블로그를 읽었습니다.
one command and a folder you own — plain files on your disk, no account, no network
'명령 한 번으로, 자신이 소유한 폴더 — 디스크 위의 일반 파일만 사용하며, 계정이나 네트워크 연결이 필요 없다'는 문구가 인상적이었습니다. 에이전트가 한번 해결했던 문제의 해법을 자신의 디스크에 파일로 축적하고 다음 세션에서 다시 읽어오는 방식 자체는 간단하면서도 매력적으로 보였습니다.
다만 '계정 불필요, 네트워크 연결 불필요'라는 주장은 상당히 강한 주장이라, 실제로 npx @lorekit/cli install을 실행해보고 코드도 읽으면서 실측해봤습니다.
검증은 npm 공개 패키지 (@lorekit/[email protected], MIT, zero-dependency)를 격리된 샌드박스 환경에 설치하는 방식으로 진행했습니다. 실제 홈 디렉토리의 ~/.lorekit 등에는 손대지 않고, 환경 변수 LOREKIT_HOME으로 모든 것을 로컬 검증용 디렉토리에 가두었습니다.
확인하고 싶은 것들
npx @lorekit/cli install만으로 Claude Code의 훅(hook)으로 기능하는지 - 한 번 작성한 지식이 정말 다른 세션에서 읽어와지는지
- '고정 크기의 컨텍스트 창'이라는 주장이 구현상으로 지켜지고 있는지
- 태그, 스코프, TTL이 의도대로 잘 제한되는지
- '계정 불필요, 네트워크 연결 불필요'가 실제로 그런 것인지
1. 설치해보기
$ npx --yes @lorekit/cli install --project --hooks all
LoreKit install
install: project — this repo only
...
.claude/settings.json에 Claude Code의 SessionStart / UserPromptSubmit / PostToolUseFailure / Stop 네 가지 이벤트에 대한 훅이 설치되었습니다. 훅으로 기능한다는 점은 당연하게 확인할 수 있었습니다.
궁금했던 것은 자동 생성된 .mcp.json의 내용입니다.
{
의 기본 동작은 아니다. README 자체에는 local / remote / off 세 가지 모드가 병기되어 있어 거짓말을 하고 있지는 않지만, 블로그 소개문에서는 이 구분이 나오지 않는다.
## 2. 기본(Default) 텔레메트리 측정
npm 패키지를 전개하여 소스를 읽어보니, `src/telemetry.mjs`라는 OpenTelemetry 전송용 코드와, `src/telemetry-token.mjs`라는 인증 토큰이 내장된 파일이 있었다.
// One span + one counter data point per human-facing command
// (install / uninstall / doctor / list / search / show / stats / scopes /
// diff / tree / lint / dedupe / link / migrate), fired to Dash0 so the
...
CLI의 주요 명령어를 실행할 때마다, 명령어명・플래그・OS/Node 버전을 OTLP 형식으로 외부 관측성 SaaS인 Dash0에 전송하는 구현이 되어 있다. `LOREKIT_TELEMETRY=0` 또는 `DO_NOT_TRACK=1`로 비활성화할 수 있지만, **기본값은 유효**하다.
공식적으로 이 프로브를 테스트할 전용 명령어가 준비되어 있었기에, opt-out 하지 않고 단 한 번만 실행해 보았다.
$ unset LOREKIT_TELEMETRY
$ lorekit doctor --telemetry
특별한 설정을 하지 않은 상태에서, 실제로 Dash0으로의 HTTPS 통신이 성립되었고, HTTP 200으로 수신되었다. 코드를 읽었을 뿐만 아니라, 실제로 통신이 발생하는 것을 확인할 수 있었다. '로컬 완결'을 내세우는 도구의 순수 설치 직후 동작으로는 의외였다.
## 3. 로컬 모드에서 '재사용' 시도
여기서는 `LOREKIT_MODE=local`・`LOREKIT_HOME`(검증용 디렉토리)・`LOREKIT_TELEMETRY=0`을 명시적으로 지정하여, 완전히 로컬로 완결되게 검증했다.
먼저, 막히기 쉬운 지식을 작성한다(세션 A라고 가정).
$ lorekit write --local
⚠️ [IMG:N] 형식 토큰은 이미지 placeholder 입니다. 번역하지 말고 원래 위치에 그대로 유지하세요.
DEFAULT_SESSION_START_MAX_CHARS = 3000
DEFAULT_SESSION_START_MAX_LESSONS = 100
더미 지식(knowledge)을 대량으로 작성하여 실제 투입되는 문자 수를 측정해 보았습니다.
| 메모리 개수 | additionalContext의 문자 수 | 표시 |
|---|
| 31개 | 3002자 | "23 of 31 memories loaded" |
| 151개 | 3024자 | "23 of 100 memories loaded" |
개수를 31개에서 151개로 약 5배 늘렸음에도 불구하고, 실제로 컨텍스트에 주입되는 문자 수는 3002자 → 3024자로 거의 변하지 않았습니다(차이는 1% 미만). 개수의 상한선(100개)보다 먼저 문자 수의 상한선(3000자)에서 잘리고 있으며, 항상 23개 전후만 선택되는 형태입니다. '메모리가 늘어도 컨텍스트가 무한정 커지지 않는다'는 주장은 구현 레벨에서 실측과 같이 작동하고 있었습니다.
5. 태그 · 스코프 · TTL
- 스코프 제한(Scope Restriction):
global::org-wide-rule을 작성하고, list --scope global을 실행하자 다른 스코프의 151개 항목은 포함되지 않고 해당 1개만 표시되었습니다. - 태그/전체 텍스트 검색(Tag/Full-text Search): search "org-wide"로 해당 엔트리가 검색되었습니다(풀 텍스트 검색). - TTL 만료(TTL Expiration): --ttl-days 1로 작성한 후, 생성된 .md 파일의 expires_at을 수동으로 과거 날짜로 변경하고 list를 재실행하자 해당 엔트리는 목록에서 사라졌습니다. TTL 로직은 실제로 작동합니다.
모두 의도대로의 동작이었기에 특별히 놀라지는 않았습니다.
요약
실제로 구동해 보니, 좋은 부분과 홍보 문구 사이의 괴리 모두 사실이라는 것을 알게 되었습니다.
작동으로 확인된 부분
- Claude Code의 훅(hook)으로 올바르게 기능한다.
- 로컬 모드에서는 특정 세션의 지식이 다른 세션에서 실제로 읽힌다.
- '고정 크기 컨텍스트 창'은 실측과 같이 작동한다(5배 개수를 늘려도 투입량은 거의 일정).
- 태그 · 스코프 · TTL은 의도대로 작동한다.
홍보 문구와 괴리된 부분
- 'no account, no network'는 로컬 모드를 명시적으로 선택한 경우의 이야기이며, 순수한
install의 기본 동작은 아니다. 아무것도 지정하지 않으면 .mcp.json에 호스트형 Supabase 서버가 작성되고, doctor의 기본 모드는 remote가 된다(토큰 미설정 시 FAIL). - CLI 명령어 실행 자체가 기본적으로 opt-out 방식의 텔레메트리로서 외부 SaaS (Dash0)로 전송된다. 실제로 아무 설정도 변경하지 않고 doctor --telemetry를 실행하자, HTTP 200으로 수락되는 통신이 발생했다.
'로컬 완결(Local completion)'을 실현하고 싶다면, LOREKIT_MODE=local의 명시적 지정과 텔레메트리 opt-out (LOREKIT_TELEMETRY=0)를 함께 수행해야 한다. 역으로 말하면, 이 두 가지만 막으면 블로그의 주장대로 로컬에서 완결되어 작동한다는 것이 이번 실측 결과였습니다.
환경
논의(Discussion)