제3자 통합 기반 AI 기능

로컬 개발 환경에서 GitLab Duo 기능 설정 지침

필수: AI Gateway 설치

이유: 모든 Duo 기능은 LLM 요청을 AI Gateway를 통해 라우팅합니다.

방법: 이 지침을 따라 GDK로 AI Gateway를 설치하세요. 대부분의 사용자에게 이 경로를 권장합니다.

또한 AI Gateway를 다음 방법으로 설치할 수 있습니다:

  1. 저장소를 직접 복제하기.
  2. 서버를 로컬에서 실행하기.

우리는 GDK를 통해 AI Gateway를 실행하지 않을 특별한 이유가 있는 사용자에게만 이 방법을 권장합니다.

필수: GitLab-Rails에서 라이센스 설정

이유: GitLab Duo는 Premium 및 Ultimate 고객에게만 제공됩니다. GDK를 위해 Ultimate 라이센스가 필요할 것입니다. Ultimate는 모든 GitLab Duo 기능에 접근할 수 있게 해줍니다.

방법:

귀하의 로컬 인스턴스에 대한 EE 라이센스를 획득하는 프로세스를 따르고 라이센스를 업로드하세요.

라이센스가 적용되었는지 확인하려면 관리 영역 > 구독으로 이동하여 구독 계획을 확인하세요.

GDK 설정 및 실행

옵션 A: SaaS (GitLab.com) 모드에서

이유: 대부분의 Duo 기능은 먼저 GitLab.com에서 제공되므로 SaaS 모드로 실행하면 대부분의 기능에 접근할 수 있습니다.

방법:

그룹에 대한 Duo 기능을 설정하기 위해 Rake 작업을 실행하세요:

GITLAB_SIMULATE_SAAS=1 bundle exec 'rake gitlab:duo:setup[test-group-name]'
gdk restart

test-group-name을 모든 최상위 그룹의 이름으로 바꾸세요. Duo는 해당 그룹에 대해 구성됩니다. 그룹이 존재하지 않으면 새 그룹이 생성됩니다.

스크립트가 성공적으로 실행되었는지 확인하세요. 오류 메시지를 인쇄하며 어떤 오류도 해결하는 방법에 대한 링크를 제공합니다. 성공할 때까지 스크립트를 다시 실행할 수 있습니다.

SaaS 모드에서는 Duo 기능이 활성화된 그룹의 구성원이 많은 AI 기능을 사용할 수 있게 합니다. 테스트 사용자가 Duo 기능이 활성화된 그룹의 구성원(test-group-name)인지 확인하세요.

이 Rake 작업은 해당 그룹에 연결된 Duo Enterprise 애드온을 생성합니다.

Duo Pro 애드온이 필요한 경우 다음을 사용하세요:

GITLAB_SIMULATE_SAAS=1 bundle exec 'rake gitlab:duo:setup[test-group-name,duo_pro]'

Duo Pro 애드온은 더 작은 범위의 기능을 제공합니다. 애드온의 사용은 사용하고자 하는 기능에 따라 다릅니다.

옵션 B: Self-managed 모드에서

이유: Custom Models와 같이 Self-managed에 특정한 것을 테스트하고 싶을 경우입니다.

방법:

인스턴스에 대한 Duo 기능을 설정하기 위해 Rake 작업을 실행하세요:

GITLAB_SIMULATE_SAAS=0 bundle exec 'rake gitlab:duo:setup_instance'
gdk restart

이 Rake 작업은 귀하의 인스턴스에 연결된 Duo Enterprise 애드온을 생성합니다.

Duo Pro 애드온이 필요한 경우 다음을 사용하세요:

GITLAB_SIMULATE_SAAS=0 bundle exec 'rake gitlab:duo:setup_instance[duo_pro]'

Duo Pro 애드온은 더 작은 범위의 기능을 제공합니다. 애드온의 사용은 사용하고자 하는 기능에 따라 다릅니다.

추천: CLOUD_CONNECTOR_SELF_SIGN_TOKENS 환경 변수 설정

