
상주형 AI 에이전트의 '그럴듯한 거짓말'을 전송 전에 차단하는 설계 패턴
요약
상주형 AI 에이전트의 할루시네이션 문제를 해결하기 위해 발언 전 기계적으로 검증하는 설계 패턴을 제안합니다. 원천 데이터와의 대조, 추측과 사실의 분리, 그리고 정보 부족 시 침묵을 허용하는 프롬프트 전략을 통해 오정보 전송을 방지합니다.
핵심 포인트
- 상주형 에이전트는 인간의 실시간 검증이 불가능하므로 전송 전 가드 메커니즘이 필수적임
- 원천 데이터와 추출된 주장(Claims)을 단순 대조하여 명백한 날조를 검출함
- 사실과 추측을 구분하여 출력 형식을 설계함으로써 오해의 소지를 줄임
- 정보가 부족할 경우 'insufficient_data'를 반환하도록 하여 억지 답변을 방지함
대화형 챗봇이라면 할루시네이션 (Hallucination, 그럴듯한 오정보)이 섞이더라도 인간이 그 자리에서 "그거 틀리지 않아?"라고 지적할 수 있습니다. 하지만 상주형 에이전트는 아무도 보고 있지 않은 사이에 자발적으로 채팅에 발언합니다. 그 자리에서 검증해 줄 인간이 없기 때문에, 잘못된 요약이나 존재하지 않는 수치를 그대로 보내버리면, 알아차릴 때까지 사내에 잘못된 정보가 계속 남게 됩니다. 이 기사에서는 상주형 에이전트의 발언을 전송하기 전에 기계적으로 가드(Guard)하는 설계 패턴을 정리합니다.
대화형 챗봇의 할루시네이션 (Hallucination) 대책은 많은 경우 "답변 정밀도를 높이는" 방향으로 투자됩니다. 오답이 나와도 질문한 본인이 그 자리에서 위화감을 느낄 가능성이 높기 때문입니다.
반면, 상주형 에이전트는 다음과 같은 성질을 가집니다.
- 발언의 트리거가 인간의 질문이 아니라, 감시 대상의 변화 (이벤트 드리븐 (Event-driven))이다
- 발언 내용을 사전에 체크하는 인간이 발언하는 순간에는 존재하지 않는다
- "진척률 80%", "상대방은 긍정적"과 같은
수치나 단정을 포함하는 요약을 자발적으로 생성하기 쉽다
즉, 정밀도를 아무리 높여도 놓치는 부분이 제로가 되지 않는다는 전제하에, 잘못된 내용을 검지하여 멈추는 메커니즘을 발언 경로에 포함시켜야 합니다.
LLM의 출력을 그대로 채팅에 흘려보내는 것이 아니라, 전송 전에 "원천 데이터에 존재하지 않는 정보가 혼입되지 않았는가"를 기계적으로 대조합니다.
async function verifyBeforeSend(draft: AgentMessage, sourceDocs: SourceDoc[]) {
const claims = extractClaims(draft.text); // 수치·고유명사·단정 표현을 추출
const unverified = claims.filter(
...
여기서 supports는 엄격한 자연어 추론 (Natural Language Inference)일 필요는 없습니다. 우선은 "그 수치·고유명사가 원천 데이터의 어딘가에 문자열로서 존재하는가" 수준의 단순한 대조만으로도, 명백한 날조 (원천 데이터에 전혀 등장하지 않는 숫자를 내보내는 등)는 상당히 검출할 수 있습니다.
모든 오류를 검출로 막는 것은 현실적이지 않습니다. 검출하지 못한 부분은 표현의 레벨에서 오해를 부르지 않도록 하는 접근법을 병용합니다.
- 원천 데이터에 명기되어 있는 사실 → "~입니다"라고 단정하여 쓰게 함
- LLM이 여러 정보로부터 추측한 내용 → "~라고 생각됩니다 (추측)"라고 명시하게 함
프롬프트 (Prompt) 측에서 출력 형식을 분리해 두면, 후속 체크에서도 "추측 라벨이 붙은 문장에 수치가 포함되어 있지 않은가" 등, 단정문보다 완화된 규칙으로 처리할 수 있습니다.
{
"facts": ["A사와의 상담은 3/15에 실시되었다"],
"inferences": ["상대방의 반응으로 보아, 가격 면에서의 우려가 있을 가능성이 있습니다"]
...
의외로 간과하기 쉽지만, LLM에게 침묵·보류라는 선택지를 명시적으로 허용하는 것만으로도 할루시네이션 (Hallucination)은 상당히 줄어듭니다. "반드시 요약해 주세요"라는 지시는 재료가 부족하더라도 억지로 문장을 만들게 하는 방향으로 작용합니다.
const systemPrompt = `
정보가 부족하여 판단할 수 없는 경우에는 억지로 결론을 내지 말고
"status": "insufficient_data" 를 반환해 주세요.
...
insufficient_data를 받았을 경우, 에이전트는 가만히 아무것도 보내지 않거나, "정보가 갖춰지지 않았기 때문에 이번에는 보류합니다"라는 정형 메시지만 보내도록 합니다.
아무리 가드를 겹겹이 쌓아도 검출을 빠져나가는 오류는 제로가 되지 않습니다. 설계로서는 오전송의 발생 자체를 방지하는 것만큼이나, 오전송을 알아차렸을 때 정정하기 쉽게 만드는 것에 투자해야 합니다.
- 전송한 메시지에는 내부 ID를 갖게 하여, 나중에 "방금 전의 ◯◯라는 발언은 오류였습니다"라고 연결하여 정정 발언을 보낼 수 있도록 한다
- 차단된 발언 (패턴 1·3에서 멈춘 것)은 로그에 남겨, 왜 멈췄는지를 인간이 나중에 확인할 수 있도록 한다
정정 동선을 미리 만들어 둠으로써 가드 정밀도에 대한 심리적 압박도 낮아지고, 과도하게 보수적인 (아무것도 발언하지 않는) 튜닝을 피할 수 있습니다.
- 상주형 에이전트는 현장에서의 인간 체크 (Human-in-the-loop)가 작동하지 않기 때문에, 발언의 「전송 전」에 기계적인 가드 (Guard)를 삽입하는 설계가 필요함
- 원본 데이터에 존재하지 않는 수치·단정적 표현을 탐지하는 것, 사실과 추측을 출력 형식에서 분리하는 것, 「모름」을 허용하는 것, 이 세 가지는 구현 비용 대비 효과가 매우 큼
- 가드를 통과한 오류는 반드시 발생한다는 전제하에, 사후에 정정 내용을 보낼 수 있는 동선도 함께 설계함
「자율적으로 발언하는」 설계는 가치의 원천인 동시에, 잘못된 정보에 대한 리스크도 자발적으로 짊어지게 됩니다. 발언의 자유도를 높이기 전에, 이 4가지 패턴을 한 번 적용해 두면 사고를 줄일 수 있습니다.
필자는 Slack / Teams / Chatwork에 상주하는 기업용 AI 스태프 「HACH」를 개발하고 있습니다. 바로 이 전송 전 가드 설계를 통해 매일 운영하고 있습니다. 유사한 에이전트를 개발·운영하고 계신 분들께 참고가 되기를 바랍니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기