콘텐츠로 이동

프롬프트 권한 분리와 provider cache

기본 설정은 기존 입력을 그대로 보존합니다. 먼저 canary 환경에서 runtime context 위치와 provider cache 정책을 각각 명시적으로 켜세요.

.env
LLAMON_PROMPT_CONTEXT_MODE=stable_tail
app/config.py
from llamon_agent import ExtensionConfig, LLMConfig, PromptCacheConfig
EXT = ExtensionConfig(
llm=LLMConfig(
id="registry-model-id",
prompt_cache=PromptCacheConfig(
mode="stable_prefix",
key="support-agent-v1",
ttl={"anthropic": "1h", "openai": "30m"},
),
),
)

code-first Agent도 같은 LLMConfig를 사용합니다.

app/main.py
from llamon_agent import Agent, LLMConfig, PromptCacheConfig
agent = Agent(
llm=LLMConfig(
model="openai/gpt-5.6",
prompt_cache=PromptCacheConfig(mode="stable_prefix"),
),
system_prompt="승인된 도구만 사용하세요.",
)

두 설정은 독립적입니다. 환경변수는 SDK가 만든 변동 context의 message 위치를 정하고, PromptCacheConfig는 provider가 지원하는 breakpoint와 cache option만 제어합니다. 응답 내용을 저장해 재사용하는 의미 응답 cache는 만들지 않습니다.

모드system messageSDK 소유 변동 context기본값
legacy_system기존 operator prompt와 동적 suffixknowledge, recalled facts, summary를 system 말미에 추가
stable_tail같은 operator prompt와 고정 권한 정책canonical JSON synthetic HumanMessage로 전달아니요

prompts.system.bindings는 두 모드 모두 operator 명령으로 렌더링됩니다. binding의 source, 변수명 또는 값의 변경 빈도를 근거로 SDK가 role을 바꾸지 않습니다. 사용자 입력에서 오는 binding을 stable_tail에서 발견하면 보안 진단 warning만 남기며 실행 의미는 유지합니다.

stable_tail의 synthetic message는 최신 실제 HumanMessage 바로 뒤, 그 뒤의 AI/tool message 앞에 삽입됩니다. 동일 ReAct turn에서는 첫 snapshot을 재사용하고 원본 state에는 쓰지 않으므로 checkpoint와 A2A metadata.history에 저장되지 않습니다. 기존 synthetic message가 있으면 교체하며 AIMessage(tool_calls)ToolMessage pair는 분리하지 않습니다.

MemoryConfig.history_aware의 기본값과 조건은 바뀌지 않습니다.

  • 이전 AIMessage가 없으면 history 안내가 없습니다.
  • 이전 AIMessage가 있고 history_aware=True일 때만 기존 안내를 system 말미에 붙입니다.
  • history_aware=False면 항상 붙이지 않습니다.

따라서 첫 턴과 둘째 턴 사이에는 history 안내가 생겨 system prefix가 한 번 바뀔 수 있습니다. 둘째 턴 이후에는 operator, skill, tools가 같으면 이 부분이 안정됩니다. A2A JSON-RPC metadata.history[]의 스키마, 기본 50개 메시지 cap, 입력 순서, cold-start 시드와 warm-thread checkpoint 우선 규칙도 그대로입니다. 자세한 사용법은 멀티턴 메모리를 참고하세요.

필드기본값의미
enabledTrueFalse면 SDK cache marker와 option을 보내지 않음
modeprovider_default기존 provider 동작 유지. stable_prefix에서만 확인된 명시적 기능 사용
keyNone선택적 cache cohort. 생략하면 안정 prefix fingerprint를 사용
ttl{}provider별 TTL. Anthropic 5m/1h, OpenAI legacy in_memory/24h, GPT-5.6+ explicit 30m