이유: 이 환경 변수를 설정하면 로컬 GitLab 인스턴스가 CustomersDot과 먼저 동기화하지 않고도 토큰을 스스로 발급할 수 있습니다.

이 설정으로 인해, CustomersDot 설정을 건너 뛸 수 있습니다.

방법: 다음은 GDK 루트의 env.runit 파일에 설정해야 합니다:

# <GDK-root>/env.runit

export CLOUD_CONNECTOR_SELF_SIGN_TOKENS=1

변경 사항을 적용하려면 GDK를 재시작해야 합니다.

CLOUD_CONNECTOR_SELF_SIGN_TOKENS=1을 사용할 경우, root/admin 사용자는 seat assigned를 받아야 합니다 “Code completion test was successful” 알림을 http://localhost:3000/admin/code_suggestions 페이지의 건강 검사를 통해 받을 수 있습니다.

우리 고객(운영 환경)은 코드 제안 건강 검사를 실행하기 위해 그렇게 할 필요가 없습니다.

추천: Rails 콘솔에서 클라이언트 테스트

이유: 모든 설정 단계를 완료했으므로 이제 GitLab Duo가 실제로 작동하는지 확인할 차례입니다.

방법:

설정이 완료된 후 GitLab-Rails에서 클라이언트가 AI Gateway에 올바르게 연결되는지 테스트할 수 있습니다:

  1. gdk start를 실행합니다.
  2. gdk rails console로 Rails 콘솔에 로그인합니다.
  3. 모델과 대화합니다:

    # Anthropic 모델과 대화
    Gitlab::Llm::Anthropic::Client.new(User.first, unit_primitive: 'duo_chat').complete(prompt: "\n\nHuman: Hi, How are you?\n\nAssistant:")
    
    # Vertex AI 모델과 대화
    Gitlab::Llm::VertexAi::Client.new(User.first, unit_primitive: 'documentation_search').text_embeddings(content: "How can I create an issue?")
    
    # `/v1/chat/agent` 엔드포인트 테스트
    Gitlab::Llm::Chain::Requests::AiGateway.new(User.first).request(prompt: [{role: "user", content: "Hi, how are you?"}])
    

참고: 이 문서를 참조하여 Cloud Connector에서 unit primitives를 등록하세요.

선택 사항: AI Gateway에서 인증 및 권한 부여 활성화

이유: AI Gateway는 인증 및 권한 부여 흐름을 통해 클라이언트가 기능에 접근할 권한이 있는지 검증합니다. 인증은 GitLab 인프라 팀이 호스팅하는 모든 라이브 환경에서 시행됩니다. 이 흐름을 로컬 개발 환경에서 테스트할 수 있습니다.

참고: 개발 환경(GDK 등)에서는 기본적으로 이 프로세스가 비활성화되어 있습니다.

권한 부여 검사를 활성화하려면 AI Gateway의 애플리케이션 설정 파일(<GDK-root>/gitlab-ai-gateway/.env)에서 AIGW_AUTH__BYPASS_EXTERNALfalse로 설정하세요.

옵션 1: GitLab 인스턴스를 공급자로 사용

이유: 이는 인증을 테스트하는 가장 간단한 방법으로, GitLab.com의 설정을 반영합니다.

방법: AI Gateway를 GDK로 실행한다고 가정하고, GDK에 다음 구성을 적용합니다:

# <GDK-root>/env.runit

export GITLAB_SIMULATE_SAAS=1

AI Gateway에서 애플리케이션 설정 파일을 업데이트합니다:

# <GDK-root>/gitlab-ai-gateway/.env

AIGW_AUTH__BYPASS_EXTERNAL=false
AIGW_GITLAB_URL=<your-gdk-url>

그런 다음 gdk restart를 실행합니다.

옵션 2: customersDot 인스턴스를 프로바이더로 사용하기

이유: 기능 테스트 또는 업데이트를 원하는 경우 클라우드 라이센스와 관련된 customersDot 설정이 필요합니다. 또는 GDK를 비 SaaS 모드로 실행하는 경우에도 필요합니다.

