컨텍스트 시프팅
컨텍스트 시프팅은 반드시 유지되어야 하는 것은 전부 유지하면서 가장 덜 중요한 컨텍스트를 제거하거나 압축하여 조립된 대화를 모델의 토큰 예산에 맞춥니다.
요청 전 단계
요청을 보내기 전에 파이프라인은 다음 단계를 따릅니다.
- 토크나이저 프로필과 모델의 컨텍스트 한도를 결정합니다.
- 응답을 위한 공간을 예약합니다.
- 시스템 프롬프트, 캐릭터, 필수 로어북 항목, 고정된 메시지를 유지합니다.
- 가장 오래된 고정되지 않은 블록부터 제거하거나 압축합니다.
- 도구 호출과 도구 결과 메시지는 쌍으로만 제거합니다.
- 모든 변경 후 토큰을 다시 계산합니다.
- 제외되거나 요약된 내용을 사용자에게 보여줍니다.
보호된 컨텍스트만으로 예산을 초과하면, 예산 초과 요청을 프로바이더로
보내는 대신 안정적인 TOKEN_BUDGET_EXCEEDED 오류로 생성이
종료됩니다.
시프팅 동작 방식
shiftContext(messages, countTokens, budget)은 대화를 토큰 예산에
맞춥니다. 세 개의 목록을 반환합니다.
kept— 들어맞는 메시지;excluded— 제거된 메시지로, 사용자에게 표시됩니다;truncated— 버리는 대신 압축된 블록.
시스템 메시지와 고정된 메시지는 항상 보호됩니다. 가장 오래된 고정되지
않은 블록이 먼저 제거됩니다. 도구 호출과 결과는 toolCallId,
tool_call_id, 또는 callId를 통해 연결되며, 인접하지 않아도 하나의
그룹으로 제거됩니다.
기본 제공 전략
전략은 contextStrategy 설정으로 선택되고 ContextStrategyRegistry를
통해 적용됩니다.
- truncate — 가장 오래된 고정되지 않은 그룹을 제거합니다.
- summarize — 제외된 기록의 로컬 추출 요약을 만들고 현재 사용자 입력 앞에 유지합니다.
- vector-recall — 관련성이 낮은 로어북과 메모리 블록을 높은 관련성 블록보다 먼저 버린 다음 오래된 기록을 줄입니다.
- manual — 먼저
meta.manualExcluded: true로 표시된 메시지(쌍을 이루는 도구 호출과 도구 결과 포함)를 제외하고, 더 많은 공간이 필요하면 일반 축소를 계속합니다.
플러그인과 예산
플러그인은 추가 전략을 등록할 수 있으며, 등록은 정리 함수를 반환합니다. 플러그인 전략은 예산을 우회할 수 없습니다.
- 호스트가 필수 메시지를 복원하고 보호된 컨텍스트를 제거한 전략을 거부합니다;
- 호스트가 실제 예산을 독립적으로 다시 계산합니다;
- 계산과 시프팅은 플러그인 인터셉터 전에 실행되고, 필수 재계산과 최종 시프팅은 그 후에 실행됩니다. 플러그인이 늦게 메시지를 추가해 한도를 몰래 넘길 수 없습니다.
컨텍스트 감사
모든 생성은 네트워크 호출 전에 PromptContextAudit를 만들고
completed, failed, cancelled 중 하나의 종료 상태로 마칩니다.
감사는 다음을 기록합니다.
- 생성 ID, 프로바이더, 모델;
- 실제 순서의 모든 프롬프트 블록과 토큰 수, 포함 또는 제외의 안정적인 이유;
- 컨텍스트 한도, 응답 예약, 최종 프롬프트 토큰 수;
- 토크나이저 프로필과 근사 여부;
- 최종 프로바이더 메시지와 플러그인 인터셉터 진단;
- 업스트림 응답 본문이 없는 정규화된 프로바이더 오류 코드.
채팅별로 마지막 완료 감사만 데이터베이스에 유지됩니다. 새 요청이
이전 것을 원자적으로 교체하며, 채팅을 삭제하면 감사도 삭제됩니다.
UI는 GET /api/v2/chats/:id/context-audit로 이를 읽습니다.
실시간 미리보기 엔드포인트 POST /api/v2/context-preview는 메시지,
브랜치, 감사를 만들지 않고 같은 페르소나, 로어북, 메모리, 템플릿,
토크나이저, 시프팅 단계를 실행합니다.