Opus 5.5 에이전트가 일을 끝내기 전에 멈추는 네 가지 경우

claudeopusai-agentprompt-engineering

안녕하세요! 재니미입니다.

지난번 프롬프팅 팁 글에서 Opus 5.5가 긴 작업 중간에 진행 상황만 말하고 턴을 끝낼 수 있다고 짧게 적었습니다. 공식 문서를 다시 보니 이 부분을 꽤 자세히 다루고 있어서 따로 정리합니다. 요약하면 텍스트로 끝난 턴은 완료가 아니라 보고로 봐야 하고, 모델이 멈추는 네 가지 경우를 시스템 프롬프트에 구체적으로 적어주면 덜 멈춥니다.

이 글은 Anthropic 공식 문서 Prompting Claude Opus 5.5를 읽고 정리한 것입니다.

왜 멈추나

Opus 5.5는 여러 단계로 된 긴 작업을 하면서 사용자에게 중간중간 진행 상황을 알립니다. 그중 일부는 도구 호출 없이 텍스트로 턴을 끝냅니다(stop_reason: "end_turn"). 사람이 보고 있는 채팅이라면 “계속해”라고 답하면 되지만, 사람 없이 혼자 도는 에이전트는 이걸 작업 완료로 받아들이고 거기서 멈춥니다.

모델이 멈추는 네 가지 경우

문서가 권하는 시스템 프롬프트 예시에는 사용자가 원하지 않는 조기 종료 유형이 네 가지로 나와 있습니다.

  1. 한 일을 길게 요약하고 “다음엔 이걸 하겠습니다”로 끝냅니다. 도구 호출이 없으니 그 다음 일은 시작되지 않습니다.
  2. “원하시면 계속하겠습니다”처럼 제안만 하고 답을 기다립니다. 사람이 지켜보지 않으면 답할 사람이 없습니다.
  3. 사용자가 결정할 목록을 내놓습니다. 그런데 모델 스스로 봐도 그중 어떤 것도 나머지 작업을 막지 않습니다.
  4. 턴이 길어졌거나 한 단계가 끝났다는 이유로 보고하기 좋은 시점이라고 판단합니다.

Opus 5.5는 피해야 할 멈춤을 이렇게 구체적으로 짚어주는 지시에 잘 반응한다고 합니다. 반대로 멈춰도 되는 경우도 같이 적어주는 게 좋습니다. 사용자 없이는 아무것도 진행할 수 없을 때나, 막고 있는 것이 일부러 모델에게서 보호된 것일 때입니다.

시스템 프롬프트에 넣을 문단

문서의 예시 문단은 영어로 되어 있습니다. 사람의 확인 없이 끝까지 혼자 도는 에이전트를 전제로 쓴 것이라 그대로 쓰기보다는 출발점으로 삼으라고 합니다.

A standing instruction from the user, the person you are working for. It is about how your turns end. A message with no tool call in it ends your turn, and the work stops there until you are asked to continue. The user has seen you end turns in four ways while work they asked for was still owed, and does not want any of them. One: a long summary of what was done that closes by announcing the next step and has no tool call, so the next thing never starts. Two: an offer to carry on with something unless the user would prefer otherwise, which stops to wait for an answer the user was not going to give. Three: a list of decisions for the user when, by your own account, none of them blocks the rest of the work. Four: deciding that this is a good place to report, because the turn has been long or a milestone is done. Status notes are welcome, and so are your recommendations on open decisions, but put them in the same message as your next tool call and carry on with whatever does not depend on the user's answer. If you notice yourself inviting the user to redirect you or offering to wait, delete it and do the next thing. The stops the user does want are the ones where nothing can move without them, or where the thing blocking you is deliberately protected from you. This does not override the need for confirmation on risky or destructive actions.

번역하면 이렇습니다. 실제로 넣을 때는 공식 문서가 테스트한 영어 원문을 쓰는 편이 안전합니다.