참고: 이 설정은 도전적입니다. 고객Dot 통합을 로컬에서 더 쉽게 테스트할 수 있는 방법에 대한 문제가 있습니다.

그 문제가 해결되기 전까지 이 설정 과정은 시간이 많이 걸리며 가능한 한 피해야 합니다.

어떤 이유로든 로컬 GitLab Rails 인스턴스에서 customersDot이 작동해야 하는 경우, Slack에서 #s_fulfillment_engineering에 문의하세요. AI 사용 사례를 제공하기 위한 CDot와 다른 시스템의 통합에 관한 질문은 #g_cloud_connector에 문의하세요.

도움말

로컬 개발을 위한 팁

  1. 응답이 사용자 인터페이스에 나타나기까지 시간이 너무 오래 걸리는 경우, gdk restart rails-background-jobs를 실행하여 Sidekiq를 재시작하는 것을 고려하세요. 그렇지 않으면 gdk kill을 시도한 다음 gdk start를 시도하세요.

  2. 또는 Sidekiq를 완전히 우회하고 서비스를 동기식으로 실행하세요. 이렇게 하면 GraphQL 오류가 이제 Sidekiq 로그 대신 네트워크 인스펙터에서 사용 가능하므로 오류 디버깅에 도움이 됩니다. 그렇게 하려면 Llm::CompletionWorker 클래스의 perform_for 메서드를 임시로 변경하여 perform_asyncperform_inline으로 바꾸세요.

기능 개발 (추상화 계층)

기능 플래그

AI 기능 작업에 다음 기능 플래그를 적용하세요:

  • 모든 GitLab Duo Chat 기능에 적용되는 일반 플래그(ai_duo_chat_switch). 기본적으로 활성화되어 있습니다.

  • 모든 기타 AI 기능에 적용되는 일반 플래그(ai_global_switch). 기본적으로 활성화되어 있습니다.

  • 해당 기능에 특화된 플래그. 기능 플래그 이름은 라이센스 있는 기능 이름과 다르게 해야 합니다.

모든 기능 플래그 목록과 사용하는 방법은 기능 플래그 추적 에픽을 확인하세요.

AI 게이트웨이에 기능 플래그 푸시하기

기능 플래그를 AI 게이트웨이에 푸시할 수 있습니다. 이렇게 하면 AI 게이트웨이에 있는 기능이 사용자에게 공개되는 변화를 점진적으로 롤아웃하는 데 도움이 됩니다. 다음 예제를 참조하세요:

# AI 게이트웨이에 기능 플래그 상태를 푸시합니다.
Gitlab::AiGateway.push_feature_flag(:new_prompt_template, user)

이후 AI 게이트웨이에서 기능 플래그 상태를 다음과 같은 방식으로 사용할 수 있습니다:

from ai_gateway.feature_flags import is_feature_enabled

# "new_prompt_template" 기능 플래그가 활성화되어 있는지 확인합니다.
if is_feature_enabled('new_prompt_template'):
  # 새 프롬프트 템플릿에서 프롬프트를 빌드합니다.
else:
  # 이전 프롬프트 템플릿에서 프롬프트를 빌드합니다.

중요: 청소 단계에서 AI 게이트웨이 리포지토리에서 플래그를 제거하기 전에 GitLab-Rails 리포지토리에서 플래그를 제거하세요.

먼저 GitLab-Rails 리포지토리에서 플래그를 정리하면 AI 게이트웨이의 기능 플래그가 즉시 비활성화되어 기본 상태가 되므로 놀라운 동작을 경험할 수 있습니다.

중요: AI 게이트웨이에서 기능 플래그를 정리하면 변경 사항이 GitLab.com, Self-managed GitLab, 그리고 전용 GitLab을 포함한 모든 GitLab 인스턴스에 즉시 배포됩니다.

기술 세부정보: push_feature_flag가 활성화된 기능 플래그에서 실행될 때, 플래그 이름이 현재 컨텍스트에 캐시되어 나중에 GitLab-Sidekiq/Rails가 AI 게이트웨이에 요청할 때 x-gitlab-enabled-feature-flags HTTP 헤더에 첨부됩니다.

