작동 원리

Grounded 답변

문서가 에이전트가 답변할 수 있는 형태로 변환되는 과정 — 청킹, 컨텍스트 헤더, 쿼리 재작성, 그리고 관련성 임계값

"문서에서 얻은 답변"은 주장하기는 쉽지만 잘 실행하기는 어렵습니다. 이 페이지는 파일 업로드부터 근거 있는 문장 생성까지 플랫폼이 실제로 수행하는 과정을, 일반적으로 공개되지 않는 부분을 포함하여 설명합니다.

파일에서 청크로

수집: 문서당 한 번

1. 파싱

파일이 텍스트로 파싱됩니다 — 그림이 있는 문서의 경우 그림도 읽습니다(아래 참조). 포맷별 추출이 여기서 발생하며, 이후 모든 단계에서는 평문 텍스트만 처리됩니다.

2. 청크 분할

토큰 단위로 크기가 조정된 청크로 분할됩니다 — 하지만 텍스트는 문자 단위로 분할되므로, 토큰과 문자 간의 비율은 문서의 스크립트 자체를 기반으로 추정됩니다. 라틴어 계열 언어에 적용된 비율을 중국어에 사용하면 의도한 크기보다 몇 배 큰 청크가 생성됩니다.

3. 헤더

각 청크에는 문서 제목(및 선택적으로 생성된 참고 사항)이 접두사로 추가됩니다. 이 헤더는 임베딩에만 사용됩니다. 저장된 텍스트는 변경되지 않으며, 헤더는 벡터가 해당 구절의 출처를 반영하도록 하기 위해 존재합니다.

4. 임베딩

청크와 헤더가 벡터로 임베딩됩니다.

5. 저장

암호화되어 저장되며, 해당 공간(space)으로 범위가 제한됩니다. 여기서부터는 해당 공간 내에서만 검색 가능합니다.

문서가 업로드될 때 실행됩니다. 아래의 쿼리 경로는 모든 질문에 대해 실행됩니다.

쿼리: 질문당 한 번

1. 질문

고객이 무언가를 묻습니다 — 종종 문맥에서만 의미가 있는 후속 질문입니다: "그것의 이율은 얼마인가요?"

2. 재작성

질문이 이전 대화 맥락에 의존하는 경우, 검색용 벡터에만 자기 완결형(self-contained) 질문으로 재작성됩니다. 모델에는 여전히 고객의 원문이 전달되며, 실패 시 원문으로 폴백됩니다.

3. 임베딩

(재작성된) 질문은 청크에 사용된 동일한 모델로 임베딩됩니다.

4. 검색

코사인 유사도 기반 최근접 이웃 검색이 수행되며, 거리 순으로 정렬됩니다. 애플리케이션 필터가 아닌 데이터베이스 수준에서 해당 최종 사용자의 공간으로 범위가 제한됩니다.

5. 바닥값

최대 거리보다 먼 매칭은 제외됩니다. 요청한 수보다 적은 구절을 반환하는 것이 올바른 결과입니다 — 검색 시스템이 유창하지만 잘못된 답변을 생성하는 방식은 결과를 고정된 개수로 채우는 것입니다.

6. 답변

살아남은 구절은 복호화되어 모델로 전달됩니다. 아무것도 살아남지 않으면 에이전트는 답변이 없다고 말합니다.

바닥값(floor) 단계는 에이전트가 답변할지 여부를 결정합니다.

업로드된 문서는 텍스트로 파싱되고, 청크로 분할되며, 임베딩되고, 암호화되어 저장됩니다. 분할 과정에서 두 가지 세부 사항이 겉보기보다 더 중요합니다.

청크 크기는 토큰 단위로 측정되지만, 텍스트는 문자 단위로 분할됩니다 — 따라서 플랫폼은 토큰과 문자 간 변환을 수행해야 하며, 이 변환은 언어에 따라 다릅니다. 라틴어 계열 언어에 대한 대략적인 토큰당 ~4자의 비율은 중국어, 일본어, 한국어에는 크게 잘못되었습니다. 이러한 언어에서는 단일 문자가 거의 전체 토큰에 가깝기 때문입니다. 전역 상수를 하나 사용하면 CJK(중국어, 일본어, 한국어) 문서의 청크가 의도한 크기의 몇 배가 됩니다: 청크가 할당된 컨텍스트를 초과하고, 검색 시 텍스트의 벽(walls of text)이 반환됩니다.

