/ingest 프롬프트를 손보다가 발견한 이슈들을 하나씩 정리하던 중이었다.
그중 두 개를 처리하면서, 완전히 같은 종류의 실수를 같은 세션 안에서
두 번 저지를 뻔했다.
”XML이 더 안정적이라는 근거가 없다”고 결론 냈는데
ingest/merge/split이 AI 응답을 받을 때 XML 태그로 감싸서 받고, 그걸 다시 마크다운으로 조립하는 단계가 있었다. 이 단계가 정말 필요한지 궁금해서, 실제 Gemini API를 대표 입력 3종 × 2조건 × 2회, 총 12번 호출해서 XML 방식과 마크다운 네이티브 방식의 파싱 안정성을 비교했다. 12번 다 이슈가 0건이길래 “XML이 더 안정적이라는 근거는 없다”고 결론 내렸다.
그런데 검증하면서 스스로 “확인 안 해봤다”고 적어둔 엣지 케이스가 두 개 있었다 — 본문에 헤딩과 비슷한 텍스트가 있는 경우, summary가 여러 줄인 경우. 자연스러운 입력으로 이 두 조건을 재현해보려 했는데, 모델이 알아서 그런 케이스를 잘 만들어내지 않아서 시도가 그대로 흐지부지됐다. 그렇게 넘어가려던 참에 다시 지적받았다: “그거 테스트할 수 있는 거 아니냐, 못 하는 거랑 안 해본 거랑은 다르다.”
다시 해봤다. 프롬프트를 더 노골적으로 바꿔서 모델을 떠보니, 실제로 summary를 두 줄로 쓴 응답이 나왔다 — 그리고 한 줄만 잡는 naive 파서였다면 둘째 문장이 통째로 사라졌을 상황이었다. 합성 입력으로 파서를 직접 찔러서 재확인까지 마치고 나서야, 진짜로 “마크다운 쪽이 문제없다”는 근거를 손에 쥐었다. 처음 12번의 검증은 사실 절반짜리였던 셈이다.
결국 마크다운 네이티브 방식으로 옮겼다. 그리고 이 과정에서 얻은 부수적인 이득이 하나 있었다 — XML을 “추출해서 재조립”하던 단계 자체가 없어지면서, summary를 따로 뽑아내는 코드 자체가 사라졌다. 그 결과 방금 잡은 버그는 “고쳐진” 게 아니라 애초에 “일어날 자리가 없는” 구조가 됐다. 버그를 하나씩 잡는 것보다, 버그가 생길 자리 자체를 없애는 재설계가 더 근본적이라는 걸 우연히 다시 확인한 셈이다.
”이미 검증된 문구”라고 말했는데 — /refactor 판단 매트릭스 재사용
같은 세션 뒷부분에서, /ingest가 병합/분할을 판단하는 기준이
/refactor보다 느슨하다는 이슈를 다루게 됐다. 해결책으로 /refactor가
이미 쓰고 있는 판단 매트릭스를 /ingest에도 그대로 재사용하기로
했는데, 이때 “이미 검증된 문구니까 괜찮다”고 말해버렸다. 근거가
아예 없는 말은 아니었다 — 이 매트릭스는 0.70.0부터 실사용 중이던,
이미 자리 잡은 프롬프트였다. “실사용 중이니 안전하다”는 감각이었던
셈인데, 그 감각이 뭘 놓치고 있었는지는 바로 다음 지적에서 드러났다.
바로 정정당했다: “검증된 건 그 문구가 실행된다는 것뿐이지, 판단 내용이 실제로 맞는지는 아직 안 본 거다.” 정확히 조금 전 XML 검증에서 나온 것과 같은 지적이었다 — “실행된다”와 “옳다”를 또 헷갈렸다.
그래서 합성 카탈로그(병합해야 할 문서 쌍, 분할해야 할 문서, 비슷하지만 합치면 안 되는 쌍, 서로 무관한 문서)를 만들어서 실제 Gemini를 3번 호출해봤다. 4가지 시나리오 전부 정답을 냈다는 걸 확인한 뒤에야 설계를 확정했다.
배운 점
“실행된다”와 “옳다”는 다른 질문이다. 코드가 에러 없이 돌아간다는 것과, 그 코드가 만들어내는 결과가 실제로 맞다는 것 사이엔 늘 검증이라는 다리가 하나 더 필요하다. 이번엔 같은 세션 안에서 이 다리를 두 번이나 건너뛸 뻔했는데, 두 번 다 붙잡혔다는 게 그나마 다행이었다.