파이프라인 단계
생성은 사용자 입력에서 메시지 저장까지 14개의 고정 단계를 거치며, 모든 플러그인 훅은 우선순위, 타임아웃, 취소, 권한, 오류 격리에 대해 같은 규칙을 따릅니다.
단계 순서
순서는 모든 생성에서 고정되고 동일합니다.
User input
→ Macros
→ Character/persona data
→ Lorebook
→ Memory/RAG
→ Token counting
→ Context shifting
→ Plugin interceptors
→ Instruct format rendering
→ Provider serialization
→ Request
→ Streaming response
→ Post-processing hooks
→ Save message
단계별 설명
- 사용자 입력 — 이 요청의 초안 메시지와 생성 옵션이 캡처됩니다.
- 매크로 —
{{user}},{{char}}, 사용자 지정 변수가replaceMacros로 해석됩니다. 알 수 없는 매크로는 그대로 남습니다. - 캐릭터/페르소나 데이터 — 캐릭터 카드 필드와 활성 페르소나가 메시지 배열로 조립됩니다.
- 로어북 — 일치하는 로어북 항목이 활성화 규칙에 따라 삽입됩니다. 필수로 표시된 항목은 제거로부터 보호됩니다.
- 메모리/RAG — 메모리와 벡터 회상 블록이 검색되어 순위가 매겨집니다.
- 토큰 계산 — 로컬 토크나이저 프로필이 조립된 컨텍스트를 셉니다.
- 컨텍스트 시프팅 — 컨텍스트가 토큰 예산에 맞춰집니다. 컨텍스트 시프팅을 참조하세요.
- 플러그인 인터셉터 — 플러그인이 메시지 배열을 검사하고 수정할 수 있습니다. 마지막 인터셉터 후에 파이프라인은 토큰을 다시 세고 예산을 다시 적용하므로 어떤 플러그인도 이를 우회할 수 없습니다.
- 인스트럭트 포맷 렌더링 — 깨끗한 메시지 배열이 선택된 인스트럭트 포맷으로 렌더링되거나 구조화된 채 유지됩니다. 인스트럭트 포맷을 참조하세요.
- 프로바이더 직렬화 — 어댑터가 프로바이더 요청을 만듭니다. 채팅 어댑터는 구조화된 메시지 배열을 받고, 텍스트 어댑터는 렌더링된 프롬프트 문자열을 받습니다.
- 요청 — 요청은
AbortSignal, 타임아웃, 클라이언트 연결 끊김 처리를 가지고 전송됩니다. - 스트리밍 응답 — 응답이 SSE로 스트리밍됩니다. 선택적인
assistantPrefill은 첫 델타에 정확히 한 번 앞에 붙습니다. - 사후 처리 훅 — 플러그인이 저장 전에 스트리밍된 응답을 처리할 수 있습니다.
- 메시지 저장 — 최종 메시지, 변형, 생성 메타데이터가 하나의 트랜잭션으로 저장됩니다.
훅 규칙
모든 플러그인 훅은 같은 계약으로 정의됩니다.
- 순서와 우선순위 — 훅은 우선순위 순으로 실행됩니다. 동일한 우선순위는 결정적으로 정렬됩니다.
- 타임아웃 — 각 훅에는 타임아웃이 있습니다. 초과하는 훅은 중단됩니다.
- 취소 — 훅은 생성의
AbortSignal을 받으며 신호가 발생하면 작업을 멈춰야 합니다. - 권한 — 훅은 플러그인이 선언한 능력이 요구하는 권한을 보유한 경우에만 실행됩니다.
- 예외 격리 — 한 플러그인 훅의 오류는 잡히고 로깅되며 건너뜁니다. 파이프라인은 계속 진행되며, 망가진 인터셉터가 조용히 전체 생성을 망가뜨려서는 안 됩니다.
- 진단 로그 — 모든 프롬프트 변경이 기록됩니다. 변경 로그는 생성
진단에 반환되고 응답 메시지의
meta에 저장되므로 실제로 보낸 내용을 항상 확인할 수 있습니다.
프롬프트 사후 처리
채팅 모드에서 메시지 배열은 직렬화 전에 선택적인 재구축 단계를 거칠
수 있습니다. 기존 mergeMessages 알고리즘의 포팅입니다. 모드에는
merge, semi, strict, single과 도구 메시지를 보존하는 _tools
변형이 있습니다. 텍스트 모드에서는 인스트럭트 렌더가 이미 역할을
하나의 문자열로 접었으므로 이 단계가 건너뜁니다.
함께 보기
- 예산이 강제되는 방식은 컨텍스트 시프팅.
- 토큰 계산이 동작하는 방식은 토큰화.
- 인터셉터 및 사후 처리 등록 API는 Plugin SDK.