완성된 SystemMessage 내부를 임의로 쪼개지 않습니다. tools는 기존 local → MCP → A2A 조립 순서를 유지하고 정렬하지 않으므로, operator/skill 내용이나 tool schema·순서가 바뀌면 별도 cache shard가 됩니다. 원본 message와 tool 객체도 변경하지 않고 provider에 전달할 사본에만 marker를 넣습니다.

Providerprovider_defaultstable_prefix
Anthropic기존 완성 system breakpoint 유지system, 마지막 tool, 마지막 eligible message breakpoint와 선택적 5m/1h TTL
OpenAI native GPT-5.6+provider automatic cachesystem explicit breakpoint, cache key/options, 선택적 30m TTL
OpenAI native 이전 모델provider automatic cachecache key와 선택적 in_memory/24h retention; 미지원 explicit breakpoint는 보내지 않음
vLLM·custom OpenAI-compatible기존 요청확인되지 않은 cache 전용 필드를 보내지 않음

SDK의 capability gate는 알려진 endpoint와 model에만 필드를 보냅니다. Anthropic은 tools → system → messages 순서와 breakpoint를, OpenAI는 prompt cache key·retention·explicit breakpoint를 각 provider 문서의 현재 계약에 맞춰 사용합니다.

cache 재사용은 provider가 실제 wire prefix를 직렬화한 결과를 기준으로 판단합니다. tools, system과 breakpoint까지의 messages, provider, model, cohort가 같아야 하며 TTL 안에서 선행 write가 끝나고 provider의 최소 cacheable token 조건도 충족해야 합니다. SDK fingerprint가 같다는 사실만으로 hit를 추정하지 않습니다.

code-first, Registry, A2A와 Studio의 invoke/stream 경계는 같은 task-local usage scope를 사용합니다. 중첩 실행이면 한 provider usage event를 모든 활성 scope가 받습니다.

prompt cache usage: scope=registry.invoke stats={
'total_input': 4210,
'cache_read': 3072,
'cache_write': 0,
'status': 'read',
...
}

OpenAI와 Anthropic 응답을 total_input, cache_read, cache_write로 정규화합니다. status=read|write|miss는 provider usage가 보고한 token만으로 결정합니다. 요청 관측에는 provider, model, mode, message 수, prefix 길이와 fingerprint만 남기고 prompt 원문, binding 값과 cache key 원문은 기록하지 않습니다. code-first root trace에는 같은 cache_stats 집계가 metadata로 붙습니다.

기본 KnowledgeConfig(delivery="automatic")은 호환 모드에 맞춰 검색 결과를 system suffix 또는 synthetic runtime context로 전달합니다. 더 강한 role 경계가 필요한 agent는 실제 retrieval tool을 opt-in할 수 있습니다.

from llamon_agent import KnowledgeConfig
knowledge = KnowledgeConfig(
sources=["project", "sdk-core"],
delivery="tool",
)

이 모드에서는 자동 knowledge 주입을 중단하고 read-only retrieve_okf_knowledge를 local tool로 등록합니다. 모델이 호출한 검색 결과는 authority="reference_data"인 canonical JSON ToolMessage로 돌아옵니다. 검색 문서 안의 지시문은 operator 정책을 덮어쓸 수 없습니다. 자세한 source와 검색 설정은 KnowledgeConfig를 참고하세요.

먼저 render-only shadow와 녹화 eval로 message sequence와 provider payload를 비교한 뒤 stable_tail을 5% → 25% → 100%로 올립니다. 각 단계는 최소 24시간·500 turn을 관찰하고 다음을 모두 만족할 때만 확대합니다.

  • 신규 provider payload 오류 0건
  • tool 성공률, 구조화 응답 성공률과 핵심 eval 하락 1%p 이하
  • p95 latency 악화 5% 이하
  • operator/history golden contract 위반 0건

이상 징후가 있으면 배포 설정 하나로 되돌립니다.

LLAMON_PROMPT_CONTEXT_MODE=legacy_system

최소 한 minor release 동안 이 rollback 경로를 유지하고, output 동일성은 cache hit 여부가 아니라 녹화 eval과 canary 결과로 판단하세요.