Obsidian 플러그인 쪽 버그를 하나 고쳤다. 원인 자체는 금방 찾았는데, 고치고 나서 남은 생각이 버그보다 더 오래갔다.
시작은 숫자 하나가 안 맞는 거였다
/status 명령으로 인제스트 진행률을 확인했는데, 82개 raw 파일 중 81개만 완료로 떴다. 방금 끝난 ingest 작업 자체는 “82개 성공, 0개 누락”이라고 보고했는데, 바로 다음에 돌린 /status는 1개가 대기 중이라고 했다. 같은 세션에서 나온 두 보고가 서로 모순됐다.
마침 /status에 “대기 중인 파일 목록”을 보여주는 기능을 막 추가해둔 참이라, 정확히 어떤 파일이 걸렸는지 바로 알 수 있었다. Obsidian에서 그 파일의 백링크를 확인해보니 0개. 어딘가에 이 파일을 인용하는 문서가 있어야 하는데, 아무도 링크하고 있지 않았다.
전체 검색으로 이 파일 내용을 실제로 담고 있는 위키 문서를 찾아냈다. 그 문서의 source frontmatter를 열어서 실제 raw 파일명이랑 한 글자씩 대조했다.
- 실제 파일명:
...69년생 이후는 **꼭** 그렇지 않다 - ... - 문서에 적힌 source:
...69년생 이후는 그렇지 않다 - ...
“꼭” 한 단어가 빠져 있었다.
AI는 파일명을 “베끼지” 않고 “기억해서 다시 쓴다”
raw/ 접두사도 맞고 [[...]] 위키링크 형식도 맞았다. 그런데 정작 그 안의 파일명 자체를, AI가 옮겨 적으면서 미묘하게 한 단어를 빠뜨렸다. 존재하지 않는 이름을 가리키는 깨진 링크가 만들어진 거고, 그래서 백링크도 0개, /status의 정확한 문자열 매칭도 실패했다.
이건 사실 꽤 근본적인 문제다. 사람이라면 “이 파일명 그대로 복사해서 붙여넣어”라는 지시를 받으면 정말 그대로 한다. 하지만 LLM은 매 토큰을 확률적으로 생성한다 — 길고 의미 있는 한국어 문장이 파일명 안에 들어있으면, 그걸 “복사”가 아니라 “그 비슷한 내용을 다시 생성”하는 쪽으로 새는 경우가 생긴다. 같은 프롬프트를 다시 넣어도 이번엔 정확히 맞을 수도, 다음엔 또 다른 단어가 빠질 수도 있다. 결정론적으로 재현되는 버그가 아니라는 뜻이다.
고친 방식은 AI를 더 잘 가르치는 게 아니라, AI의 출력을 못 믿는다는 전제로 후처리를 넣는 쪽이었다. [[raw/...]] 링크를 스캔해서 실제 vault에 있는 파일명과 정확히 일치하지 않으면, Levenshtein 거리로 가장 가까운 진짜 파일을 찾아 자동으로 고쳐 끼워 넣는다. 정확히 일치하면 아무것도 안 건드린다. AI가 “거의 맞게” 쓴 걸 코드가 뒤에서 조용히 정확하게 만들어주는 구조다.
같은 날, 같은 문제가 다른 얼굴로 또 나타났다
이 버그를 고치던 도중에 별개의 사고가 하나 더 있었다. 테스트 함수 하나를 추가하는, 정말 몇 줄 안 되는 작업이었는데 AI 응답이 finish_reason='length'로 계속 잘렸다. max_tokens를 32768 → 65536 → 131000(문서상 모델 최대 출력 한도 근처)까지 올렸는데도, 똑같은 patch 하나에서 다섯 번 연속으로 잘렸다.
토큰 한도 문제가 아니었다. 같은 작업을 다시 시도할 때마다 뭔가 다르게 반응하다가, 어느 시점엔 멀쩡히 끝내고 어느 시점엔 폭주하듯 잘렸다. 결국 그 테스트 함수는 내가 직접 써서 마무리했다.
파일명 한 단어를 빠뜨리는 것과 응답이 무한정 길어지다 잘리는 것 — 겉보기엔 완전히 다른 증상인데, 뿌리는 같다. 같은 입력에 같은 출력을 보장하지 않는다. 어제는 됐다고 오늘도 된다는 보장이 없고, 방금 성공한 패턴을 다음 시도에서 그대로 반복한다는 보장도 없다.
남는 생각
이번엔 운이 좋았다. /status가 숫자 불일치를 표면화해줬고, 파일명이라는 게 원래 “정확히 일치해야 의미 있는” 데이터라 어긋난 게 눈에 띄었다. 근데 지금 AI에게 맡기고 있는 다른 일들 중엔, 이렇게 눈에 잘 띄는 검증 장치가 없는 것들이 분명히 더 있을 거다. 결과물이 “그럴듯하게 맞아 보이면” 아무도 한 글자씩 대조해보지 않으니까.
당장 뭘 바꿔야 할지는 아직 모르겠다. 다만 “AI가 했다고 하니 됐겠지”라고 믿고 넘어가는 지점들을 하나씩 다시 짚어봐야겠다는 생각이 든다 — 특히 정확한 재현이나 일관성이 중요한, 그런데 그동안 별생각 없이 AI한테 통으로 맡겨왔던 부분들부터.