AI 협업 개발

Session Handoffs가 여러 AI 코딩 세션에 걸쳐 컨텍스트를 유지하는 방법

AI 코딩 에이전트는 세션이 끝나면 모든 것을 잊어버립니다. 짧은 인계 메모는 수행한 작업, 미완성된 작업, 그리고 다음에 할 일을 전달합니다.

이 글은 영어 원문을 AI 모델이 번역한 것입니다. 표현이 원문과 다를 수 있습니다. 영어 원문 보기

AI 코딩 에이전트는 제한된 컨텍스트 창을 가지고 있으며, 실제 작업이 그 안에 들어가는 경우는 거의 없습니다. 세션이 가득 차거나, 하루 작업을 중단하거나, 모델의 속도를 유지하기 위해 새 대화를 시작합니다. 그런 일이 발생하면 에이전트가 작업에 대해 알고 있던 모든 것, 즉 무엇을 변경했는지, 왜 변경했는지, 무엇이 아직 고장 나 있는지, 다음에 무엇을 하려고 했는지가 사라집니다. 해결책은 오래되고 지루합니다. 사람이 교대 근무를 인계할 때 메모를 남깁니다. AI 세션도 동일한 메모를 남겨야 하며, 다음 세션은 그것을 먼저 읽어야 합니다.

AI 세션이 맥락을 놓치는 이유

컨텍스트 창은 에이전트의 전체 작업 메모리입니다. 여기에는 여러분이 열었던 파일, 논의를 거쳐 내린 결정, 이미 제외한 막다른 길, 그리고 머릿속에만 있고 글로 쓰이지 않은 미완성 계획이 담겨 있습니다. 이 모든 것은 오직 하나의 대화 속에만 존재하며 다른 곳에는 없습니다.

그 메모리는 휘발성입니다. 세 가지 일반적인 이유 때문에 세션이 끝나면 그 내용은 살아남지 못합니다. 긴 작업으로 인해 창이 가득 차면 가장 오래된 메시지들이 범위에서 벗어납니다. 노트북을 닫고 다음 날 돌아오면 새로운 대화가 시작됩니다. 또는 비대해진 컨텍스트가 모델을 느리게 만들고 집중력을 잃게 할 가능성을 높이기 때문에 의도적으로 다시 시작하기도 합니다. 어떤 경우든 다음 세션은 빈 상태로 시작되며, 코드베이스를 다시 설명하고, 목표를 다시 명시하고, 한 시간 전에 이미 내렸던 결정을 다시 도출하는 등 동일한 대가를 치러야 합니다. 세네 번의 세션에 걸친 작업에서 이러한 반복 설명의 대부분은 순전한 낭비입니다.

문제는 에이전트가 잘 잊어버린다는 것이 아닙니다. 문제는 그 기억이 영구적인 곳에 전혀 기록되지 않았다는 것입니다. 이번 세션에서 말한 어떤 것도 디스크에 저장되지 않습니다. 이 문제를 해결하면 세션의 경계는 더 이상 절벽이 아니게 됩니다.

메모리를 디스크로 외부화하기

핵심 아이디어는 한 가지입니다. 바로 컨텍스트 창에 있던 상태를 가져와 파일에 넣는 것입니다. 인계 노트가 바로 그 파일입니다. 그것은 작업이 어디까지 진행되었는지에 대한 작고 영구적인 기록으로, 한 세션이 끝날 때 작성되어 다음 세션이 시작될 때 불러올 수 있습니다.

이는 사람들이 이미 일하는 방식을 반영합니다. 교대 근무자는 로그를 남깁니다. 휴가를 가는 개발자는 팀원이 티켓을 이어받을 수 있도록 인계 문서를 작성합니다. 아무도 다음 사람이 diff만 보고 3일간의 추론 과정을 재구성하리라 기대하지 않습니다. 노트는 그 간극을 넘어 추론 과정을 전달합니다. AI 세션도 같은 이유로 동일한 것이 필요합니다. 다만 그 간극이 두 사람 사이가 아니라, 동일한 도구와의 두 대화 사이에 있다는 점이 다릅니다.

상태가 파일에 저장되면, 연속성은 더 이상 메모리에 의존하지 않게 됩니다. 오늘이든 다음 주든, 어떤 세션에서든 노트를 읽고 전체 그림을 파악한 상태로 작업을 재개할 수 있습니다. 중요한 부분이 저장되었기 때문에 컨텍스트 창은 일회용이 됩니다.

