RAG 작업


Red Hat OpenShift AI Cloud Service 1

Red Hat OpenShift AI Cloud Service에서 RAG 사용

초록

클러스터 관리자는 Red Hat OpenShift AI에 RAG 스택을 배포할 수 있습니다.

1장. RAG 개요

OpenShift AI의 RG(검색 강화형 생성)는 도메인별 데이터 소스를 모델의 컨텍스트에 직접 통합하여 LLM( Large Language Model)을 개선합니다. 도메인별 데이터 소스는 관계형 데이터베이스 테이블 또는 PDF 문서와 같은 구조화되지 않은 데이터일 수 있습니다.

RAG는 콘텐츠를 인덱싱하고 데이터 과학자 및 AI 엔지니어가 쿼리할 수 있는 내장 저장소를 구축합니다. 데이터 과학자 또는 AI 엔지니어가 RAG chatbot에 질문을 하는 경우, RAG 파이프라인은 가장 관련 있는 데이터를 검색하고, context로 Cryostat에 전달하며, 프롬프트와 검색된 콘텐츠 모두를 반영하는 응답을 생성합니다.

데이터 과학자와 AI 엔지니어는 RAG를 구현함으로써 데이터 사이언스 프로젝트 내에서 자체 데이터 집합을 기반으로 복잡한 쿼리에 대한 조정되고 정확하며 검증 가능한 답변을 얻을 수 있습니다.

1.1. RAG 대상

RAG의 대상 대상은 OpenShift AI 인프라를 사용하여 데이터 지주 대화 AI 애플리케이션을 구축하는 실무자입니다.

Data Scientists의 경우
데이터 과학자는 RAG를 사용하여 낮은 수준의 포함 파이프라인 또는 벡터 저장소를 관리하지 않고도 데이터 소스에 대해 자연어 쿼리에 응답하는 모델을 프로토 타입하고 검증할 수 있습니다. 검색 인프라를 구축하는 대신 프롬프트를 생성하고 모델 출력을 평가하는 데 중점을 둘 수 있습니다.
MLOps 엔지니어의 경우
MLOps 엔지니어는 일반적으로 프로덕션에서 RAG 파이프라인을 배포하고 운영합니다. OpenShift AI 내에서 Cryostat 끝점을 관리하고 성능을 모니터링하며 검색 및 생성 규모가 안정적으로 유지됩니다. RAG는 제공 계층에서 벡터 저장소 유지 관리를 분리하여 MLOps 엔지니어가 CI/CD 워크플로를 데이터 수집 및 모델 배포에 적용할 수 있도록 지원합니다.
데이터 엔지니어의 경우
데이터 엔지니어는 OpenShift AI 인덱스를 사용하는 스토리지로 데이터를 로드하기 위해 워크플로를 빌드합니다. 이는 chatbot 응답이 정확한지 확인하기 위해 S3 버킷 또는 관계형 표와 같은 소스 시스템과 동기화되는 것을 계속 포함합니다.
AI 엔지니어의 경우
AI 엔지니어는 프롬프트 템플릿, 검색 방법 및 대체 논리를 정의하여 RAG chatbots를 설계합니다. 에이전트를 구성하고 OpenShift 작업 트리거와 같은 도메인별 툴을 추가하여 빠르게 반복할 수 있습니다.

2장. 데이터 사이언스 프로젝트에 RAG 스택 배포

중요

OpenShift AI에 RAG 스택을 배포하는 것은 개발자 프리뷰 기능입니다. 개발자 프리뷰 기능은 Red Hat에서 지원하지 않으며 기능적으로 완전하거나 프로덕션 준비가 되지 않습니다. 프로덕션 또는 비즈니스 크리티컬 워크로드에는 개발자 프리뷰 기능을 사용하지 마십시오. 개발자 프리뷰 기능을 사용하면 Red Hat 제품에 포함될 수 있는 기능을 미리 미리 활용할 수 있습니다. 고객은 이러한 기능을 사용하여 기능을 테스트하고 개발 프로세스 중에 피드백을 제공할 수 있습니다. 개발자 프리뷰 기능에는 문서가 없으며 언제든지 변경 또는 제거될 수 있으며 제한된 테스트를 수신했습니다. Red Hat은 관련 SLA 없이 개발자 프리뷰 기능에 대한 피드백을 제출하는 방법을 제공할 수 있습니다.

Red Hat Developer Preview 기능의 지원 범위에 대한 자세한 내용은 개발자 프리뷰 지원 범위를 참조하십시오.

OpenShift 클러스터 관리자는 OpenShift AI에서 Retrieval-Augmented Generation (RAG) 스택을 배포할 수 있습니다. 이 스택은 데이터 과학자 및 AI 엔지니어가 프로젝트에서 대화 워크플로를 구축하는 데 사용하는 Cryostat 추론, 벡터 스토리지 및 검색 서비스를 포함한 인프라를 제공합니다.

데이터 사이언스 프로젝트에 RAG 스택을 배포하려면 다음 작업을 완료합니다.

  • OpenShift AI에서 L#178a Stack Operator를 활성화합니다.
  • OpenShift 클러스터에서 GPU 지원을 활성화합니다. 이 작업에는 필요한 NVIDIA Operator 설치가 포함됩니다.
  • 유추 모델을 배포합니다(예: llama-3.2-3b-instruct 모델). 이 작업에는 스토리지 연결 생성 및 GPU 할당 구성이 포함됩니다.
  • RAG 기능을 활성화하려면 L#178a StackDistribution 인스턴스를 생성합니다. 이 작업은 Milvus 벡터 저장소와 함께 L#178aStack을 배포하고 두 구성 요소를 유추 모델에 연결합니다.
  • 데이터 사이언스 파이프라인 또는 metapyter에서 Docling을 실행하여 도메인 데이터를 Milvus로 수집합니다. 이 프로세스는 포함 항목을 소스 데이터와 동기화합니다.
  • 모델 끝점을 노출하고 보호합니다.

2.1. L#178a Stack Operator 활성화

OpenShift AI Operator DataScienceCluster CR(사용자 정의 리소스)에서 managementStateManaged 로 설정하여 OpenShift 클러스터에서 L#178a Stack Operator를 활성화할 수 있습니다. 이 설정을 사용하면 Operator 서브스크립션을 다시 설치하거나 직접 편집하지 않고도 Lmetaa 기반 모델이 서비스를 제공할 수 있습니다. OpenShift 웹 콘솔에서 또는 OpenShift CLI(명령줄 인터페이스)를 사용하여 CR을 편집할 수 있습니다.

