다음을 통해 공유


AI 애플리케이션에 대한 사용자 지정 데이터 처리

이 빠른 시작에서는 AI 애플리케이션에 대한 사용자 지정 데이터를 처리하고 준비하는 데이터 수집 파이프라인을 만드는 방법을 알아봅니다. 앱은 Microsoft.Extensions.DataIngestion 라이브러리를 사용하여 문서를 읽고, AI로 콘텐츠를 강화하며, 텍스트를 의미적으로 청크하고, 의미 검색을 위해 벡터 데이터베이스에 임베딩을 저장합니다.

데이터 수집은 대량의 구조화되지 않은 데이터를 처리하고 AI 애플리케이션을 검색할 수 있도록 해야 하는 RAG(검색 보강 생성) 시나리오에 필수적입니다.

사전 요구 사항

앱 만들기

다음 단계를 완료하여 .NET 콘솔 앱을 만듭니다.

  1. 컴퓨터의 빈 디렉터리에서 dotnet new 명령을 사용하여 새 콘솔 앱을 만듭니다.

    dotnet new console -o ProcessDataAI
    
  2. 디렉터리를 앱 폴더로 변경합니다.

    cd ProcessDataAI
    
  3. 필요한 패키지를 설치합니다.

    dotnet add package Azure.AI.OpenAI
    dotnet add package Microsoft.Extensions.AI.OpenAI --prerelease
    dotnet add package Microsoft.Extensions.Configuration
    dotnet add package Microsoft.Extensions.Configuration.UserSecrets
    dotnet add package Microsoft.Extensions.DataIngestion --prerelease
    dotnet add package Microsoft.Extensions.DataIngestion.Markdig --prerelease
    dotnet add package Microsoft.Extensions.Logging.Console
    dotnet add package Microsoft.ML.Tokenizers.Data.O200kBase
    dotnet add package Microsoft.SemanticKernel.Connectors.SqliteVec --prerelease
    

AI 서비스 만들기

  1. Azure OpenAI 서비스 및 모델을 프로비전하려면 Azure OpenAI 서비스 리소스 만들기 및 배포 문서의 단계를 완료합니다. 이 빠른 시작에서는 두 가지 모델 gpt-5 ( 및 text-embedding-3-small.)을 프로비전해야 합니다.

  2. 터미널 또는 명령 프롬프트에서 프로젝트 디렉터리의 루트로 이동합니다.

  3. 다음 명령을 실행하여 샘플 앱에 대한 Azure OpenAI 엔드포인트 및 API 키를 구성합니다.

    dotnet user-secrets init
    dotnet user-secrets set AZURE_OPENAI_ENDPOINT <your-Azure-OpenAI-endpoint>
    dotnet user-secrets set AZURE_OPENAI_API_KEY <your-Azure-OpenAI-API-key>
    

편집기에서 앱 열기

Visual Studio Code(또는 선택한 편집기)에서 앱을 엽니다.

code .

샘플 데이터 만들기

  1. sample.md 파일을 프로젝트 디렉터리에 있는 폴더 data 에 복사합니다.
  2. 이 파일을 출력 디렉터리에 복사하도록 프로젝트를 구성합니다. Visual Studio를 사용하는 경우 솔루션 탐색기에서 파일을 마우스 오른쪽 단추로 클릭하고 속성을 선택한 다음 복사 를 출력 디렉터리 로 설정하여 최신인 경우 복사합니다.

앱 코드 추가

