블로그

긴 에이전트 턴을 컨텍스트 윈도우 안에 담아 두기

모델이 한 번에 읽을 수 있는 양에는 한계가 있습니다. 컨텍스트 윈도우라고 부릅니다. Mythex의 에이전트는 긴 작업을 합니다. 많은 파일을 읽고, 명령을 실행하고, 범위가 정해진 작업을 서브 에이전트에게 넘깁니다. 긴 작업이 깨지는 방식을 세 가지 찾았습니다. 서브 에이전트가 커져서 모델이 모든 요청을 거부했고, 서브 에이전트가 공간이 모자란다고 판단해 일찍 멈췄으며, 러시아어, 중국어, 일본어 텍스트의 토큰 수를 크게 잘못 셌습니다. 무엇을 바꿨는지 설명합니다.

먼저 용어

  • 토큰은 모델이 읽는 조각입니다. 한도와 비용은 글자나 단어가 아니라 토큰으로 셉니다.
  • 컨텍스트 윈도우는 모델이 한 번의 요청에서 읽을 수 있는 최대량입니다. 우리는 비용과 속도를 적당하게 유지하려고 요청마다 더 낮은 자체 예산을 따로 둡니다.
  • 도구 결과는 에이전트가 도구에서 돌려받는 것입니다. 읽은 파일의 내용이나 실행한 명령의 출력입니다. 긴 작업에서는 보내지는 내용의 대부분이 바로 이것입니다.
  • 서브 에이전트는 메인 에이전트가 독립적인 작업을 위해 시작하는 도우미입니다. 예를 들어 "이 장들을 메모와 대조해 줘" 같은 일입니다. 서브 에이전트는 지시를 하나 받은 뒤 스스로 많은 도구 호출을 거칩니다.

문제 1: 서브 에이전트가 커져서 모델이 거부했다

에이전트는 매 단계마다 지금까지의 대화를 모델에 보냅니다. 그것이 너무 커지면 우리 코드가 줄였습니다. 다만 사용자 메시지의 시작 지점에서만 잘라서, 도구 호출과 그 결과가 떨어지는 일이 없었습니다. 첫 메시지를 유지하고, 이전 대화가 잘렸다는 메모를 추가하고, 들어가는 가장 최근의 완전한 턴을 유지했습니다.

서브 에이전트에는 사용자 메시지가 정확히 하나 있습니다. 바로 지시입니다. 자를 지점이 없었습니다. 그래서 서브 에이전트는 매 단계마다 전체 기록을 보냈고, 점점 커져서 결국 모델이 받아들이는 크기를 넘어섰습니다. 약 100만 토큰이었습니다. 이런 서브 에이전트 8개로 테스트했더니 8개 모두 거부되었습니다.

해결: 오래된 도구 결과를 먼저 비우기

이제 요청은 세 단계로 예산에 맞춥니다. 앞 단계로 부족할 때만 다음 단계를 시도합니다.

  1. 가장 오래된 도구 결과를 비웁니다. 그 내용은 짧은 메모로 대체됩니다. 결과는 대화가 모델의 컨텍스트 안에 머물도록 비워졌고, 필요하면 에이전트가 도구를 다시 실행할 수 있다는 내용입니다. 한 시간 전에 읽은 파일은 보통 요청에서 가장 크면서 가장 쓸모없는 것이고, 파일은 여전히 다시 읽을 수 있습니다. 가장 최근 결과는 온전하게 남습니다.
  2. 완전한 사용자 턴을 유지합니다. 전과 같습니다. 첫 메시지, 메모, 들어가는 가장 최근의 완전한 턴입니다.
  3. 완전한 도구 라운드를 유지합니다. 서브 에이전트가 가진 유일한 종류인, 하나의 긴 턴 안에서는 첫 메시지, 메모, 그리고 "도구를 호출하고 결과를 받는" 가장 최근의 완전한 라운드를 유지합니다.

이것은 보내는 내용의 형태만 바꿉니다. 에이전트의 저장된 기록에는 모든 것이 그대로 남습니다. 같은 테스트에서 8개 중 거부된 것은 0개였고, 8개 모두 끝까지 완료했습니다.

캐싱이 계속 동작하도록 묶음 단위로 비우기

모델 제공자는 요청의 시작 부분이 직전 요청과 동일하면 그 작업을 재사용할 수 있습니다. 프리픽스 캐시라고 합니다. 호출할 때마다 결과를 하나씩 더 비운다면, 요청의 시작 부분이 매번 바뀌어 캐시가 전혀 도움이 되지 않습니다.

그래서 가장 오래된 결과는 하나씩이 아니라 네 개씩 비웁니다. 그러면 비워진 부분이 여러 호출에 걸쳐 그대로 유지됩니다. 메모보다 크지 않은 결과는 그대로 둡니다. 비운다 해도 거의 아무것도 줄지 않는데 요청의 시작 부분만 바뀌기 때문입니다. 얼마나 온전하게 남길지는 개수가 아니라 크기로 정합니다. 예산의 4분의 1에 들어가는 가장 최근 결과들은 남기고, 최소한 하나는 항상 남깁니다. 이전 버전은 항상 여섯 개를 온전하게 남겼는데, 짧은 명령 출력에는 맞았지만 긴 파일 읽기에서는 오래된 결과가 예산 대부분을 차지하게 만들었습니다.