따라서 분할기는 문서 내용 자체에서 비율을 추정하며, CJK와 라틴어 비율 사이를 보간합니다. 텍스트 중 CJK가 차지하는 비율에 따라 결정됩니다. 중국어/영어 혼합 계약서는 두 극단 사이의 어딘가에 위치합니다.

가능하면 단락을 유지합니다. 청크는 대상 크기에 도달할 때까지 단락 단위로 누적됩니다. 단락 자체가 oversized한 경우에만 강제로 분할됩니다. 연속된 청크는 구성 가능한 양만큼 겹치며, 이전 청크의 끝부분을 다음 청크로 이어지게 하여 경계를 가로지르는 사실도 양쪽에서 검색 가능하도록 합니다.

기본값은 플랫폼 구성의 chunk_target_tokenschunk_overlap_tokens입니다. 이는 고정된 보증이 아닌 테넌트(tenant)가 조정 가능한 값이며, 적절한 크기는 귀하의 문서에 따라 다릅니다.

텍스트 레이어뿐만 아니라 그림도

대부분의 문서 추출은 텍스트 레이어에서 멈춥니다. 데이터시트, 설치 매뉴얼 또는 보고서를 업로드하면 일반적인 파이프라인은 본문 텍스트를 추출하고, 입력된 것이 아니라 그려진 모든 것 — 배선도, 회로 레이아웃, 페이지 중간에 있는 차트 — 을 조용히 버립니다. 파일은 "처리"되었지만, 그 내용이 절반은 읽히지 않았습니다. "CPU 팬의 헤더는 어디인가?"라고 묻더라도, 답변은 인덱스에 없습니다. 왜냐하면 그 정보가 그림에만 있었기 때문입니다.

이 플랫폼은 그것들도 읽습니다.

  • 스캔된 또는 이미지 전용 PDF — 텍스트 레이어가 전혀 없음 — 은 페이지별로 렌더링되고 비전 모델에 의해 전사되므로, 사진 찍힌 계약서나 스캔된 양식이 검색 가능한 텍스트가 됩니다.
  • 혼합 문서 — 텍스트 레이어 plus 그림 — 는 다른 시스템이 놓치는 경우입니다. 실제 그림이 포함된 페이지는 렌더링되고 비전 모델에 의해 설명되며, 그 설명은 문서의 텍스트에 통합되어 청크로 분할되고 임베딩되어 본문과 함께 검색 가능해집니다. 회로 레이아웃 페이지는 커넥터 이름과 그 위치를 반환합니다. 차트는 추세와 숫자를 반환합니다.
  • Word 파일의 임베딩 이미지는 문서에서 추출되어 동일한 방식으로 설명됩니다.

어려운 부분은 비전 모델을 호출하는 것이 아닙니다 — 장식적인 사이드바에 대해 40번 호출하지 않는 것입니다. 매뉴얼은 모든 페이지에 로고와 페이지 테두리를 반복합니다. 이를 설명하는 것은 순수한 비용과 순수한 노이즈입니다. 따라서 그림 감지는 실제 다이어그램(많은 벡터 경로, 큰 사진, 이미지의 몽타주)과 템플릿 장식(콘텐츠가 동일한 이미지가 페이지 전반에 걸쳐 반복됨)을 구분하며, 정보가 있는 페이지만 전송합니다.

그림 설명은 비전 모델을 사용하므로 텍스트 전용 추출보다 비용이 더 듭니다. 두 가지 안전 장치: 그림이 많은 문서는 청구 금액이 불어나기 전에 확인을 요청하며, 이미지 설명 비용은 사용량에서 vision_image라는 자체 항목으로 표시되므로 항상 어디에 지출되었는지 확인할 수 있습니다.

컨텍스트 헤더

단독으로 임베딩된 청크는 그것이 특정 문서에서 왔다는 사실을 잃어버립니다. "차항 7.2는 차환자가 디폴트 상태일 때 적용된다"는 구절은 "브리지 상품에 대한 납부를 놓치면 어떻게 되나요?"라는 쿼리에 대해 검색이 잘 되지 않습니다 — 해당 청크는 자신이 속한 상품을 언급하지 않기 때문입니다.

임베딩 전에 각 청크에는 컨텍스트 헤더가 접두사로 추가됩니다 — 문서 제목 및 선택적으로 LLM이 생성한 상황 참고 사항 — 벡터가 구절과 그것이 속한 내용을 모두 반영하도록 합니다. 저장된 텍스트는 변경되지 않으며, 헤더는 임베딩 입력에만 포함됩니다.

쿼리 재작성: 대부분의 시스템이 건너뛰는 부분