당신이 일하고 있는 대상인 사용자가 상시로 내리는 지시입니다. 턴을 끝내는 방식에 관한 것입니다. 도구 호출이 없는 메시지는 턴을 끝내고, 계속하라는 요청을 받을 때까지 작업은 거기서 멈춥니다. 사용자는 요청한 작업이 아직 남아 있는데도 당신이 턴을 끝내는 모습을 네 가지 방식으로 봐왔고, 그중 어느 것도 원하지 않습니다. 첫째, 한 일을 길게 요약하고 다음 단계를 예고하며 끝나지만 도구 호출이 없어서 다음 일이 시작되지 않는 경우. 둘째, 사용자가 달리 원하지 않으면 무언가를 계속하겠다고 제안하며, 사용자가 할 생각도 없던 답을 기다리느라 멈추는 경우. 셋째, 당신 스스로 보기에도 나머지 작업을 막지 않는 결정 사항들을 사용자에게 목록으로 내미는 경우. 넷째, 턴이 길어졌거나 한 단계가 끝났다는 이유로 지금이 보고하기 좋은 시점이라고 판단하는 경우. 상태 메모는 환영하며, 열려 있는 결정에 대한 당신의 추천도 마찬가지입니다. 다만 그것들은 다음 도구 호출과 같은 메시지에 넣고, 사용자의 답에 달려 있지 않은 일은 계속 진행하세요. 사용자에게 방향을 바꿔달라고 권하거나 기다리겠다고 제안하는 자신을 발견하면, 그 부분을 지우고 다음 일을 하세요. 사용자가 원하는 멈춤은 사용자 없이는 아무것도 진행할 수 없을 때, 또는 당신을 막고 있는 것이 의도적으로 당신에게서 보호된 것일 때뿐입니다. 이 지시가 위험하거나 파괴적인 작업에 필요한 확인 절차를 대신하지는 않습니다.

넣을 때 주의할 점이 몇 가지 있습니다.

  • 세션 첫 요청부터 넣습니다. 중간에 추가하면 시스템 프롬프트가 바뀌어서 앞선 사고 블록이 무효가 됩니다.
  • display: "updates"를 같이 켭니다. 이 문단은 상태 메모를 다음 도구 호출과 같은 메시지에 넣으라고 시키는데, 그 메모는 기본 설정에서 내용이 빈 사고 블록으로 옵니다.
  • 사람이 지켜보는 앱에서는 빼세요. 확인하려고 멈추는 게 오히려 필요한 환경입니다.
  • 위험한 작업의 확인 단계는 따로 유지합니다. 모델이 원래라면 멈췄을 지점에서 계속 가기 때문입니다.
  • 작업당 도구 호출과 출력 토큰이 조금 늘어납니다.

하네스에서 할 일

프롬프트만으로 다 막히지는 않으니 하네스에도 장치를 둡니다.

작업 항목은 할 일 도구나 파일 같은 체크리스트로 관리하게 합니다. 턴이 끝났는데 남은 항목이 있고 막힌 이유도 말하지 않았다면, 남은 항목을 짚어서 짧게 다시 보냅니다.

Your task list still has open items: migrate the remaining two endpoints and update their tests. Continue with them. If one is blocked, say what is blocking it.
작업 목록에 아직 남은 항목이 있습니다. 남은 엔드포인트 두 개를 마이그레이션하고 그 테스트를 업데이트하세요. 계속 진행하세요. 막힌 항목이 있다면 무엇이 막고 있는지 말해주세요.

완료 조건을 처음에 정해두고, 턴이 끝날 때마다 더 작은 모델이 대화를 그 조건에 비춰 확인하게 하는 방법도 있습니다. 조건을 못 채웠으면 그 이유를 다음 사용자 메시지로 돌려보냅니다.

어느 쪽이든 같은 작업에 자동 재촉은 두세 번까지만 합니다. 정말로 막힌 실행은 거기서 끝내고 사람이 봐야 합니다. 백그라운드 명령이나 하위 에이전트가 아직 돌고 있다면 완료로 치지 말고, 끝날 때까지 기다렸다가 결과를 다음 사용자 메시지로 넘깁니다.

조용한 구간 줄이기

멈추지는 않는데 한참 아무 말이 없는 것도 비슷한 문제입니다. display: "updates"를 켠 상태에서, 사용자에게 보여줄 텍스트 없이 도구만 호출한 단계가 연속으로 몇 번(예를 들어 다섯 번) 이어지면 하네스가 짧은 알림을 붙입니다.

The user hasn't heard from you in a while — say in a few words what you're doing, then continue.
사용자가 한동안 당신 소식을 듣지 못했습니다. 지금 무엇을 하고 있는지 몇 마디로 말한 뒤 계속하세요.

이 알림은 턴 범위 시스템 메시지(clear_at: "next_user_message", 베타)로 최신 도구 결과 뒤에 붙이고 지우지 않고 남겨둡니다. 그래야 프롬프트 캐시가 계속 맞고 뒤따르는 사고 블록도 유효합니다. 알림도 두세 번까지만 보냅니다. Anthropic 테스트에서는 긴 침묵 구간이 생긴 작업 비율이 대략 절반으로 줄었고 비용 차이는 측정되지 않았다고 합니다.

감사합니다.


참고 자료