거부는 이제 그렇다고 말합니다

모델이 잘못되었다고 거부한 요청은 더 이상 재시도하지 않습니다. 같은 요청을 다시 보내도 같은 답이 나오기 때문입니다. 대화가 모델이 한 번에 읽기에 너무 길면, 사용자에게 이렇게 보입니다. "이 대화가 모델이 한 번에 읽기에는 너무 길어졌습니다. 다음 단계는 새 채팅에서 시작하세요. 지금까지 만든 것은 모두 남아 있습니다." 이것은 사용자가 조치할 일이지 장애가 아니므로, 우리를 호출하지 않습니다.

문제 2: 에이전트가 "공간을 아끼려고" 멈췄다

40개의 긴 장을 읽으라고 요청받은 서브 에이전트가 2개를 읽고 공간을 아끼고 싶다며 멈췄습니다. 400,000 토큰 예산 중 약 100,000 토큰만 쓴 상태였습니다.

이제 오래된 결과가 자신을 위해 비워질 것이라는 사실을 에이전트는 알 방법이 없었습니다. 그래서 알려 주었습니다. 에이전트의 지시문에는 이제 이렇게 적혀 있습니다. 대화가 모델이 받을 수 있는 크기를 넘으면 가장 오래된 도구 결과가 비워지고 가장 최근 결과는 온전하게 남습니다. 그러니 공간을 아끼려고 긴 작업을 멈추지 말고, 계속 진행하세요. 비워진 내용이 필요하면 파일을 다시 읽으면 됩니다.

모델이 볼 수 없는 수정은 모델의 관점에서는 수정이 아닙니다. 이 메커니즘은 에이전트가 신뢰할 때만 도움이 됩니다.

문제 3: 모든 글이 영어인 것처럼 토큰을 셌다

토크나이저를 실행하지 않고, 글자 수를 4로 나누어 토큰을 추정했습니다. 영어에는 합리적인 어림 규칙입니다. 다른 문자 체계에는 맞지 않습니다. 러시아어는 토큰당 약 2.2글자이고, 중국어나 일본어는 약 1글자입니다.

그래서 러시아어 장을 읽는 서브 에이전트는 약 640,000 토큰짜리 요청을 보냈지만, 우리 추정은 400,000 예산 아래라고 말했습니다. 그 추정은 모델의 하드 한도를 넘는 요청도 똑같이 쉽게 통과시킬 수 있었습니다.

이제 추정은 문자 체계별로 셉니다. 일반 ASCII는 토큰당 4글자, 중국어, 일본어, 한국어는 1글자, 그 밖의 것(키릴 문자, 그리스 문자, 아랍 문자, 악센트가 있는 글자, 이모지)은 2글자로 셉니다. 추정은 높게 잡도록 설계되어 있습니다. 러시아어 장 하나에 대해 이제 실제 측정치 약 44,600 토큰에 대해 43,423 토큰으로 추정합니다. 이전에는 25,023이라고 했습니다. 메시지는 한 번 쓰이면 바뀌지 않으므로, 추정치는 매 단계마다 다시 계산하지 않고 한 번 계산해서 기억해 둡니다.

얻은 교훈

  • 크기가 실제로 있는 곳에서 잘라내세요. 에이전트 작업에서는 그것이 사용자 메시지가 아니라 도구 결과입니다.
  • 에이전트에게 자신의 안전장치를 알려 주세요. 그렇지 않으면 더 이상 적용되지 않는 한도를 기준으로 계획을 세웁니다.
  • "글자 수 ÷ 4"는 영어를 전제로 한 가정입니다. 다국어 사용자를 위해 토큰을 세는 것은 문자 체계별로 세거나, 실제 토크나이저를 써야 합니다.
  • 캐시를 고려하세요. 매 호출마다 앞부분이 바뀌는 요청은 비용이 더 들고 더 느리게 실행됩니다.

자신의 앱에 AI 기능을 넣고 있다면, LLM이란 무엇인가와 LLM API 사용법에서 컨텍스트 윈도우와 토큰을 처음부터 다룹니다. Mythex에서 서브 에이전트가 어떻게 작동하는지는 서브 에이전트 문서에 더 자세히 있습니다.

Mythex · Pricing · AI로 무엇이든 만들기 · 웹사이트 및 앱 템플릿 · Mythex 비교 · AI 앱 개발 용어집 · 무료 AI 앱 개발 도구 · English

English አማርኛ العربية Български বাংলা Bosanski Català Čeština Dansk Deutsch Ελληνικά Español Español (España) Eesti فارسی Suomi Français Français (Canada) ગુજરાતી हिन्दी Hrvatski Magyar Հայերեն Bahasa Indonesia Íslenska Italiano 日本語 ქართული Қазақ тілі ಕನ್ನಡ Lietuvių Latviešu Македонски മലയാളം Монгол मराठी Bahasa Melayu မြန်မာ Norsk bokmål Nederlands ਪੰਜਾਬੀ Polski Português (Brasil) Português (Portugal) Română Русский Slovenčina Slovenščina Soomaali Shqip Srpski Svenska Kiswahili தமிழ் తెలుగు ไทย Tagalog Türkçe Українська اردو Tiếng Việt 简体中文 繁體中文(香港) 繁體中文(台灣)