참고

이 절차의 단계를 따르는 대신 다음 명령을 실행하여 OpenShift CLI(명령줄 인터페이스)에서 L declarationa Stack Operator를 활성화할 수 있습니다.

$ oc patch datasciencecluster <name> --type=merge -p {"spec":{"components":{"llamastackoperator":{"managementState":"Managed"}}}}
Copy to Clipboard Toggle word wrap

&lt ;name& gt;을 DataScienceCluster 이름(예: default-dsc )으로 바꿉니다.

사전 요구 사항

프로세스

  1. OpenShift 웹 콘솔에 클러스터 관리자로 로그인합니다.
  2. 관리자 화면에서 Operator → 설치된 Operator 를 클릭합니다.
  3. Red Hat OpenShift AI Operator 를 클릭하여 세부 정보를 엽니다.
  4. Data Science Cluster 탭을 클릭합니다.
  5. DataScienceClusters 페이지에서 default-dsc 오브젝트를 클릭합니다.
  6. YAML 탭을 클릭합니다.

    포함된 YAML 편집기가 열리고 DataScienceCluster 사용자 정의 리소스의 구성이 표시됩니다.

  7. YAML 편집기에서 spec.components 섹션을 찾습니다. llamastackoperator 필드가 없는 경우 추가합니다. 그런 다음 managementState 필드를 Managed 로 설정합니다.

    spec:
      components:
        llamastackoperator:
          managementState: Managed
    Copy to Clipboard Toggle word wrap
  8. 저장을 클릭하여 변경 사항을 적용합니다.

검증

L#178a Stack Operator를 활성화한 후 클러스터에서 실행 중인지 확인합니다.

  1. OpenShift 웹 콘솔에서 워크로드Pod 를 클릭합니다.
  2. 프로젝트 목록에서 redhat-ods-applications 네임스페이스를 선택합니다.
  3. app.kubernetes.io/name=llama-stack-operator 레이블이 있고 상태가 Running 인 Pod가 표시되는지 확인합니다.

2.2. KServe를 사용하여 Llana 모델 배포

OpenShift AI에서 L#178a Stack 및 retrieval-augmented generation(RAG) 워크로드를 사용하려면 vLLM 모델 서버를 사용하여 L appreciatea 모델을 배포하고 표준 배포 모드에서 KServe를 구성해야 합니다.

사전 요구 사항

프로세스

이러한 단계는 OpenShift AI 버전 2.19 이상에서만 지원됩니다.

  1. OpenShift AI 대시보드에서 프로젝트 세부 정보 페이지로 이동하여 모델 탭을 클릭합니다.
  2. 단일 모델 제공 플랫폼 타일에서 단일 모델 선택을 클릭합니다.
  3. 배포 모델 버튼을 클릭합니다.

    모델 배포 대화 상자가 열립니다.

  4. 모델의 배포 속성을 구성합니다.

    1. 모델 배포 이름 필드에 배포에 대한 고유한 이름을 입력합니다.
    2. Serving 런타임 필드의 드롭다운 목록에서 KServe에 대한 vLLM NVIDIA GPU 제공 런타임 을 선택합니다.
    3. 배포 모드 필드의 드롭다운 목록에서 Standard 를 선택합니다.
    4. 배포할 모델 서버 복제본 수를 1 로 설정합니다.
    5. 모델 서버 크기 필드의 드롭다운 목록에서 Custom 을 선택합니다.

      • 요청된 CPU 를 하나의 코어 로 설정합니다.
      • 요청된 메모리10GiB 로 설정합니다.
      • CPU 제한을 2 코어 로 설정합니다.
      • 메모리 제한을 14GiB 로 설정합니다.
      • 액셀러레이터NVIDIA GPU 로 설정합니다.
      • 액셀러레이터 수1 로 설정합니다.
    6. 연결 유형에서 드롭다운 목록에서 관련 데이터 연결을 선택합니다.
  5. 추가 제공 런타임 인수 필드에서 다음 권장 인수를 지정합니다.

    --dtype=half
    --max-model-len=20000
    --gpu-memory-utilization=0.95
    --enable-chunked-prefill
    --enable-auto-tool-choice
    --tool-call-parser=llama3_json
    --chat-template=/app/data/template/tool_chat_template_llama3.2_json.jinja
    Copy to Clipboard Toggle word wrap
    1. Deploy 를 클릭합니다.

      참고

      모델 배포에는 특히 클러스터에 배포된 첫 번째 모델의 경우 몇 분이 걸릴 수 있습니다. 초기 배포에는 관련 이미지가 다운로드되는 동안 10분 이상 걸릴 수 있습니다.