유사한 개념으로, 우리는 push_frontend_feature_flag를 사용하여 프론트엔드에 기능 플래그를 푸시합니다.

GraphQL API

AI 제공자 API에 Abstraction Layer를 사용하여 연결하려면, aiAction이라는 확장 가능한 GraphQL API를 사용합니다.

input은 키/값 쌍을 받아들이며, key는 수행해야 하는 작업입니다.

우리는 하나의 AI 작업만 각 뮤테이션 요청에 허용합니다.

변경 요청의 예:

mutation {
  aiAction(input: {summarizeComments: {resourceId: "gid://gitlab/Issue/52"}}) {
    clientMutationId
  }
}

예를 들어, “코드 설명” 작업을 구축하고 싶다고 가정해 보겠습니다.

이를 위해, 새로운 키 explainCodeinput을 확장합니다.

뮤테이션은 다음과 같이 보일 것입니다:

mutation {
  aiAction(
    input: {
      explainCode: { resourceId: "gid://gitlab/MergeRequest/52", code: "foo() { console.log() }" }
    }
  ) {
    clientMutationId
  }
}

그 후 GraphQL API는 Anthropic Client를 사용하여 응답을 전송합니다.

응답을 받는 방법

AI 제공자에 대한 API 요청은 백그라운드 작업으로 처리됩니다.

그러므로 요청을 유지하지 않으며, 프론트엔드는 요청과 구독의 응답을 일치시켜야 합니다.

경고:

userIdresourceId만 사용하면 요청에 대한 올바른 응답을 결정하는 데 문제가 발생할 수 있습니다.

예를 들어, 두 AI 기능이 동일한 userIdresourceId를 사용하는 경우, 두 구독은 서로의 응답을 받게 됩니다.

이 간섭을 방지하기 위해 clientSubscriptionId를 도입했습니다.

aiCompletionResponse 구독의 응답을 일치시키기 위해, aiAction 뮤테이션에 clientSubscriptionId를 제공할 수 있습니다.

  • clientSubscriptionId는 각 기능에 대해 고유해야 하며, 다른 AI 기능과 간섭하지 않기 위해 페이지 내에서 고유해야 합니다. UUID를 사용할 것을 권장합니다.
  • clientSubscriptionIdaiAction 뮤테이션의 일부로 제공되어야만 aiCompletionResponse 방송에 사용됩니다.
  • clientSubscriptionId가 제공되지 않으면, 오직 userIdresourceIdaiCompletionResponse에 사용됩니다.

댓글 요약을 위한 예시 뮤테이션에서 randomId를 뮤테이션의 일부로 제공합니다:

mutation {
  aiAction(
    input: {
      summarizeComments: { resourceId: "gid://gitlab/Issue/52" }
      clientSubscriptionId: "randomId"
    }
  ) {
    clientMutationId
  }
}

우리의 컴포넌트에서는 userId, resourceIdclientSubscriptionId("randomId")를 사용하여 aiCompletionResponse를 수신합니다:

subscription aiCompletionResponse(
  $userId: UserID
  $resourceId: AiModelID
  $clientSubscriptionId: String
) {
  aiCompletionResponse(
    userId: $userId
    resourceId: $resourceId
    clientSubscriptionId: $clientSubscriptionId
  ) {
    content
    errors
  }
}

Chat의 구독은 다르게 동작합니다.

동시 구독이 너무 많지 않도록, 뮤테이션이 전송될 때까지 구독에 skip() 기능을 사용해야 합니다.

현재 추상화 레이어 흐름

다음 그래프는 VertexAI를 예로 사용합니다. 다른 제공자를 사용할 수 있습니다.

