langchain-core==1.7.5, 모델 거부 응답에 표준 형식 제공
LangChain은 11월 4일 langchain-core==1.7.5를 출시하며, 취소된 도구와 언어 간 메시지 로딩 관련 수정과 함께 표준화된 모델 거부 응답 처리를 추가했다. 이번 변화의 핵심은 오해를 부를 수 있는 결과를 다룬다. 공급자 수준에서는 요청이 성공적으로 완료될 수 있지만, 애플리케이션이 활용할 수 있는 결과는 전혀 전달되지 않을 수 있다.
이 차이는 에이전트와 모델이 작업을 선택하고 외부 함수를 호출하도록 하는 애플리케이션을 구축하는 팀에 중요하다. 요청 완료가 반드시 작업 완료를 뜻하지는 않는다. 거부 응답, 중단된 작업, 손상된 대화 복원은 각각 다른 대응을 요구한다.
이번 릴리스는 OpenAI, Anthropic, Google의 응답 차이를 동일한 동작으로 만들지 않으면서도 부각한다. 실질적인 의미는 응답을 받는 것과 무슨 일이 일어났는지 이해하는 것 사이의 경계가 더 분명해졌다는 데 있다. 애플리케이션 팀은 여전히 그 결과가 사용자에게 무엇을 의미하는지 결정해야 한다.
버전 번호를 넘어 langchain-core==1.7.5가 바꾸는 것
이번 릴리스는 더 나은 모델 답변을 약속하기보다, 애플리케이션이 성공하지 못한 결과를 인식하는 방식을 개선한다.
공개된 릴리스 변경 사항에는 버전 1.7.4 이후 네 가지 핵심 업데이트가 명시돼 있다. 거부 응답 표준화, Gemini 안전 차단 변환, 도구 취소, LangChain.js가 직렬화한 메시지 객체 로딩을 다룬다. 나머지 항목은 릴리스 자체를 처리한다.
이 변화들은 서로 다른 소프트웨어 경계를 다룬다. 거부 응답 처리는 모델 응답과 애플리케이션 로직 사이의 경계와 관련된다. 취소는 실행과 모니터링 사이의 경계와 관련된다. 메시지 로딩은 JavaScript와 Python 사이의 경계와 관련된다.
이들의 공통 주제는 작업이 예상한 결과를 내지 못할 때 의미를 보존하는 것이다. 응답은 모델이 요청을 거절했다는 사실을 전달해야 한다. 취소된 작업은 계속 활성 상태인 것처럼 보이지 않아야 한다. 저장된 메시지는 다른 런타임이 읽을 때도 인식 가능한 상태로 남아야 한다.
따라서 이는 중요한 애플리케이션 측면의 추가 기능을 포함한, 범위가 명확한 유지보수 릴리스다. 릴리스 노트는 더 빠른 생성, 향상된 추론, 더 높은 답변 정확도를 입증하지 않는다. 그런 주장은 별도의 근거가 필요하며 업그레이드 근거에 포함돼서는 안 된다.
개발자에게 유용한 출발점은 애플리케이션이 영향을 받는 경계 중 하나에 의존하는지 여부다. 텍스트 전용 프로토타입은 즉각적인 차이를 거의 느끼지 못할 수 있다. 응답을 파싱하고, 결과를 스트리밍하며, 저장된 대화를 복원하는 에이전트는 더 많은 동작을 점검해야 한다.
시점에도 구체적인 설명이 있다. 거부 응답 표준화 변경은 11월 3일 병합됐고, 이어 Gemini 변환 변경이 11월 4일 병합됐다. 이번 릴리스는 이와 관련된 변경을 함께 패키징한다. 이 순서는 더 광범위한 회사 전략을 추측할 필요 없이 범위를 설명한다.
패치 버전 번호는 이 작업을 운영상 사소하게 보이게 할 수 있다. 하지만 오류 분류는 실행이 문제를 보고할 때 대응하는 코드인 예외 처리기를 훨씬 넘어선 의사결정에 영향을 준다. 사용자 메시지, 에스컬레이션, 모니터링, 다른 요청의 시작 여부에 영향을 줄 수 있다.
그러므로 적절한 해석은 구체적이다. LangChain은 이전에는 모호했던 여러 결과를 더 명시적으로 만들고 있다. 이번 릴리스는 모든 애플리케이션이 어떻게 대응해야 하는지를 결정하지 않으며, 그 변경 사항을 완전한 에이전트 안전 시스템으로 오해해서도 안 된다.
이 구분은 뉴스를 사실에 기반하게 유지한다. 중요한 추가 사항은 반환되는 정보에 대한 공동의 기대를 뜻하는, 더 유용한 애플리케이션 계약이다. 이 계약은 소프트웨어가 실제로 이를 읽고 그에 따라 행동할 때 가치가 생긴다.
모델 거부 응답 처리는 애플리케이션 팀에 압박을 가한다
인식 가능한 거부 응답은 개발자에게 더 나은 신호를 제공하지만, 일반적인 실패 처리를 정당화하기는 더 어렵게 만든다.
거부 응답은 모델이 요청된 출력을 제공하지 않기로 하는 것이다. 구조화된 출력은 미리 정의된 데이터 형태에 맞아야 하는 응답이다. 이 두 경로가 만날 때, 예상 밖의 모든 응답을 형식 문제로 처리하면 실제 원인을 가릴 수 있다.
병합된 모델 거부 응답 처리 변경은 표준 거부 응답 콘텐츠 블록과 전용 ModelRefusalError를 도입한다. 작성자는 이전에 공급자 거부 응답이 최종 답변이나 일반적인 파싱 실패로 나타났던 사례를 설명한다. 이 변경에는 인식된 거부 응답을 오류로 전환할 수 있는 가로채기 계층인 선택적 에이전트 미들웨어도 포함된다.
즉각적인 압박은 모델 사용자보다 애플리케이션 소유자에게 가해진다. 개발자는 거부 응답이 워크플로를 종료할지, 더 안전한 재구성을 유도할지, 또는 사람 검토자에게 전달될지를 결정해야 한다. 프레임워크는 어떤 대응이 제품에 맞는지 알지 못한 채 상태를 드러낼 수 있다.
기술 요청을 구조화된 작업 항목으로 전환하는 가상의 내부 어시스턴트를 생각해 보자. 유효한 답변은 초안 티켓을 만든다. 잘못된 형식은 복구 경로로 이동한다. 거부 응답은 자체적인 처리를 받아야 한다. 형식을 복구해도 콘텐츠 제공을 보류하기로 한 결정은 해결되지 않기 때문이다.
이 구분이 없으면 애플리케이션은 잘못된 질문을 할 수 있다. 관련 질문이 요청된 출력이 왜 거절됐는지인데도, 응답이 왜 검증에 실패했는지 물을 수 있다. 그러면 디버깅은 실제 응답 상태가 아니라 예상 데이터의 정의인 스키마 쪽으로 향하게 된다.
운영상의 의미는 간단하다. 팀은 재시도 결정을 단순히 오류 존재 여부와 분리해야 한다. 일부 일시적 실패에는 요청을 반복하는 것이 합리적이다. 하지만 모델이 요청 자체를 거절했을 때는 다른 결정이 필요하다.
이는 모든 거부 응답이 옳다는 근거가 아니라 애플리케이션 설계 판단이다. 모델은 정당한 요청도 거절할 수 있다. 따라서 유용한 제품에는 거부 응답을 인식하는 것과 그 근본적인 판단을 지지하는 것을 구분하는 방법이 필요하다.
사용자 경험 팀도 관련된 선택에 직면한다. 빈 답변, 일반적인 실패 메시지, 명시적인 설명은 각각 다른 내용을 전달한다. 표준화된 신호는 더 명확한 메시징을 지원할 수 있지만, 모든 맥락에 적합한 설명을 작성할 수는 없다.
기업 구매자는 비슷하게 구체적인 질문을 해야 한다. 제품은 거절된 요청과 실행 실패를 구분할 수 있는가? 어시스턴트가 오류를 처리한다는 광범위한 주장은 이 동작에 대해 거의 말해 주지 않는다. 이 차이는 워크플로가 불편한 사례에 도달할 때만 드러난다.
검색 가능한 지식 기반을 유지하는 개발자에게 이런 결정은 통합 메모 및 알려진 제한 사항과 함께 다뤄져야 한다. 예상 결과를 기록하면 이후 변경으로 서로 다른 상태가 같은 일반 메시지로 합쳐지는 일을 막는 데 도움이 된다.
압박의 핵심은 어디에나 더 복잡한 예외 처리를 추가하는 것이 아니다. 책임을 명확히 배정하는 일이다. 누군가는 거부 응답 이후 무엇이 일어나는지 결정해야 하며, 그 결정은 공급자나 애플리케이션 구성 요소가 바뀌어도 유지돼야 한다.
Gemini 거부 응답 블록은 공유 형식의 한계를 드러낸다
공통 거부 응답 레이블은 공급자별 동작을 지우지 않으면서 애플리케이션 의사결정을 단순화할 수 있다.
핵심 기술적 긴장은 공유 인터페이스와 공급자가 실제로 반환하는 서로 다른 신호 사이에 있다. 표준화는 변환이 올바른 결정을 뒷받침할 만큼 충분한 정보를 보존할 때만 작동한다. 익숙한 레이블은 유용하지만, 적용 범위도 그만큼 중요하다.
Gemini 안전 차단 변경은 지정된 Google 차단 신호를 거부 응답 콘텐츠 블록으로 매핑한다. 설명에는 프롬프트 차단과 함께 SAFETY, PROHIBITED_CONTENT, BLOCKLIST 종료 사유가 언급돼 있다. 또한 공급자 식별 정보가 없으면 프롬프트 차단 경로에서 변환이 이뤄지지 않는 후속 통합 요구 사항도 문서화한다.
이 제한은 릴리스 분석의 핵심이다. 핵심 변환 기능이 존재한다는 이유만으로, 모든 관련 경로가 보이게 된다고 애플리케이션이 가정할 수는 없다. 응답은 변환이 기대하는 정보를 갖춘 상태로 그 변환 단계에 도달해야 한다.
OpenAI, Anthropic, Google은 여전히 서로 다른 비교 대상이다. 이들의 신호는 서로 다른 응답 구조를 통해 프레임워크에 들어온다. 엔지니어링 목표는 일관된 애플리케이션 처리이지, 근본 공급자들이 동일한 정책이나 의사결정 과정을 공유한다는 주장이 아니다.
공급자 자체 소프트웨어 개발 키트, 즉 서비스 호출을 위해 제공되는 라이브러리를 사용하는 팀에는 직접 접근도 합리적인 대안으로 남아 있다. 이는 네이티브 응답을 즉시 확인할 수 있게 해준다. 그 대가로 애플리케이션은 변환 작업을 더 많이 직접 책임져야 한다.
LangChain의 접근 방식은 그 작업 일부를 공유 구성 요소로 옮긴다. 장점은 반복되는 공급자별 검사 작업을 줄일 가능성이 있다는 것이다. 비용은 또 하나의 의존성이다. 애플리케이션은 통합이 관련 응답을 인식하고 유용한 세부 정보를 보존한다고 신뢰해야 한다.
어느 경로도 책임을 없애지는 않는다. 직접 통합은 공급자 필드를 잘못 해석할 수 있다. 공유 프레임워크는 통합 경로를 놓칠 수 있다. 의미 있는 비교는 변환이 어디에 존재하는지, 어떻게 테스트되는지, 현실과 일치하지 않게 됐을 때 누가 알아차리는지에 있다.
Gemini 사례는 이 비교를 구체적으로 보여 준다. 팀은 표준화 노력을 지지하면서도, 실제 배포된 응답 경로가 표준 표현에 도달한다는 증거를 요구할 수 있다. 인터페이스 설계와 작동하는 통합은 별개의 주장이라는 점에서 두 입장은 양립할 수 있다.
이 구분은 모니터링에도 영향을 준다. 인식된 거부 응답을 공통 범주로 묶으면 애플리케이션 보고서를 더 쉽게 해석할 수 있다. 그러나 범주를 지나치게 공격적으로 통합하면 어떤 공급자 상태가 발생했는지, 어떤 시정 조치가 적절한지를 숨길 수 있다.
따라서 실용적인 애플리케이션은 공통 결정과 이를 뒷받침하는 증거의 차이를 보존해야 한다. 공통 결정은 자동 처리를 중단하는 것일 수 있다. 증거는 여전히 어떤 응답이 그 결정을 촉발했는지 설명해야 한다.
이 때문에 LangChain의 거부 응답 처리는 새로운 타입 이름을 넘어 주목할 만하다. 가치는 공급자 출력을 의미 있는 애플리케이션 분기로 연결하는 데 있다. 이 연결이 실패하면 표준화된 형식은 이론상 존재해도 사용자는 여전히 설명 없는 빈 결과를 받는다.
따라서 이 릴리스는 통합 경계를 넘나들며 평가해야 한다. 공급자 패키지, 응답 변환, 애플리케이션 로직이 일치할 때 그 의미는 커진다. 고립된 구성 요소를 업그레이드하는 것만으로는 그 일치를 입증할 수 없다.
취소된 도구와 저장된 메시지는 같은 명확성 문제에 직면한다
함께 제공된 수정은 관련된 요구 사항을 다룬다. 실행이 예상 경로를 벗어난 뒤에도 소프트웨어는 무슨 일이 일어났는지 정확하게 보고해야 한다.
도구는 에이전트가 호출할 수 있는 외부 함수다. 추적 스팬은 작업에 대한 모니터링 기록이다. 취소가 이 기록을 닫지 않은 채 실행을 중단하면, 모니터링 화면은 이미 멈춘 작업을 잘못 표시할 수 있다.
도구 취소 수정은 이러한 불일치를 해결한다. 설명에 따르면 취소는 더 광범위한 Python 예외 범주를 사용하기 때문에, 이전에는 취소된 도구가 예상된 완료 콜백을 거치지 않았다. 이 변경은 오류를 보고한 뒤 원래 예외를 다시 발생시켜 취소가 계속 전파되도록 한다.
이 범위는 중요하다. 모니터링 기록을 종료하는 일은 외부 작업을 되돌리는 일과 다르다. 이번 릴리스가 도구 취소 시 이미 전송된 이메일, 데이터베이스 업데이트 또는 외부에서 수락된 요청까지 취소된다는 점을 입증하는 것은 아니다.
가상의 지원 어시스턴트를 예로 들면, 사용자가 중지를 누른 뒤에는 여러 질문을 각각 확인해야 한다. 로컬 실행이 취소를 받았는가? 모니터링 기록이 종료되었는가? 외부 서비스가 이미 작업을 수락했는가? 한 질문에 대한 답이 더 명확해졌다고 해서 나머지 질문까지 해결되는 것은 아니다.
운영상의 이점은 더 나은 해석이다. 정확하게 종료된 기록은 중단된 요청과 계속 진행 중인 작업을 구분하는 데 도움이 될 수 있다. 외부 효과가 실제로 발생했는지 조사할 때는 여전히 별도의 증거가 필요하다.
저장된 메시지 변경은 또 다른 종류의 단절된 이해를 다룬다. 직렬화는 객체를 저장하거나 전송할 수 있는 표현으로 변환하는 과정이다. 역직렬화는 이를 다시 구성한다. 송신 런타임이 아는 객체를 수신 런타임이 인식하지 못하면 호환성이 깨진다.
cross-language message loading 수정은 LangChain.js에서 직렬화한 RemoveMessage 객체를 Python에서 불러올 수 있도록 지원을 추가한다. 작성자는 해당 객체를 포함한 저장된 그래프 상태를 영향받는 사례로 지목한다. 이 수정은 지원되는 메시지 허용 목록에도 해당 클래스를 포함한다.
이는 모든 저장 객체가 언어 간에 자유롭게 이동한다는 일반적 보장이 아니라, 제한적인 상호운용성 복구다. 허용 목록은 허용된 객체 유형을 명시적으로 정한 집합이다. 하나의 유형을 추가하는 것은 특정 누락 매핑을 해결한다.
JavaScript 애플리케이션과 Python 분석 서비스를 운영하는 가상의 팀은 그 중요성을 보여 준다. 저장된 대화 대부분은 정상적으로 로드될 수 있다. 그러나 덜 흔한 메시지 작업은 해당 작업이 저장된 상태에 들어간 뒤에야 호환성 격차를 드러낼 수 있다.
교훈은 대표적인 텍스트만이 아니라 대표적인 상태를 평가해야 한다는 점이다. 대화에는 화면에 보이는 메시지와 함께 제어 정보가 포함될 수 있다. 일반적인 질의응답만 테스트하면 덜 눈에 띄는 객체는 검증 범위 밖에 남는다.
이 수정들을 함께 보면, 이번 릴리스는 단절된 변경 목록이 시사하는 것보다 더 일관된 모습을 보인다. 거부 번역은 결과를 명확히 한다. 취소 보고는 작업의 수명 주기를 명확히 한다. 언어 간 로딩은 저장된 상태를 해석할 수 있는 능력을 보존한다.
langchain-core==1.7.5에서 더 넓은 엔지니어링 주제는 이것이다. 주변 시스템에는 불완전하거나 예외적인 작업에 대한 정확한 설명이 필요하다. 각 문제는 모델 주도 활동을 해석하는 소프트웨어에서 발생하므로, 답변만 개선해서는 이러한 실패를 해결할 수 없다.
표준 거부가 안전을 보장하지는 않는다
가장 강한 회의적 해석은 완전한 애플리케이션 경로가 이를 올바르게 사용할 때에만 더 명확한 분류가 도움이 된다는 것이다.
이번 릴리스를 환영할 만한 합리적인 근거는 있다. 인식 가능한 결과는 개발자에게 의사결정에 더 유용한 자료를 제공한다. 반대로, 애플리케이션이 이를 일관되게 채택하지 않는다면 또 하나의 유형과 선택적 통합이 복잡성만 키울 수 있다는 합리적인 이의도 있다.
이 이의는 새로운 결함의 증거를 요구하지 않는다. 이는 아키텍처에서 비롯된다. 이후 코드가 응답 표현을 무시하거나 버리거나 일반 문자열로 변환한다면, 응답 표현만으로 애플리케이션 동작을 결정할 수는 없다.
모든 모델 응답을 사용자에게 보여 줄 출력을 준비하는 컴포넌트인 동일한 텍스트 렌더러로 표시하는 가상의 제품을 생각해 보자. 프레임워크는 거부를 정확하게 보존할 수 있다. 그럼에도 제품은 사용자가 보기 전에 그 구분을 잃어버릴 수 있다.
애플리케이션 설계에서는 반대 문제도 가능하다. 팀이 이번 변경 소식을 듣고 모든 빈 응답을 거부로 간주할 수 있다. 이는 명시적 신호 대신 추측을 사용하는 것이며, 관련 없는 문제를 감출 수 있다.
합리적인 기준은 의사결정 지점의 증거다. 개발자는 재시도, 표시, 에스컬레이션 또는 중지를 담당하는 코드까지 어떤 정보가 도달하는지 확인해야 한다. 이전 컴포넌트가 거부 블록을 지원한다는 확인은 유용하지만 충분하지 않다.
또 다른 한계는 정책에 관한 것이다. 제공자가 거부했다는 사실을 인식한다고 해서 그 요청이 유해했는지, 정당했는지 또는 오해된 것이었는지는 판단할 수 없다. 이번 릴리스는 표현과 처리를 바꾼다. 모든 제공자 결정의 품질에 관한 독립적 판단을 만들어 주지는 않는다.
이는 구매자와 안전성 주장을 논의할 때 중요하다. 제품은 거부를 정확히 인식하면서도 다른 위험한 요청을 부실하게 처리할 수 있다. 경로마다 거부를 일관성 없이 처리할 수도 있다. 표준 블록 유형이 존재한다는 사실만으로는 어느 가능성도 해결되지 않는다.
버전 범위 역시 동일하게 신중히 다뤄야 한다. 더 광범위한 거부 작업은 핵심 기능, 제공자 통합 및 에이전트 동작에 걸쳐 있다. 팀은 하나의 고정된 패키지가 병합된 변경 사항에 설명된 모든 기능을 활성화한다고 가정하지 말고, 자신들이 의존하는 설치된 구성 요소를 확인해야 한다.
테스트에는 예상된 성공 사례도 포함해야 한다. 예외적 결과에 초점을 둔 릴리스라 해도, 결국 일반적인 답변을 올바르게 반환해야 하는 애플리케이션에 적용된다. 유용한 평가는 구분이 개선되는 동시에 관련 없는 결과가 예상치 않게 바뀌지 않는지 점검한다.
여기에는 도입 후 사고가 줄어들었는지, 운영 비용이 낮아졌는지 또는 거부 정확도가 향상됐는지를 입증하는 독립적인 프로덕션 벤치마크가 제시되지 않았다. 이는 팀이 측정해야 할 결과로 남아 있다. 이번 릴리스는 구체적인 엔지니어링 변경을 제공할 뿐, 누군가가 이에 연결할 수 있는 모든 비즈니스 이점의 증거는 아니다.
따라서 적절한 업그레이드 근거는 더 제한적이고 방어 가능하다. 문서화된 변경이 관련 애플리케이션 동작을 다루므로 릴리스를 채택하고, 이후 맥락 속에서 그 동작을 검증해야 한다. 표준화만으로 에이전트가 신뢰할 수 있게 된다고 주장하지는 말아야 한다.
릴리스 이후 개발자가 주시해야 할 사항
다음으로 유용한 신호는 통합 적용 범위, 애플리케이션 동작, 재현 가능한 호환성 결과와 관련된다.
첫 번째 신호는 문서화된 Google 통합 작업의 후속 진행이다. 팀은 이후 변경이 프롬프트 차단 응답에 대한 제공자 식별과 메시지가 Gemini로 돌아갈 때 거부 블록 처리 문제를 다루는지 지켜봐야 한다.
이러한 증거는 공유 표현이 고립된 응답 번역만이 아니라 관련 워크플로를 포괄한다는 주장을 강화할 것이다. 지속적인 공백이 있다면 영향을 받는 Google 통합에서의 실질적 이점은 줄어든다.
중요한 관찰 대상은 전체 요청 경로에서의 동작이다. 후속 작업에 대한 릴리스 노트는 유용한 단서다. 설치된 통합에서 재현 가능한 결과는 애플리케이션의 차단된 응답 경로가 이제 의도대로 작동한다는 더 강한 증거다.
두 번째 신호는 명시적 거부 결정의 애플리케이션 채택이다. 유용한 증거는 거부가 빈 답변이나 일반적인 서식 오류로 나타나는 대신, 뚜렷한 제품 결과로 이어지는 모습을 보여 줄 것이다. 프레임워크 지원이 사용자에게 보이는 개선으로 바뀌는 지점이 바로 여기다.
팀은 포괄적인 신뢰성 점수를 공개하지 않고도 이 구분을 평가할 수 있다. 거절된 요청이 적절히 중지되는지, 관련 진단 정보를 보존하는지, 다른 실패 범주를 위해 마련된 자동 작업을 피하는지를 점검할 수 있다.
애플리케이션이 이러한 결과를 계속 하나로 뭉뚱그린다면 더 광범위한 표준화 논거는 약해진다. 프레임워크는 여전히 더 많은 정보를 노출하겠지만, 제품은 그 정보를 더 나은 결정으로 전환하지 못할 것이다.
세 번째 신호는 취소된 도구와 언어 간 상태에 대한 회귀 증거다. 회귀 검사는 이전에 수정된 동작이 계속 올바르게 유지되는지 확인한다. 여기서 유용한 사례는 중단된 실행과 영향을 받는 메시지 객체를 포함한 저장 상태를 다룰 것이다.
통과 결과는 구체적인 유지보수 주장을 뒷받침한다. 재현 가능한 실패는 문제가 핵심 패키지, 인접 통합 또는 애플리케이션의 가정 중 어디에 있는지 파악하는 데 도움이 된다. 어느 결과도 가능한 모든 워크플로에 관한 주장으로 확대해서는 안 된다.
앞으로 몇 달 동안 이러한 신호는 다운로드 수나 일반적 열의보다 더 나은 평가 기준을 제공한다. 이는 변경 사항이 그에 의존하는 사람과 시스템에 실제로 도달하는지를 묻는다. 또한 평가를 문서화된 범위에 계속 연결해 둔다.
langchain-core==1.7.5를 고려하는 팀이라면, 먼저 예상한 작업이 도착하지 않을 때 애플리케이션이 내리는 결정부터 살펴보라. 거부, 중단된 작업, 읽을 수 없는 저장 대화를 어떻게 구분하는지 검토하라. 그런 다음 사용자와 운영자가 실제로 보는 구성 요소 전반에서 이러한 결과를 추적하라.
평가는 이해할 수 있을 만큼 작게, 중요할 만큼 현실적으로 유지하라. 영향을 받는 사례와 함께 일반적인 성공 요청을 포함하고, 각 결과를 생성한 패키지 버전을 기록하라. 진단에 도움이 되는 제공자 세부 정보는 보존하되, 사용자 메시지는 명확하게 유지하라. 이 증거를 바탕으로 어떤 애플리케이션 분기에 변경이 필요한지 결정하라. 오늘날 시스템이 설명할 수 있는 결과는 무엇이며, 어떤 결과가 여전히 일반적인 실패 메시지 뒤로 사라지는가?