검색 품질은 일반적으로 랭킹 문제로 논의됩니다. 종종 그렇지 않습니다 — 종종 쿼리에는 정보가 전혀 포함되어 있지 않습니다.

고객이 "그것의 이율은 얼마인가요?"라고 묻습니다. 대명사는 두 턴 전에 언급된 것을 참조합니다. 그 문장을 임베딩하면 벡터는 특정 것과 유사하지 않으며, 해당 턴의 검색은 거의 무작위입니다. 리랭킹이 아무리 많아도 신호가 없었으므로 해결되지 않습니다.

따라서 임베딩 전에 이전 맥락에 의존하는 후속 질문은 자기 완결형 질문으로 재작성됩니다. 세 가지 의도적인 선택:

  • 과도한 트리거링을 선호합니다. 참조 표현식의 정규식 재작성 시도를 결정합니다. 불필요하게 트리거링하는 것은 값싼 호출 하나와 변경되지 않은 자기 완결형 질문을 초래합니다; 트리거링하지 못하면 해당 턴의 검색이 완전히 실패합니다.
  • 키워드가 아닌 더 긴 문장으로 재작성합니다. 임베딩 모델은 문장에 대해 학습되었습니다. 키워드로 줄이면 관계("차환자의 채권자에 대한 책임"과 그 역)가 동일한 벡터로 수렴하고, 부정("보증인이 필요하지 않은 사례는 무엇인가")이 손실됩니다.
  • 검색 벡터에만 영향을 미칩니다. 모델로 전달되는 메시지는 항상 고객의 원문입니다. 재작성은 프롬프트, 대화 기록 또는 저장소에 들어가지 않으며, 실패 시 원문으로 폴백되므로 최악의 경우에도 기존 동작과 정확히 동일합니다.

검색 및 관련성 바닥값

쿼리 벡터는 해당 최종 사용자의 공간으로 범위가 제한된 청크와 코사인 거리로 비교됩니다. 이 범위는 잊혀질 수 있는 애플리케이션 수준의 필터가 아닙니다 — 데이터베이스 수준에서 강제됩니다.

상위 매칭은 이후 최대 거리에 의해 필터링됩니다. 이것이 유용한 에이전트와 자신감 있는 에이전트를 구분하는 부분입니다:

Illustrative — try it
Question
토요일에 예약을 받습니까?
0.19
0.34
0.52
0.78
영업 시간반환됨

월요일부터 금요일까지 9:00부터 17:00까지 직원이 상주합니다.

예약 정책반환됨

예약은 최소 한 영업일 전에 진행됩니다.

취소삭제됨

24시간 이내 취소는 수수료의 절반이 부과됩니다.

소개삭제됨

1998년 두 파트너에 의해 설립되었으며, 현재 9명의 팀원입니다.

The agent replies
월요일부터 금요일까지 9:00부터 17:00까지 운영합니다 — 토요일 예약은 받지 않습니다.

Illustrative. 가상의 클리닉을 위한 샘플 거리입니다. 실제 값은 귀하의 문서와 임베딩 모델에 따라 다르며 — 여기서는 측정되지 않았으며, 바닥값은 테넌트 구성 가능함.

요청한 수보다 적은 수의 청크를 반환하는 것이 올바른 결과이며, 부족이 아닙니다. 지식 베이스에 관련 있는 것이 없으면 에이전트는 아무것도 얻지 못하고 그렇게 말하며, 가장 덜 관련 없는 구절들을 넘겨받아 그 사이를 연결하는 내용을 발명하지 않습니다. 결과를 고정된 개수로 채우는 것은 검색 시스템이 유창하고 출처가 있는 것처럼 보이지만 잘못된 답변을 생성하는 방식입니다.

필터는 SQL 술어에서가 아닌 랭킹된 후 적용됩니다 — 결과가 이미 거리 순으로 정렬되어 있으므로 결과는 동일하지만, 전체 테이블 후처리(post-filter)로 저하되는 대신 깔끔한 인덱스 스캔을 유지합니다.

검색은 성공했지만 여전히 실패하는 경우

관련성 바닥값은 충분히 가까운 것이 없는 경우를 잡아냅니다. 그러나 이를 볼 수 없는 더 어려운 경우가 있습니다: 모든 구절이 바닥값을 통과하고, 주제는 맞지만 질문이 다루던 한 가지 사실이 그 어느 것에도 포함되어 있지 않습니다.