flowchart TD A[GitLab 프론트엔드] -->B[AiAction GraphQL 변이] B --> C[Llm::ExecuteMethodService] C --> D[서비스 중 하나, 예: Llm::GenerateSummaryService] D -->|scheduled| E[AI 작업자: Llm::CompletionWorker] E -->F[::Gitlab::Llm::Completions::Factory] F -->G[`::Gitlab::Llm::VertexAi::Completions::...` 클래스가 `::Gitlab::Llm::Templates::...` 클래스를 사용] G -->|호출| H[Gitlab::Llm::VertexAi::Client] H --> |응답| I[::Gitlab::Llm::GraphqlSubscriptionResponseService] I --> J[GraphqlTriggers.ai_completion_response] J --> K[::GitlabSchema.subscriptions.trigger]

새로운 액션 구현 방법

새로운 AI 액션을 구현하기 위해서는 GitLab 모놀리식과 AI 게이트웨이 모두에서 변경이 필요합니다.

우리는 주어진 프롬프트에 따라 사용자가 문제 설명을 다시 작성할 수 있도록 하는 액션을 구현하려고 하는 예를 사용할 것입니다.

1. Cloud Connector 기능 목록에 액션 추가하기

Cloud Connector 구성은 서비스를 액세스하는 데 필요한 권한과 추가 메타데이터를 저장합니다.

자세한 내용은 Cloud Connector: 구성을 참조하세요.

# ee/config/cloud_connector/access_data.yml

services:
  # ...
  rewrite_description:
    backend: 'gitlab-ai-gateway'
    bundled_with:
      duo_enterprise:
        unit_primitives:
          - rewrite_issue_description

2. AI 게이트웨이에 에이전트 정의 만들기

AI 게이트웨이 프로젝트에서

ai_gateway/agents/definitions 아래에 새로운 에이전트 정의를 만듭니다.

AI 액션의 이름에 해당하는 새로운 하위 폴더와 에이전트에 대한 새로운 YAML 파일을 생성합니다.

사용하려는 모델과 제공자를 지정하고 모델에 제공될 프롬프트를 설정합니다.

프롬프트에 끼워 넣을 입력은 {}를 사용하여 지정할 수 있습니다.

# ai_gateway/agents/definitions/rewrite_description/base.yml

name: 설명 다시 작성기
model:
  name: claude-3-sonnet-20240229
  params:
    model_class_provider: anthropic
prompt_template:
  system: |
    당신은 자원의 설명을 다시 작성하는 유용한 조수입니다. 현재 설명과 어떻게 다시 작성해야 하는지에 대한 프롬프트를 제공합니다. 
    당신의 다시 작성된 설명만 응답하세요.

    <description>{description}</description>

    <prompt>{prompt}</prompt>

AI 액션이 더 넓은 기능의 일부인 경우 정의는 트리 구조로 조직될 수 있습니다:

# ai_gateway/agents/definitions/code_suggestions/generations/base.yml

name: 코드 생성
model:
  name: claude-3-sonnet-20240229
  params:
    model_class_provider: anthropic
...

여러 모델에 대한 프롬프트를 지정하려면 정의의 파일 이름으로 모델의 이름을 사용하세요:

# ai_gateway/agents/definitions/code_suggestions/generations/mistral.yml

name: 코드 생성
model:
  name: mistral
  params:
    model_class_provider: litellm
...

3. Completion 클래스 생성

  1. ee/lib/gitlab/llm/ai_gateway/completions/ 아래에 새로운 completion을 만들고 Base AI Gateway Completion을 상속합니다.
# ee/lib/gitlab/llm/ai_gateway/completions/rewrite_description.rb

module Gitlab
  module Llm
    module AiGateway
      module Completions
        class RewriteDescription < Base
          def agent_name
            'base' # AI Gateway에서 정의한 에이전트의 이름과 일치해야 합니다.
          end

          def inputs
            { description: resource.description, prompt: prompt_message.content }
          end
        end
      end
    end
  end
end

4. 서비스 생성

  1. ee/app/services/llm/ 아래에 새로운 서비스를 만들고 BaseService를 상속합니다.
  2. resource는 우리가 작업하려는 객체입니다. Ai::Model을 포함하는 모든 객체일 수 있습니다. 예를 들어, Project, MergeRequest, 또는 Issue일 수 있습니다.
