Skip to content
게으른 엔지니어의 기술 블로그
Go back

LLM에게 병합 노트 이름을 물었더니 판정이 흔들렸고, 이름 비교 몇 줄로 끝났다

Read in English →

LLM 노트 정리를 실측으로 고친 기록 · 4/4편

만들고 있는 Obsidian 플러그인은 기사를 넣으면 LLM이 개념·인물·회사별 노트를 만들고, 그 뒤 자동 정리 단계가 같은 개념을 다룬 노트 묶음을 찾아 “합치자”고 제안한다. 앞 글에서 보상 해킹(reward hacking) 노트 세 개, 즉 상위 개념 노트와 강화학습 편, LLM 에이전트 편을 합치자는 제안은 맞는 제안이었다고 결론 냈다. 남은 문제는 합친 노트의 이름이었다. 이름은 상위 개념인 “Reward Hacking”이어야 하는데, 실제로는 “Reward Hacking in LLM Agents”로 잡혔다. 코드를 보니 묶음의 첫 노트 이름을 그대로 썼고, 그 순서는 Obsidian이 파일 목록을 돌려주는 순서라 보장되지 않았다.

LLM에게 제목도 함께 물었더니 판정이 흔들렸다 — 프롬프트에 질문 추가

처음 떠오른 방법은 LLM에게 묻는 것이었다. 두 노트가 같은 개념인지 판정하는 호출이 이미 있으니, 거기에 “합친다면 어느 쪽 제목을 쓸까”를 함께 묻게 했다. 실제 노트 172쌍으로 두 번씩 재 보니 제목은 대체로 개념 전체 쪽을 골랐다. 그런데 판정 자체가 두 번 모두 바뀐 쌍이 2개 나왔다. “Hannibal”과 “Battle of Cannae”, AlpaSim과 AlpaGym처럼 이름이 따로 있는 별개 대상을 같은 개념이라고 답했고, 이유 문장은 새로 넣은 제목 질문을 근거로 들었다. 질문 하나를 보탰더니 원래 질문의 답이 흔들린 것이다.

제목만 따로 물으면 동작은 했지만 호출이 늘었다 — LLM 호출 수

그래서 제목만 따로 묻는 호출로 옮겼다. 같은 개념으로 판정된 88쌍에 두 번씩 물으니 73쌍이 두 번 다 같은 제목을 골랐고, 에이전트 하네스(“Agent Harness”와 그 적용 예시 노트) 쌍과 보상 해킹 쌍은 둘 다 상위 노트를 골랐다. 동작은 했지만, 이 방식은 병합할 쌍마다 LLM 호출을 하나씩 늘린다. 문제가 하나 생길 때마다 호출이 느는 구조는 바람직하지 않다고 봤다.

게다가 보상 해킹 묶음은 “LLM 에이전트 편–강화학습 편”, “강화학습 편–상위 노트”라는 두 쌍이 이어진 모양이었다. 상위 노트와 LLM 에이전트 편은 서로 같은 개념으로 판정되지 않아 쌍이 없다. 그래서 쌍마다 고른 제목을 세면 1 대 1 동점이었고, 동점이면 다시 첫 노트 이름으로 돌아간다.

상위 개념의 이름은 하위 노트 이름 안에 있다 — LLM 호출 없는 규칙

마지막에 고른 규칙은 LLM을 부르지 않는다. 상위 개념의 이름은 대개 하위 노트 이름 안에 그대로 들어 있다. “Reward Hacking”은 “Reward Hacking in LLM Agents” 안에, “Agent Harness”는 “Coding Agent Harness Example” 안에 있다. 그래서 묶음 안에서 다른 노트 이름에 가장 많이 들어 있는 이름을 고른다(대소문자와 기호는 무시한다). 그런 이름이 없거나 동점이면 예전처럼 첫 노트 이름을 쓴다. 한국어 이름과 영어 이름이 섞인 묶음은 한국어 이름 중에서만 고르는 기존 규칙을 그대로 뒀다.

