요약
UpdateMemory 가 매 호출마다 memory.json 전체를 다시 읽고 JSON 을 재직렬화해 다시 씁니다. 노트가 누적될수록 단일 추가 비용이 2차 증가합니다. 보안 취약점(자원 고갈)과 버그(보호 패턴 replace 의미)도 같은 코드에서 발생합니다.
문제
// internal/agent/memory.go:88-118
func UpdateMemory(patch MemoryPatch) (Memory, error) {
memory, err := LoadMemory() // ← 매번 전체 파일 재읽기
...
if patch.Note != "" {
memory.Notes = append(memory.Notes, patch.Note) // ← 무한 누적
}
if err := SaveMemory(memory); err != nil { ... } // ← 매번 전체 재직렬화 + 재작성
}
// internal/agent/memory.go:106-108 — 보호 패턴은 append 변수명이지만 실제는 replace
if len(patch.ProtectedInstancePatterns) > 0 {
memory.ProtectedInstancePatterns = append([]string(nil), patch.ProtectedInstancePatterns...)
}
재현 / 증거
8KB 노트 100개씩 추가하며 단계별 누적 비용 측정:
PERF-4: 누적 노트 100개일 때 다음 100개 추가 = 397.924584ms
PERF-4: 누적 노트 200개일 때 다음 100개 추가 = 1.079682084s
PERF-4: 누적 노트 300개일 때 다음 100개 추가 = 2.045627417s
PERF-4: 누적 노트 400개일 때 다음 100개 추가 = 2.837943334s
PERF-4: 누적 노트 500개일 때 다음 100개 추가 = 3.659746958s
| 누적 노트 |
다음 100개 추가 |
배율 |
| 100개 |
398ms |
1.0× |
| 300개 |
2.05s |
5.1× |
| 500개 |
3.66s |
9.2× |
거의 완벽한 2차 성장.
영향
성능: 노트 500개 누적 시 1회 추가에 3.66초. 장기 운용에서 record_agent_memory 가 눈에 띄게 느려짐.
보안: 노트 개수/길이 제한이 없어 클라이언트가 반복 호출로 디스크와 IO 를 고갈시킬 수 있음 (CWE-400, 로컬 DoS).
버그: 보호 패턴 갱신이 append 변수명이지만 실제로는 replace. 운용자가 "추가"라고 생각하고 기존 보호 패턴을 날릴 수 있음.
제안 수정
세 문제를 한 번에 해결하는 재설계:
- 노트 상한: 최근 N 개(예: 100개)만 유지하고 오래된 것은 자동 삭제
- 노트 별도 저장: 노트는 별도 JSONL 파일로
O_APPEND 한 줄 추가 → SaveMemory 가 전체 재작성 안 함
- 보호 패턴 의미 정비: 진짜 append 로 변경하거나, replace 라면 입력/문서에 명확히 표시
// 노트 상한 예시
const maxNotes = 100
if patch.Note != "" {
memory.Notes = append(memory.Notes, patch.Note)
if len(memory.Notes) > maxNotes {
memory.Notes = memory.Notes[len(memory.Notes)-maxNotes:]
}
}
영향받는 코드
internal/agent/memory.go:88-118 (UpdateMemory)
internal/agent/memory.go:71-86 (SaveMemory)
internal/agent/memory.go:106-108 (보호 패턴 replace)
요약
UpdateMemory가 매 호출마다 memory.json 전체를 다시 읽고 JSON 을 재직렬화해 다시 씁니다. 노트가 누적될수록 단일 추가 비용이 2차 증가합니다. 보안 취약점(자원 고갈)과 버그(보호 패턴 replace 의미)도 같은 코드에서 발생합니다.문제
재현 / 증거
8KB 노트 100개씩 추가하며 단계별 누적 비용 측정:
거의 완벽한 2차 성장.
영향
성능: 노트 500개 누적 시 1회 추가에 3.66초. 장기 운용에서
record_agent_memory가 눈에 띄게 느려짐.보안: 노트 개수/길이 제한이 없어 클라이언트가 반복 호출로 디스크와 IO 를 고갈시킬 수 있음 (CWE-400, 로컬 DoS).
버그: 보호 패턴 갱신이
append변수명이지만 실제로는 replace. 운용자가 "추가"라고 생각하고 기존 보호 패턴을 날릴 수 있음.제안 수정
세 문제를 한 번에 해결하는 재설계:
O_APPEND한 줄 추가 →SaveMemory가 전체 재작성 안 함영향받는 코드
internal/agent/memory.go:88-118(UpdateMemory)internal/agent/memory.go:71-86(SaveMemory)internal/agent/memory.go:106-108(보호 패턴 replace)