# ee/app/services/llm/rewrite_description_service.rb

module Llm
  class RewriteDescriptionService < BaseService
    extend ::Gitlab::Utils::Override

    override :valid
    def valid?
      super &&
        # 서비스가 적용되는 리소스의 타입을 제한할 수 있습니다.
        resource.to_ability_name == "issue" &&
        # 항상 사용자가 리소스에 대해 이 작업을 수행할 수 있는지 확인합니다.
        Ability.allowed?(user, :rewrite_description, resource)
    end

    private

    def perform
      schedule_completion_worker
    end
  end
end

5. 카탈로그에 기능 등록

Gitlab::Llm::Utils::AiFeaturesCatalogue로 가서 AI 작업에 대한 새로운 항목을 추가합니다.

class AiFeaturesCatalogue
  LIST = {
    # ...
    rewrite_description: {
      service_class: ::Gitlab::Llm::AiGateway::Completions::RewriteDescription,
      feature_category: :ai_abstraction_layer,
      execute_method: ::Llm::RewriteDescriptionService,
      maturity: :experimental,
      self_managed: false,
      internal: false
    }
  }.freeze

기존 작업을 AI Gateway로 마이그레이션하는 방법

AI 작업은 처음에 GitLab 모놀리식 내에서 구현되었습니다. 우리의

AI Gateway as the Sole Access Point for Monolith to Access Models Epic

의 일환으로 프롬프트, 모델 선택 및 모델 매개변수를 AI Gateway로 마이그레이션하고 있습니다. 이는 프롬프트와 모델 변경을 모놀리틱 릴리스와 분리하여 자가 관리 사용자가 개선 사항을 더 빠르게 제공할 수 있도록 합니다. 기존 작업을 마이그레이션하려면:

  1. 새 작업을 구현하는 방법에서 1단계에서 3단계까지 따릅니다.
  2. 카탈로그에서 AI 작업의 항목을 수정하여 새 completion 클래스를 aigw_service_class로 나열합니다.
class AiFeaturesCatalogue
  LIST = {
    # ...
    generate_description: {
      service_class: ::Gitlab::Llm::Anthropic::Completions::GenerateDescription,
      aigw_service_class: ::Gitlab::Llm::AiGateway::Completions::GenerateDescription,
      prompt_class: ::Gitlab::Llm::Templates::GenerateDescription,
      feature_category: :ai_abstraction_layer,
      execute_method: ::Llm::GenerateDescriptionService,
      maturity: :experimental,
      self_managed: false,
      internal: false
    },
    # ...
  }.freeze

기능 플래그 ai_gateway_agents가 활성화되면 aigw_service_class가 AI 작업을 처리하는 데 사용됩니다.

작동이 올바른지 검증한 후, aigw_service_class 키를 제거하고 새 AiGateway::Completions 클래스로 service_class를 교체하여 영구적인 제공자로 만듭니다.

AI 작업을 마이그레이션하는 데 필요한 변경 사항의 전체 예시는 다음 MRs를 참조하세요:

GitLab-Rails의 권한 부여

기능의 권한 부여를 처리하기 위해 정책을 사용하는 것을 권장합니다. 현재 우리는 다음 검사를 수행해야 합니다:

기본적인 권한 부여는 더 전문화된 클래스의 기본 클래스인 Abstraction Layer 클래스에 포함되어 있습니다.

코드에 포함해야 할 내용:

  1. 기능 플래그 호환성 확인: Gitlab::Llm::Utils::FlagChecker.flag_enabled_for_feature?(ai_action) - Llm::BaseService 클래스에 포함되어 있습니다.

  2. 리소스 승인 여부 확인: Gitlab::Llm::Utils::Authorizer.resource(resource: resource, user: user).allowed? - 또한 Llm::BaseService 클래스에 포함되어 있습니다.

  3. 위 두 가지 검사는 ::Gitlab::Llm::FeatureAuthorizer.new(container: subject_container, feature_name: action_name).allowed?에 포함되어 있습니다.

  4. AI 기능에 대한 액세스는 여러 가지 요인에 따라 달라집니다. 예를 들어: 그들의 성숙도, 셀프 관리에서 사용 가능 여부, 애드온 내에서 번들되어 있는지 여부 등.

    • 예제 특정 리소스에 연결되지 않은 정책.
    • 예제 특정 리소스에 연결된 정책.