데이터 수집 파이프라인은 문서를 처리하기 위해 함께 작동하는 여러 구성 요소로 구성됩니다.

  • 문서 리더: 디렉터리에서 Markdown 파일을 읽습니다.
  • 문서 프로세서: AI에서 생성된 대체 텍스트를 사용하여 이미지를 보강합니다.
  • 청커: 임베딩을 사용하여 문서를 의미 청크로 분할합니다.
  • 청크 프로세서: 각 청크에 대한 AI 요약을 생성합니다.
  • 벡터 저장소 작성기: SQLite 데이터베이스에 포함된 청크를 저장합니다.
  1. Program.cs 파일에서 기존 코드를 삭제하고 다음 코드를 추가하여 문서 판독기를 구성합니다.

    // Configure document reader.
    IngestionDocumentReader reader = new MarkdownReader();
    

    이 클래스는 MarkdownReader Markdown 문서를 읽고 큰 언어 모델에서 잘 작동하는 통합 형식으로 변환합니다.

  2. 파이프라인에 대한 로깅을 구성하는 코드를 추가합니다.

    using ILoggerFactory loggerFactory =
        LoggerFactory.Create(builder => builder.AddSimpleConsole());
    
  3. 보강 및 채팅을 위해 AI 클라이언트를 구성하는 코드를 추가합니다.

    // Configure IChatClient to use Azure OpenAI.
    IConfigurationRoot config = new ConfigurationBuilder()
        .AddUserSecrets<Program>()
        .Build();
    
    string endpoint = config["AZURE_OPENAI_ENDPOINT"];
    string apiKey = config["AZURE_OPENAI_API_KEY"];
    string chatModel = "gpt-5";
    string embeddingModel = "text-embedding-3-small";
    
    AzureOpenAIClient azureClient = new(
        new Uri(endpoint),
        new AzureKeyCredential(apiKey));
    
    IChatClient chatClient =
        azureClient.GetChatClient(chatModel).AsIChatClient();
    
  4. AI 생성 설명을 사용하여 이미지를 보강하는 문서 프로세서를 구성하는 코드를 추가합니다.

    // Configure document processor.
    EnricherOptions enricherOptions = new(chatClient)
    {
        // Enricher failures should not fail the whole ingestion pipeline,
        // as they are best-effort enhancements.
        // This logger factory can create loggers to log such failures.
        LoggerFactory = loggerFactory
    };
    
    IngestionDocumentProcessor imageAlternativeTextEnricher =
        new ImageAlternativeTextEnricher(enricherOptions);
    

    ImageAlternativeTextEnricher 대형 언어 모델을 사용하여 문서 내 이미지에 대한 설명적인 대체 텍스트를 생성합니다. 이 텍스트는 접근성을 높이고 의미를 향상시킵니다.

  5. 벡터 표현을 만들기 위한 포함 생성기를 구성하는 코드를 추가합니다.

    // Configure embedding generator.
    IEmbeddingGenerator<string, Embedding<float>> embeddingGenerator =
        azureClient.GetEmbeddingClient(embeddingModel).AsIEmbeddingGenerator();
    

    포함 은 벡터 유사성 검색을 가능하게 하는 텍스트 의미 체계 의미의 숫자 표현입니다.

  6. 문서를 의미 체계 청크로 분할하는 청커를 구성하는 코드를 추가합니다.

    // Configure chunker to split text into semantic chunks.
    IngestionChunkerOptions chunkerOptions = new(TiktokenTokenizer.CreateForModel(chatModel))
    {
        MaxTokensPerChunk = 2000,
        OverlapTokens = 0
    };
    
    IngestionChunker<string> chunker =
        new SemanticSimilarityChunker(embeddingGenerator, chunkerOptions);
    

    문장 SemanticSimilarityChunker 간의 의미 체계 유사성을 분석하여 관련 콘텐츠가 함께 유지되도록 하여 문서를 지능적으로 분할합니다. 이 프로세스는 단순 문자 또는 토큰 기반 청크보다 의미와 컨텍스트를 더 잘 유지하는 청크를 생성합니다.

  7. 요약을 생성하는 청크 프로세서를 구성하는 코드를 추가합니다.

    // Configure chunk processor to generate summaries for each chunk.
    IngestionChunkProcessor<string> summaryEnricher = new SummaryEnricher(enricherOptions);
    

    SummaryEnricher 청크에 대한 간결한 요약을 자동으로 생성하므로 콘텐츠에 대한 개략적인 개요를 제공하여 검색 정확도를 향상시킬 수 있습니다.

  8. embeddings를 저장하기 위해 SQLite 벡터 저장소를 구성하는 코드를 추가합니다.

    // Configure SQLite Vector Store.
    using SqliteVectorStore vectorStore = new(
        "Data Source=vectors.db;Pooling=false",
        new()
        {
            EmbeddingGenerator = embeddingGenerator
        });
    
    // The writer requires the embedding dimension count to be specified.
    using VectorStoreWriter<string> writer = new(
        vectorStore,
        dimensionCount: 1536,
        new VectorStoreWriterOptions { CollectionName = "data" });
    

    벡터 저장소는 청크를 임베딩과 함께 저장하여 빠른 의미 기반 검색을 가능하게 합니다.

  9. 전체 파이프라인에 모든 구성 요소를 구성하는 코드를 추가합니다.

    // Compose data ingestion pipeline
    using IngestionPipeline<string> pipeline =
        new(reader, chunker, writer, loggerFactory: loggerFactory)
    {
        DocumentProcessors = { imageAlternativeTextEnricher },
        ChunkProcessors = { summaryEnricher }
    };
    

    IngestionPipeline<T> 모든 구성 요소를 처음부터 끝까지 문서를 처리하는 응집력 있는 워크플로로 결합합니다.

  10. 디렉터리에서 문서를 처리하는 코드를 추가합니다.

    await foreach (IngestionResult result in pipeline.ProcessAsync(
        new DirectoryInfo("./data"),
        searchPattern: "*.md"))
    {
        Console.WriteLine($"Completed processing '{result.DocumentId}'. " +
            $"Succeeded: '{result.Succeeded}'.");
    }
    

    파이프라인은 디렉터리의 모든 Markdown 파일을 ./data 처리하고 각 문서의 상태를 보고합니다.

  11. 처리된 문서를 대화형으로 검색할 수 있도록 코드를 추가합니다.

    // Search the vector store collection and display results
    VectorStoreCollection<object, Dictionary<string, object?>> collection =
        writer.VectorStoreCollection;
    
    while (true)
    {
        Console.Write("Enter your question (or 'exit' to quit): ");
        string? searchValue = Console.ReadLine();
        if (string.IsNullOrEmpty(searchValue) || searchValue == "exit")
        {
            break;
        }
    
        Console.WriteLine("Searching...\n");
        await foreach (VectorSearchResult<Dictionary<string, object?>> result in
            collection.SearchAsync(searchValue, top: 3))
        {
            Console.WriteLine($"Score: {result.Score}\n\tContent: {result.Record["content"]}");
        }
    }
    

    검색 기능은 사용자 쿼리를 포함으로 변환하고 벡터 저장소에서 가장 의미상 유사한 청크를 찾습니다.

앱 실행

  1. dotnet run 명령을 사용하여 앱을 실행합니다.

    dotnet run
    

    앱은 디렉터리의 모든 Markdown 파일을 ./data 처리하고 각 문서에 대한 처리 상태를 표시합니다. 처리가 완료되면 자연어 질문을 입력하여 처리된 콘텐츠를 검색할 수 있습니다.

  2. 프롬프트에 질문을 입력하여 데이터를 검색합니다.

    Enter your question (or 'exit' to quit): What is data ingestion?
    

    앱은 유사성 점수와 함께 문서에서 가장 관련성이 큰 청크를 반환합니다.

  3. 애플리케이션을 종료하려면 입력 exit 합니다.

자원을 정리하세요

더 이상 필요하지 않은 경우 Azure OpenAI 리소스 및 모델 배포를 삭제합니다.

  1. Azure PortalAzure OpenAI 리소스로 이동합니다.
  2. Azure OpenAI 리소스를 선택한 다음, 삭제선택합니다.

다음 단계