Nova Adiutrix: My Second Agent Built My First Project's To-Do List
두 번째 에이전트가 첫 프로젝트의 할 일을 구현했습니다
AWS Bedrock 기반 고객 지원 에이전트 Nova Adiutrix를 만들며 검색 정확도, 주문 소유권 검사, 테스트 검증, 클라우드 자원 정리에서 겪은 문제를 기록합니다. 프롬프트 지시만으로 보안을 맡기지 않고 코드와 실행 증거로 검증한 과정이 중심입니다.
- 주제
AI 요약
AWS 나노디그리의 두 번째 프로젝트로 온라인 상점 고객 지원 에이전트 Nova Adiutrix를 만들었습니다. 주문 조회와 환불, 정책·상품 문의, 로열티 할인 계산, 실시간 웹 페이지 조회를 맡깁니다. 첫 프로젝트 Nova Trivium의 README에 적어 둔 미구현 항목 가운데 검색과 구조화된 출력을 이번 프로젝트에서 다뤘습니다. 작성자는 에이전트를 만들며 첫 프로젝트에서 만난 문제를 한 단계 깊은 곳에서 다시 겪었다고 설명합니다.
프롬프트 삽입과 검색의 차이
Nova Trivium은 32개 항목으로 된 짧고 안정적인 FAQ를 빌드 스크립트로 시스템 프롬프트에 넣었습니다. 모델이 별도로 검색하지 않아도 답변에 필요한 내용이 항상 주어졌습니다. 다만 자료가 커지면 프롬프트에 전부 담기 어렵습니다.
Nova Adiutrix는 상품 카탈로그와 정책 문서를 Amazon Bedrock Knowledge Base에 넣었습니다. 관리형 벡터 저장소가 문서를 청크로 나누고 의미를 나타내는 벡터로 바꾼 뒤, 질문과 가까운 청크를 찾아 에이전트에 전달합니다. 이 방식은 자료의 양보다 검색 결과의 관련성이 문제입니다. 예를 들어 질문과 가까운 문장으로 잘못 검색된 15일 전자제품 반품 기간을 모델이 근거로 삼아 자신 있게 답할 수 있습니다. 작성자는 짧은 FAQ에는 프롬프트 삽입이 적절했다고 봅니다. 다만 RAG가 큰 문서 모음에 유리하다는 문서상의 설명과 실제 검색 오류를 마주하는 경험은 다르다고 짚습니다.
주문 권한 검사는 프롬프트 밖에서
시스템 프롬프트에는 고객이 메시지에 적은 주문 ID만으로 소유권을 인정하지 말고, 도구 데이터로 로그인한 고객의 주문인지 확인하라는 규칙을 넣었습니다. 하지만 주문 조회 함수 자체에는 소유권 검사가 없었습니다. 모델에게 지시하는 것만으로는 보안 통제를 보장하지 못하기 때문에 Python 래퍼로 검사를 옮겼습니다.
Claude가 첫 구현을 검토하면서 소유권 조회에서 오류가 나면 주문을 그대로 반환하는 실패 허용(fail open) 동작을 발견했습니다. 또 단일 주문 조회만 검사하고, 고객의 전체 주문 내역을 반환하는 도구는 모델이 전달한 고객 ID를 그대로 사용한다는 점도 확인했습니다. 두 문제를 수정한 뒤 첫 테스트에서 에이전트가 주문 정보를 거부했습니다. 소유권 조회 도구가 코드에서 예상한 방식으로 호출되지 않아 소유 여부를 확인하지 못했기 때문입니다. 확인이 안 될 때 거부하는 실패 폐쇄(fail closed) 동작은 의도한 보안 행동이지만, 로그만 보면 시스템이 정상적으로 방어하는 것처럼 보여 문제를 알아차리기 어렵다고 설명합니다.
체크포인트는 실행 결과로 확인
첫 프로젝트에서는 “버그 대화에서 도구 호출이 대화 기록에 보인다” 같은 서술형 조건으로 QA 체크포인트를 만들었습니다. 빌드 에이전트 Kiro는 테스트 스크립트가 저장소에 없는데도 구현이 조건을 만족한다고 판단해 체크를 완료했습니다. 조건을 문장으로만 쓰면 에이전트가 실행 없이 스스로 통과를 선언할 수 있었습니다.
두 번째 프로젝트에서는 체크포인트마다 명령어와 실행 결과를 남겼습니다. 결과를 붙여 넣을 수 없으면 통과로 처리하지 않았습니다. 이 방식으로 코드 검토에서 놓친 소유권 래퍼 버그 두 건과, 밑줄로 시작하는 _orig 매개변수 때문에 도구 데코레이터의 스키마 생성 단계에서 임포트가 실패하는 문제를 찾았습니다. Claude의 코드 검토는 이 문제를 잡지 못했지만, Kiro가 작성하고 실행한 스텁 테스트는 AWS 자원을 만들기 전에 빠르게 발견했습니다. 작성자는 에이전트가 생성한 결과를 사람이 검증하고 판단하는 흐름을 유지하되, 검증 대상이 실제로 실패하는 모습을 보여야 한다고 강조합니다.
AWS 자원 해제도 테스트 대상
Nova Adiutrix는 OpenSearch Serverless 벡터 저장소를 사용합니다. 이 서비스는 사용하지 않을 때도 자원이 존재하면 비용이 발생합니다. 권장 설정 절차는 컬렉션을 자동 생성하지만, Knowledge Base를 삭제해도 컬렉션까지 지우지는 않습니다. 그래서 자원을 생성하는 순간 해제 명령을 정리 스크립트에 추가했고, 컬렉션 삭제 명령은 생성보다 먼저 작성했습니다. 마지막에는 AWS 계정에서 프로젝트 이름으로 태그된 자원을 검색해 결과가 없어야 정리를 완료한 것으로 처리했습니다.
한 번 작업하는 동안 비용은 시간당 약 50~70센트였고, 작업이 끝난 뒤에는 0이 됐습니다. 마지막 검색에서는 한 달 전 Nova Trivium 작업 뒤 남아 있던 게이트웨이와 메모리 저장소도 발견했습니다. 작성자는 첫 프로젝트를 완전히 정리했다고 생각했지만 실제로는 아니었다고 덧붙입니다. 세 번째 프로젝트에서는 아직 구현하지 않은 가드레일을 다룰 예정이며, 에이전트가 스스로 인증할 수 없는 체크포인트를 만드는 더 나은 방법에 관한 의견도 요청합니다.
dev.to 반응
- @brianainews — 에이전트 2번으로 에이전트 1번의 미완성 목록을 처리한 메타적인 구성이 마음에 듭니다. 에이전트형 시스템이 내세우는 이야기를 하나로 보여주는 사례 같네요. 이런 글에서 제가 보고 싶은 부분은 인수인계 품질입니다. Nova Adiutrix가 맥락을 깔끔하게 이어받았나요, 아니면 세션 사이에 목표와 제약을 다시 설명해야 했나요? 두 번째 에이전트가 첫 프로젝트를 제멋대로 수정하기 시작한 뒤에도 자동화하지 않기로 한 부분, 예를 들면 권한, 배포, 비밀 정보가 있었는지도 궁금합니다.
- @earlgreyhot1701d — 수강 중인 과정의 두 번째 프로젝트였기 때문에 새로운 맥락은 깔끔하게 이어받았습니다. 첫 프로젝트를 만들 때는 요구사항이 있었고, 여유가 있는 부분도 범위를 좁혀 진행한 뒤 README에 적었습니다. 두 번째 프로젝트에서는 첫 프로젝트에서 멈춘 부분 가운데 일부를 이어서 만들고 있다는 걸 깨달았습니다. 새 요구사항을 바탕으로 첫 프로젝트에서 중단한 작업을 이어간다고 기록했습니다. 세 번째 프로젝트는 10월 말에 시작하는데, 앞선 두 프로젝트를 어떻게 이어받을지 정말 궁금합니다.
원문: dev.to / 번역·요약: Trawling