콘텐츠로 이동

대화 기록

긴 대화는 결국 단단한 벽에 부딪힙니다. 바로 모델의 컨텍스트 윈도우입니다. 이 페이지의 모든 내용은 그 벽이 있기 때문에 존재하며, 흥미로운 부분은 무엇이 버려지고, 무엇이 남고, 무엇을 되찾을 수 있는가입니다.

컨텍스트를 되찾는 네 가지 방법

섹션 제목: “컨텍스트를 되찾는 네 가지 방법”

이 넷은 서로 대안이라기보다 하나의 사다리에 가깝습니다. 비용이 가장 적은 것부터 시작합니다.

메커니즘 비용 남기는 것 잃는 것
생략 없음 서술의 모든 단어 별일 없던 오래된 도구 결과
이미지 제거 없음 그 주변의 텍스트 오래된 스크린샷
스냅샷 없음 픽셀 형태로 남긴 모든 단어 비전 모델이 아닌 모델의 가독성
요약 모델 호출 1회 하나의 서술 고르지 않은 세부 사항

생략과 이미지 제거가 먼저 실행되는 이유는 무료이고, 중요한 의미에서는 손실이 없기 때문입니다. 아무도 다시 읽지 않을 분량만 버립니다.

요약은 넷 중 유일하게 모델 호출을 소비하는 방식이며, 무엇이 중요했는지 대신 판단해 주는 유일한 방식입니다. 둘 다 실제 비용입니다. 더 흥미로운 쪽은 모델 호출인데, 그것이 언제 일어나는지 때문입니다.

압축은 보통 벽에 부딪히기 전에 임계값을 기준으로 실행됩니다. 하지만 프로바이더가 요청이 너무 크다고 거부한 뒤에 반응적으로 실행되기도 합니다. 휴리스틱 추정이 프로바이더가 실제로 측정한 양을 적게 세었기 때문입니다. 이 상황에서 요약 방식 압축기는 컨텍스트를 줄이기 위해 요청을 보내야 하는데, 그 요청은 방금 넘쳐 버린 바로 그 요청입니다.

스냅샷 압축은 버려진 기록을 픽셀 글리프가 빽빽한 페이지로 렌더링해 이미지로 되돌려줍니다.

전제는 청구 방식의 특이점입니다. 비전 모델은 이미지에 대해 문자가 몇 개 들어 있는지와는 무관한 정액 또는 면적 비례 요율로 요금을 청구합니다. 버려지는 대화 12,000자는 12,000자어치 텍스트 토큰을 차지합니다. 같은 문자를 한 페이지에 렌더링하면 비용은 이미지 한 장 값입니다.

이 방식이 그저 영리한 것을 넘어 쓸 만한 이유는 모델 호출도, 키도, 네트워크도 필요 없다는 점입니다. 오버플로에서 복구할 때 언제나 쓸 수 있는 유일한 전략입니다.

재구성 형태는 앞부분은 원문 그대로, 중간은 이미지로, 뒷부분은 원문 그대로입니다. 앞부분은 작업과, 뒤따르는 모든 내용이 참조하는 제약 사항입니다. 뒷부분은 현재 작업이 있는 지점입니다. 중간은 다시 읽히는 일이 가장 적으면서 비용은 가장 많이 드는 부분입니다.

스냅샷은 매번 보관된 원본 텍스트에서 다시 렌더링하며, 이전 단계의 픽셀에서 렌더링하는 일은 없습니다. 이미지를 다시 이미지로 만들면 압축 한 번마다 글리프가 한 세대씩 열화되어, 결국 아무것도 읽을 수 없게 됩니다.

예전에는 모든 하네스 실행이 빈 기록에서 시작했고, 프롬프트의 <context> 블록에서 연속성을 다시 만들었습니다. 대화 자체가 아니라 대화의 요약을 넣은 것입니다. 여기서 세 가지 문제가 따라왔습니다.

  • 재개는 다시 들려주기였습니다. 모델은 자신의 이전 추론이나 도구가 실제로 반환한 바이트를 본 적이 없고, 그에 대한 설명만 보았습니다.
  • 되감기는 프로세스와 함께 사라졌습니다. checkpoint는 살아 있는 메시지 목록의 인덱스이므로, 다시 시작하면 모델이 붙여 둔 라벨이 모두 사라졌습니다.
  • 재시도는 “재시도할 것이 없음”과 “아무것도 로드되지 않음”을 구분하지 못했습니다. 다시 시작한 뒤에는 어느 쪽이든 실패한 턴이 라이브 상태에서 사라지기 때문입니다.

이 세 가지는 모두 트랜스크립트를 영속화하면 해결됩니다. 트랜스크립트는 매 턴 경계에서 저장되며 턴 중간에는 절대 저장되지 않습니다. 도구 호출과 그 결과 사이에서 캡처한 기록은 어떤 프로바이더도 받아들이지 않기 때문입니다. 그래서 그 순간에 크래시가 나면 재생할 수 없는 반쪽 턴이 아니라 이전 턴이 복원됩니다.

재개한 실행은 가장 최근 메시지까지만 남기고 잘라내며, 고아가 된 도구 결과가 아닌 경계에서 자릅니다. 호출이 잘려 나간 결과는 프로바이더가 곧바로 거부하는 요청이고, 보낼 수 없는 트랜스크립트는 짧은 것보다 못합니다.

모든 메시지는 자신이 이어받는 메시지를 기록하고, 모든 대화는 현재의 브랜치 끝을 가리킵니다. 이 하나의 결정이 이 기능의 전부입니다.

브랜치는 아무것도 쓰지 않습니다. 포인터를 옮길 뿐입니다. 떠나온 경로가 그대로 남아 있으므로 되돌아가는 것도 복원이 아니라 포인터를 한 번 더 옮기는 일입니다. 그리고 프롬프트를 수정해 다시 실행해도 비교하던 답을 잃지 않습니다.

이것이 없다면 되돌아가는 모든 방식이 메시지를 숨기거나 삭제해야 하고, 숨기는 것은 다음 읽는 이가 꿰뚫어 볼 수 없는 거짓말이 됩니다.

브랜치 포크
무슨 일이 일어나는가 포인터가 이동합니다 경로가 복사됩니다
어디로 가는가 같은 대화 새 대화
비용 없음 브랜치 한 벌 복사

포크는 행을 공유하지 않고 새 ID로 복사합니다. 두 대화가 행을 공유하면 서로의 이후 메시지가 보이게 되는데, 이는 포크가 절대 해서는 안 되는 일입니다.

되감기도 같은 포인터를 사용합니다

섹션 제목: “되감기도 같은 포인터를 사용합니다”

실행 중의 checkpoint / rewind 쌍은 깨끗한 턴 경계를 표시하고, 탐색을 마친 뒤 다이제스트를 남긴 채 그 경계로 돌아옵니다. 체크포인트는 트랜스크립트와 함께 영속화되므로, 다시 시작하기 전에 모델이 붙인 라벨도 붙인 위치에 그대로 도착합니다. 대상이 잘라내기에서 살아남지 못한 체크포인트는 다른 곳으로 밀어 넣지 않고 버립니다. “라벨로” 되감았는데 다른 곳에 도착하는 것이 바로 라벨이 막으려는 실패입니다.