짧은 답
2026년 10월 10일, 앱 안의 어시스턴트 Starling이 한 사용자에게 4마디 왼손을 낮은음자리표로 바꿨다고 말했어요. 하지만 그 마디는 여전히 높은음자리표였어요. 세 가지가 겹쳤어요. 편집 도구가 아무것도 바꾸지 않은 편집에 “Applied”라고 답했고, 악보를 텍스트로 읽은 결과에는 곡 중간의 음자리표 변경이 나오지 않았고, 모델은 악보 페이지의 그림을 믿었어요. 저희는 세 가지를 모두 도구에서 고친 다음 공통 규칙 하나를 더했어요. 바꾸기 전후를 비교하는 측정은 아직 하지 못했어요.
무슨 일이 있었나요?
피아노 악보의 아래 보표가 4마디 한 마디에서만 높은음자리표로 바뀌었다가 그 뒤로 다시 낮은음자리표로 돌아왔어요. 분산화음이 높은 음역에 있는 마디예요. 사용자는 악보 옆의 Starling에게 4마디 왼손을 낮은음자리표로 해 달라고 요청했어요. Starling은 편집 도구를 호출해 성공 응답을 받고 다 됐다고 말했어요. 그런데 페이지에는 4마디가 여전히 높은음자리표로 보였어요. 사용자가 아무것도 바뀌지 않았다고 말하자, 모델은 더 그럴듯하게 들리는 쪽 설명을 따라갔고 그 마디를 다시 읽지 않았어요.
저희는 같은 날 스테이징 서버에 저장된 채팅과 악보의 버전 기록을 읽다가 이 문제를 찾았어요.
어시스턴트는 왜 편집이 됐다고 믿었나요?
가진 정보가 모두 그렇다고 하거나 아무 말도 하지 않았기 때문이에요. 원인이 하나뿐이었다면 그냥 넘어갈 수 있었을 거예요.
- 요청“4마디, 왼손, 낮은음자리표”
- 편집보표의 시작 음자리표를 지정하지만 이미 낮은음자리표였음
- 결과새 버전 번호와 함께 “Applied”
- 읽기시작 음자리표만 보여 주므로 문제가 없어 보임
- 답변“완료했어요”
- 편집은 아무것도 바꾸지 않았는데도 성공했어요. 저희 도구는 유효한 요청이면 모두 새 버전으로 취급했어요. 보표를 이미 있던 음자리표로 설정하는 요청도 유효했기 때문에, 서버는 똑같은 악보를 저장하고 새 버전 번호와 함께 “Applied”라고 답했어요. 모델에게는 의심할 이유가 없었어요.
- 읽기 결과가 중요한 부분을 가렸어요. 악보의 텍스트 읽기 결과에는 파트마다 시작 음자리표와 조만 나오고, 곡 중간의 변경은 나오지 않았어요. 4마디에서 바뀐 음자리표는 텍스트에서 보이지 않았어요. 더 나쁜 점도 있었어요. 다음 마디의 음자리표를 미리 알리려고 마디 끝에 찍는 예고 음자리표가 그 마디 자신의 음자리표로 집계됐어요.
- 모델은 그림을 믿었어요. 텍스트와 렌더링된 페이지가 어긋나거나 텍스트가 아무 말도 하지 않을 때, 모델은 이미지를 보고 판단했어요. 그런데 한 줄 안의 작은 음자리표는 이미지에서 잘못 읽기 쉬워요.
무엇을 바꿨나요?
바꾼 것은 네 가지이고, 모두 2026년 10월 10일에 Starling과 MCP 커넥터가 함께 쓰는 서버에서 했어요.
- 악보를 그대로 두는 편집은 거부해요. 도구는 “Nothing changed: this edit leaves the score as it was, so no new version was saved”라는 오류를 돌려주고, 버전 번호는 그대로예요. 실행 취소와 다시 실행은 예외예요.
- 편집마다 무엇을 썼는지 나열해요. 결과에
bar 4: lower staff clef treble -> bass나bars 1-4: key C major -> F major같은 줄이 들어가서, 모델이 편집 후 악보에 실제로 있는 내용을 보고해요. - 읽기 결과에 곡 중간의 변경이 나와요. 악보 읽기는 음자리표, 조, 박자가 바뀌는 마디마다 그 내용을 알려 주고, 검토 텍스트는 “treble clef from here”와 조 변경을 그 자리에 표시해요. 예고 음자리표는 이제 그것이 알리는 마디의 음자리표로 집계돼요.
- 모든 경로에 같은 규칙 하나. Starling, MCP 서버, 저희 플러그인 스킬의 지침에 이제 이런 내용이 들어 있어요. 도구 결과에 나온 것만 말해요. 오류나 “Nothing changed”는 편집이 이뤄지지 않았다는 뜻이니 그렇게 말해요. 음자리표, 조, 음은 그림이 아니라 텍스트 읽기 결과로 판단해요. 사용자가 이의를 제기하면 그 마디들을 다시 읽어요.
순서가 중요해요. 앞의 두 가지는 모델이 읽는 결과 안에 사실을 넣는 일이라서, 프롬프트의 어떤 문구로도 대신할 수 없어요. MCP 명세도 같은 구분을 설명해요. 도구를 실행하다 생긴 오류는 isError를 표시해 도구 결과에 담아야 모델이 그것을 보고 스스로 바로잡을 수 있다고요. 저희의 “Applied”는 오류여야 할 자리에 나온 성공이었어요.
어떻게 테스트하나요?
방법은 두 가지이고, 하나는 끝났고 하나는 기다리는 중이에요.
- 테스트 스위트의 검사 하나가 마디 안에서 아래 보표의 음자리표가 바뀌고 나중에 조도 바뀌는 악보를 열어요. 그런 다음 모든 읽기 결과에 두 변경이 나오는지, 편집이 자신이 쓴 음자리표와 조를 나열하는지, 아무것도 바꾸지 않는 편집이 새 버전 없이 거부되는지 확인해요. 이 검사는 풀 리퀘스트마다 다른 빠른 검사와 함께 돌아가요.
- 평가는 문제가 생겼던 곡과 같은 구조로 만든 12마디 피아노 곡에 대해 Starling에게 요청 여섯 개를 보내요. 음자리표를 실제로 고치는 요청, 이미 낮은음자리표인 마디에 같은 수정을 요청하기, 변경 뒤의 조를 묻는 질문, 아무것도 바꾸지 않는 음높이 편집, 페달 편집, 마디 수 묻기예요. 별도의 모델이 답변 속 주장을 하나씩 뽑아, 그 답변이 끝난 시점에 저장된 악보와 대조해 표시해요. 어시스턴트 자신의 말과 대조하는 일은 없어요. 변경 전후로 아직 돌려 보지 못했기 때문에, 보고할 환각 비율은 없어요.
규칙은 거짓 주장의 비율을 낮출 뿐, 0으로 만들지는 못해요. 모델은 그림만 보면 여전히 마디를 잘못 읽을 수 있어요. 그래서 규칙이 모델을 텍스트로 보내고, 모델이 한 편집에는 표시가 남고 실행 취소도 할 수 있게 한 거예요.
도구를 쓰는 에이전트를 만드는 분께 어떤 조언을 드릴까요?
- 도구는 아무 일도 하지 않고 성공을 보고해서는 안 돼요. 호출이 상태를 바꿀 수 없다면, 모델이 읽을 수 있는 오류를 돌려주세요.
- 무엇을 썼는지 그 분야의 용어로 돌려주세요. 요청을 그대로 되풀이하는 것은 아무것도 증명하지 못해요.
- 모델이 자기 작업을 확인하는 데 필요한 사실은 모두 텍스트에 담으세요. 사실이 그림에만 있으면 모델은 그림을 보고 판단해요.
- 대화를 읽어 보세요. 저희는 이 문제를 지표가 아니라 저장된 채팅 하나에서 찾았어요.
출처
- Model Context Protocol, Specification 2025-11-25: Tools, Error Handling 항목.
- 2026년 10월 10일 ScoreStarling의 저장된 채팅과 악보 기록, 그리고 이어진 변경과 테스트.
질문과 답변
아무것도 바꾸지 않은 편집을 도구가 왜 성공이라고 보고하나요?
저희 도구는 유효한 요청이면 모두 새 버전으로 취급했어요. 음자리표를 이미 있던 음자리표로 설정하는 요청도 유효했기 때문에, 똑같은 악보를 저장하고 “Applied”라고 답했어요. 2026년 10월 10일부터는 그런 편집을 “Nothing changed”로 거부하고 버전도 저장하지 않아요.
프롬프트 규칙만으로 에이전트가 하지 않은 편집을 했다고 말하는 것을 막을 수 있나요?
확실하게는 못 막아요. 규칙이 도움은 되지만, 무엇이 사실인지는 모델이 여전히 알아야 해요. 가장 중요한 변화는 도구에 있어요. 아무것도 바꾸지 않는 편집을 거부하고, 편집마다 무엇을 썼는지 나열해서 모델이 읽는 결과 안에 사실이 들어 있게 하는 거예요.
ChatGPT와 Claude에도 해당하나요?
네. Starling과 MCP 커넥터는 같은 도구를 호출해요. 그래서 ChatGPT, Claude 등 다른 MCP 클라이언트도 같은 거부 응답과 같은 변경 목록을 받고, 같은 규칙이 서버의 지침에도 들어 있어요.



