확대를 위한 검색 컨텍스트 준비

Completed

Tip

자세한 내용은 텍스트 및 이미지 탭을 참조하세요.

이제 RAG이란 무엇이고 언제 사용해야 하는지 이해하게 되었습니다. 다음 단원에서는 T-SQL에서 RAG 워크플로의 각 단계를 구현하는 방법을 알아봅니다.

고객이 "지난 달에 구입한 산악 자전거에 맞는 페달은 무엇인가요?"라고 묻는 시나리오를 고려해 보세요. 데이터베이스를 쿼리하고, 순서를 찾고, 자전거 모델을 식별하고, 호환되는 구성 요소를 찾습니다. 이 단계는 RAG: 검색의 "R"을 나타냅니다. 언어 모델에 대한 해당 데이터를 검색하고 준비해 보겠습니다. SQL에서 데이터를 검색하는 방법은 여러 가지가 있지만 RAG의 경우 모델에서 실제로 사용할 수 있는 구조화된 컨텍스트를 제공하는 것이 목표입니다.

관계형 데이터를 JSON으로 변환

언어 모델은 관계형 구조가 아닌 텍스트를 처리합니다. 원시 쿼리 결과를 전달하는 경우 모델은 열 이름, 데이터 형식 또는 관계를 해석할 방법이 없습니다. JSON은 구조체를 텍스트 형식으로 유지하여 이 문제를 해결합니다. 필드 이름은 값에 계속 연결됩니다. 중첩된 개체는 관계를 나타냅니다. 모델은 "ProductName": "Mountain-500"을 읽고 해당 응답에서 특정 제품을 참조할 수 있습니다.

JSON은 또한 상황을 예측 가능하게 유지합니다. 모델이 대답을 반환할 때 명시적으로 제공한 필드에서 응답이 나왔다는 것을 알 수 있습니다. 구조화되지 않은 텍스트를 대신 덤프한 경우 모델이 응답을 작성하는 데 사용하는 내용을 덜 제어할 수 있습니다.

FOR JSON을 사용하여 쿼리 결과 서식 지정

JSON 문자열을 직접 빌드할 필요가 없습니다. SELECT의 끝에 추가 FOR JSON 하기만 하면 SQL에서 작업을 수행합니다.

  • FOR JSON AUTO 쿼리 구조에 따라 출력 형식을 지정합니다. 열 이름은 자동으로 필드 이름이 됩니다.

    SELECT Name, ListPrice, Color
    FROM Production.Product
    WHERE ProductID = @ProductID
    FOR JSON AUTO;
    

    이 쿼리는 다음과 같은 항목을 반환합니다. [{"Name":"Mountain-500 Black, 48","ListPrice":564.99,"Color":"Black"}]

  • FOR JSON PATH 에서는 JSON 구조에 대한 명시적 제어를 제공합니다. 열 별칭을 사용하여 필드 이름 및 중첩을 정의합니다.

    SELECT 
        Name AS 'product.name',
        ListPrice AS 'product.price',
        Size AS 'product.size'
    FROM Production.Product
    WHERE ProductID = @ProductID
    FOR JSON PATH;
    

    이 쿼리는 다음과 같은 항목을 반환합니다. [{"product":{"name":"Mountain-500 Black, 48","price":564.99,"size":"48"}}]

JSON 출력 옵션 제어

몇 가지 옵션을 사용하여 출력을 셰이프할 수 있습니다.

  • WITHOUT_ARRAY_WRAPPER 는 단일 레코드를 검색할 때 대괄호를 제거합니다. 이 옵션은 한 번에 하나의 고객, 한 제품 또는 한 주문을 검색하는 경우가 많기 때문에 RAG에 유용합니다.

    SELECT Name, Description, Size, Weight
    FROM Production.Product
    WHERE ProductID = @ProductID
    FOR JSON PATH, WITHOUT_ARRAY_WRAPPER;
    
  • INCLUDE_NULL_VALUES 는 null 필드를 생략하는 대신 출력에 유지합니다. 값이 없는 것이 의미 있는 경우 이 매개 변수를 사용합니다.

  • ROOT('name') 는 명명된 루트 요소에 전체 출력을 래핑하여 모델이 수신하는 데이터의 종류를 이해하는 데 도움이 될 수 있습니다.