인수인계에 실제로 담겨야 할 내용

좋은 인수인계는 네 가지 질문에만 답합니다. 그것은 일기가 아닌 상태 보고서입니다. 여기서는 길이가 적입니다. 장문의 글은 사람이든 관련 내용을 훑어보는 모델이든 읽지 않기 때문입니다.

섹션 담을 내용 분량
완료된 작업 이번 세션에서 완료한 작업, 각 한 줄로 몇 개의 글머리 기호
주요 결정 사항 코드를 형성하는 선택과 그 이유 다른 사람이 보면 놀랄 만한 것들
미완료 및 다음 작업 미완료된 작업과 다음 세션에서 피해야 할 함정 가장 중요한 것부터
참조 참조할 곳: 파일, 커밋, 티켓, 로그 모호한 힌트가 아닌 정확한 경로

첫 번째 섹션은 결과 요약으로, 다음 세션에서 이미 다룬 범위를 알 수 있게 합니다. 두 번째는 재구성하는 데 비용이 많이 드는 부분입니다. 즉, 결정의 근거, 거부한 옵션과 그 이유, 코드에서 명확하게 드러나지 않는 제약 조건 등입니다. 세 번째는 다음 단계와 그 근처의 지뢰를 명시하므로 실제 연속성이 발생하는 부분입니다. 네 번째는 노트를 색인으로 만들어 다음 세션에서 30개가 아닌 3개의 파일을 읽게 합니다.

내용을 밀도 있게 유지하세요. 애매하게 표현하고 반복하는 인수인계는 아무도 끝까지 읽지 않으며, 이는 목적에 어긋납니다.

핸드오프 템플릿

고정된 양식은 노트를 빠르게 작성하고 빠르게 훑어볼 수 있게 해줍니다. 매번 동일한 제목을 사용하면 다음 세션에서 다음 단계를 위해 어디를 봐야 할지 정확히 알 수 있습니다. 다음은 오랜 작업에서도 유용하게 사용된 템플릿입니다.

# Handoff: <task name> (<date>)

## Done this session
- Wired the payment webhook to the new queue
- Added retry with backoff, capped at 5 attempts

## Key decisions
- Idempotency key is the provider event id, not our order id.
  The provider can resend an event, and order id is not unique per event.
- Chose an at-least-once queue over exactly-once. Handlers are already
  idempotent, so duplicates are safe and the setup is far simpler.

## Open / next
- NEXT: the dead-letter path is not wired yet. Failed events vanish
  after 5 retries. Start here.
- Trap: the staging webhook secret differs from prod. Do not copy the
  prod value into staging config.

## Pointers
- Handler: internal/payments/webhook.go
- Queue setup: internal/queue/consumer.go:42
- Failing test: TestWebhookRetry (currently skipped)
- Related commit: a1b9f30

두 가지 세부 사항 덕분에 이 템플릿이 효과적입니다. 다음 단계는 레이블이 지정되어 섹션 상단에 위치하므로, 작업을 재개하는 세션에서 찾아 헤맬 필요 없이 바로 조치를 취할 수 있습니다. 그리고 함정은 산문 속에 묻히는 것이 아니라 함정이라고 명시되어 있습니다. 핸드오프의 진정한 가치는 다음 세션이 예측할 수 없는 실수를 저지르지 않도록 경고하는 데 있기 때문입니다.

핸드오프 자동화

매번 손으로 노트를 작성하는 것은 마찰이며, 마찰은 그 일이 일어나지 않음을 의미합니다. 더 나은 버전은 자동입니다. 세션이 끝나는 신호를 감시하고, 그 순간에 핸드오프를 생성하거나 새로 고칩니다.

신호는 포착하기 쉽습니다. 사람이 "여기서 마무리하죠", "오늘은 여기까지", 또는 "새 세션을 시작해"와 같은 내용을 입력합니다. 도구는 컨텍스트 창이 한계에 가까워지는 것을 감지할 수 있습니다. 이 중 어떤 것이든 노트를 트리거할 수 있습니다. 내용은 작업 상태에 맞춰 조정됩니다. 작업이 완료되면 핸드오프는 짧아지며, 작업이 완료되었고 어디에 저장되었는지를 알리는 두어 줄의 내용이 됩니다. 작업이 진행 중이라면, 노트는 열린 섹션과 다음 섹션에 중점을 둡니다. 다음 세션에 가장 필요한 것이 바로 그것이기 때문입니다.

