
AI에게 부탁하는 방식이 정반대로 바뀌었다: 실패를 스스로 구조로 바꾸는 자기 확장 지식 베이스
요약
Claude Code 사용 시 반복되는 실수를 방지하기 위해, AI가 스스로 실패를 분석하고 이를 'hook'이라는 자동화 스크립트로 구조화하여 지식 베이스를 확장하는 새로운 워크플로우를 소개합니다.
핵심 포인트
- 명시적 지시 대신 AI가 스스로 규칙을 만들도록 유도
- 세션 간 지식 단절 문제를 'hook'을 통해 해결
- 실패를 분석하여 영구적인 대응 규칙으로 자동 전환
- AI가 스스로 지식 베이스를 확장하는 자기 성장 구조 구축
Claude Code를 1년 이상 매일 개발에 사용해 왔다. 그 과정에서 최근 가장 크게 변한 것이 있다면, AI에게 부탁하는 방식이다. 정반대가 되었다.
이전에는 명령어를 직접 골라 실행하고, 요구사항을 불렛 포인트로 작성하며, "이 스킬을 사용해"라고 명시적으로 지시했다. 정중하게 지시하지 않으면 실패할 것이라고 생각했기 때문이다. 지금은 반대로, "commit"이라든가 "이거 진행해 둬"와 같이 한 마디만 던진다.
그럼에도 불구하고 제대로 돌아가는 이유는, 실패가 AI 자신의 손에 의해 규칙으로 변해가는 구조를 만들었기 때문이다. 이 기사에서는 그 내용과, 그 단계에 이르기까지 부탁하는 방식이 어떻게 변해왔는지에 대해 써보고자 한다.
먼저 용어부터 정리하자. 여기서 말하는 hook이란, Claude Code가 정해진 타이밍(세션을 열었을 때, 메시지를 보냈을 때, 응답이 끝났을 때 등)에 자동으로 실행하는 작은 스크립트를 말한다. 이것이 이번의 주인공이다.
초기 프롬프트는 이런 식이었다. "남은 작업을 전부 issue로 만들어줘. 디자인은 더 풍부하게, 제한 시간은 15초로". 절차도 수치도, 사용하는 커맨드도 전부 내가 직접 지정했다. 그것이 올바른 부탁 방식이라고 생각했다.
하지만 똑같은 실수가 몇 번이고 되풀이되었다. 알기 쉬운 예가 커밋(commit)이다. "머지(merge)까지 진행해 줘"라고 부탁하면, AI가 멋대로 공동 저자(Co-authored-by) 태그를 붙여 커밋한다. 지적한다. 수정한다. 그리고 며칠 뒤, 다른 세션에서 완전히 똑같은 일을 저지른다. 새로운 세션의 AI는 이전 세션에서 내가 똑같은 주의를 주었다는 사실을 모르기 때문이다. 나는 똑같은 잔소리를 몇 번이고 반복해서 입력해야 했다.
원인은 명확하다. 나의 주의 사항은 해당 세션의 대화 속에만 남는다. 새로운 세션이 시작되면 AI는 백지 상태에서 시작하므로, 이전에 똑같은 말을 몇 번 들었는지 알지 못한다. 실수에 대한 반성이 세션을 넘어 축적되지 않는다는 점이 근본적인 문제였다. 부탁을 정중하게 해도, 한 번뿐이고 사라져 버릴 주의 사항을 매번 다시 입력하고 있을 뿐이라 반복은 멈추지 않았다.
어느 시점부터 부탁하는 방식을 반대로 바꿨다. 정중하게 지시하는 것을 그만두고 대충 던진다. 그리고 제대로 되지 않았다면 원인을 본인에게 설명하게 한다. 실제로 내가 보냈던 메시지는 다음과 같다.
"당신은 이번에 스킬을 무시하고 진행했습니까? 왜 실패했는지 분석해 주세요."
원인을 말하게 했다면, 다음에 이렇게 이어진다.
"향후 이런 실수를 하지 않도록 영구적인 대응을 한 뒤에 진행해 주세요. 새로 시작되는 세션이 이후에 이런 실수를 하지 않도록."
핵심은 마지막 문장이다. "내가 주의하겠다"가 아니라, "다음 세션의 AI가 두 번 다시 하지 않도록 구조를 고쳐 두어라". 하지만 당시에는 이렇게 부탁해도 허사였다. 고친 구조를 저장해 둘 곳이 없었기 때문이다. 이 결과물을 담을 그릇을 마련하고 나서야 비로소 이 부탁 방식이 효과를 발휘하기 시작했다. 그것이 바로 아래의 hooks이다.
지식을 "문서로서 놓아두는 것"을 그만두고, 행동하는 순간에 hook으로 개입시키기로 했다. 개입에는 강도가 다른 3가지 종류가 있다.
| 종류 | 작동 타이밍 | 하는 일 | 강도 |
|---|---|---|---|
| 읽어오기 | 세션 시작 시 | 자신용 메모의 목차를 통째로 대화에 포함 | 약함 (올려두기만 함 · 잊힐 수 있음) |
| ... |
그리고 이 기사에서 가장 전달하고 싶은 것은 바로 여기다. "되돌아보게 하기"를 통해 포착한 실패를 AI 스스로가 한 줄의 규칙으로 덧붙여, 다음부터는 그 상황에서 자동으로 주의를 줄 수 있게 만들 수 있다. 새로운 hook을 인간이 작성하는 것이 아니라, AI가 스스로 규칙을 늘려가는 것이다. 따라서 실패할수록 구조가 조금씩 성장하게 된다. 도식화하면 다음과 같은 이미지다.
대충 던지기 ("commit")
│
▼
...
남은 절에서는 각 단계가 실제로 어떻게 작성되어 있는지 순서대로 살펴보고자 한다.
이 루프의 심장은 규칙을 보유하는 방식이다.
이전에는 새로운 규칙을 늘릴 때마다 전용 hook 스크립트를 하나씩 작성하고 설정 파일에 연결했다. 함정은 hook의 신규 연결 시 나의 승인이 필요하다는 점이었다. hook은 셸 커맨드(shell command)를 그대로 실행할 수 있기 때문에, Claude Code는 새로운 hook을 등록하기 전에 반드시 확인 절차를 거친다. 즉, AI가 자신의 판단만으로는 규칙을 추가할 수 없다는 것이다. "AI가 자신을 고치는" 루프가 인간의 승인 대기 상태에서 멈춰버리게 된다.
그래서 규칙을 코드에서 데이터로 옮겼다. rules.jsonl이라는 한 줄에 하나의 규칙을 담는 파일에, 트리거(trigger)가 될 정규 표현식과 트리거가 발동했을 때 내릴 지시(directive)만을 작성한다.
{"id":"공유 문구의 규율","trigger":"LINE|메일|문구|게시|tweet","directive":"사람에게 보내는 문구에는 사실 확인이 완료된 URL을 첨부한다. 수치는 확인 없이 단정하지 않는다."}
이것이 메시지를 보낼 때마다, 단 하나의 hook이 이 파일을 전부 읽고, 정규 표현식이 일치하는 행의 지시(directive)만을 대화에 삽입한다. 내용은 이것뿐이다.
if printf '%s' "$prompt" | grep -Eiq -- "$trig"; then
d="$(printf '%s' "$line" | jq -r '.directive')"
out+="【${id}】${d}" # 일치하는 지시를 AI에 주입
...
이 형태로 바꾼 순간, "새로운 규칙을 추가하는 것"이 "JSON을 한 줄 추가하는 것"으로 바뀌었다. rules.jsonl의 추가는 AI가 평소에 하는 단순한 파일 편집과 같아서, 셸(shell) 실행이 연관되지 않으므로 승인의 벽에 부딪히지 않는다. 루프가 멈추지 않게 된 것은 거의 이 한 수 덕분이라고 생각한다. 참고로, 위험한 조작을 물리적으로 차단하는 "중단" 계열은 이것과는 별개로, 승인을 거쳐 만든 전용 hook이 담당하고 있다. AI가 스스로 추가할 수 있는 것은 이 rules.jsonl의 "주의를 촉구하는" 계층까지다.
"배움이 있다면 써라"라고 압박하는 hook은, AI의 응답이 3번 끝날 때마다 다음과 같은 문구를 자동으로 삽입한다(실제로 사용 중인 문구를 짧게 줄인 것이다). 숫자 3에는 이론적인 근거가 없다. 매번 하면 출력이 너무 많아지고, 간격이 너무 길면 최근의 실패를 잊어버린다. 시도해 본 결과 적당하다고 느껴진 것이 3이었다는 것뿐이다.
최근의 작업을 되돌아봐라. 기록할 만한 배움(실수의 원인과 재발 방지,
새로운 관례)이 있다면, "지금" 해당 파일에 작성해라.
항상 지키게 하고 싶은 규칙은 산문이 아니라 rules.jsonl에 한 줄 추가하여 배선(wiring)해라.
...
마지막 한 줄이 효과적이다. 이 한 줄을 넣기 전에는, 딱히 배움이 없는 회차에서도 "〇〇에 주의하면 좋다"와 같은 무난한 일반론을 AI가 쥐어짜 내어 메모를 더럽히곤 했다. "없으면 쓰지 마라"를 같은 문구에 공존시키고 나서 그것이 멈췄다. 이 되돌아보기(retrospective)가, 아까의 "왜 실패했는지 분석해줘"를 내가 매번 입력하지 않아도 자동으로 돌려주는 부분이다.
흥미로운 점은, 이 배선이 깔끔한 설계가 아니라 거의 전부 실패의 사후 처리 과정에서 생겨났다는 것이다. 세 가지를 들겠다. 다만 "누가 배선했는가"는 동일하지 않다.
| 대충 부탁한 것 | AI가 실수한 것 | 배선된 영구적 대응 | 배선한 사람 |
|---|---|---|---|
| "머지(merge)까지 진행해줘" | 커밋에 AI의 서명(공동 저자 태그)을 멋대로 붙임 | 커밋에 AI의 서명이 섞여 있으면 되돌리는 hook | AI가 제안, 내가 승인 |
| ... |
앞의 두 가지는 AI가 "이런 hook을 추가합시다"라고 제안하고 내가 승인하여 넣었다. hook을 새로 만들려면 승인이 필요하기 때문이다(구현 ①에서 언급했듯이). 세 번째만 다르다. 스크린샷 건으로 3번 연속 수정을 시킨 뒤, AI가 자신의 반성을 rules.jsonl에 한 줄 추가했다. 나는 승인조차 하지 않았다. 규칙을 데이터로 만듦으로써 비로소 실패로부터 영구적 대응까지가 AI의 손안에서 완결되었다. 이 지점이 이 글의 핵심이다.
매일 부탁하는 방식을 다듬는 것은 그만두었다. 프롬프트(prompt)를 아무리 정성스럽게 작성해도 그 주의사항은 해당 세션 안에서만 사라져 버린다. 효과가 있었던 것은 실패를 구조로 바꾸는 경로를 미리 만들어 두는 것이었다. 대충 부탁할 수 있는 것은 게을러서가 아니라, 대충 부탁해서 실패하더라도 그 실패가 다음 규칙이 될 것임을 알고 있기 때문이다.
마찬가지로 "매번 똑같은 잔소리를 하고 있다"는 느낌이 든다면, 가장 작은 부분부터 시도해 보는 것이 좋다. 몇 번을 말해도 듣지 않는 주의사항을 하나 골라, 그것을 세션 시작 시점이나 메시지 전송 시에 자동으로 삽입되는 hook으로 옮겨 보는 것이다. 문서에 써 두는 것과 행동의 순간에 삽입하는 것이 얼마나 다르게 작용하는지. 그다음은 실패할 때마다 한 줄씩 추가해 나간다. 단, 배움이 없는 회차에 억지로 쓰게 하지 않는 제동 장치만은 잊지 말 것.
- Claude Code 공식 hooks 가이드
- Claude Code에 "되돌아보기"를 가르쳐 보았더니… (세션을 넘어 배움을 승격시키는 선행 구현)
- Claude Code Memory: Storage Is Solved, Injection Isn't ("저장은 해결되었고, 주입이 과제다"라는 논)
- Self-Harness: Harnesses That Improve Themselves (AI 스스로가 하네스(harness)를 개선하는 학술 선행 연구)
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기