주의: AI Gateway에서 인증 및 권한 부여에 대한 더 많은 정보는 GitLab AI Gateway 문서를 참조하세요.

요청과 응답 쌍

여러 사용자의 요청을 병렬로 처리할 수 있기 때문에, 응답을 받을 때 원래의 요청과 응답을 연결하기 어려울 수 있습니다. requestId 필드는 이 목적을 위해 사용될 수 있으며, 요청과 응답 모두 동일한 requestId UUID를 갖습니다.

캐싱

AI 요청 및 응답은 캐시될 수 있습니다. 캐시된 대화는 AI 기능과의 사용자 상호작용을 표시하는 데 사용됩니다. 현재 구현에서는 사용자가 요청을 반복할 때 AI 서비스에 대한 연속 호출을 건너뛰기 위해 이 캐시가 사용되지 않습니다.

query {
  aiMessages {
    nodes {
      id
      requestId
      content
      role
      errors
      timestamp
    }
  }
}

이 캐시는 채팅 기능에 사용됩니다. 다른 서비스에서는 캐싱이 비활성화되어 있습니다. cache_response: true 옵션을 사용하여 서비스에 대해 이를 활성화할 수 있습니다.

캐시는 다음과 같은 제한 사항이 있습니다:

  • 메시지는 Redis 스트림에 저장됩니다.
  • 사용자당 단일 메시지 스트림이 있습니다. 즉, 현재 모든 서비스가 동일한 캐시를 공유합니다. 필요하다면, Redis가 예상 메시지 수를 처리할 수 있는지 인프라 팀과 확인한 후 사용자당 여러 스트림으로 확장할 수 있습니다.
  • 마지막 50개의 메시지(요청 + 응답)만 유지됩니다.
  • 스트림의 만료 시간은 마지막 메시지가 추가된 후 3일입니다.
  • 사용자는 자신의 메시지만 접근할 수 있습니다. 캐시 레벨에서는 권한 부여가 없으며, (현재 사용자가 아닌 경우 접근할 경우) 서비스 레이어에서 권한 부여가 이루어질 것으로 예상됩니다.

네임스페이스 설정에 따라 이 리소스에 대해 기능이 허용되는지 확인

AI 기능 사용을 제한하는 루트 네임스페이스 수준에서 허용되는 설정이 있습니다:

  • experiment_features_enabled

주어진 네임스페이스에 대해 해당 기능이 허용되는지 확인하려면 다음을 호출합니다:

Gitlab::Llm::StageCheck.available?(namespace, :name_of_the_feature)

기능의 이름을 Gitlab::Llm::StageCheck 클래스에 추가합니다. 실험적 기능과 베타 기능을 구분하는 배열이 있습니다.

이렇게 하면 다음과 같은 다양한 경우에 대비할 수 있습니다:

  • 기능이 어떤 배열에도 포함되어 있지 않으면, 검사는 true를 반환합니다. 예를 들어, 기능이 GA로 이동되었습니다.

기능을 실험 단계에서 베타 단계로 이동하려면 EXPERIMENTAL_FEATURES 배열에서 기능의 이름을 BETA_FEATURES 배열로 이동하면 됩니다.

AI API 호출 및 프롬프트 구현

CompletionWorker는 서비스 초기화 및 API에 대한 실제 호출 실행을 담당하는 Completions::Factory를 호출합니다.

우리의 예제에서는 VertexAI를 사용하고 두 개의 새로운 클래스를 구현합니다:

# /ee/lib/gitlab/llm/vertex_ai/completions/rewrite_description.rb