이에 대한 보상은 별도의 노력 없이도 노트가 최신 상태로 유지된다는 것입니다. 노트를 작성해야 한다는 것을 기억할 필요도 없고, 업데이트해야 한다는 것을 기억할 필요도 없습니다. 작업이 끝났다는 신호를 보내는 순간, 작업 상태는 이미 디스크에 저장되고 다음 세션은 바로 읽을 내용을 갖게 됩니다.

핸드오프가 가치 없는 경우

핸드오프는 오버헤드이며, 오버헤드는 그에 상응하는 무언가를 얻을 때만 감수할 가치가 있습니다. 단일 세션 내에서 시작하고 끝나는 짧은 일회성 작업의 경우, 핸드오프는 아무런 이득을 주지 않습니다. 변수 이름 변경, 오타 수정, 작은 함수 하나 작성과 같은 작업에는 메워야 할 간극이 없으므로, 메모를 작성하는 것은 순전히 비용일 뿐입니다. 하지 마십시오.

핸드오프의 가치는 두 가지 형태의 작업에서 나타납니다. 첫 번째는 한 세션에 끝내기에는 너무 큰 작업으로, 이 경우 메모가 자신의 세션 경계를 넘어 맥락을 전달하는 역할을 합니다. 두 번째는 여러 사람이나 여러 에이전트 사이를 오가는 작업으로, 이 경우 메모가 그들 사이의 인터페이스 역할을 합니다. 두 경우 모두, 몇 개의 핵심적인 불렛 포인트를 작성하는 비용은 오후 내내 파악한 맥락을 처음부터 다시 재구성하는 비용에 비하면 아주 작습니다.

솔직한 규칙은 이렇습니다. 작업이 세션을 넘어 계속될 것 같으면 핸드오프를 하십시오. 그렇지 않다면 생략하십시오. 비용이 적게 드는 쪽으로 잘못 추측하여 필요 없는 메모를 작성하는 데에는 1분 정도가 소요됩니다. 비용이 많이 드는 쪽으로 잘못 추측하여 여러 세션에 걸친 작업에 대한 메모를 건너뛰면, 다음 세션에서 한 시간을 낭비하게 됩니다.

인수인계를 사실대로 유지하기

인수인계에는 없는 것보다 더 나쁜 한 가지 실패 모드가 있습니다. 바로 정보가 낡아지는 것입니다. 만약 메모에 데드-레터 경로가 연결되지 않았다고 쓰여 있지만, 지난 세션에서 당신이 조용히 그것을 연결하고 메모를 업데이트하지 않았다면, 다음 세션은 거짓된 내용을 읽게 됩니다. 그것은 잘못된 상황을 바탕으로 작업하게 되고, 지도가 실제 지형과 일치하지 않는다는 것을 발견하느라 시간을 낭비합니다. 잘못된 인수인계는 없는 것보다 더 위험합니다. 왜냐하면 없는 메모는 컨텍스트가 없다는 것을 인지하고 새로 구축하게 만드는 반면, 낡은 메모는 이미 거짓인 컨텍스트를 신뢰하게 만들기 때문입니다.

이것이 바로 자동화가 편의성 이상의 의미를 갖는 이유입니다. 매 세션이 끝날 때마다 새로 고쳐지는 메모는 현실을 추적하는 메모입니다. 손으로 편집되어 서서히 현실과 멀어지는 것이 아니라, 매번 현재 상태로부터 다시 작성되기 때문입니다. 하나의 정식 인수인계 파일을 유지하고 그것을 덮어쓰십시오. 읽는 사람이 어느 것이 최신인지 추측해야 하는, 날짜가 적힌 메모 더미를 쌓아두지 마십시오.

그 메커니즘은 오래되었으며, 그것이 바로 핵심입니다. 사람들은 근무 교대라는 것이 존재해 온 이래로 계속 일지를 통해 교대 근무를 인수인계해 왔습니다. 유일하게 새로운 점은 다음 교대 근무의 동료가 지난 교대 근무에 대한 기억이 전혀 없고 당신이 남긴 메모 외에는 그 정보를 얻을 방법이 없는, 동일한 도구의 또 다른 인스턴스라는 것입니다. 메모를 작성하십시오. 간결하게 유지하십시오. 사실대로 유지하십시오. 다음 세션은, 누가 또는 무엇이 그것을 실행하든, 당신이 중단한 바로 그 지점에서부터 정확히 이어서 시작할 것입니다.

관련 글