같은 김에 이웃한 문제도 고쳤다. 병합 결과는 늘 이번 주 폴더에 쓰였다. 그래서 대상 이름이 합칠 노트 중 하나와 같은데 그 노트가 지난주 폴더에 있으면, 플러그인은 그 원본을 이름만 같은 다른 파일로 보고 결과 이름 뒤에 “_dup2”를 붙였다. 원본 둘은 지워지고 “Reward Hacking_dup2” 하나만 남는 식이다. 이름을 바르게 골라도 이 문제가 남으니 같이 고쳤다. 이제는 대상 이름이 원본과 같으면 그 원본 자리에 쓴다. 병합 제안 프롬프트도 새 이름을 짓지 말고 합칠 노트 중 개념 전체를 가리키는 노트의 이름을 쓰라고 바꿨고, 그래도 원본에 없는 이름이 오면 위 규칙으로 원본 하나를 고른다.

실제 노트로 확인 — 이름이 바뀐 묶음은 모두 상위 개념 쪽이었다

먼저 지난 테스트 기록을 다시 돌렸다. 테스트용 보관함은 실행마다 git에 커밋해 두는데, 그중 실제 정리 직후의 상태가 담긴 커밋 43개를 하나씩 꺼내 플러그인 코드로 병합 묶음을 다시 만들었다. LLM은 부르지 않고 저장된 판정만 썼다. 묶음 17개 중 이름이 바뀐 건 4개였고, 모두 상위 개념 쪽으로 바뀌었다. 보상 해킹 묶음은 “Reward Hacking”이 됐고, 리더십 실천을 다룬 세 묶음은 “Setting the Stage Leadership Practice” 대신 “Setting the Stage”처럼 짧은 개념 이름이 됐다. 나머지 13개는 이름이 그대로였다.

그다음 실제 앱에서 기사 6개씩 두 번 돌렸다. 첫 번째 실행에서 자동 정리가 하네스의 두 노트를 묶었고, 대상은 “Agent Harness”였다. 앱이 돌려주는 파일 순서로는 예시 노트가 먼저라, 예전 규칙이었다면 “Coding Agent Harness Example”이 남았을 것이다. LLM이 제안한 병합 5건은 모두 영어 노트를 같은 개념의 한국어 노트로 합치는 것이었고, LLM이 원본 이름을 그대로 대상으로 써서 다섯 건 모두 원본 노트 자리에 합쳐졌다. 합친 노트마다 합치기 전 두 노트의 내용이 빠짐없이 들어갔는지도 대조했다. 다만 이번 실행의 노트는 모두 이번 주 폴더에 있어서, “_dup2”를 고친 부분은 실제 앱에서 확인되지 않았다. 그 부분은 지난주 폴더에 원본을 둔 경우를 테스트로 옮겨 확인했다.

이 규칙이 못 잡는 경우도 있다. “현대자동차 Alpamayo 자율주행 전략”과 “현대자동차 자율주행 전략”처럼 중간에 단어가 끼면 포함 관계가 아니어서 고치기 전처럼 첫 노트 이름이 나온다. “Fearless Organization”과 “Fearless Workplace”처럼 어느 쪽도 다른 쪽에 들어 있지 않은 이름도 마찬가지인데, 이런 쌍은 대개 거의 같은 뜻이라 어느 쪽이 남아도 괜찮았다.

남는 생각

LLM에게 물으면 풀리긴 했다. 하지만 한 방법은 원래 판정을 흔들었고, 다른 방법은 호출을 늘렸다. 상위 개념의 이름이 하위 노트 이름 안에 들어 있다는 관찰 하나로 충분했고, 그건 몇 줄짜리 비교였다. 이미 판정 호출이 있으니 질문 하나 더 얹는 게 공짜처럼 보였지만, 그 질문이 원래 질문의 답을 바꿨다. 호출에 질문을 보탤 때는 보탠 질문이 아니라 원래 질문의 답이 그대로인지부터 재야 한다.


Share this post:

LLM 노트 정리를 실측으로 고친 기록

  1. 1. LLM 판정에 걸린 노트를 고쳐 쓰게 했더니, 판정이 못 보던 손실이 통과했다
  2. 2. LLM 노트 수집 시간을 44% 줄이고, 결과가 같다는 건 재생으로 증명했다
  3. 3. LLM이 제안한 노트 병합을 버그로 보고 세 번 고쳤는데, 맞는 제안이었다
  4. 4. LLM에게 병합 노트 이름을 물었더니 판정이 흔들렸고, 이름 비교 몇 줄로 끝났다