검증

  1. kserve-controller-managerodh-model-controller Pod가 실행 중인지 확인합니다.

    1. 새 터미널 창을 엽니다.
    2. CLI에서 OpenShift 클러스터에 로그인합니다.
    3. OpenShift 웹 콘솔의 오른쪽 상단에서 사용자 이름을 클릭하고 로그인 복사 명령을 선택합니다.
    4. 로그인한 후 토큰 표시를 클릭합니다.
    5. 이 토큰 명령으로 로그인을 복사하여 OpenShift CLI(명령줄 인터페이스)에 붙여넣습니다.

      $ oc login --token=<token> --server=<openshift_cluster_url>
      Copy to Clipboard Toggle word wrap
    6. 다음 명령을 입력하여 kserve-controller-managerodh-model-controller Pod가 실행 중인지 확인합니다.

      $ oc get pods -n redhat-ods-applications | grep -E 'kserve-controller-manager|odh-model-controller'
      Copy to Clipboard Toggle word wrap
    7. 다음 예와 유사한 출력이 표시되는지 확인합니다.

      kserve-controller-manager-7c865c9c9f-xyz12   1/1     Running   0          4m21s
      odh-model-controller-7b7d5fd9cc-wxy34        1/1     Running   0          3m55s
      Copy to Clipboard Toggle word wrap
    8. kserve-controller-managerodh-model-controller Pod 중 하나가 표시되지 않으면 배포에 문제가 있을 수 있습니다. 또한 Pod가 목록에 표시되지만 StatusRunning 으로 설정되지 않은 경우 Pod 로그에 오류가 있는지 확인합니다.

      $ oc logs <pod-name> -n redhat-ods-applications
      Copy to Clipboard Toggle word wrap
    9. 유추 서비스의 상태를 확인합니다.

      $ oc get inferenceservice -n llamastack
      $ oc get pods -n <data science project name> | grep llama
      Copy to Clipboard Toggle word wrap
      • 배포는 다음 리소스를 자동으로 생성합니다.

        • ServingRuntime 리소스.
        • InferenceService 리소스, 배포, 포드 및 포드를 가리키는 서비스입니다.
      • 서버가 실행 중인지 확인합니다. 예를 들면 다음과 같습니다.

        $ oc logs llama-32-3b-instruct-predictor-77f6574f76-8nl4r  -n <data science project name>
        Copy to Clipboard Toggle word wrap

        다음 예제 로그와 유사한 출력이 있는지 확인합니다.

        INFO     2025-05-15 11:23:52,750 __main__:498 server: Listening on ['::', '0.0.0.0']:8321
        INFO:     Started server process [1]
        INFO:     Waiting for application startup.
        INFO     2025-05-15 11:23:52,765 __main__:151 server: Starting up
        INFO:     Application startup complete.
        INFO:     Uvicorn running on http://['::', '0.0.0.0']:8321 (Press CTRL+C to quit)
        Copy to Clipboard Toggle word wrap
      • 배포된 모델은 배포된 프로젝트 의 Data Science 프로젝트 세부 정보 페이지의 모델 탭에 표시됩니다.
  2. /v1/chat/completions API를 쿼리할 때 Pod 로그에 ConvertTritonGPUToLLVM 오류가 표시되고 vLLM 서버가 500 Internal Server 오류를 재시작하거나 반환하는 경우 다음 해결 방법을 적용합니다.

    모델을 배포하기 전에 배포 대화 상자의 추가 제공 런타임 인수 필드에서 --enable-chunked-prefill 인수 를 제거합니다.

    오류는 다음과 유사합니다.

    /opt/vllm/lib64/python3.12/site-packages/vllm/attention/ops/prefix_prefill.py:36:0: error: Failures have been detected while processing an MLIR pass pipeline
    /opt/vllm/lib64/python3.12/site-packages/vllm/attention/ops/prefix_prefill.py:36:0: note: Pipeline failed while executing [`ConvertTritonGPUToLLVM` on 'builtin.module' operation]: reproducer generated at `std::errs, please share the reproducer above with Triton project.`
    INFO:     10.129.2.8:0 - "POST /v1/chat/completions HTTP/1.1" 500 Internal Server Error
    Copy to Clipboard Toggle word wrap

2.3. vLLM 모델 엔드 포인트 테스트

배포된 L#178a 3.2 모델이 외부에서 액세스할 수 있는지 확인하려면 vLLM 모델 서버가 네트워크 끝점으로 노출되었는지 확인합니다. 그런 다음 OpenShift 클러스터 및 OpenShift AI 인터페이스 외부에서 모델에 대한 액세스를 테스트할 수 있습니다.

중요

배포 중에 외부 경로를 통해 배포된 모델을 선택한 경우 vLLM 모델 끝점은 클러스터 외부에서 이미 액세스할 수 있습니다. 모델 서버를 수동으로 노출할 필요는 없습니다. 예를 들어 oc expose 를 사용하여 vLLM 모델 끝점을 수동으로 노출하면 인증을 구성하지 않는 한 비보안 경로가 생성됩니다. 무단 액세스를 방지하기 위해 보안 제어없이 끝점을 노출하지 마십시오.

사전 요구 사항

프로세스

  1. 새 터미널 창을 엽니다.

    1. CLI에서 OpenShift 클러스터에 로그인합니다.
    2. OpenShift 웹 콘솔의 오른쪽 상단에서 사용자 이름을 클릭하고 로그인 복사 명령을 선택합니다.
    3. 로그인한 후 토큰 표시를 클릭합니다.
    4. 이 토큰 명령으로 로그인을 복사하여 OpenShift CLI(명령줄 인터페이스)에 붙여넣습니다.

      $ oc login --token=<token> --server=<openshift_cluster_url>
      Copy to Clipboard Toggle word wrap
  2. 모델 배포 중에 토큰 인증이 필요한 경우 토큰을 검색합니다.

    $ export MODEL_TOKEN=$(oc get secret default-name-llama-32-3b-instruct-sa -n <project name> --template={{ .data.token }} | base64 -d)
    Copy to Clipboard Toggle word wrap
  3. 모델 끝점 URL을 가져옵니다.

    • 모델 배포 중에 외부 경로를 통해 배포된 모델을 사용할 수 있는 경우 OpenShift AI 대시보드의 모델 배포 페이지에서 끝점 세부 정보를 클릭하여 모델 엔드포인트 URL을 가져옵니다.
    • 또한 모델 배포 중에 토큰 인증이 필요하지 않은 경우 다음 명령을 입력하여 엔드포인트 URL을 검색할 수도 있습니다.

      $ export MODEL_ENDPOINT="https://$(oc get route llama-32-3b-instruct -n <project name> --template={{ .spec.host }})"
      Copy to Clipboard Toggle word wrap
  4. 샘플 채팅 완료 요청으로 끝점을 테스트합니다.

    • 모델 배포 중에 토큰 인증 필요 를 활성화하지 않은 경우 채팅 완료 요청을 입력합니다. 예를 들면 다음과 같습니다.

      $ curl -X POST $MODEL_ENDPOINT/v1/chat/completions \
       -H "Content-Type: application/json" \
       -d '{
       "model": "llama-32-3b-instruct",
       "messages": [
         {
           "role": "user",
           "content": "Hello"
         }
       ]
      }'
      Copy to Clipboard Toggle word wrap
    • 모델 배포 중에 토큰 인증이 필요한 경우 요청에 토큰을 포함합니다. 예를 들면 다음과 같습니다.

      curl -s -k $MODEL_ENDPOINT/v1/chat/completions \
      --header "Authorization: Bearer $MODEL_TOKEN" \
      --header 'Content-Type: application/json' \
      -d '{
        "model": "llama-32-3b-instruct",
        "messages": [
          {
            "role": "user",
            "content": "can you tell me a funny joke?"
          }
        ]
      }' | jq .
      Copy to Clipboard Toggle word wrap
      참고

      -k 플래그는 SSL 확인을 비활성화하고 테스트 환경 또는 자체 서명된 인증서에서만 사용해야 합니다.

검증

