- 피처 플래그
- 새로운 AI 작업 구현
- 로컬에서 Self-managed AI 기능 테스트
- SaaS 전용 AI 기능 로컬에서 테스트
- AI 게이트웨이를 로컬에서 사용하여 AI 기능 테스트
- 실험적인 REST API
- 추상화 레이어
- 보안
AI 기능 기반의 타사 통합
피처 플래그
모든 AI 기능 작업에 다음 피처 플래그를 적용합니다:
- 모든 GitLab Duo 채팅 기능에 적용되는 일반 플래그 (
ai_duo_chat_switch
). 기본으로 활성화됩니다. - 다른 모든 AI 기능에 적용되는 일반 플래그 (
ai_global_switch
). 기본으로 활성화됩니다. - 해당 기능에 특화된 플래그. 특허 기능 이름과 달라야 합니다.
모든 피처 플래그 디렉터리 및 사용 방법은 피처 플래그 추적 Epic에서 확인하세요.
새로운 AI 작업 구현
새로운 AI 작업을 구현하려면 우선한 AI 제공업체에 연결하세요. 다음 중 하나를 사용하여 이 API에 연결할 수 있습니다:
- 실험적인 REST API.
- 추상화 레이어.
모든 AI 기능은 실험적입니다.
로컬에서 Self-managed AI 기능 테스트
AI Gateway 설정로 건너뜁니다
SaaS 전용 AI 기능 로컬에서 테스트
자동 설정
<test-group-name>
을 활성화하려는 그룹 이름으로 대체합니다. 그룹이 없는 경우 새 그룹을 생성합니다.
스크립트를 여러 번 다시 실행해야 할 수 있으며 에러 메시지와 그 문제를 해결하는 방법에 대한 문서 링크가 표시됩니다.
GITLAB_SIMULATE_SAAS=1 RAILS_ENV=development bundle exec rake 'gitlab:duo:setup[<test-group-name>]'
매뉴얼 방법
- 로컬 인스턴스에 EE 라이선스를 얻는 과정을 따랐는지 확인합니다.
- 라이선스가 적용되었는지 확인하려면 관리자 영역 > 구독으로 이동하고 구독 플랜을 확인합니다.
- 인스턴스에서 EE 기능 사용을 허용합니다.
- 관리자 영역 > 설정 > 일반 -> 계정 및 제한으로 이동합니다.
- 라이선스된 EE 기능 사용 허용을 활성화합니다.
- GDK를 사용하여 SaaS 시뮬레이션을 설정합니다.
- 테스트하려는 그룹이 Ultimate 라이선스를 갖도록 확인합니다.
- 관리자 영역 > 개요 > 그룹으로 이동합니다.
- 선택한 그룹을 편집합니다.
- 권한 및 그룹 기능으로 이동합니다.
- 계획 디렉터리에서 Ultimate를 선택합니다.
- 테스트하려는 기능에 대한 특정 피처 플래그를 활성화합니다.
- 그룹 AI Framework에 할당된 모든 피처 플래그를 활성화하려면 Rake 작업
rake gitlab:duo:enable_feature_flags
를 사용할 수 있습니다. - AI Gateway 설정
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 액세스 구성
Gitlab::CurrentSettings.update!(anthropic_api_key: <insert API key>)
임베딩 데이터베이스
임베딩은 VertexAI 텍스트 임베딩 API를 통해 생성됩니다.
GitLab 문서의 임베딩은 임베딩 크론 작업이 실행되는 평일 오전 05:00 UTC의 최신 변경사항을 기반으로 업데이트됩니다.
아래 섹션에서는 데이터베이스에 임베딩을 생성하거나 스펙에서 사용할 임베딩을 추출하는 방법에 대해 설명합니다.
설정
- GDK에서
pgvector
을 활성화합니다. -
GDK에서 임베딩 데이터베이스를 활성화합니다.
gdk config set gitlab.rails.databases.embedding.enabled true
-
gdk reconfigure
를 실행합니다. -
GDK의
gitlab
폴더에서 데이터베이스 마이그레이션을 실행하여 임베딩 데이터베이스를 만듭니다.RAILS_ENV=development bin/rails db:migrate
채우기
이 Rake 작업을 사용하여 GitLab 문서의 임베딩을 개발 데이터베이스에 시드하세요.
RAILS_ENV=development bundle exec rake gitlab:llm:embeddings:vertex:seed
이 Rake 작업은 GitLab 문서의 벡터화된 표현을 가진 임베딩 데이터베이스를 채웁니다. 해당 Rake 작업이 사용하는 파일은 과거에 GitLab 문서의 스냅샷이며 정기적으로 업데이트되지 않습니다. 결과적으로, 이 시드 작업이 낡은 GitLab 문서를 기반으로 임베딩을 생성한다는 점을 알고 계시면 도움이 됩니다. 약간 떨어진 문서 임베딩은 개발 환경에 충분하며, 이는 시드 작업의 사용 사례입니다.
임베딩과 관련된 테스트를 작성하거나 업데이트할 때 임베딩 픽스처 파일을 업데이트하고 싶을 수 있습니다.
RAILS_ENV=development bundle exec rake gitlab:llm:embeddings:vertex:extract_embeddings
스펙에서 임베딩 사용
seed
Rake 작업은 모든 GitLab 문서에 대한 임베딩을 개발 데이터베이스에 채웁니다. extract_embeddings
Rake 작업은 임베딩의 일부분으로 픽스처 파일을 채웁니다.
Rake 작업 자체에서 나열된 질문 세트는 픽스처 파일로 끌어들일 임베딩을 결정합니다. 예를 들어, “비밀번호를 재설정하는 방법” 중 하나의 질문입니다. extract_embeddings
작업은 이 질문에 대한 가장 관련성 높은 임베딩을 개발 데이터베이스(시드 작업 데이터)에서 끌어내어 그 임베딩을 ee/spec/fixtures/vertex_embeddings
에 저장합니다. 이 픽스처는 임베딩과 관련된 테스트에서 사용됩니다.
임베딩 스펙에서 사용해야 하는 질문을 변경하고 싶다면, extract_embeddings
Rake 작업을 업데이트하고 다시 실행하세요.
임베딩이 필요한 스펙에서는 RSpec :ai_embedding_fixtures
메타데이터를 사용하세요.
context 'GitLab 사용 방법에 대한 질문', :ai_embedding_fixtures do
# ...예시
end
로컬 개발 팁
- 사용자 인터페이스에서 응답이 너무 오래 걸릴 때는
gdk restart rails-background-jobs
를 실행하여 Sidekiq를 다시 시작해보세요. 작동하지 않으면gdk kill
을 실행한 다음gdk start
를 시도해보세요. - 다른 방법으로 Sidekiq을 우회하고 채팅 서비스를 동기적으로 실행할 수도 있습니다. 이는 GraphQL 오류를 Sidekiq 로그 대신 네트워크 검사 도구에서 사용할 수 있도록 하는 디버깅 오류에 도움이 될 수 있습니다. 임시로
Llm::CompletionWorker.perform_async
문을Llm::CompletionWorker.perform_inline
로 변경하세요.
GitLab Duo 채팅 작업
GitLab Duo 채팅을 사용하는 데 참고할 사항은 가이드라인을 확인하세요.
AI 게이트웨이를 로컬에서 사용하여 AI 기능 테스트
- GitLab 16.8에서 도입되었습니다.
SaaS 및 Self-managed GitLab 인스턴스와 호환되는 AI 기능을 개발하려면 해당 기능은 직접 3rd party 모델 제공업체에 요청하는 대신 AI Gateway에 요청해야 합니다.
설정
- CustomersDot 설정 (옵션, 채팅 기능에 필요하지 않음):
- CustomersDot 설치: 내부 비디오 튜토리얼
- GitLab 개발 키트 (GDK) 설정: 내부 비디오 튜토리얼
- 개발 키트를 별도의 GDK 인스턴스로 설치하세요.
-
gdk config set license.customer_portal_url 'http://localhost:5000'
실행하세요. - gdk.test 호스트 이름 설정하세요.
- 로컬 CustomersDot 인스턴스가 GitLab 애플리케이션을 사용하도록 지시하세요 (만약 CustomersDot을 설치했다면).
- GitLab Enterprise 라이선스를 활성화하세요
- Self Managed 인스턴스를 테스트하려면 활성 코드를 사용하여 Cloud Activation 단계를 따르세요.
- SaaS를 테스트하려면 라이선스 파일로 GitLab Enterprise 라이선스 활성화를 따르세요.
- 같은 터미널 세션에 환경 변수를 내보내도록 이 환경 변수들을 내보내세요(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:")
#### GraphQL로 설정 확인
1. [GraphQL explorer](../../api/graphql/index.md#interactive-graphql-explorer)를 방문하세요.
1. `aiAction` 뮤테이션을 실행합니다. 다음은 예시입니다:
```graphql
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
를 확인하여 오류 정보가 포함되어 있는지 확인하세요.
AI 게이트웨이 설정을 피하는 임시 해결 방법
LLMs에 직접 요청을 보내기 위해 다음을 수행해야 합니다:
-
피처 플래그를 비활성화합니다.
echo "Feature.disable(:gitlab_duo_chat_requests_to_ai_gateway)" | rails c
-
필요한 액세스 토큰을 설정합니다. 액세스 토큰을 받으려면:
실험적인 REST API
실험적인 REST API 엔드포인트를 사용하여 AI 기능을 빠르게 실험 및 프로토타입화할 수 있습니다.
엔드포인트는 다음과 같습니다:
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)
배포 환경에서는 실험적 엔드포인트를 GitLab 팀 구성원만 사용할 수 있습니다. 인증을 위해 GitLab API 토큰을 사용하세요.
추상화 레이어
GraphQL API
추상화 레이어를 사용하여 AI 제공업체 API에 연결하려면, aiAction
이라는 확장 가능한 GraphQL API를 사용하세요.
input
은 key
/value
쌍을 허용하며, key
는 수행해야 하는 액션입니다.
뮤테이션 요청당 AI 액션을 하나만 허용합니다.
뮤테이션의 예시:
mutation {
aiAction(input: {summarizeComments: {resourceId: "gid://gitlab/Issue/52"}}) {
clientMutationId
}
}
예를 들어, “코드 설명” 액션을 만들고 싶다고 가정해보겠습니다. 이를 위해 input
을 새로운 키 explainCode
로 확장합니다. 뮤테이션은 다음과 같습니다:
mutation {
aiAction(input: {explainCode: {resourceId: "gid://gitlab/MergeRequest/52", code: "foo() { console.log() }" }}) {
clientMutationId
}
}
그런 다음 GraphQL API는 Anthropic Client를 사용하여 응답을 보냅니다.
응답 수신 방법
AI 제공업체로의 API 요청은 백그라운드 작업으로 처리됩니다. 따라서 요청을 계속 유지하지 않으며 프론트엔드에서 요청을 구독한 응답과 일치시켜야 합니다.
userId
와 resourceId
만 사용하는 경우, 요청에 대한 올바른 응답을 결정하는 것은 문제를 일으킬 수 있습니다. 예를 들어, 두 개의 AI 기능이 동일한 userId
및 resourceId
를 사용하는 경우, 각 구독은 서로에게 응답을 수신합니다. 이 간섭을 방지하기 위해 clientSubscriptionId
를 도입했습니다.aiCompletionResponse
구독에 대한 응답을 일치시키려면, 뮤테이션에 clientSubscriptionId
를 제공할 수 있습니다.
-
clientSubscriptionId
는 기능 당 페이지 내에서 다른 AI 기능과 간섭하지 않도록 유니크해야 합니다.UUID
를 사용하는 것을 권장합니다. -
clientSubscriptionId
가aiAction
뮤테이션의 일부로 제공되는 경우에만aiCompletionResponse
를 브로드캐스트하는 데 사용됩니다. -
clientSubscriptionId
가 제공되지 않는 경우,userId
와resourceId
만이aiCompletionResponse
에 사용됩니다.
예시로, 댓글을 요약하는 뮤테이션에 randomId
를 제공합니다:
mutation {
aiAction(input: {summarizeComments: {resourceId: "gid://gitlab/Issue/52"}, clientSubscriptionId: "randomId"}) {
clientMutationId
}
}
그러면 컴포넌트에서 userId
, resourceId
, clientSubscriptionId
("randomId"
)를 사용하여 aiCompletionResponse
를 수신합니다:
subscription aiCompletionResponse($userId: UserID, $resourceId: AiModelID, $clientSubscriptionId: String) {
aiCompletionResponse(userId: $userId, resourceId: $resourceId, clientSubscriptionId: $clientSubscriptionId) {
content
errors
}
}
채팅을 위한 구독은 다르게 동작하는 점에 유의하세요.
동시에 많은 구독을 피하기 위해 뮤테이션을 보낸 후에만 skip()을 사용하여 구독해야 합니다.
현재 추상화 레이어 흐름
다음 그래프는 VertexAI를 예로 들었습니다. 다른 제공자를 사용할 수 있습니다.
## 새로운 동작 구현 방법
### 새로운 메소드 등록
`Llm::ExecuteMethodService`로 이동하여 새로운 서비스 클래스로 새 메소드를 추가합니다.
```ruby
class ExecuteMethodService < BaseService
METHODS = {
# ...
amazing_new_ai_feature: Llm::AmazingNewAiFeatureService
}.freeze
서비스 생성
-
ee/app/services/llm/
하위에 새로운 서비스를 생성하고BaseService
를 상속받습니다. -
resource
는 우리가 작업하려는 객체입니다.Ai::Model
concern을 포함하는 모든 객체가 될 수 있습니다. 예를 들어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
권한 부여
기능에 대한 권한을 처리하기 위해 정책(policies)을 사용하는 것을 권장합니다. 현재 우리는 다음을 확인해야 합니다.
- GitLab Duo Chat 기능의 경우
ai_duo_chat_switch
가 활성화되어 있어야 합니다. - 다른 일반 AI 기능의 경우
ai_global_switch
가 활성화되어 있어야 합니다. - 기능별 피처 플래그가 활성화되어 있어야 합니다.
- 네임스페이스에는 기능을 사용하기 위한 필수 라이선스가 있어야 합니다.
- 사용자가 그룹/프로젝트의 구성원이어야 합니다.
-
experiment_features_enabled
설정이네임스페이스(Namespace)
에 설정되어 있어야 합니다.
우리의 예에서는 allowed?(:amazing_new_ai_feature)
호출을 구현해야 합니다. 예를 들어, summarize comments feature의 이슈 정책을 살펴볼 수 있습니다.
응답과 요청 매핑
여러 사용자의 요청이 병렬로 처리될 수 있기 때문에 응답을 받을 때 요청을 해당 원래 요청과 매핑하는 것이 어려울 수 있습니다. requestId
필드는 요청과 응답이 동일한 requestId
UUID를 가지고 있기 때문에 이러한 목적으로 사용할 수 있습니다.
캐싱
AI 요청과 응답은 캐시될 수 있습니다. 현재 구현에서 이 캐시는 사용자가 요청을 반복할 때 AI 서비스에 연이어 호출을 건너뛰기 위해 사용자 상호작용을 표시하는 데 사용됩니다.
query {
aiMessages {
nodes {
id
requestId
content
role
errors
timestamp
}
}
}
이 캐시는 특히 채팅 기능에 유용합니다. 다른 서비스의 경우 캐싱이 비활성화됩니다. (서비스에 대한 cache_response: true
옵션을 사용하여 서비스에 대해 활성화시킬 수 있음.)
캐싱에는 다음과 같은 제한이 있습니다.
- 메시지는 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를 사용하여 두 개의 새 클래스를 구현할 것입니다.
# /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
# /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)
AI 작업 모니터링
- 각 AI 작업의 오류 비율 및 응답 대기 시간 apdex는 Sidekiq Service 대시 보드의 SLI Detail:
llm_completion
에서 확인할 수 있습니다. - 사용된 토큰, 각 AI 기능의 사용량 및 기타 통계는 periscope 대시 보드에서 찾을 수 있습니다.
GraphQL에 AI 작업 추가
TODO
보안
인공 지능 (AI) 기능에 대한 보안 코딩 가이드라인을 참조하십시오.