Claude Opus 4.8 발표에서 개발자가 놓치기 쉬운 기능이 하나 있습니다. Anthropic은 Messages API가 이제 messages 배열 안에 system entry를 받을 수 있다고 설명했습니다. 쉽게 말해 긴 대화나 에이전트 세션 도중에 시스템 지시사항을 업데이트할 수 있습니다. 기존에는 초반 system prompt에 모든 규칙을 넣거나, 중간 변경 사항을 user 메시지처럼 우회해야 했습니다. 이제는 권한, 토큰 예산, 환경 상태, 작업 단계별 정책을 더 명확하게 주입할 수 있습니다.
이 글은 mid-conversation system messages를 “프롬프트를 더 많이 넣는 기능”이 아니라 “긴 에이전트의 상태 전환을 안전하게 만드는 기능”으로 설명합니다. 코드 에이전트, 데이터 분석 에이전트, CS 자동화, 문서 검토 봇처럼 여러 단계로 움직이는 시스템을 운영한다면 바로 체크할 만한 주제입니다.
에이전트형 앱은 시간이 지날수록 규칙이 늘어납니다. 처음에는 “코드를 수정하지 말고 조사만 해라”였지만, 사용자가 승인하면 “이제 feature branch에서 수정해라”로 바뀝니다. 테스트가 실패하면 “새 기능 구현보다 regression 분석을 우선해라”로 바뀝니다. 운영 환경에 접근하면 “production write action은 금지” 같은 규칙이 추가됩니다.
기존에는 이 모든 조건을 첫 system prompt에 넣거나, 중간에 user 메시지로 “지금부터는 이런 규칙을 따라”라고 말해야 했습니다. 첫 방식은 토큰을 낭비하고 캐시 효율을 떨어뜨립니다. 두 번째 방식은 역할이 애매합니다. 사용자 요청과 시스템 정책이 같은 레벨에 섞여, 모델이 어떤 규칙을 더 우선해야 하는지 헷갈릴 수 있습니다.
mid-conversation system messages는 이 문제를 줄입니다. 상태가 바뀌는 시점에 system role로 정책을 갱신할 수 있기 때문입니다.
실무에서 가장 먼저 적용할 곳은 permission state입니다. 예를 들어 코드 에이전트를 다음 네 단계로 나눌 수 있습니다.
각 단계가 바뀔 때 system message로 현재 권한을 갱신합니다. 이렇게 하면 모든 요청에 긴 정책표를 반복하지 않아도 되고, 로그를 봤을 때 “이 시점부터 어떤 권한이 있었는지”가 명확해집니다.
예시는 간단합니다. 사용자가 PR 작성을 승인하기 전까지는 “Do not edit files”를 system entry로 유지합니다. 승인 후에는 “You may edit files under src/ and tests/, but do not modify migrations or secrets”처럼 범위를 좁혀 업데이트합니다. 에이전트가 실수로 migration을 건드리면 정책 위반을 감지하기도 쉬워집니다.
Anthropic은 이 기능이 long-running session에서 instruction이 바뀌어도 prompt cache hit를 보존하는 데 도움이 된다고 설명합니다. 핵심은 stable prefix와 dynamic policy를 분리하는 것입니다.
stable prefix에는 바뀌지 않는 내용을 둡니다. 제품 설명, 코드 스타일, API 계약, 조직 정책, 공통 출력 형식이 여기에 들어갑니다. dynamic policy에는 현재 단계, 허용된 도구, 토큰 예산, 금지 action, 이번 턴의 목표를 둡니다. 이 구조를 쓰면 큰 고정 컨텍스트는 캐시하고, 작은 정책 변경만 추가할 수 있습니다.
반대로 매 턴마다 전체 system prompt를 새로 만들어 넣으면 cache hit가 깨질 가능성이 커집니다. 프롬프트 생성 코드가 timestamp, random id, 순서가 바뀌는 JSON을 stable 영역에 넣는 것도 피해야 합니다. 긴 에이전트에서는 캐시 hit율이 곧 비용과 지연 시간입니다.
mid-conversation system messages는 강력하지만, 상태 관리 없이 쓰면 정책이 여기저기 흩어집니다. “언제 어떤 system message를 넣었는지”가 로그에만 남고 앱 상태와 연결되지 않으면 디버깅이 어려워집니다.
권장 구조는 명시적 state machine입니다.
mode: investigate, plan, execute, verify, reportallowed_tools: read, edit, shell, browser 등write_scope: 허용 경로 또는 리소스budget: max turns, max tokens, max tool callsapproval_required: true/falsestop_conditions: production write, credential exposure, destructive action 등각 상태 전환은 서버에서 결정하고, 그 결과를 system entry로 모델에 전달합니다. 모델이 스스로 권한을 올리게 하면 안 됩니다. “이제 수정해도 될 것 같습니다”는 제안일 뿐이고, 실제 execute 모드 전환은 사용자 승인이나 서버 정책이 해야 합니다.
긴 에이전트 세션에서 문제가 생겼을 때 필요한 질문은 세 가지입니다. 당시 모델은 어떤 지시를 받았나? 어떤 권한이 있었나? 어떤 근거로 다음 action을 했나? mid-conversation system messages를 쓰면 이 질문에 답하기 쉬워질 수도, 더 어려워질 수도 있습니다. 구현 방식에 달려 있습니다.
각 system update에는 reason을 남기는 것이 좋습니다. 예를 들어 “user approved file edits”, “test failed, switching to debug mode”, “production target detected, write tools disabled”처럼 사람이 읽을 수 있는 이벤트를 저장합니다. 또한 최종 리포트에는 현재 mode와 권한 범위를 표시합니다. 에이전트가 만든 결과물만 보는 것이 아니라, 어떤 안전장치 안에서 실행됐는지 확인할 수 있어야 합니다.
mid-conversation system messages는 프롬프트 엔지니어링 팁이 아니라 에이전트 런타임 설계 도구입니다. 제대로 쓰면 긴 작업에서 정책을 더 작고 명확하게 유지할 수 있습니다. 대충 쓰면 지시사항이 세션 중간에 난잡하게 쌓여 디버깅이 더 어려워집니다. 핵심은 prompt가 아니라 상태 머신입니다.