채팅 완료가 포함된 JSON 응답이 수신되었는지 확인합니다. 예를 들면 다음과 같습니다.

{
  "id": "chatcmpl-05d24b91b08a4b78b0e084d4cc91dd7e",
  "object": "chat.completion",
  "created": 1747279170,
  "model": "llama-32-3b-instruct",
  "choices": [{
    "index": 0,
    "message": {
      "role": "assistant",
      "reasoning_content": null,
      "content": "Hello! It's nice to meet you. Is there something I can help you with or would you like to chat?",
      "tool_calls": []
    },
    "logprobs": null,
    "finish_reason": "stop",
    "stop_reason": null
  }],
  "usage": {
    "prompt_tokens": 37,
    "total_tokens": 62,
    "completion_tokens": 25,
    "prompt_tokens_details": null
  },
  "prompt_logprobs": null
}
Copy to Clipboard Toggle word wrap

예제와 유사한 응답이 수신되지 않으면 엔드포인트 URL 및 토큰이 올바른지 확인하고 모델 배포가 실행 중인지 확인합니다.

2.4. L#178aStackDistribution 인스턴스 배포

L#178aStack 및 RG(검색 대상 생성) 기능을 vLLM에서 제공하는 배포된 L Quarkusa 3.2 모델과 통합할 수 있습니다. 이러한 통합을 통해 대용량 언어 모델(LLM)과 실시간 데이터 검색을 결합한 지능형 애플리케이션을 구축할 수 있으므로 AI 워크로드에 보다 정확하고 상황에 맞는 적절한 응답을 제공할 수 있습니다.

L#178a StackDistribution CR(사용자 정의 리소스)을 생성할 때 spec.server.distribution.image 필드에 L#178a Stack 이미지 quay.io/opendatahub/llama-stack:odh 를 지정합니다. 이미지는 취약점 검사, 역할 기반 액세스 제어, 전역적으로 분산된 콘텐츠 전달을 제공하는 보안 레지스트리인 Quay.io 에서 호스팅됩니다. 이 Red Hat 검증 이미지를 사용하면 배포에서 최신 보안 패치 및 호환성 업데이트를 자동으로 받을 수 있습니다. Quay.io 사용에 대한 자세한 내용은 Quay.io 개요 를 참조하십시오.

중요

L#178a Stack 이미지는 OpenShift AI와 L#178a Stack 통합의 개발자 프리뷰 단계에서만 Quay.io 에서 호스팅됩니다. L#178a Stack 통합이 정식 출시에 도달하면 registry.redhat.io 에서 이미지를 사용할 수 있습니다.

사전 요구 사항

  • OpenShift AI에서 GPU 지원을 활성화했습니다. 여기에는 Node Feature Discovery Operator 및 NVIDIA GPU Operator 설치가 포함됩니다. 자세한 내용은 Node Feature Discovery Operator 설치NVIDIA GPU 활성화를 참조하십시오.
  • OpenShift 클러스터에 대한 클러스터 관리자 권한이 있습니다.
  • Red Hat OpenShift AI에 로그인했습니다.
  • OpenShift AI에서 L#178a Stack Operator를 활성화했습니다.
  • 예를 들어 llama-3.2-3b-instruct 모델과 같이 vLLM을 사용하여 유추 모델을 배포했으며 외부 경로를 통해 배포된 모델을 선택하고 모델 배포 중에 토큰 인증이 필요함을 선택했습니다.
  • 올바른 유추 모델 식별자(예: llama-3-2-3b)가 있습니다.
  • https://llama-32-3b-instruct-predictor:8443/v1 과 같이 /v1 로 끝나는 모델 끝점 URL이 있습니다.
  • 모델 끝점에 액세스하는 데 필요한 API 토큰이 있습니다.
  • OpenShift CLI(OpenShift Dedicated) 설치 또는 OpenShift CLI(Red Hat OpenShift Service on AWS) 설치에 설명된 대로 OpenShift 명령줄 인터페이스(oc) 를 설치했습니다.

프로세스

  1. 새 터미널 창을 엽니다.

    1. CLI에서 OpenShift 클러스터에 로그인합니다.
    2. OpenShift 웹 콘솔의 오른쪽 상단에서 사용자 이름을 클릭하고 로그인 복사 명령을 선택합니다.
    3. 로그인한 후 토큰 표시를 클릭합니다.
    4. 이 토큰 명령으로 로그인을 복사하여 OpenShift CLI(명령줄 인터페이스)에 붙여넣습니다.

      $ oc login --token=<token> --server=<openshift_cluster_url>
      Copy to Clipboard Toggle word wrap
  2. 유추 모델 환경 변수를 포함하는 보안을 생성합니다.

    export INFERENCE_MODEL="llama-3-2-3b"
    export VLLM_URL="https://llama-32-3b-instruct-predictor:8443/v1"
    export VLLM_TLS_VERIFY="false" # Use "true" in production!
    export VLLM_API_TOKEN="<token identifier>"
    
    oc create secret generic llama-stack-inference-model-secret \
      --from-literal INFERENCE_MODEL="$INFERENCE_MODEL" \
      --from-literal VLLM_URL="$VLLM_URL" \
      --from-literal VLLM_TLS_VERIFY="$VLLM_TLS_VERIFY" \
      --from-literal VLLM_API_TOKEN="$VLLM_API_TOKEN"
    Copy to Clipboard Toggle word wrap
  3. OpenShift 웹 콘솔에 로그인합니다.
  4. 왼쪽 탐색에서 관리자 보기를 선택합니다.
  5. 빠른 생성 ( quick create icon ) 아이콘을 클릭한 다음 YAML 가져오기 옵션을 클릭합니다.
  6. 표시되는 YAML 편집기에서 다음 예와 유사한 CRD(사용자 정의 리소스 정의)를 생성합니다.

    apiVersion: llamastack.io/v1alpha1
    kind: LlamaStackDistribution
    metadata:
      name: lsd-llama-milvus
    spec:
      replicas: 1
      server:
        containerSpec:
          resources:
            requests:
              cpu: "250m"
              memory: "500Mi"
            limits:
              cpu: "2"
              memory: "12Gi"
          env:
            - name: INFERENCE_MODEL
              valueFrom:
                secretKeyRef:
                  key: INFERENCE_MODEL
                  name: llama-stack-inference-model-secret
            - name: VLLM_URL
              valueFrom:
                secretKeyRef:
                  key: VLLM_URL
                  name: llama-stack-inference-model-secret
            - name: VLLM_TLS_VERIFY
              valueFrom:
                secretKeyRef:
                  key: VLLM_TLS_VERIFY
                  name: llama-stack-inference-model-secret
            - name: VLLM_API_TOKEN
              valueFrom:
                secretKeyRef:
                  key: VLLM_API_TOKEN
                  name: llama-stack-inference-model-secret
            - name: MILVUS_DB_PATH
              value: ~/.llama/milvus.db
            - name: FMS_ORCHESTRATOR_URL
              value: "http://localhost"
          name: llama-stack
          port: 8321
        distribution:
          image: quay.io/opendatahub/llama-stack:odh
        storage:
          size: "5Gi"
    Copy to Clipboard Toggle word wrap
  7. 생성을 클릭합니다.