이 사이트의 자체 사전 판매 에이전트에서 측정함. *"Starter 플랜에 있고 월 사용량이 30%씩 증가한다면, 6개월 후 얼마를 지불하게 됩니까?"*라고 묻자, 검색은 세 가지 구절을 반환했습니다: Starter 플랜 페이지, 토큰 사용 가이드, 서비스 약관. 모두 관련이 있습니다. 어느 것도 가격을 명시하지 않습니다 — 플랜 페이지는 그 플랜이 누구를 위한 것인지에 대한 페이지입니다. 숫자가 없는 "Starter"라는 제목의 문서를 주면, 모델은 숫자를 하나 공급했습니다. 5번의 실행 동안 $5, $250, $99, $0 및 $29를 생성했으며, 각각 인용 표시가 붙어 있었습니다. 실제 금액은 $49입니다.

어떤 것도 감지 가능한 방식으로 실패하지 않았습니다. 거리가 적절했으므로 보고할 검색 누락이 없었습니다. 인용은 실제로 검색된 구절을 가리켰습니다. 오직 답변만 틀렸습니다.

코드에서 결정된 두 번째 패스

따라서 첫 번째 검색 후, 돌아온 내용에 대해 두 가지 질문이 수행됩니다 — 모두 문자열 비교로 답변 가능하며, 모델에 위임되지 않습니다:

질문하는 대상이 언급되어 있는가? 질문의 고유 명사, plus 지식 베이스의 문서 제목에서 추출한 용어 — 우리가 추측한 것이 아니라 누군가가 선별한 어휘. 용어가 질문과 검색된 구절 모두에 나타나지 않으면, 해당 용어를 별도로 검색합니다.

질문하는 대상의 측면이 있는가? 이는 첫 번째 확인이 놓치는 절반이며, 위의 측정에서 맞은 부분입니다: Starter 검색된 텍스트에 있었습니다; 가격은 없었습니다. 따라서 각 질문은 또한 그것이 무엇을 묻는 것과 일치합니다. 일부는 고정된 형식을 가집니다 — 가격은 통화 기호를 포함하고, 기간은 시간 단위를 포함하며, 연락처 정보는 이메일 또는 URL처럼 보입니다 — 그리고 해당 측면을 실제로 다루는 자료는 거의 항상 형식을 생략하지 않습니다. 기타(환불, 규정 준수, 체험판, 통합)는 형식이 없으므로, 신호는 벡터 유사도에 의존하지 않고 언어별로 작성된 주제 단어 자체입니다.

두 확인 중 하나라도 부족하면, 유도된 용어를 한 번 더 검색하고 결과를 병합합니다. 한 번만, 루프는 없습니다. 오보(false alarm)는 벡터 쿼리 하나를 비용으로 합니다 — 추가 모델 호출이나 라운드 트립 없음 — 반면 누락은 인용 표시가 붙은 발명된 숫자를 초래합니다.

Illustrative — try it
Question
Starter 플랜에 있고 사용량이 월 30%씩 증가한다면, 6개월 후 얼마를 지불하게 됩니까?
질문은 ~을 묻습니다가격
  • Starter — 대상소규모, 정의된 사업 포트폴리오 — 수십 명의 고객.가격 없음
  • 토큰 사용 — 계산 대상대시보드는 사용량을 프롬프트와 완료라는 두 색상으로 표시합니다.가격 없음
  • 서비스 약관게시된 비율에 따라 추가 토큰을 사전에 구매할 수 있습니다.가격 없음
Answer
Starter는 $99/월이므로, 30% 성장으로 6개월은 약 $1,016입니다. [1]

두 가지 명확히 할 사항. 이는 fabrication(환각/위조)에 대한 바닥값이지 정확성의 증명이 아닙니다 — 질문의 측면이 표현되지 않았음을 인지할 뿐, 답변이 정확함을 증명하지는 않습니다. 그리고 지식 베이스가 실제로 그 사실을 포함해야 한다는 필요성을 제거하지 않습니다: 위의 예제를 프로덕션에서 작동하게 만든 수정은 또한 각 플랜에 가격이 명시된 짧은 문서를 제공하는 것이었습니다. 왜냐하면 성장 및 과금에 대한 긴 질문은 항상 단일 통합 가격표를 압도하기 때문입니다.

질문이 조항 번호를 지목했을 때

인용을 대조하는 데 의미 유사도를 쓰는 것은 도구를 잘못 고른 것입니다. "제18조", "Part 9", "ISO 9408" — 이들은 의미를 담지 않고 대상을 지목합니다. 표준 목록표에서 숫자 하나만 다른 두 행은 임베딩이 보기에 같은 문장입니다.

