docs: 수동 메모리 게이팅의 근거 정정 — USER.md는 prompts/ 아래 실재한다
a1033f6에서 "USER.md도 SOUL.md도 4명 전 사용자 누구에게도 없어서 memory_browse/read는 'not found' 에러만 낼 수 있다"고 적었는데 **틀렸다**. 감사 때 `ls workspace/*.md`로만 확인했고, 파일은 `workspace/prompts/` 아래에 있다 — resolvePromptPath가 PROMPT_FILES에 대해 그쪽을 **먼저** 본다(server.ts:1199). papa의 USER.md는 3.2KB에 카테고리 5개, 최종 수정 2026-08-06으로 homeclaw_memory 컬렉션의 최신 문서 날짜와 정확히 일치한다. 도구 셋 다 정상 동작한다. 게이팅 결정 자체는 유지한다 — 근거가 사용량이기 때문이다(1,011턴에서 browse 0 / read 2 / write 1회인데 매 턴 357토큰). 다만 코드·테스트 주석에 박힌 거짓 근거를 걷어낸다. "죽은 레거시라 빼도 된다"와 "멀쩡하지만 거의 안 쓰여 게이팅한다"는 다음 사람이 내릴 판단이 달라진다. memory_write는 파일이 없으면 만들지 않고 에러를 낸다는 점도 함께 정정했다(execute-tool.ts:1220). 앞선 커밋 메시지의 "없으면 새로 만든다"는 서술이 잘못이었다. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Rfme1WVEPkpNwnf5oVNXXc
This commit is contained in:
@@ -336,17 +336,18 @@ export function buildSkillToolFilter(input: ToolScopeInput): (toolName: string)
|
||||
if (name === 'kakao_send_message' && !hasKakaoKeyword) return false;
|
||||
// USER.md/SOUL.md 수동 메모리 3종. 2026-09-04 효율 감사로 게이팅.
|
||||
//
|
||||
// 이 세 개는 지금까지 **매 턴 무조건** 실려 357토큰을 냈다. 실측한 이유는 셋 다 호출이
|
||||
// 사실상 0이어서인데(사용자 턴 1,011건에서 browse 0회 / read 2회 / write 1회), 파고 보니
|
||||
// 더 근본적인 문제였다: **USER.md도 SOUL.md도 4명 전 사용자 누구에게도 없다.** 즉
|
||||
// memory_browse와 memory_read는 파일이 없어 "USER.md not found. Create it first." 에러만
|
||||
// 돌려줄 수 있는 상태로 매 턴 실려 있었다. 실제 장기기억은 일별 로그 + Chroma 벡터
|
||||
// 추출(자동)이 담당한다([[project_vector_memory_chroma]]) — USER.md 경로는 그 시스템이
|
||||
// 대체한 레거시다([[project_legacy_skill_system]]과 같은 유형).
|
||||
// 근거는 순수하게 사용량이다: 실사용 1,011턴에서 browse 0회 / read 2회 / write 1회인데
|
||||
// **매 턴 무조건** 실려 357토큰을 냈다. 게이트가 걸리면 0.3%의 턴에만 실린다.
|
||||
//
|
||||
// 제거가 아니라 게이팅인 이유: 사용자가 "기억해둬"라고 명시하는 턴에는 있어야 한다.
|
||||
// memory_write는 파일이 없으면 새로 만들므로 그 경로는 지금도 유효하다.
|
||||
// memory_stats는 벡터 스토어를 보므로 여기 해당하지 않는다(실제로 13회 호출됨).
|
||||
// 도구 자체는 멀쩡하다. USER.md·SOUL.md는 `workspace/prompts/` 아래에 실제로 있고
|
||||
// resolvePromptPath가 거기서 찾는다(papa의 USER.md는 3.2KB, 카테고리 5개). 감사 중에
|
||||
// 워크스페이스 루트만 보고 "파일이 없다"고 잘못 판단했다가 정정한 자리다 — 셋 다
|
||||
// 파일이 없으면 에러를 내므로, 없다는 판단이 맞았다면 통째로 죽은 도구였을 뻔했다.
|
||||
//
|
||||
// 제거가 아니라 게이팅인 이유: 사용자가 "기억해둬"라고 명시하는 턴에는 반드시 있어야 한다.
|
||||
// 평상시 장기기억은 일별 로그 + Chroma 자동 추출이 담당하지만([[project_vector_memory_chroma]]),
|
||||
// 그건 하루 뒤에 반영되는 배치라 "지금 이걸 기억해"의 대체재가 아니다.
|
||||
// memory_stats는 벡터 스토어를 보므로 게이트 대상이 아니다(실제로 13회 호출됨).
|
||||
if (manualMemoryToolNames.has(name) && !hasMemoryIntentKeyword) return false;
|
||||
if (name === 'sqlite_query' && !hasSqliteKeyword) return false;
|
||||
if (name === 'image_edit' && !hasImageEditKeyword) return false;
|
||||
|
||||
@@ -40,9 +40,9 @@ describe('키워드 게이트 — 관련 없는 턴에서 도구가 따라붙지
|
||||
|
||||
test('핵심 도구는 항상 남는다', () => {
|
||||
const f = filterFor('안녕');
|
||||
// 2026-09-04: memory_read를 memory_stats로 바꿨다. USER.md/SOUL.md가 4명 전 사용자
|
||||
// 누구에게도 없어서 memory_read는 "not found" 에러만 낼 수 있는 상태였고, 이제 기억 의도가
|
||||
// 있는 턴에만 실린다. memory_stats는 벡터 스토어를 보므로 계속 무조건 남는다(실제 13회 호출).
|
||||
// 2026-09-04: memory_read를 memory_stats로 바꿨다. memory_read는 이제 기억 의도가 있는
|
||||
// 턴에만 실린다(사용량 기준 게이팅). memory_stats는 벡터 스토어를 보므로 계속 무조건 남는다
|
||||
// — 실제로 13회 호출된 유일한 메모리 도구다.
|
||||
for (const name of ['web_search', 'web_fetch', 'memory_stats', 'python_eval']) {
|
||||
assert.equal(f(name), true, `${name} 이(가) 사라짐`);
|
||||
}
|
||||
@@ -404,14 +404,12 @@ describe('게이트 오탐 (2026-09-04 감사)', () => {
|
||||
/**
|
||||
* 수동 메모리 도구(USER.md/SOUL.md) — 2026-09-04 효율 감사.
|
||||
*
|
||||
* 이 셋은 매 턴 무조건 실려 357토큰을 냈다. 실사용 1,011턴에서 호출은 browse 0 / read 2 /
|
||||
* write 1회. 파고 보니 더 근본적이었다: **USER.md도 SOUL.md도 4명 전 사용자 누구에게도 없다.**
|
||||
* memory_browse와 memory_read는 파일이 없어 "USER.md not found. Create it first." 에러만
|
||||
* 돌려줄 수 있는 상태로 매 턴 실려 있었다. 실제 장기기억은 일별 로그 + Chroma 벡터 추출이
|
||||
* 담당한다 — USER.md 경로는 그 시스템이 대체한 레거시다.
|
||||
* 근거는 순수하게 사용량이다: 실사용 1,011턴에서 browse 0 / read 2 / write 1회인데 매 턴
|
||||
* 무조건 실려 357토큰을 냈다. 도구 자체는 멀쩡하다 — USER.md·SOUL.md는 workspace/prompts/
|
||||
* 아래에 실제로 있고 resolvePromptPath가 거기서 찾는다.
|
||||
*
|
||||
* 제거가 아니라 게이팅인 이유: 사용자가 "기억해둬"라고 명시하는 턴에는 있어야 하고,
|
||||
* memory_write는 파일이 없으면 새로 만들므로 그 경로는 지금도 유효하다.
|
||||
* 제거가 아니라 게이팅인 이유: "기억해둬"라고 명시하는 턴에는 반드시 있어야 한다. 평상시
|
||||
* 장기기억은 Chroma 자동 추출이 담당하지만 그건 하루 뒤 반영되는 배치라 대체재가 아니다.
|
||||
*/
|
||||
describe('수동 메모리 도구는 기억 의도가 있을 때만 (2026-09-04 감사)', () => {
|
||||
const memTools = ['memory_browse', 'memory_write', 'memory_read'];
|
||||
|
||||
Reference in New Issue
Block a user