검증

  • 왼쪽 탐색에서 워크로드포드를 클릭한 다음 L declarationaStack Pod 가 올바른 네임스페이스에서 실행 중인지 확인합니다.
  • L#178aStack 서버가 실행 중인지 확인하려면 포드 이름을 클릭하고 로그 탭을 선택합니다. 다음과 유사한 출력을 찾습니다.

    INFO     2025-05-15 11:23:52,750 __main__:498 server: Listening on ['::', '0.0.0.0']:8321
    INFO:     Started server process [1]
    INFO:     Waiting for application startup.
    INFO     2025-05-15 11:23:52,765 __main__:151 server: Starting up
    INFO:     Application startup complete.
    INFO:     Uvicorn running on http://['::', '0.0.0.0']:8321 (Press CTRL+C to quit)
    Copy to Clipboard Toggle word wrap
  • L#178aStack 백엔드에 대한 Service 리소스가 네임스페이스에 있고 실행 중인 Pod를 가리키는지 확인합니다. 웹 콘솔에서 네트워킹서비스를 클릭하여 확인할 수 있습니다.

2.5. L#178a 모델에 콘텐츠 수집

사용자 정의 및 프로토타입을 사용하여 복구 가능한 콘텐츠를 신속하게 사용자 지정할 수 있습니다.You can quickly customize and prototype your retrievable content by ingesting raw text into your model from inside a propyter laptop. 이 방법은 별도의 수집 파이프라인이 필요합니다. L#178aStack SDK를 사용하면 벡터 저장소에 텍스트를 삽입하고 저장하여 즉시 RAG 워크플로를 활성화할 수 있습니다.

사전 요구 사항

  • 귀하는 vLLM 모델 서버에 L Quarkusa 3.2 모델을 배포했으며 L#178aStack을 통합했습니다.
  • 데이터 과학 프로젝트 내에서 프로젝트 워크벤트를 생성했습니다.
  • sendpyter 노트북을 개설했으며 워크벤치 환경에서 실행되고 있습니다.
  • 벡터 데이터베이스 인스턴스를 생성 및 구성하고 해당 식별자를 알고 있습니다.

프로세스

  1. 새 노트북 셀에서 llama_stack 클라이언트 패키지를 설치합니다.

    %pip install llama_stack
    Copy to Clipboard Toggle word wrap
  2. 새로운 노트북 셀에서 RAGDocument 및 L#187aStackClient를 가져옵니다.

    from llama_stack_client import RAGDocument, LlamaStackClient
    Copy to Clipboard Toggle word wrap
  3. 새 노트북 셀에서 배포 끝점을 base_url 매개변수에 할당하여 L#178aStackClient 인스턴스를 생성합니다.

    client = LlamaStackClient(base_url="<your deployment endpoint>")
    Copy to Clipboard Toggle word wrap
  4. 사용 가능한 모델을 나열합니다.

    # Fetch all registered models
    models = client.models.list()
    Copy to Clipboard Toggle word wrap
  5. 등록된 모델 목록에 L#178a 모델 및 포함 모델이 포함되어 있는지 확인합니다. 다음은 등록된 모델 목록의 예입니다.

    [Model(identifier='llama-32-3b-instruct', metadata={}, api_model_type='llm', provider_id='vllm-inference', provider_resource_id='llama-32-3b-instruct', type='model', model_type='llm'),
     Model(identifier='ibm-granite/granite-embedding-125m-english', metadata={'embedding_dimension': 768.0}, api_model_type='embedding', provider_id='sentence-transformers', provider_resource_id='ibm-granite/granite-embedding-125m-english', type='model', model_type='embedding')]
    Copy to Clipboard Toggle word wrap
  6. 첫 번째 Cryostat 및 첫 번째 포함 모델을 선택합니다.

    model_id = next(m.identifier for m in models if m.model_type == "llm")
    
    embedding_model = next(m for m in models if m.model_type == "embedding")
    embedding_model_id = embedding_model.identifier
    embedding_dimension = embedding_model.metadata["embedding_dimension"]
    Copy to Clipboard Toggle word wrap
  7. 새 노트북 셀에서 다음 매개변수를 정의합니다.

    • vector_db_id: 벡터 데이터베이스를 식별하는 고유 이름입니다(예: my_milvus_db ).
    • provider_id: L#178a Stack 게이트웨이가 활성화된 커넥터 키입니다. Milvus 벡터 데이터베이스의 경우 이 커넥터 키는 "milvus" 입니다. 사용 가능한 커넥터를 나열할 수도 있습니다.

      print(client.vector_dbs.list_providers()) # lists available connectors
      
      vector_db_id = "<your vector database ID>"
      provider_id  = "<your provider ID>"
      Copy to Clipboard Toggle word wrap
  8. 새 노트북 셀에서 포함된 항목을 저장할 벡터 데이터베이스를 등록하거나 확인합니다.

    _ = client.vector_dbs.register(
    vector_db_id=vector_db_id,
    embedding_model=embedding_model_id,
    embedding_dimension=embedding_dimension,
    provider_id=provider_id,
    )
    print(f"Registered vector DB: {vector_db_id}")
    Copy to Clipboard Toggle word wrap
    중요

    이 단계를 건너뛰면 결과적으로 벡터 데이터베이스를 벡터 데이터베이스 ID로 등록하지 않으면 벡터 데이터베이스로 텍스트를 수집하려고 하면 오류가 발생합니다.

  9. 새 노트북 셀에서 벡터 저장소에 포함할 원시 텍스트를 정의합니다.

    # Example raw text passage
    raw_text = """
    LlamaStack can embed raw text into a vector store for retrieval.
    This example ingests a small passage for demonstration.
    """
    Copy to Clipboard Toggle word wrap
  10. 새 노트북 셀에서 RAGDocument 오브젝트를 생성하여 원시 텍스트를 포함합니다.

    document = RAGDocument(
    document_id="raw_text_001",
    content=raw_text,
    mime_type="text/plain",
    metadata={"source": "example_passage"},
    )
    Copy to Clipboard Toggle word wrap
  11. 새 노트북 셀에서 원시 텍스트를 수집합니다.

    client.tool_runtime.rag_tool.insert(
        documents=[document],
        vector_db_id=vector_db_id,
        chunk_size_in_tokens=100,
    )
    print("Raw text ingested successfully")
    Copy to Clipboard Toggle word wrap
  12. 새로운 노트북 셀에서 HTML 소스에서 RAGDocument를 생성하고 벡터 저장소에 수집합니다.

    source = "https://www.paulgraham.com/greatwork.html"
    print("rag_tool> Ingesting document:", source)
    
    document = RAGDocument(
        document_id="document_1",
        content=source,
        mime_type="text/html",
        metadata={},
    )
    Copy to Clipboard Toggle word wrap
  13. 새 노트북 셀에서 벡터 저장소로 콘텐츠를 수집합니다.

    client.tool_runtime.rag_tool.insert(
        documents=[document],
        vector_db_id=vector_db_id,
        chunk_size_in_tokens=50,
    )
    print("Raw text ingested successfully")
    Copy to Clipboard Toggle word wrap