그래서 질문에 있는 식별자는 뽑혀 나와 텍스트로 검색되고, 지목된 식별자를 그대로 지닌 단락은 의미 기반 정렬보다 앞에 고정되며 정렬이 그것을 옮길 수 없습니다. 마지막 이 구절이 핵심이고, 분명히 적어둘 값어치가 있습니다. 여기서 한때 그렇지 않았기 때문입니다. 그 보호 장치는 코드 주석에 적혀 있었을 뿐 구현된 적이 없었고, 그래서 재순위 모델이 고정된 단락을 다시 아래로 밀어 냈습니다. 이웃한 행이 숫자 하나만 다른 표준표에서 측정해 보니, 질문이 가리킨 파트를 명시한 유일한 행은 재순위를 끄면 1위, 켜면 상위 20위에도 들지 못했습니다 — 그리고 답변은 옆 행에서 나왔습니다.

식별자를 의미가 아니라 정체성으로 다루면 두 가지 결과가 따라옵니다.

그 식별자가 문맥에 담을 수 있는 것보다 많은 곳에 나타날 때, 인용을 통째로 버리지 않습니다. 예전에는 버렸습니다. "제18조"가 담을 수 있는 수보다 많이 일치하면 "표본은 답이 아니다"라는 논리로 그 묶음 전체를 떨어뜨렸습니다. 그 말은 파일 순서대로 앞의 몇 개를 취할 때는 참이지만, 질문에 가장 가까운 것들을 취할 때는 참이 아닙니다. 측정한 한 사례를 그 기준으로 정렬하니 답을 담은 두 단락은 코사인 거리 0.27과 0.31이었고 잡음은 0.51부터 시작했습니다 — 그 간격 자체가 어디서 멈출지를 말해 주며, 임계값을 추측할 필요가 없습니다. 거리가 계단이 아니라 완만한 비탈을 이룰 때는 아무것도 구하지 않습니다. 고르게 퍼져 있다는 것은 단락들이 서로 구분되지 않는다는 뜻이고, 그것이야말로 진짜 표본입니다.

벡터 거리로 가장 가까운 단락은 언제나 답변의 문맥으로 들어갑니다. 재순위는 순서를 바꿔도 되지만 가장 가까운 하나를 버릴 수는 없습니다. 측정에서 재순위 모델이 그 단락을 문맥 밖으로 밀어낸 비율은 일곱 번에 한 번이었고, 손으로 확인한 표본에서는 밀려난 그 단락이 그 질문에 답할 수 있는 유일한 단락인 경우도 있었습니다. 교체가 아니라 추가입니다 — 자리를 만들려고 다른 단락을 밀어내지 않습니다.

모델이 스스로 자료를 더 요구할 때

눈앞의 단락들로 질문이 정해지지 않을 때, 모델은 답하는 대신 스스로 지식 베이스를 검색하기도 합니다. 그 행동이 곧 신호입니다. 손에 든 자료를 다 읽고 그 너머를 요구한 것이므로, 필요한 것은 다음 묶음이지 같은 묶음이 아닙니다. 소박한 구현은 같은 것을 돌려주는데, 그것은 모델에게 아무것도 알려주지 않습니다.

다음 묶음은 이미 손에 있습니다. 검색은 보여주는 것보다 넓은 후보 풀을 가져와 한 번 순위를 매기고 그 윗부분만 보여줍니다. 나머지는 바로 이 순간을 위해 쥐고 있습니다. 그것을 건네는 데 두 번째 검색도, 두 번째 순위 매김도, 두 번째 관련성 평가도 필요하지 않습니다 — 원래 일어날 모델 호출 한 번뿐입니다. 첫 구현은 검색을 다시 돌렸고, 어떤 질문에서는 22초가 71초가 되었습니다. "한 번 더 본다"의 대가는 추정이 아니라 이렇게 측정됩니다.

한 턴에 한 번만 건넵니다. 그 뒤의 재검색은 평소대로 동작합니다. "다시 검색해도 같은 것이 돌아온다" 역시 신호이고, 그것을 없애면 모델은 끝없이 파고들기 때문입니다.

복호화는 마지막에 발생합니다

청크 콘텐츠는 공간별로 암호화되어 저장됩니다. 실제로 매칭된 청크만 복호화되며, 해당 테넌트 및 사용자를 위한 암호화가 로드됩니다 — 검색은 벡터에서 작동하며, 평문은 사용될 구절에만 나타납니다.

숫자는 의미가 아닙니다