module Gitlab
  module Llm
    module VertexAi
      module Completions
        class AmazingNewAiFeature < Gitlab::Llm::Completions::Base
          def execute
            prompt = ai_prompt_class.new(options[:user_input]).to_prompt

            response = Gitlab::Llm::VertexAi::Client.new(user, unit_primitive: 'amazing_feature').text(content: prompt)

            response_modifier = ::Gitlab::Llm::VertexAi::ResponseModifiers::Predictions.new(response)

            ::Gitlab::Llm::GraphqlSubscriptionResponseService.new(
              user, nil, response_modifier, options: response_options
            ).execute
          end
        end
      end
    end
  end
end
# /ee/lib/gitlab/llm/vertex_ai/templates/rewrite_description.rb

module Gitlab
  module Llm
    module VertexAi
      module Templates
        class AmazingNewAiFeature
          def initialize(user_input)
            @user_input = user_input
          end

          def to_prompt
            <<~PROMPT
            당신은 다음 컨텍스트를 위한 코드를 작성하는 도우미입니다:

            context: #{user_input}
            PROMPT
          end
        end
      end
    end
  end
end

여러 AI 공급자를 지원하기 때문에 같은 예제에서 이러한 공급자도 사용할 수 있습니다:

Gitlab::Llm::VertexAi::Client.new(user, unit_primitive: 'your_feature')
Gitlab::Llm::Anthropic::Client.new(user, unit_primitive: 'your_feature')

모니터링

로그

개요

GitLab Rails Monolith 인스턴스의 표준 로깅 외에도 대형 언어 모델(LLMs)을 기반으로 한 기능에 대한 전문 로깅이 제공됩니다.

기록된 이벤트

현재 기록된 이벤트는 여기에 문서화되어 있습니다.

구현

로거 클래스

LLM 전용 로깅을 구현하려면 Gitlab::Llm::Logger 클래스를 사용합니다.

개인 정보 보호 고려사항

중요: 사용자 입력 및 사용자 데이터를 포함하는 전체 프롬프트는 명시적으로 허가되지 않는 한 로깅하지 않아야 합니다.

기능 플래그

expanded_ai_logging라는 기능 플래그는 민감한 데이터의 로깅을 제어합니다.

기능 플래그 상태에 따라 조건부 로깅을 위한 conditional_info 도우미 메서드를 사용하세요:

  • 현재 사용자에 대해 기능 플래그가 활성화된 경우, 정보 수준에서 정보를 기록합니다(로그는 Kibana에서 접근할 수 있음).
  • 현재 사용자에 대해 기능 플래그가 비활성화된 경우, 선택적 매개변수 없이 정보 수준에서 정보를 기록합니다(로그는 Kibana에서 접근할 수 있으나 필수 필드만 포함됨).

모범 사례

LLM 기능에 대한 로깅을 구현할 때 다음 사항을 고려하세요:

  • 디버깅을 위한 중요한 정보를 식별합니다.
  • 적절한 권한 없이 민감한 사용자 데이터를 로깅하지 않도록 개인정보 보호 요구 사항을 준수합니다.
  • conditional_info 헬퍼 메서드를 사용하여 expanded_ai_logging 기능 플래그를 존중합니다.
  • 문제 해결 및 분석을 위한 의미 있는 통찰력을 제공하도록 로그를 구조화합니다.

사용 예시

# 로깅을 처리하는 concern 포함
include Gitlab::Llm::Concerns::Logger

# 잠재적으로 민감한 정보 로깅
log_conditional_info(user, message:"사용자 프롬프트가 처리되었습니다", event_name: 'ai_event', ai_component: 'abstraction_layer', prompt: sanitized_prompt)

# 애플리케이션 오류 정보 로깅
log_error(user, message: "시스템 애플리케이션 오류", event_name: 'ai_event', ai_component: 'abstraction_layer', error_message: sanitized_error_message)

중요: 우리의 데이터 보존 정책을 숙지하고 사용자 입력 및 LLM 생성 출력을 로깅하고 있지 않은지 확인하십시오.

보안

인공지능(AI) 기능을 위한 보안 코딩 가이드라인을 참조하세요.