검증

  • 출력을 검토하여 성공적인 수집 여부를 확인합니다. 수집 후 일반적인 응답에는 삽입된 텍스트 청크 수와 경고 또는 오류가 포함됩니다.
  • client.models.list() 에서 반환된 모델 목록에는 L declarationa 3.2 모델과 포함 모델이 포함되어 있습니다.

2.6. L#178a 모델에서 수집된 콘텐츠 쿼리

sendpyter 노트북에서 L#178aStack SDK를 사용하여 벡터 데이터베이스에 저장된 원시 텍스트 또는 HTML 소스에서 RG(검색 대상 생성) 쿼리를 실행하여 수집한 콘텐츠를 쿼리할 수 있습니다. 수집된 콘텐츠를 쿼리할 때 별도의 검색 서비스를 설정하지 않고 일회성 조회를 수행하거나 다중 대화 흐름을 시작할 수 있습니다.

사전 요구 사항

  • OpenShift AI에서 GPU 지원을 활성화했습니다. 여기에는 Node Feature Discovery Operator 및 NVIDIA GPU Operator 설치가 포함됩니다. 자세한 내용은 Node Feature Discovery Operator 설치NVIDIA GPU 활성화를 참조하십시오.
  • GPU 가속을 사용하는 경우 하나 이상의 NVIDIA GPU를 사용할 수 있습니다.
  • OpenShift 웹 콘솔에 로그인했습니다.
  • OpenShift AI에서 L#178a Stack Operator를 활성화했습니다.
  • 유추 모델을 배포했습니다(예: llama-3.2-3b-instruct 모델).
  • RAG 기능을 활성화하기 위해 L declarationa StackDistribution 인스턴스를 생성하여 L#178a Stack 배포를 구성했습니다.
  • 데이터 과학 프로젝트 내에서 프로젝트 워크벤트를 생성했습니다.
  • sendpyter 노트북을 개설했으며 워크벤치 환경에서 실행되고 있습니다.
  • 해당 모델에 내용을 수집했습니다.
참고

이 절차에서는 특정 유형의 콘텐츠가 필요하지 않습니다. 이는 이미 일부 텍스트, HTML 또는 문서 데이터를 벡터 데이터베이스로 수집하고 이 콘텐츠를 검색에 사용할 수 있어야 합니다. 이전에 사용한 콘텐츠가 있는 경우 해당 콘텐츠를 쿼리할 수 있습니다. 아직 콘텐츠를 수집하지 않은 경우 이 절차의 쿼리는 빈 결과 또는 오류를 반환합니다.

프로세스

  1. 새 노트북 셀에서 llama_stack 클라이언트 패키지를 설치합니다.

    %pip install llama_stack_client
    Copy to Clipboard Toggle word wrap
  2. 새 노트북 셀에서 에이전트, Agent EventLogger, LDelaya StackClient 가져오기:

    from llama_stack_client import Agent, AgentEventLogger, LlamaStackClient
    Copy to Clipboard Toggle word wrap
  3. 새 노트북 셀에서 배포 끝점을 base_url 매개변수에 할당하여 L#178a StackClient 인스턴스를 생성합니다. 예를 들면 다음과 같습니다.

    client = LlamaStackClient(base_url="http://lsd-llama-milvus-service:8321/")
    Copy to Clipboard Toggle word wrap
  4. 새 노트북 셀에서 사용 가능한 모델을 나열합니다.

    models = client.models.list()
    Copy to Clipboard Toggle word wrap
  5. 등록된 모델 목록에 L#178a 모델 및 포함 모델이 포함되어 있는지 확인합니다. 다음은 등록된 모델 목록의 예입니다.

    [Model(identifier='llama-32-3b-instruct', metadata={}, api_model_type='llm', provider_id='vllm-inference', provider_resource_id='llama-32-3b-instruct', type='model', model_type='llm'),
     Model(identifier='ibm-granite/granite-embedding-125m-english', metadata={'embedding_dimension': 768.0}, api_model_type='embedding', provider_id='sentence-transformers', provider_resource_id='ibm-granite/granite-embedding-125m-english', type='model', model_type='embedding')]
    Copy to Clipboard Toggle word wrap
  6. 새 노트북 셀에서 등록된 모델 목록의 첫 번째 Cryostat를 선택합니다.

    model_id = next(m.identifier for m in models if m.model_type == "llm")
    Copy to Clipboard Toggle word wrap
  7. 새 노트북 셀에서 vector_db_id 를 정의합니다. 이는 벡터 데이터베이스(예: my_milvus_db )를 식별하는 고유한 이름입니다. 벡터 데이터베이스 ID를 모르는 경우 관리자에게 문의하십시오.

    vector_db_id = "<your vector database ID>"
    Copy to Clipboard Toggle word wrap
  8. 새 노트북 셀에서 하위 수준 RAG 도구를 사용하여 수집 한 콘텐츠를 쿼리합니다.

    # Example RAG query for one-off lookups
    query = "What benefits do the ingested passages provide for retrieval?"
    result = client.tool_runtime.rag_tool.query(
        vector_db_ids=[vector_db_id],
        content=query,
    )
    print("Low-level query result:", result)
    Copy to Clipboard Toggle word wrap
  9. 새 노트북 셀에서 상위 수준 에이전트 API를 사용하여 수집한 콘텐츠를 쿼리합니다.

    # Create an Agent for conversational RAG queries
    agent = Agent(
        client,
        model=model_id,
        instructions="You are a helpful assistant.",
        tools=[
            {
                "name": "builtin::rag/knowledge_search",
                "args": {"vector_db_ids": [vector_db_id]},
            }
        ],
    )
    
    prompt = "How do you do great work?"
    print("Prompt>", prompt)
    
    # Create a session and run a streaming turn
    session_id = agent.create_session("rag_session")
    response = agent.create_turn(
        messages=[{"role": "user", "content": prompt}],
        session_id=session_id,
        stream=True,
    )
    
    # Log and print the agent's response
    for log in AgentEventLogger().log(response):
        log.print()
    Copy to Clipboard Toggle word wrap