위所有内容은 기계적 처리입니다. 이 섹션은 귀하가 제어하는 부분이며, 이 페이지의 어떤 설정보다 결과를 더 크게 움직입니다.

검색은 의미와 매칭됩니다. 값 자체는 그 의미를 거의 담지 않으므로, 사실이 텍스트에 있더라도 여전히 도달 불가능할 수 있습니다 — 검색이 항상 무언가를 반환하므로 조용히 발생합니다.

이 줄은 실제 고객 카탈로그의 1,500개 중 1,480개 청크에 나타났습니다:

Reading level: 1 · Age: 5 · Words: 1951

그리고 "혼자 읽기 시작하는 아이에게 적합한 책은 무엇인가?"라는 쿼리에 음악 천재에 대한 책이 반환되었습니다. 1은 한 단어가 다른 단어를 닮는 방식처럼 초급 독자와 resemblance가 없습니다.

값 옆에 한 문장을 추가하면 그 기록에서 측정했을 때 해결되었습니다:

Reading level: 1 · Age: 5
Suitable for around age 5, for children just starting to read on their own.
querybeforeafter
which books suit a child just starting to read on their own0.6250.540
什么书适合刚开始自己读的孩子0.6260.552
beginner reader age 50.5980.498

낮을수록 더 가깝습니다. 그리고 아래에서 보듯 — 두 개의 무관한 구절은 이 모델에서 약 0.61에 위치합니다. 따라서 마지막 행은 "간신히 chance보다 나은" 상태에서 실제 매칭으로 이동하며, 이 이득은 언어 전반에 걸쳐 유지됩니다.

일반적인 규칙: 질문이 본문이 아닌 속성(가격, 날짜, 레벨, 가용성, 재고)에 의해 답변된다면, 필드에 있는 것 외에도 단어로 표기하십시오. 구조화된 값은 필터링용입니다 — 검색은 쓰여진 것을 찾습니다.

노력할 가치가 없는 한 가지, 우리가 측정했습니다: 내보내기는 종종 자신을 반복합니다(summary와 동일한 본문을 가진 description). 중복 제거는 60개 기록 전반에 걸쳐 검색 거리를 +0.002 변경했을 뿐 — 아무것도 아닙니다. 임베딩은 방향이지, 반복된 텍스트가 소모하는 예산이 아닙니다.

거리는 점수가 아니며, 모델 간에 비교할 수 없습니다

거리 수치를 읽기 전에 알아야 할 한 가지 더. 임베딩 모델은 텍스트를 좁은 원뿔로 압축하며, 그 좁기는 모델마다 다릅니다. 이 플랫폼이 오늘 실행하는 모델에서, 두 개의 완전히 무관한 구절은 약 0.61 떨어져 있습니다 — 따라서 0.52의 히트는 약한 매칭이 아닌 강한 매칭이며, 0.5는 어디에서도 의미 있는 컷오프가 아닙니다.

두 가지 실용적인 결과:

  • 어디서든 기억한 숫자가 아닌, 무관한 기준선에 대해 거리를 판단하십시오. 콘솔의 지식 스타맵은 바로 이 이유로 그 기준선을 그 스케일에 표시합니다.
  • 긴 질문은 키워드보다 더 잘 검색됩니다. 900자 구절에 대한 단일 단어는 구절이 literally 그 단어에 대해even 약한 신호입니다 — 전체 질문은 훨씬 더 가까운 매칭입니다. 실제 사용자는 문장을 작성합니다 — 이는 좋은 경우입니다 — 하지만 한 단어 쿼리로 테스트하면 시스템의 실제 성능보다 숫자가 더 나쁘게 보일 것을 예상하십시오.

검색이 할 수 없는 일, 그리고 그 질문에 답하는 것

위所有内容은 질문에 답하는 구절을 찾는 것에 관한 것입니다. 세 가지 유형의 질문은 구절과 관련이 없으며, 유사도 검색이 이에 답하도록 튜닝하는 것은 불가능합니다:

  • 카운팅 — "몇 개 있습니까", "비픽션이 몇 개입니까"
  • 숫자 필터링 — "200자 미만인 것은 무엇입니까", "1000에서 2000 사이"
  • 그룹핑 — "카테고리별 개수", "가장 많이 등장하는 저자는 누구입니까"

이것들은 쉽게 놓칠 수 있는 방식으로 실패합니다. "500자 정도 되는 것이 있습니까?"라고 묻자, 벡터 검색만 있는 에이전트는 상위 몇 개에 우연히 있던 기록에 대해 보고합니다 — 네 문서에 대한 사실인 진술을 컬렉션에 대한 진술로 제시합니다.