포함할 내용 선택

컨텍스트에 포함되지 않는 열도 존재합니다. 예를 들어 내부 ID, 감사 타임스탬프 및 웨어하우스 코드는 모델이 고객의 질문에 답변하는 데 도움이 되지 않습니다. 그들은 단지 토큰을 소비하고 노이즈를 추가합니다.

제품 질문의 경우 제품 이름, 설명, 사양 및 가격을 포함합니다. rowguid, 수정 날짜, 중단된 플래그는 직접 관련이 없는 경우 제외하는 것이 좋습니다.

토큰 제한도 중요합니다. 보내는 모든 토큰은 비용이 들며 모델의 컨텍스트 창에 포함됩니다. 여러 제품을 검수할 때는 각각을 건조한 상태로 보관하세요. 모델은 포함할 수 있는 모든 것보다 포커스가 있는 컨텍스트에서 더 잘 수행됩니다.

여러 원본 결합

RAG 컨텍스트는 종종 여러 테이블에서 제공됩니다. 페달 호환성 질문에는 제품 세부 정보, 사양 및 관련 구성 요소가 필요합니다. 먼저 벡터 검색을 사용하여 관련 제품을 찾은 다음 다른 테이블에 조인하여 전체 그림을 작성할 수 있습니다.

실제로는 다음과 같습니다. 먼저 사용자의 질문을 임베딩으로 변환합니다. VECTOR_DISTANCE 그런 다음, 가장 가까운 일치 항목을 찾고, 관련 테이블을 조인하고, 모든 항목을 JSON으로 서식을 지정합니다.

DECLARE @userQuestion NVARCHAR(1000) = 'Which pedals are compatible with the Mountain-500?';
DECLARE @questionVector VECTOR(1536);
DECLARE @context NVARCHAR(MAX);

-- Generate embedding for the question
SELECT @questionVector = AI_GENERATE_EMBEDDINGS(@userQuestion USE MODEL my_embedding_model);

-- Find relevant products and format as JSON
SET @context = (
    SELECT TOP 3
        p.Name AS ProductName,
        p.Color,
        p.Size,
        pc.Name AS Category,
        pm.Name AS Model
    FROM Production.Product p
    INNER JOIN Production.ProductSubcategory ps ON p.ProductSubcategoryID = ps.ProductSubcategoryID
    INNER JOIN Production.ProductCategory pc ON ps.ProductCategoryID = pc.ProductCategoryID
    INNER JOIN Production.ProductModel pm ON p.ProductModelID = pm.ProductModelID
    ORDER BY VECTOR_DISTANCE('cosine', p.DescriptionVector, @questionVector)
    FOR JSON PATH
);

이제 변수 @context 는 프롬프트에 사용할 준비가 된 JSON 문자열을 보유합니다. 이 JSON 문자열은 확대를 위해 형식이 지정된 검색 결과입니다.

주요 내용

목표는 실제로 사용할 수 있는 언어 모델 구조화된 컨텍스트를 제공하는 것입니다. JSON은 데이터를 텍스트로 읽을 수 있게 유지하면서 데이터의 의미를 유지합니다. 빠른 결과를 원할 때 FOR JSON AUTO를 사용하고, 필드 이름 및 중첩을 제어해야 할 때는 FOR JSON PATH를 사용하세요. 단일 레코드 쿼리에는 WITHOUT_ARRAY_WRAPPER를 추가합니다. 모델에 필요한 열만 포함하여 JSON을 간결하게 유지합니다. 노이즈가 적다는 것은 더 나은 답변과 낮은 토큰 비용을 의미합니다.