검증

  • 노트북은 낮은 수준의 RAG 툴과 높은 수준의 에이전트 API 모두에 대한 쿼리 결과를 출력합니다.
  • 출력에 오류가 표시되지 않으므로 모델이 수집된 콘텐츠를 검색하고 응답할 수 있는지 확인합니다.

2.7. L#178a Stack 검색에 대한 Docling을 사용하여 문서 준비

Docling 지원 데이터 사이언스 파이프라인을 사용하여 소스 문서를 변환하고 L#178a Stack 벡터 저장소로 출력을 수집할 수 있습니다. 이러한 모듈식 접근 방식은 문서 준비와 수집과 분리되지만, RAG(end-to-end, retrieval-augmented generation) 워크플로를 계속 제공합니다.

파이프라인은 Milvus 벡터 데이터베이스를 등록하고 소스 PDF를 다운로드한 다음 병렬 처리를 위해 파일을 분할하고 Docling을 사용하여 각 배치를 마크다운으로 변환합니다. 마크다운에서 문장 변환기 포함을 생성하여 벡터 저장소에 저장하여 L#178a Stack에서 문서를 즉시 검색할 수 있습니다.

사전 요구 사항

  • OpenShift AI에서 GPU 지원을 활성화했습니다. 여기에는 Node Feature Discovery Operator 및 NVIDIA GPU Operator 설치가 포함됩니다. 자세한 내용은 Node Feature Discovery Operator 설치NVIDIA GPU 활성화를 참조하십시오.
  • OpenShift 웹 콘솔에 로그인했습니다.
  • 데이터 사이언스 프로젝트가 있고 OpenShift AI 대시보드에서 파이프라인에 액세스할 수 있습니다.
  • 워크벤치가 포함된 데이터 사이언스 프로젝트 내에서 파이프라인 서버를 생성하고 구성했습니다.
  • OpenShift AI에서 L#178a Stack Operator를 활성화했습니다.
  • 유추 모델을 배포했습니다(예: llama-3.2-3b-instruct 모델).
  • RAG 기능을 활성화하기 위해 L declarationa StackDistribution 인스턴스를 생성하여 L#178a Stack 배포를 구성했습니다.
  • 데이터 과학 프로젝트 내에서 프로젝트 워크벤트를 생성했습니다.
  • sendpyter 노트북을 개설했으며 워크벤치 환경에서 실행되고 있습니다.
  • 데이터 사이언스 프로젝트에 연결 추가에 설명된 대로 로컬 오브젝트 스토리지 버킷 및 생성된 연결을 설치했습니다.
  • RAG 데모 샘플 또는 사용자 정의 파이프라인 중 하나로 Docling 변환을 포함하는 데이터 사이언스 파이프라인을 YAML로 컴파일했습니다.
  • 데이터 과학 프로젝트 할당량은 파이프라인 실행을 위해 500밀리코어(0.5 CPU)와 4개의 CPU 코어를 허용합니다.
  • 데이터 사이언스 프로젝트 할당량은 파이프라인 실행을 위해 최대 6GiB RAM 2GiB까지 가능합니다.
  • GPU 가속을 사용하는 경우 하나 이상의 NVIDIA GPU를 사용할 수 있습니다.

프로세스

  1. 새 노트북 셀에서 llama_stack 클라이언트 패키지를 설치합니다.

    %pip install llama_stack_client
    Copy to Clipboard Toggle word wrap
  2. 새 노트북 셀에서 에이전트, AgentEventLogger 및 L declarationaStackClient를 가져옵니다.

    from llama_stack_client import Agent, AgentEventLogger, LlamaStackClient
    Copy to Clipboard Toggle word wrap
  3. 새 노트북 셀에서 배포 끝점을 base_url 매개변수에 할당하여 L#178aStackClient 인스턴스를 생성합니다.

    client = LlamaStackClient(base_url="<your deployment endpoint>")
    Copy to Clipboard Toggle word wrap
  4. 사용 가능한 모델을 나열합니다.

    models = client.models.list()
    Copy to Clipboard Toggle word wrap
  5. 첫 번째 Cryostat 및 첫 번째 포함 모델을 선택합니다.

    model_id = next(m.identifier for m in models if m.model_type == "llm")
    embedding_model = next(m for m in models if m.model_type == "embedding")
    embedding_model_id = embedding_model.identifier
    embedding_dimension = embedding_model.metadata["embedding_dimension"]
    Copy to Clipboard Toggle word wrap
  6. 새 노트북 셀에서 다음 매개변수를 정의합니다.

    • vector_db_id: 벡터 데이터베이스를 식별하는 고유 이름입니다(예: my_milvus_db ).
    • provider_id: L#178a Stack 게이트웨이가 활성화된 커넥터 키입니다. Milvus 벡터 데이터베이스의 경우 이 커넥터 키는 "milvus" 입니다. 사용 가능한 커넥터를 나열할 수도 있습니다.

      print(client.vector_dbs.list_providers()) # lists available connectors
      
      vector_db_id = "<your vector database ID>"
      provider_id  = "<your provider ID>"
      Copy to Clipboard Toggle word wrap
      중요

      RAG 데모 리포지토리의 샘플 Docling 파이프라인을 사용하는 경우 파이프라인은 데이터베이스를 자동으로 등록하고 이 단계를 건너뛸 수 있습니다. 그러나 자체 파이프라인을 사용하는 경우 데이터베이스를 직접 등록해야 합니다.

  7. 새 노트북 셀에서 포함된 항목을 저장할 벡터 데이터베이스를 등록하거나 확인합니다.

    _ = client.vector_dbs.register(
    vector_db_id=vector_db_id,
    embedding_model=embedding_model_id,
    embedding_dimension=embedding_dimension,
    provider_id=provider_id,
    )
    print(f"Registered vector DB: {vector_db_id}")
    Copy to Clipboard Toggle word wrap
  8. OpenShift 웹 콘솔에서 데이터 사이언스 파이프라인 가져오기에 설명된 대로 docling 파이프라인이 포함된 YAML 파일을 데이터 사이언스 프로젝트로 가져옵니다.
  9. 파이프라인 실행 실행에 설명된 대로 Docling 파이프라인 을 실행하는 파이프라인 실행을 생성합니다. 파이프라인 실행은 CSV 문서를 벡터 데이터베이스에 삽입합니다. RAG 데모 샘플 리포지토리에서 Docling 파이프라인을 실행하는 경우 파이프라인 실행을 시작하기 전에 다음 매개변수를 선택적으로 사용자 지정할 수 있습니다.

    • base_url: PDF 파일을 가져올 기본 URL입니다.
    • pdf_filenames: 다운로드 및 변환할 PDF 파일 이름의 쉼표로 구분된 목록입니다.
    • num_workers: 병렬 작업자 수입니다.
    • vector_db_id: Milvus 벡터 데이터베이스 ID입니다.
    • service_url: Milvus 서비스 URL입니다.
    • embed_model_id: 사용할 포함 모델입니다.
    • max_tokens: 각 청크의 최대 토큰입니다.
    • use_gpu: GPU 가속도를 활성화하거나 비활성화합니다.