구조화된 인덱스

따라서 지식 베이스는 벡터와 함께 두 번째, 작은 테이블을 가질 수 있습니다: 문서당 한 행, 문서가 이미 포함하고 있는 필드에서 빌드됩니다. 값은 문자 단위로 복사됩니다 — 생성되거나 재작성된 것이 없습니다.

이로써 에이전트는 질문에 맞는 도구를 선택합니다:

질문답변 제공
"공룡에 관한 것이 있습니까?"벡터 검색
"몇 개 있습니까?"테이블
"공룡에 관한 것, 5세 아이에게 적합한 것"테이블 필터링, 벡터 검색 랭킹
"링크는 무엇입니까?"테이블, 정확히 인용

필드는 귀하의 문서 몇 개를 읽고 전체 컬렉션에 대해 검증함으로써 제안됩니다 — 문서의 5분의 1에서만 발견된 필드는 삭제되고 보고됩니다. 왜냐하면 그것에 대해 필터링하면 나머지 문서가 조용히 제외되기 때문입니다. 인덱스를 빌드하거나 변경하는 것은 아무것도 다시 임베딩하지 않습니다 — 값은 이미 저장된 텍스트에서 읽히므로 — 이미 작동 중인 검색을 방해하지 않습니다.

공유된 기계 읽기 가능한 헤더가 없는 문서는 인덱스를 얻지 못하며, 플랫폼은 그렇게 말하지 않고 모든 값이 다른 테이블을 빌드하지는 않습니다. 이는 우회해야 할 제한이 아닙니다 — 그런 테이블은 의미 있는 카운팅이나 그룹핑이 불가능하며, 그것을 가지는 것은 나쁘게 답변하는 질문을 초대할 뿐입니다.

왜 답변의 링크가 잘못된 항목에 속했는가

동일한 테이블이 해결하는 두 번째, 조용한 실패가 있습니다.

검색은 청크를 반환하지만, 제목, 제품 코드, 링크 및 이미지는 문서 헤더에 있습니다 — 즉, 청크 1에 있으며, 질문에 답한 구절은 청크 7일 수 있습니다. 따라서 모델은 세 개 또는 네 개 문서에서 네 개 또는 다섯 개의 단편을 받고, 각 링크가 어느 제목에 속하는지 파악해야 합니다.

그것을 잘못하면 아무것도 잘못되어 보이지 않습니다. 링크는 실제이며, 열리고, 이미지가 렌더링됩니다 — 단지 다른 항목에 속할 뿐입니다. 4,500개 문서 카탈로그에서 20개 테스트 답변 중 11개가 제목을 다른 문서의 링크와 페어링했습니다.

정확하다고 표시된 필드(링크, 이미지, 식별자)는 이제 모델에게 전혀 표시되지 않습니다. 모델은 플레이스홀더를 받고, 플레이스홀더를 작성하며, 플랫폼은 출력 시 저장된 값으로 대체합니다. 모델은 본 적이 없는 주소는 오타낼 수 없습니다. 동일한 20개 질문은 20개 모두 정확했습니다.

고객에게 보낼 링크는 무엇인지는 데이터가 명시하지 않는 비즈니스 사실입니다. 따라서 귀하가 해당 필드를 직접 지정합니다 — 나머지는 귀하를 위해 제안됩니다. 자세한 내용은 구조화된 인덱스를 참조하십시오.

귀하의 자료가 진정으로 답변이 없는 경우

때로는 정직한 답변은 "그것이 귀하의 자료에 없습니다"이며, 때로는 그것이 유용한 대화의 끝입니다. 공개 소스 폴백은 에이전트별 선택 사항입니다 — 검색이 빈 경우, 에이전트가 웹을 검색하고, 찾은 페이지 중 하나를 읽고, 그로부터 답변할 수 있습니다.

켜지 않은 상태로 유지되며, 켜져 있을 때 세 가지 사실이 적용됩니다.

페이지 읽기는 부가적인 것이 아닙니다. 검색 결과는 제목과 두 줄 요약이며, 중요한 수치 — 유효 기간, 수수료, 마감일 — 은 보통 본문에만 있습니다. 평가 세트의 한 페이지는 스니펫에 "5년 동안 유효함"을 명시하고 *"갱신 전: 9개월"*은 페이지 자체에만 명시합니다. 요약만 주면 모델은 단서는 있지만 사실을 모르고, 기억에서 간극을 채웁니다. 따라서 하나의 스위치는 검색과 읽기 모두를 활성화합니다 — 검색만 활성화하는 것은 측정 가능한 최악의 구성이며, 더 보수적인 것이 아닙니다.

