이득:
- 사용자 권한에 따라 검색을 필터링하는 액세스 제어(ACL) 설정
- 컨텍스트와 사용자 질문을 올바르게 배치하는 견고한 프롬프트 템플릿 작성
- 다각적인 대화를 통해 질문 독립성과 이력 관리 연습
우리는 아키텍처를 확립했습니다. 이제 안전하고 일관되며 대화 가능하게 만들어 보겠습니다. 이 단원에는 세 가지 중요한 주제가 있습니다. (1) 사용자 권한에 따라 검색을 필터링하는 액세스 제어, (2) 컨텍스트와 질문을 올바르게 배치하는 강력한 프롬프트 템플릿, (3) 다단계 채팅에서 질문 독립성과 대화 기록 관리입니다. 이 세 가지가 없으면 어시스턴트는 데이터를 유출하거나 일관되지 않은 답변을 제공하거나 후속 질문에서 무너질 것입니다.
액세스 제어: 승인되지 않은 데이터는 절대 도착하지 않아야 합니다.
기업의 가장 큰 위험: 사용자가 볼 수 없는 문서가 응답으로 누출됩니다. 매우 흔한 초보자 실수는 "프롬프트에서 모델에게 '숨겨진 문서 표시'를 지시하는 것"입니다. 이것은 안전하지 않습니다. 모델이 지시를 잊어버릴 수도 있고, 즉각적인 주입이 지시를 회피할 수도 있습니다. 올바른 장소는 회수 단계입니다. 승인되지 않은 조각은 전혀 가져오면 안 됩니다.
이를 수행하는 방법은 검색 중에 각 부분에 필터로 적용한 권한 메타데이터(부서, 역할, 개인 정보 수준)를 적용하는 것입니다. 애플리케이션 계층에서 사용자가 누구인지(ID 및 역할) 안전하게 확인하고 호출에 ACL(액세스 제어 목록) 필터를 추가합니다.
# 권한 검색으로 필터링됨 (개념적)user = authenticate(session) # 신뢰할 수 있는 소스에서 인증됨 = user.roles + ["everyone"] # 예: ["HR", "admin"]result = vektor_db.search( vektor=embed(question), top_k=20, filter={"permission_group": {"in": allowed}, # 허용되는 부분만 "privacy": {"lte": user.level}} # 수준 아래)
주의: 절대로 모델에게 권한을 요청하거나 프롬프트에 의존하지 마십시오. 신원과 권한은 애플리케이션의 신뢰할 수 있는 계층에서 결정됩니다. 검색 필터는 필수이며 프롬프트 지침은 추가 레이어일 뿐입니다. "프롬프트에 썼습니다"는 보안이 아닙니다.
솔리드 프롬프트 템플릿
프롬프트 템플릿은 검색의 컨텍스트, 사용자 질문, 행동 지침을 함께 가져오는 뼈대입니다. 좋은 템플릿의 일부: 역할/작업 설명, 행동 규칙(기본, 권한을 모르겠습니다, 리소스 요청, 어조), 맥락, 질문.
당신은 기업 HR 보조원입니다. 귀하의 임무는 다음 CONTEXT를 토대로 직원의 질문에 답변하는 것입니다. 규칙:- 답변이 문맥상 명확하지 않은 경우 "문서에서 이에 대한 정보를 찾을 수 없습니다. HR 팀에 문의하십시오."라고 적으십시오. 추측하지 말고 꾸며내지 마십시오.- 문맥상 출처가 상충되는 경우 공식 정책을 근거로 삼아 모순을 기술하십시오.- 각 주장 끝에 [출처: 파일, 섹션]으로 의존하는 출처를 추가하십시오.- 짧고 명확하며 전문적인 언어로 답변하십시오. 컨텍스트:{numbered_parts}질문: {user_question}
문맥 부분([1], [2], ...)에 번호를 매기면 모델을 인용하기가 더 쉽습니다. 또한 모델이 올바르게 인용할 수 있도록 각 작품의 시작 부분에 출처를 적어주세요.
팁: 프롬프트 템플릿을 일정하게 유지하고 변수(컨텍스트, 질문)를 항상 같은 위치에 배치하세요. 고정 템플릿은 일부 시스템의 신속한 캐싱 덕분에 테스트 가능성을 높이고 비용을 절감합니다.
맥락:[1] (출처: ik_el_kitabi.pdf, 섹션 5.2) 연간 유급 휴가는 14일입니다...[2] (출처: ik_el_kitabi.pdf, 섹션 5.4) 휴가는 5년 이상 근속자의 경우 20일입니다.
약한 프롬프트 / 강한 프롬프트
약함(근거 없음, 소스 없음, 정체성 혼합):
다음 문서를 사용하고 질문에 답하십시오: {parts}사용자: {question}# 문제: 모델이 맥락을 벗어나고, 구성하고, 출처를 인용하지 않고, # 임의로 모순되게 행동합니다.
강력(역할 + 규칙 + 번호가 매겨진 컨텍스트 + 소스 필수):
당신은... CONTEXT에 의존하세요. 그렇지 않으면 "모르겠어요"라고 말하세요. 충돌할 경우 공식 정책을 선택합니다. 각 주장에 [출처: ...]를 추가하세요.CONTEXT: [1]... [2]... QUESTION: {질문}# 결과: 문맥에 충실하고, 출처를 밝히고, 모순을 올바르게 관리하는 답변입니다.
멀티투어 대화 관리
실제 사용자는 질문 하나도 하지 않고 그대로 놔둡니다. 말한다. "나의 연차휴가는 며칠인가요?" → “6년차 직원은요?” → “어떻게 신청하나요?” 두 번째와 세 번째 질문만으로는 의미가 없습니다. 이전 상황에 따라 달라집니다.
두 가지 문제를 해결해야 합니다. 첫 번째는 검색을 위한 것입니다. 후속 질문을 독립적으로 만듭니다(질문 재작성). “6년차 직원은요?” → "6년차 근로자의 연차휴가는 몇일인가요?" 이 독립적인 질문으로 검색합니다. 두 번째는 생산을 위한 것입니다. 또한 대화 기록을 모델에 제공하여 일관되게 계속되도록 합니다.
# 2단계: 독립화 → 검색 → 기록을 사용하여 생성(개념적) independent = model.uret( "대화 기록을 사용하여 질문을 자체적으로 이해할 수 있도록 만듭니다.\nHistory: {history}\nQuestion: {follow_question}") context = retrieval(independent) # 독립적인 질문을 사용하여 검색답변 = model.uret(prompt(context, History, follow_question))
기록이 늘어나면(긴 대화) 한 번에 모두 보내는 것은 비용이 많이 들고 컨텍스트 창을 채웁니다. 해결책: 이전 라운드를 요약하거나 마지막 N 라운드를 유지하고 이전 라운드를 요약으로 줄입니다. 따라서 비용은 통제되고 일관성이 유지됩니다.
상태
문제
솔루션
후속 질문에는 맥락이 없습니다.
의미 없는 검색 검색
질문을 독립적으로 만들기(다시 작성)
긴 대화
비용 및 창문 팽창
지난 투어 요약
사용자가 주제를 변경했습니다.
이전 컨텍스트가 감염됨
새로운 주제에 대한 과거의 영향력 감소
권한은 투어마다 다를 수 있습니다.
누출 위험
매 라운드마다 ACL 필터를 다시 적용합니다.
미니 케이스 3개
사례 1 — 즉각적인 "보안" 오류. 한 회사는 누구나 물어볼 수 있는 급여 기밀 문서를 비서에게 올려줬지만, 프롬프트에는 '연봉 정보를 알려주지 마세요'라고만 썼다. 모델은 사용자가 우회적으로 질문을 했을 때 급여 범위를 유출했습니다. ACL 필터가 검색에 추가되었을 때(HR 역할에 대한 급여 부분만) 누출이 완전히 닫혔습니다. 왜냐하면 그 부분은 더 이상 가져오지 않기 때문입니다.
사례 2 — 맥락 없는 스토킹. 지원 도우미에서 사용자가 "반품 기간은요?"라고 묻습니다. → “깨진 제품은 어떡해요?” 시스템은 "깨진 제품"과 관련 없는 부품을 가져왔습니다. 질문 독립성('깨진 제품의 반품 기간은 얼마나 되나요?')을 추가하자 정답률이 44%에서 90%로 높아졌습니다.
사례 3 — 과거가 부어올랐습니다. 어시스턴트와의 30라운드 채팅에서 각 통화는 전체 기록을 전송했습니다. 비용은 라운드당 3배씩 증가했고, 반응도 느려졌습니다. 마지막 6라운드를 유지하고 이전 라운드를 요약하는 구조로 전환했을 때 토큰 비용이 62% 감소하고 일관성이 유지되었습니다.
일반적인 실수
- 권한을 프롬프트에 남기기: 모델이 잊어버리거나 우회합니다. 검색 시 ACL 필터가 필수입니다.
- 맥락을 열거하지 않음: 모델이 올바른 출처를 인용할 수 없습니다.
- 후속 질문을 독립화하지 않음: 검색 검색이 무의미합니다.
- 모든 내역을 블라인드로 보내기: 비용과 지연이 폭발적으로 증가합니다. 요약하다.
- 모순 규칙을 작성하지 않음: 모델은 신뢰할 수 없는 출처를 공식적으로 제시할 수 있습니다.
요약하면
- 액세스 제어는 검색 단계에서 메타데이터 필터를 사용하여 구현됩니다. 승인되지 않은 부품은 절대 가져오시면 안됩니다.
- 신원과 권한은 신뢰할 수 있는 애플리케이션 계층에서 결정됩니다. 즉각적인 지시는 추가적인 방어 계층일 뿐입니다.
- 강력한 프롬프트 템플릿에는 역할, 행동 규칙(근거, 모르는 권한, 출처, 갈등), 번호가 매겨진 컨텍스트 및 질문이 포함됩니다.
- 다단계 대화에서는 후속 질문이 분리되고 모델은 기록과 함께 일관된 답변을 생성합니다.
- 오랜 역사를 요약함으로써 비용 및 상황 창을 통제할 수 있습니다. ACL은 매 라운드마다 다시 적용됩니다.
응용과제
(1) 자신의 비서에 대해 최소 3개의 권한 그룹(예: 모든 사람, 부서, 관리자)을 정의하고 어떤 문서 유형이 어떤 그룹에 공개되는지 표에 작성합니다. (2) 자신의 역할과 어조에 따라 위의 프롬프트 템플릿을 적용하고 작성합니다. 컨텍스트에 번호를 매기고 소스를 지정합니다. (3) 3단계의 현실적인 대화 시나리오(질문 → 후속 조치 → 후속 조치)를 작성하고 각 후속 질문의 독립적인 버전을 수동으로 생성합니다. (4) 이 시나리오에서 매 라운드마다 ACL 필터를 다시 적용해야 하는 이유를 한 문장으로 설명합니다.
체크리스트
- [ ] 검색 필터를 사용하여 액세스 제어를 구현하지만 프롬프트에 의존하지 않습니다.
- [ ] 프롬프트 템플릿에 근거, 권한, 소스 및 충돌 규칙을 알 수 없음을 추가합니다.
- [ ] 문맥 부분에 번호를 매기고 참조했습니다.
- [ ] 나는 검색 전에 후속 질문을 독립적으로 만듭니다.
- [ ] 오랜 대화 내역을 정리하여 비용과 창구를 관리합니다.