검증

  1. sendpyter 노트북에서 수집된 콘텐츠와 관련된 질문을 통해 Cryostat를 쿼리합니다. 예를 들면 다음과 같습니다.

    from llama_stack_client import Agent, AgentEventLogger
    import uuid
    
    rag_agent = Agent(
        client,
        model=model_id,
        instructions="You are a helpful assistant",
        tools=[
            {
                "name": "builtin::rag/knowledge_search",
                "args": {"vector_db_ids": [vector_db_id]},
            }
        ],
    )
    
    prompt = "What can you tell me about the birth of word processing?"
    print("prompt>", prompt)
    
    session_id = rag_agent.create_session(session_name=f"s{uuid.uuid4().hex}")
    
    response = rag_agent.create_turn(
        messages=[{"role": "user", "content": prompt}],
        session_id=session_id,
        stream=True,
    )
    
    for log in AgentEventLogger().log(response):
        log.print()
    Copy to Clipboard Toggle word wrap
  2. vector 데이터베이스에서 청크를 쿼리합니다.

    query_result = client.vector_io.query(
        vector_db_id=vector_db_id,
        query="what do you know about?",
    )
    print(query_result)
    Copy to Clipboard Toggle word wrap

2.8. L declarationa 스택 검색 유형 정보

L#178a Stack은 검색 기능(RAG) 워크로드에서 컨텍스트를 검색하기 위한 키워드, 벡터 및 하이브리드 검색 모드를 지원합니다. 각 모드는 정확성, 회수, 의미 깊이 및 컴퓨팅 비용의 다양한 절충을 제공합니다.

2.8.1. 지원되는 검색 모드

2.8.2. 데이터베이스 지원 검색

Milvus는 Llana Stack에 대해 지원되는 검색 데이터베이스입니다. 현재 벡터 검색을 제공합니다. 그러나 키워드 및 하이브리드 검색 기능은 현재 지원되지 않습니다.

법적 공지

Copyright © 2025 Red Hat, Inc.
The text of and illustrations in this document are licensed by Red Hat under a Creative Commons Attribution–Share Alike 3.0 Unported license ("CC-BY-SA"). An explanation of CC-BY-SA is available at http://creativecommons.org/licenses/by-sa/3.0/. In accordance with CC-BY-SA, if you distribute this document or an adaptation of it, you must provide the URL for the original version.
Red Hat, as the licensor of this document, waives the right to enforce, and agrees not to assert, Section 4d of CC-BY-SA to the fullest extent permitted by applicable law.
Red Hat, Red Hat Enterprise Linux, the Shadowman logo, the Red Hat logo, JBoss, OpenShift, Fedora, the Infinity logo, and RHCE are trademarks of Red Hat, Inc., registered in the United States and other countries.
Linux® is the registered trademark of Linus Torvalds in the United States and other countries.
Java® is a registered trademark of Oracle and/or its affiliates.
XFS® is a trademark of Silicon Graphics International Corp. or its subsidiaries in the United States and/or other countries.
MySQL® is a registered trademark of MySQL AB in the United States, the European Union and other countries.
Node.js® is an official trademark of Joyent. Red Hat is not formally related to or endorsed by the official Joyent Node.js open source or commercial project.
The OpenStack® Word Mark and OpenStack logo are either registered trademarks/service marks or trademarks/service marks of the OpenStack Foundation, in the United States and other countries and are used with the OpenStack Foundation's permission. We are not affiliated with, endorsed or sponsored by the OpenStack Foundation, or the OpenStack community.
All other trademarks are the property of their respective owners.
Red Hat logoGithubredditYoutubeTwitter

자세한 정보

평가판, 구매 및 판매

커뮤니티

Red Hat 문서 정보

Red Hat을 사용하는 고객은 신뢰할 수 있는 콘텐츠가 포함된 제품과 서비스를 통해 혁신하고 목표를 달성할 수 있습니다. 최신 업데이트를 확인하세요.

보다 포괄적 수용을 위한 오픈 소스 용어 교체

Red Hat은 코드, 문서, 웹 속성에서 문제가 있는 언어를 교체하기 위해 최선을 다하고 있습니다. 자세한 내용은 다음을 참조하세요.Red Hat 블로그.

Red Hat 소개

Red Hat은 기업이 핵심 데이터 센터에서 네트워크 에지에 이르기까지 플랫폼과 환경 전반에서 더 쉽게 작업할 수 있도록 강화된 솔루션을 제공합니다.

Theme

© 2026 Red Hat
맨 위로 이동