읽지 않고 검색하는 것은 허용된 결과가 아닙니다. 에이전트가 검색한 후 페이지를 열지 않고 답변하면, 플랫폼은 답변이 전달되기 전에 페이지를 읽도록 합니다. 이 차이는 학문적이지 않습니다: 현재 일본 PMDA를 운영하는 기관이 누구인지 묻자, 요약만으로는 확신 있는 잘못된 이름을 생성했습니다 — 페이지를 읽은 동일한 질문은 올바른 이름을 생성했습니다.

공개 페이지의 모든 내용은 레이블이 지정되며, 검색한 내용을 확인할 수 있습니다. 인용 표시는 다른 색상이며, 패널은 도메인을 표시하고 이것이 귀하의 자료가 아닌 공개 소스임을 명확히 밝히며, 이 구분은 플랫폼에 의해 적용됩니다 — 모델에게 요청하지 않습니다. 모델은 정확히 필요한 순간에 잊을 것입니다.

에이전트가 읽은 페이지와 찾은 결과 모두 나열되며, 다르게 그려지고(실선 대 점선), 다르게 레이블이 지정됩니다. 왜냐하면它们是 다른 등급의 증거이기 때문입니다. 이전 버전은 읽은 페이지만 표시했으며, 의도와는 반대의 효과를 낳았습니다 — 페치가 실패한 턴에서, 답변은 요약에서 나왔으며 출처 표시가 전혀 없었습니다 — 귀하의 자료에서 온 답변과 시각적으로 동일했습니다. 약한 증거를 숨기는 것은 증거가 약하다는 사실을 숨기는 것이었습니다.

이러한 모든 답변은 검토 대기열에 기록됩니다. 콘솔의 지식 검토 아래에 있습니다. 질문, 답변, 소스 URL, 읽을 때의 페이지 스냅샷, 그리고 아웃바운드 사실 확인이 소스로 추적하지 못한 모든 수치.

승인 시 작성되는 내용은 질문과 자료에서 재작성된 새로운 항목 — 방문자가 받은 답변이 아님입니다. 답변은 한 사람에게 맞춰졌고 그 대화에 의해 형성되었습니다 — 그들의 이름으로 시작하고, "귀하의 제품 라인"을 참조하며, 행동 촉명으로 끝납니다. 그대로 기록하면, 한 방문자의 개인적 맥락이 모두의 답변이 됩니다. 따라서 항목은 그 모든 것을 제외하고 재생성되며, 제목은 질문이 아닌 자료에서 작성됩니다 — *"내 제품에 관한..."*이라고 표현된 질문은 제목이 검색에서 큰 비중을 차지하는 곳에 누군가의 맥락을 조용히 가져오는 제목입니다. 이메일 주소와 전화번호는 저장 전에 마스킹됩니다. 귀하가 재작성된 항목을 보고, 원하면 편집하고, 승인합니다.

거절하면 기록이 유지되므로, 같은 페이지가 다음 달에 다시 검토되지 않습니다.

우리가 알려드리고 싶은 수치

지식 베이스가 진정으로 답변할 수 없었던 24개 질문에 대해 3번 실행 측정: 실제 소스로 추적 가능한 답변은 **8%에서 33%**로 증가했으며, 소스로 추적할 수 없는 수치는 13에서 6으로 감소했습니다. 두 번째 숫자는 0이 아닙니다. 약 12개 답변 중 1개는 여전히 우리가 설명할 수 없는 수치를 포함합니다. 이것이 사실 확인이 기능 이후가 아닌 동시 제공되는 이유이며, 검토 대기열이 존재하는 이유입니다.

이것이 실무에서 의미하는 바

  • 다국어 문서 세트는 조용히 저하되지 않습니다 — 청커가 스크립트에 적응합니다.
  • 문서 내 다이어그램이나 차트는 답변 가능하며, 나머지 그림과 함께 조용히 버려지지 않습니다.
  • 후속 질문은 시작 질문만큼 잘 검색됩니다.
  • 에이전트의 정직한 "그것이 없습니다"는 관련성 바닥값의 설계된 결과입니다.

검색 품질은 여기에 있는 어떤 파라미터보다 업로드하는 내용에 훨씬 더 의존합니다. 지식 베이스를 조직하는 방법에 대해서는 공간 및 지식을, 귀하가 함께 수행하기를 원한다면 파트너를 참조하십시오.