3rd-party 통합 기반 AI 기능
GitLab 15.11에 도입됨
시작하기
접근
GCP Vertex
로컬 개발을 위한 GCP 서비스 키를 얻으려면 다음 단계를 따르세요:
- 이 페이지를 방문하여 지시 사항을 따르거나 이 템플릿을 사용하여 기존 그룹 GCP 프로젝트에 대한 액세스를 요청하여 샌드박스 GCP 프로젝트를 만듭니다.
- 개별 GCP 프로젝트를 사용하는 경우 Vertex AI API를 활성화해야 할 수 있습니다:
- 환영 페이지를 방문하여 프로젝트를 선택합니다(예: jdoe-5d23dpe).
- API 및 서비스 > 활성화된 API 및 서비스로 이동합니다.
- + API 및 서비스 활성화를 선택합니다.
-
Vertex AI API
를 검색합니다. - Vertex AI API를 선택한 다음 활성화를 선택합니다.
-
gcloud
CLI를 설치합니다. -
gcloud auth application-default login
명령을 사용하여 로컬로 GCP에 인증합니다. - Rails 콘솔을 열고 설정을 업데이트합니다:
# PROJECT_ID = "your-gcp-project-name"
Gitlab::CurrentSettings.update(vertex_ai_project: PROJECT_ID)
Anthropic
액세스 요청을 작성한 후, Anthropic 계정을 등록하고 API 키를 생성할 수 있습니다. 그런 다음 다음과 같이 구성하세요:
Gitlab::CurrentSettings.update!(anthropic_api_key: <insert API key>)
로컬 설정
- GitLab 16.8에 도입됨
SaaS 및 Self-Managed GitLab 인스턴스와 호환되는 AI 기능을 개발하려면, 해당 기능이 3rd party 모델 제공업체에 직접 요청하는 대신 AI Gateway에 요청해야 합니다.
- GitLab 개발 키트 (GDK) 설정: 내부 비디오 튜토리얼
- 별도의 GDK 인스턴스로 설치합니다.
-
gdk config set license.customer_portal_url 'http://localhost:5000'
명령을 실행합니다. -
여기의
gdk.test
호스트명으로 이동합니다. - CustomersDot을 설치한 경우 로컬 CustomersDot 인스턴스가 GitLab 애플리케이션을 사용하도록 지침을 따릅니다.
- GitLab 엔터프라이즈 라이선스를 활성화합니다
- Self Managed 인스턴스를 테스트하려면 앞서 받은 클라우드 활성화 코드를 사용해서 클라우드 활성화 단계를 따릅니다.
- SaaS를 테스트하려면 라이선스 파일로 GitLab 엔터프라이즈 라이선스를 활성화합니다.
-
gdk start
명령으로 동일한 터미널 세션에서 이러한 환경 변수를 내보냅니다:- 환경 변수를 항상 내보내도록 터미널을 구성할 수도 있습니다(예: 환경 변수를
~/.bash_profile
또는~/.zshrc
에 추가).
export AI_GATEWAY_URL=http://0.0.0.0:5052 # 로컬 AI Gateway 인스턴스의 URL export LLM_DEBUG=1 # 디버그 로깅 활성화
또는 위의 스니펫과 동일한 내용의
env.runit
파일을 GDK의 루트에 만들 수 있습니다. - 환경 변수를 항상 내보내도록 터미널을 구성할 수도 있습니다(예: 환경 변수를
- 모든 AI 피처 플래그를 활성화합니다:
rake gitlab:duo:enable_feature_flags
- AI Gateway 설정: 내부 비디오 튜토리얼
- 설치합니다.
- 다음을 Rails 콘솔에서 호출하여 AI 기능을 확인합니다:
Gitlab::Llm::AiGateway::Client.new(User.first).stream(prompt: "\n\nHuman: Hi, how are you?\n\nAssistant:")
구독 테스트를 위한 추가 설정 (DuoChat 설정에 필수가 아님)
- CustomersDot 설정:
- 설치에 대한 내부 비디오 튜토리얼을 참조합니다(비디오 캡션에 포함된 비활성 구독 플랜 ID URL을 아래에서 제공하는 계획 ID가 포함된 링크의 활성 구독 플랜 ID로 교체합니다).
GraphQL로 설정 확인
- GraphQL 탐색기를 방문합니다.
-
aiAction
뮤테이션을 실행합니다. 다음은 예시입니다:mutation { aiAction( input: { chat: { resourceId: "gid://gitlab/User/1", content: "Hello" } } ){ requestId errors } }
-
(GitLab Duo Chat 전용) 다음 쿼리를 실행하여 응답을 가져옵니다:
query { aiMessages { nodes { requestId content role timestamp chunkId errors } } }
응답을 가져올 수 없는 경우
graphql_json.log
,sidekiq_json.log
,llm.log
또는modelgateway_debug.log
에 오류 정보가 있는지 확인하세요.
SaaS 전용 기능
이러한 기능은 아키텍처 청사진을 아직 따르지 않기 때문에 AI Gateway를 사용하지 않고 LLM 공급자에 직접 연결합니다. 이러한 설정에서 개발된 기능은 시간이 지남에 따라 Self Managed 제공으로 이동될 예정입니다.
자동화된 설정
<test-group-name>
을 사용할 그룹 이름으로 대체합니다. 그룹이 없는 경우 새 그룹을 만듭니다. 스크립트를 여러 번 다시 실행해야 할 수 있으며, 오류 메시지와 그것을 해결하는 방법에 대한 문서 링크가 표시됩니다.
GITLAB_SIMULATE_SAAS=1 RAILS_ENV=development bundle exec rake 'gitlab:duo:setup[<test-group-name>]'
AI Gateway는 자동화된 설정 사용 시에도 설정해야 합니다.
매뉴얼 방식
- 로컬 인스턴스에 EE 라이선스를 얻는 절차를 따랐는지 확인하고 Ultimate 라이선스를 적용했는지 확인합니다.
- 라이선스가 적용된 것을 확인하려면 Admin Area > Subscription으로 이동하고 구독 플랜을 확인합니다.
- 인스턴스에서 EE 기능을 사용할 수 있도록 허용합니다.
- Admin Area > Settings > General로 이동합니다.
- Account and limit 섹션을 확장합니다.
- Licensed EE features 사용 허용을 활성화합니다.
- SaaS를 시뮬레이션하기 위해 GDK를 시뮬레이션합니다.
- 테스트하려는 그룹이 권한을 갖는 Ultimate 라이선스를 가지고 있는지 확인합니다.
- Admin Area > Overview > Groups로 이동합니다.
- 원하는 그룹을 선택한 다음 편집을 선택합니다.
- 권한 및 그룹 피처로 이동합니다.
- 플랜 디렉터리에서 Ultimate를 선택합니다.
- 그룹 AI Framework에 할당된 모든 피처 플래그를 활성화합니다.
- 원하는 기능에 대한 특정 피처 플래그를 활성화합니다.
- 특정 피처 플래그를 모두 활성화하려면 Rake 작업
rake gitlab:duo:enable_feature_flags
를 사용합니다. - AI Gateway를 설정합니다.
도움말
로컬 개발 팁
- 사용자 인터페이스에서 응답이 너무 오래 걸릴 때에는
gdk restart rails-background-jobs
를 실행하여 Sidekiq를 재시작하는 것을 고려해보세요. 이것이 도움이 되지 않는다면,gdk kill
을 시도한 후gdk start
를 해보세요. - 또는, Sidekiq를 완전히 우회하고 서비스를 동기적으로 실행할 수 있습니다. GraphQL 오류가 Sidekiq 로그가 아닌 네트워크 검사기에서 사용 가능해지므로 이것은 디버깅 오류에 도움이 될 수 있습니다. 이를 위해서는
Llm::CompletionWorker
클래스의perform_for
메서드를 일시적으로 수정하여perform_async
를perform_inline
로 변경하면 됩니다.
기능 개발 (추상화 레이어)
피처 플래그
모든 AI 기능 작업에 다음 피처 플래그를 적용하세요:
- 모든 GitLab Duo Chat 기능에 적용되는 일반 플래그(
ai_duo_chat_switch
). 기본적으로 활성화됩니다. - 다른 모든 AI 기능에 적용되는 일반 플래그(
ai_global_switch
). 기본적으로 활성화됩니다. - 해당 기능에 특화된 플래그. 피처 플래그 이름은 라이선스가 있는 기능 이름과 다른 이름이어야 합니다.
모든 피처 플래그 디렉터리 및 사용 방법은 피처 플래그 추적 Epic을 참조하세요.
실험적 REST API
빠르게 실험하고 AI 기능을 프로토타입화하기 위해 실험적 REST API 엔드포인트를 사용하세요.
엔드포인트는 다음과 같습니다:
https://gitlab.example.com/api/v4/ai/experimentation/anthropic/complete
https://gitlab.example.com/api/v4/ai/experimentation/vertex/chat
이러한 엔드포인트는 고객에게 기능을 롤아웃하는 것이 아니라 프로토타입화에만 사용됩니다.
로컬 개발 환경에서 이러한 엔드포인트를 피처 플래그를 활성화한 상태로 실험할 수 있습니다:
Feature.enable(:ai_experimentation_api)
Production에서 실험적 엔드포인트는 GitLab 팀 멤버에게만 제공됩니다. 인증을 위해 GitLab API 토큰을 사용하세요.
GraphQL API
추상화 레이어를 사용하여 AI 제공 업체 API에 연결하려면, aiAction
이라는 확장 가능한 GraphQL API를 사용하세요(https://gitlab.com/gitlab-org/gitlab/blob/master/ee/app/graphql/mutations/ai/action.rb).
input
은 키/값 쌍을 허용하는데, 여기서 키
는 수행해야 하는 동작입니다. 하나의 GraphQL 요청당 하나의 AI 동작만 허용됩니다.
변이 예시:
mutation {
aiAction(input: {summarizeComments: {resourceId: "gid://gitlab/Issue/52"}}) {
clientMutationId
}
}
예를 들어, “코드 설명” 동작을 구현하려면, 새로운 키 explainCode
로 input
을 확장합니다.
mutation {
aiAction(input: {explainCode: {resourceId: "gid://gitlab/MergeRequest/52", code: "foo() { console.log() }" }}) {
clientMutationId
}
}
GraphQL API는 그런 다음 Anthropic Client를 사용하여 응답을 보냅니다.
응답 수신 방법
AI 제공자에 대한 API 요청은 백그라운드 작업으로 처리됩니다. 따라서 요청을 유지하지 않고 Frontend에서 구독에 대한 응답을 매치시키어야 합니다.
userId
및 resourceId
만 사용할 때, 요청에 대한 올바른 응답을 결정하는 것은 문제를 일으킬 수 있습니다. 예를 들어, 두 AI 기능이 동일한 userId
및 resourceId
를 사용하는 경우, 두 구독은 서로의 응답을 받을 것입니다. 이러한 간섭을 방지하기 위해 clientSubscriptionId
를 도입했습니다.“댓글 요약”에 대한 예시 변이에서 mutation
에 clientSubscriptionId
를 제공합니다:
mutation {
aiAction(input: {summarizeComments: {resourceId: "gid://gitlab/Issue/52"}, clientSubscriptionId: "randomId"}) {
clientMutationId
}
}
그런 다음 컴포넌트에서 aiCompletionResponse
를 청취하여 userId
, resourceId
, 그리고 clientSubscriptionId
("randomId"
)를 사용합니다.
채팅에 대한 구독
과 다르게 동작합니다.
많은 동시 구독을 하지 않기 위해, skip()
을 사용하여 변수를 설정하기 전에 한 번만 구독해야 합니다.
현재 추상화 레이어 흐름
다음 차트는 예시로 VertexAI를 사용합니다. 여러분은 다른 제공 업체를 사용할 수 있습니다.
새로운 작업 구현 방법
새로운 방법 등록
Llm::ExecuteMethodService
로 이동하고 새로운 서비스 클래스를 추가하여 새로운 방법을 추가하세요.
class ExecuteMethodService < BaseService
METHODS = {
# ...
amazing_new_ai_feature: Llm::AmazingNewAiFeatureService
}.freeze
서비스 생성
-
ee/app/services/llm/
하위에 새로운 서비스를 작성하고BaseService
에서 상속받으세요. -
resource
는 동작하려는 객체입니다.Ai::Model
관심사를 포함하는 모든 객체가 될 수 있습니다. 예를 들어,Project
,MergeRequest
, 또는Issue
가 될 수 있습니다.
# ee/app/services/llm/amazing_new_ai_feature_service.rb
module Llm
class AmazingNewAiFeatureService < BaseService
private
def perform
::Llm::CompletionWorker.perform_async(user.id, resource.id, resource.class.name, :amazing_new_ai_feature)
success
end
def valid?
super && Ability.allowed?(user, :amazing_new_ai_feature, resource)
end
end
end
권한 부여
기능에 대한 권한을 처리하기 위해 정책을 사용하는 것을 권장합니다. 현재 다음 확인 사항을 확인해야 합니다.
- GitLab Duo Chat 기능의 경우
ai_duo_chat_switch
가 활성화되어 있는지 확인해야 합니다. - 다른 일반적인 AI 기능의 경우
ai_global_switch
가 활성화되어 있는지 확인해야 합니다. - 특정 기능의 feature flag가 활성화되어 있는지 확인해야 합니다.
- 네임스페이스에는 해당 기능에 필요한 라이선스가 있는지 확인해야 합니다.
- 사용자가 그룹/프로젝트의 구성원인지 확인해야 합니다.
-
네임스페이스
의experiment_features_enabled
설정이 설정되어 있는지 확인해야 합니다.
예를 들어, 우리의 예제에서는 allowed?(:amazing_new_ai_feature)
호출을 구현해야 합니다. 예를 들어, Summarize Comments 기능의 이슈 정책을 확인할 수 있습니다. 우리의 예제 경우, 이슈에 대한 기능을 구현하려고 합니다:
:::ruby # ee/app/policies/ee/issue_policy.rb
module EE module IssuePolicy extend ActiveSupport::Concern prepended do with_scope :global condition(:ai_available) do ::Feature.enabled?(:ai_global_switch, type: :ops) end
with_scope :subject
condition(:amazing_new_ai_feature_enabled) do
::Feature.enabled?(:amazing_new_ai_feature, subject_container) &&
subject_container.licensed_feature_available?(:amazing_new_ai_feature)
end
rule do
ai_available & amazing_new_ai_feature_enabled & is_project_member
end.enable :amazing_new_ai_feature
end end end
응답과 요청을 짝지어서 보관
여러 사용자의 요청이 병렬로 처리될 수 있기 때문에, 응답을 받을 때 응답을 원래의 요청과 짝지어 보관하기가 어려울 수 있습니다. 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
는 Completions::Factory
를 호출하며, 이를 통해 서비스를 초기화하고 API에 대한 실제 호출을 실행합니다.
우리의 예에서는 VertexAI를 사용하고 두 개의 새로운 클래스를 구현할 것입니다:
:::ruby # /ee/lib/gitlab/llm/vertex_ai/completions/amazing_new_ai_feature.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).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
:::ruby # /ee/lib/gitlab/llm/vertex_ai/templates/amazing_new_ai_feature.rb
module Gitlab module Llm module VertexAi module Templates class AmazingNewAiFeature def initialize(user_input) @user_input = user_input end
def to_prompt
<<~PROMPT
You are an assistant that writes code for the following context:
context: #{user_input}
PROMPT
end
end
end
end end end
이 예제의 경우 다른 AI 제공업체도 지원하므로, 이러한 제공업체를 위해 비슷한 방법으로 사용할 수 있습니다:
Gitlab::Llm::VertexAi::Client.new(user)
Gitlab::Llm::Anthropic::Client.new(user)
GraphQL에 AI 작업 추가
TODO
임베딩 데이터베이스
임베딩은 채팅 문서 도구에서 작동하려면 생성되어야 합니다. 현재 시점에서 문서 도구는 Saas에서만 작동합니다.
GitLab 문서의 임베딩은 최신 변경 사항을 기반으로 업데이트됩니다. UTC 시간 05:00에 매주 월요일부터 일요일까지 가장 최근의 변경 사항을 반영하기 위해서임베딩 레일스의 잡 크론 잡이 실행됩니다.
아래 섹션에서는 DB에 임베딩을 채우거나 명세서에서 사용할 임베딩을 추출하는 방법에 대해 설명합니다.
설정
- GDK에서
pgvector
를 활성화합니다. -
GDK에서 임베딩 데이터베이스를 활성화합니다.
gdk config set gitlab.rails.databases.embedding.enabled true
-
gdk reconfigure
를 실행합니다. -
GDK의
gitlab
폴더에서 데이터베이스 마이그레이션을 실행하여 임베딩 데이터베이스를 만듭니다.RAILS_ENV=development bin/rails db:migrate
채우기
GitLab 문서의 임베딩을 개발용 데이터베이스에 이 Rake 작업을 사용하여 씨드합니다.
RAILS_ENV=development bundle exec rake gitlab:llm:embeddings:vertex:seed
이 Rake 작업은 GitLab 문서의 모든 vectorized 표현을 데이터베이스 내 개발용 씨드를 생성합니다. Rake 작업이 사용하는 파일은 지난 시점의 GitLab 문서 스냅샷이며 정기적으로 업데이트되지 않습니다. 따라서 이 씨드 작업은 구식 문서에 기반한 임베딩을 생성합니다. 약간 구식화된 문서 임베딩은 개발 환경에 충분하며, 이는 씨드 작업의 사용 목적입니다.
임베딩과 관련된 테스트를 작성하거나 업데이트할 때, 임베딩 픽스처 파일을 업데이트하는 것이 좋을 수 있습니다.
RAILS_ENV=development bundle exec rake gitlab:llm:embeddings:vertex:extract_embeddings
사양에서 사용하기
seed
Rake 작업은 GitLab 문서의 모든 포함 항목을 개발용 데이터베이스에 채웁니다. extract_embeddings
Rake 작업은 포함 항목의 일부를 담은 fixture 파일을 작성합니다.
Rake 작업에 나열된 질문 세트 자체가 fixture 파일로 가져오는 포함 항목을 결정합니다. 예를 들어, 하나의 질문은 “비밀번호를 재설정하는 방법”입니다. extract_embeddings
작업은 이 질문에 대한 가장 관련성 있는 포함 항목을 개발용 데이터베이스(여기에는 seed
Rake 작업의 데이터가 포함됨)에서 추출하여 이러한 포함 항목을 ee/spec/fixtures/vertex_embeddings
에 저장합니다. 이 fixture는 포함 항목과 관련된 테스트에 사용됩니다.
포함 항목에서 포함 항목을 사용해야 하는 경우, RSpec :ai_embedding_fixtures
메타데이터를 사용하세요.
context 'GitLab 사용 방법에 대해 질문할 때', :ai_embedding_fixtures do
# ...예시
end
모니터링
- 각 AI 액션의 오류 비율 및 응답 대기 시간 apdex는 Sidekiq Service 대시보드의 SLI Detail:
llm_completion
에서 찾을 수 있습니다. - 사용된 토큰, 각 AI 기능의 사용 및 기타 통계는 periscope 대시보드에서 찾을 수 있습니다.
보안
인공 지능 (AI) 기능을 위한 안전한 코딩 지침을 참조하세요.