Status | Authors | Coach | DRIs | Owning Stage | Created |
---|---|---|---|---|---|
ongoing |
@reprazent
|
@andrewn
@stanhu
|
@m_gill
@mksionek
@marin
| devops modelops | 2023-07-14 |
AI-gateway
요약
AI-gateway는 GitLab의 모든 사용자에게 AI 기능에 액세스 할 수있는 standalone-service입니다. 사용 중인 인스턴스가 무엇이든 Self-managed, 전용 또는 GitLab.com을 사용하는 경우입니다.
초반에는 모든 AI-gateway 배포가 GitLab(조직)에의해 관리되며, GitLab.com 및 모든 GitLab Self-managed 인스턴스가 동일한 게이트웨이를 사용합니다. 그러나 필요에 따라 미래에는 지역별 게이트웨이 또는 심지어 고객별 게이트웨이도 배포 할 수 있습니다.
AI-Gateway는 클라이언트 (이 경우 GitLab 설치)에서 트래픽을 수신하고 여기서 AI-제공 업체 및 모델로 리다이렉트하는 API-Gateway입니다. 이러한 North/South 트래픽 패턴을 통해 우리는 필요에 따라 요청을 어디로 보낼지 제어하고 리다이렉트 된 요청의 콘텐츠를 필요한 곳으로 변환할 수 있습니다.
현재, 멀티 리전 배포는 지원되지 않으며 고려중인 기능입니다. 기존 다이어그램은 여러 지역에 걸쳐 배포하는 가능성 있는 아키텍처를 보여줍니다.
GitLab의 제어 하에 호스팅 된 서비스를 사용함으로써, 우리는 모든 GitLab 인스턴스에 확장 가능한 방식으로 AI 기능을 제공할 수 있습니다. 이 작은 상태를 유지해야하는 서비스를 확장하는 것이 GitLab-rails 및 해당 의존성 (데이터베이스, Redis)을 확장하는 것보다 쉽습니다.
Self-managed 설치 사용자가 자신의 모델을 호스팅하거나 타사 제공업체에 연결할 필요없이 AI를 사용할 수 있도록합니다.
언어: Python
AI-Gateway는 원래 IDE에서 Code Suggestions을 제공하기위해 시작된 “model-gateway”로, Python으로 작성되었습니다.
Python은 루비 개발자에게 익숙한 객체 지향 언어로, 젊은 코드베이스를 통해 루비 개발자들이 습득하는 데 충분히 익숙한 언어입니다. 또한 이미 Python 경험이있는 데이터 및 ML 엔지니어들이 기여하기 쉬워집니다.
API
AI-gateway를위한 기본 안정적인 API
AI-gateway의 API가 다양한 GitLab 인스턴스에서 사용되므로 안정적이면서도 유연한 API를 설계하는 것이 중요합니다.
이를 위해 우리는 빌드 한 경우마다 API 엔드 포인트를 구현할 수 있습니다. 이는 GitLab과 AI-gateway 간의 인터페이스가 우리가 구축하고 소유하기 때문입니다. 이를 통해 미래의 확장성, 구성 가능성 및 보안을 보장합니다.
API에는 버전이 없지만 역 호환성이 있습니다. 크로스 버전 호환성을 참조하십시오. AI-gateway는 최근 2가지 주요 버전을 지원합니다. 예를 들어, GitLab 17.2를 사용할 때, GitLab 17 및 GitLab 16을 모두 지원합니다.
또한 GitLab-rails에서와 마찬가지로 이 스택 수준에서도 rate-limiting, circuit-breakers 및 secret redaction과 같은 공통 기능을 추가 할 수 있습니다.
프로토콜
AI-Gateway 서비스와 클라이언트 (GitLab Rails 응용 프로그램 포함)간의 통신은 JSON 기반 API를 사용해야합니다.
AI-Gateway API는 서로 다른 AI 기능에 액세스를 제공하는 단일 목적 엔드 포인트를 노출해야합니다. 이 문서의 나중 섹션은 특정 엔드 포인트를 구축하기 위한 자세한 지침을 제공합니다.
AI Gateway 통신 프로토콜은 기능별 동적 정보를 래핑하는 기본적인 봉투만 예상해야합니다. 제안된 프로토콜 아키텍처는 API 엔드 포인트가 버전에 상관없이 지원되도록하며, AI-Gateway API를 GitLab (또는 GitLab을 통해 게이트웨이 사용하는 기타 클라이언트)의 여러 버전과 호환되도록합니다.
즉, 모든 클라이언트는 버전과 관계없이 동일한 AI-Gateway API 기능 엔드 포인트 집합을 사용합니다. AI-gateway 기능 엔드 포인트는 다른 클라이언트 버전을 지원해야하며, 지원되는 클라이언트 버전 당 여러 기능 엔드 포인트를 생성하지 않습니다.
그러나 특정 엔드 포인트를 발전시키려는 경우에는 경로에 버전을 추가 할 수 있습니다. 이렇게 자주하지 않을 것으로 예상하지만 경로에 버전을 유지하는 것은 옵션을 열어 두는 데 도움이 됩니다. 이점은 개별 GitLab 마일스톤 릴리스가 엔드 포인트 버전을 유지되었다가 손쉽게 새로운 엔드 포인트 버전을 소개할 수 있도록유지하면서 빠르게 반복 할 수 있습니다.
또한, vscode에 대한 새로운 Ruby-gRPC 서버가있는 빠른 속도가되기 때문에 의존성을 제한할 수 있어도 가능성이 높은 gRPC와 JSON API는 이러한 항목에서 차이가 있습니다.
gRPC | REST + JSON |
---|---|
+ 더 쉽게 진화시킬 수있는 엄격한 프로토콜 정의로 버전 정보 X | - 엄격한 스키마가 없으므로 구현은 지원되는 다양한 버전을 지원하려면 적절한 조치를 취해야합니다 |
+ vscode에 대한 새로운 Ruby-gRPC 서버: 확장성이 좋을 확률이 높습니다 (모듈화된 단일 모놀리) | - vscode에 대한 기존 그레이프 API: 느린 부팅 시간 및 불필요한 리소스로 인한 의미없는 리소스 로딩 |
+ 양방향 스트리밍 | - 요청 및 응답을 스트리밍하는 간단한 방법 (아직 추가 될 수 있음) |
- 새로운 Python-gRPC 서버: 우리는 gRPC-Python 서버를 실행하는 경험이 없습니다 | + 이미 구현 된 Python fastapi 서버가 있으며 이미 확장된 Code Suggestions를 위해 사용 중 |
- vscode를 통해 GitLab-Rails를 통해 ai-gateway로 알 수없는 메시지를 전달하는 것은 어렵습니다 | + 더 최신의 VS Code + 최신 AI-gateway를 지원하기위한 이전 GitLab 인스턴스를 통한 더 쉬운 지원 |
- 다른 클라이언트에서 gRPC에 대한 알려진 지원 | + 모든 외부 클라이언트에서 지원 |
- 가능한 프로토콜 불일치 (VSCode –REST–> Rails –gRPC–> AI 게이트웨이) | + 스택 전체에서 동일한 프로토콜 |
토론: 이미 부분적으로 존재하는 기능을 포팅하기위해 현재 REST+JSON을 선택했기 때문에 gRPC 또는 웹소켓을 사용하여 새로운 기능을 제외 할 필요는 없습니다. 예를 들어: 채팅 기능은 요청과 응답을 스트리밍하는 것이 더 나을 수 있습니다. 우리는 사용 사례 당 엔드 포인트를 제안하고 있기 때문에 다른 프로토콜을 사용할 수도 있습니다. 단, 신중하게 버전 호환성을 유지해야합니다.
단일 목적 엔드 포인트
AI를 사용하는 기능의 경우, AI 제공 업체 API를 직접 프록시로 노출하는 대신 안정적인 API로 단일 목적 엔드 포인트를 구축하는 것을 선호합니다.
일부 기능에는 특정 엔드 포인트가 있고, 다른 기능은 엔드 포인트를 공유할 수 있습니다. 예를 들어 Code Suggestions 나 채팅은 자체 엔드 포인트를 가질 수 있으며, 문제 또는 Merge Request을 요약하는 여러 기능은 동일한 엔드 포인트를 사용할 수 있지만 페이로드에서 제공되는 정보에 대한 구분을 지을 수 있습니다.
우리의 목표는 GitLab 모놀리식 코드베이스에 AI와 관련된 로직을 고정하는 것을 피함으로써 고객을 대신하는 코드를 최소화하는 것입니다.
- 고객이 최신 기능을 도입하는 데 소요되는 시간을 최소화하고
- 우리의 제품에 대한 변경을 쉽게 하면서 오래된 인스턴스의 지원을 중단하지 않는 유연성을 유지하려합니다.
- 최소한의 복잡성으로 모든 GitLab 배포(.com SaaS, Self-managed 및 전용)를 제공 할 수있도록합니다.
- 통제 평면을 통해 AI 기능을 격리하여 리스크를 줄이고
- 최고의 다중 모델 앙상블 접근 방식을 지원하도록 통일 된 구현을 제공하여 여러 AI 모델 및 AI 제품 공급업체를 쉽게 지원할 수 있도록합니다.
- 비용을 통제하고 메트릭하는 단일 지점이 필요합니다.
- 가능한 경우, 게이트웨이에서 여러 포인트에 분산 된 대신(사용 통계, 응답 실패, 사용 패턴, 질문 범주 등) 일부 메트릭을 기록 할 수 있어야합니다.
GitLab-Rails에서 비즈니스 로직을 보유하게되면 고객은 16.6에서 버그가 있고 16.5를 사용하고 다음 업그레이드가 3 개월 후에 예정되면 3 개월 동안 버그가있는 기능을 사용해야합니다.
이것은 AI-gateway 내에 prompts를 구축해야한다는 의미가 아닙니다. 그러나 prompts가 단일 목적 엔드 포인트의 페이로드의 일부인 경우, 페이로드에 prompts에 대한 기타 메타 데이터와 함께 어떤 모델을 위해 구축되었는지를 지정해야합니다. 이렇게하면 AI 게이트웨이에서 더 이상 지원되지 않을 수도 있는 prompt 페이로드 중 하나가 포함되는 경우 우아하게 업그레이드 할 수 있습니다. 이는 AI의 변화에 따라 오랜 기간 존재하는 GitLab 설치에서 기능을 중단하지 않도록하는 가능성이 있습니다.
AI-Gateway API 프로토콜
각 단일 목적의 엔드포인트를 버전에 무관하게 구축하는 것이 중요합니다. 그렇게 함으로써 다른 GitLab 인스턴스(및 간접적으로 외부 클라이언트)에서 사용할 수 있습니다. 이러한 목표를 달성하기 위해:
AI-Gateway 프로토콜은 모든 기능별 정보를 감싸는 간단한 JSON 래퍼에 의존해야 합니다. AI-Gateway 프로토콜은 OSI 모델(예: TCP, UDP)의 전송 계층 프로토콜로 볼 수 있으며, 정보가 무엇인지에 대해 인식하지 않고 노드 간에 정보를 전송하는 방법을 정의합니다.
AI-Gateway 프로토콜은 단일 목적의 엔드포인트가 수신한 정보를 어떻게 처리해야 하는지 또한 어떤 방식으로 처리해야 하는지를 명시하지 않습니다. 엔드포인트에게 프로토콜 래퍼에서 오는 데이터를 사용할지 또는 무시할지를 자유롭게 결정할 수 있도록 합니다.
AI-Gateway 프로토콜은 다음과 같은 방식으로 각 요청을 정의합니다:
- 각 단일 목적의 엔드포인트는 단일 키
prompt_components
를 포함하는 JSON 객체를 포함하는 요청을 수락해야 합니다. -
prompt_components
키는 다음 규칙에 따라 작성된 JSON 래퍼의 배열을 포함해야 합니다.
각 JSON 래퍼는 3가지 요소를 포함합니다:
-
type
: 래퍼에 표시되는 정보 유형을 지정하는 문자열 식별자로, AI-Gateway 단일 목적의 엔드포인트는 알지 못하는 유형은 무시할 수 있습니다. -
payload
: AI-Gateway 단일 목적의 엔드포인트가 3rd party AI 서비스 제공업체에 요청을 보내기 위해 사용할 수 있는 실제 정보입니다.payload
요소 내의 데이터는type
및 제공하는payload
의 버전에 따라 달라질 수 있으므로 AI-Gateway 단일 목적의 엔드포인트는payload
내에 존재하는 데이터의 구조와 유형을 고려해야 하며, 누락된 정보 또는 비정형 정보를 우아하게 처리해야 합니다. -
metadata
: 이 필드에는prompt_components
래퍼를 빌드한 클라이언트에 관한 정보가 포함되어 있습니다.metadata
필드의 정보는 GitLab이 트래픽 데이터 수집(Telemetry)에 사용할 수도 있고 사용하지 않을 수도 있습니다.payload
와 마찬가지로metadata
내의 모든 필드는 선택 사항으로 간주되어야 합니다.
가장 자주 변경될 것으로 예상되는 래퍼 필드는 payload
입니다. 여기서 모든 필드가 선택 사항이며 필드의 이름을 변경하거나 삭제하거나 다른 목적으로 사용하지 않도록 해야 합니다.
payload
의 내용을 문서화하고 유효성을 검사하기 위해 JSON-schema를 사용하여 그들의 형식을 지정할 수 있습니다.
AI-Gateway 컴포넌트에 따른 예시 요청은 다음과 같습니다:
{
"prompt_components": [
{
"type": "prompt",
"metadata": {
"source": "GitLab EE",
"version": "16.7.0-pre",
},
"payload": {
"content": "...",
"params": {
"temperature": 0.2,
"maxOutputTokens": 1024
},
"model": "code-gecko",
"provider": "vertex-ai"
}
},
{
"type": "editor_content",
"metadata": {
"source": "vscode",
"version": "1.1.1"
},
"payload": {
"filename": "application.rb",
"before_cursor": "require 'active_record/railtie'",
"after_cursor": "\nrequire 'action_controller/railtie'",
"open_files": [
{
"filename": "app/controllers/application_controller.rb",
"content": "class ApplicationController < ActionController::Base..."
}
]
}
}
]
}
다른 예시 사용 사례로, prompt_components
페이로드에 전달되는 두 가지 버전의 프롬프트가 포함될 수 있습니다. 각 버전은 다른 3rd party AI 모델 제공업체를 위해 맞춤 설정되어 있습니다:
{
"prompt_components": [
{
"type": "prompt",
"metadata": {
"source": "GitLab EE",
"version": "16.7.0-pre",
},
"payload": {
"content": "You can fetch information about a resource called an issue...",
"params": {
"temperature": 0.2,
"maxOutputTokens": 1024
},
"model": "text-bison",
"provider": "vertex-ai"
}
},
{
"type": "prompt",
"metadata": {
"source": "GitLab EE",
"version": "16.7.0-pre",
},
"payload": {
"content": "System: You can fetch information about a resource called an issue...\n\nHuman:",
"params": {
"temperature": 0.2,
},
"model": "claude-2",
"provider": "anthropic"
}
}
]
}
버전 간 호환성
payload
내의 필드 이름을 변경하거나 삭제하거나 다른 목적으로 사용해야 할 경우 영향받는 래퍼 유형을 사용하는 단일 목적의 엔드포인트는 이전 버전의 필드 지원을 AI-Gateway에 구축해야 하며, 적어도 GitLab의 2개의 주요 버전 동안에 지원을 유지해야 합니다.
역호환성을 지원하는 데 도움이 될 수 있는 좋은 실천 방안: prompt_components
내부에서 프롬프트의 컴포넌트를 제공하는 것이 아니라 완전한 프롬프트를 제공하는 것 대신, 프롬프트를 컴파일하는 책임을 컴포넌트에서 AI-Gateway로 이동시킴으로써 미래에 보다 유연한 프롬프트 조정이 가능해질 수 있습니다.
예시 기능: 코드 제안
예를 들어, 미완전한 코드 제안 서비스는 다음과 같을 수 있습니다:
POST /v3/code/completions
{
"prompt_components": [
{
"type": "prompt",
"metadata": {
"source": "GitLab EE",
"version": "16.7.0-pre",
},
"payload": {
"content": "...",
"params": {
"temperature": 0.2,
"maxOutputTokens": 1024
},
"model": "code-gecko",
"provider": "vertex-ai"
}
},
{
"type": "editor_content",
"metadata": {
"source": "vscode",
"version": "1.1.1"
},
"payload": {
"filename": "application.rb",
"before_cursor": "require 'active_record/railtie'",
"after_cursor": "\nrequire 'action_controller/railtie'",
"open_files": [
{
"filename": "app/controllers/application_controller.rb",
"content": "class ApplicationController < ActionController::Base..."
}
]
}
}
]
}
응답은 다음과 같을 수 있습니다:
{
"response": "require 'something/else'",
"metadata": {
"identifier": "deadbeef",
"model": "code-gecko",
"timestamp": 1688118443
}
}
metadata
필드에는 지표 엔드포인트에서 활용할 수 있는 정보가 포함되어 있습니다. 여기에는 제안 수락율 등이 포함될 수 있습니다.
코드 제안에 대한 트래픽 데이터 수집(Telemetry)을 어떻게 받게 될 지에 대한 논의는 #415745에서 진행 중입니다. 모든 AI 관련 기능을 위한 아키텍처를 고안하려고 노력할 것입니다.
AI 프로바이더 노출
GitLab-Rails에는 이미 많은 AI 기능이 내장되어 있으며, 현재 다양한 AI 프로바이더로 직접 프롬프트를 작성하고 제출합니다. 작성 시점에서 다음과 같은 프로바이더에 대한 GitLab의 API 클라이언트가 있습니다:
이러한 기능을 Self-managed 인스턴스에서 사용할 수 있도록 하려면 각각의 프로바이더에 대한 엔드포인트를 제공해야 합니다. GitLab.com, Self-managed 또는 전용 설치에서 이러한 기능을 사용할 수 있도록 엔드포인트를 제공해야 합니다.
최초의 반복에서는 엔드포인트를 구축하여 요청을 AI 프로바이더로 프록시할 수 있습니다. 예를 들어, Anthropic의 엔드포인트는 다음과 같이 보일 수 있습니다:
POST /internal/proxy/anthropic/(*endpoint)
*endpoint
는 클라이언트가 무엇을 호출할지를 지정하는 것을 의미하며, 예를 들어 /v1/complete
와 같습니다. 요청 본문은 AI 프로바이더로 완전히 전달됩니다. AI 게이트웨이는 요청이 올바르게 인증되도록 합니다.
GitLab와 AI 프로바이더 사이에 프록시를 두면 AI 프로바이더로 전송되는 내용을 여전히 통제할 수 있으며, 필요한 경우 다른 프로바이더로 요청을 조작하거나 재경로 설정할 수 있습니다. 이를 통해, AI 프로바이더의 API가 변경되거나 특정 프로바이더와의 작업을 중단하기로 결정하더라도 이전 GitLab 설치의 기능을 계속 지원할 수 있습니다.
API 범주에 포함되어 있는 기능들은 현재 실험적인 경우가 있지만, 이러한 일반 API 엔드포인트로 변환하기 전에 Self-managed 설치용으로 일반적으로 사용 가능하게 만들어야 합니다. 이를 통해 AI 프로바이더의 경향이 변경되더라도 더 오랜 기간 동안 기능을 지원하는 것이 더 쉬워집니다.
GitLab 팀 멤버용으로 제공되는 실험적 REST API 또한 단기간 내에 이 프록시를 사용해야 합니다. 장기적으로는 개발자들이 GitLab의 소유 인증을 사용하여 여러 AI 프로바이더에 액세스할 수 있도록 하는 별도의 프록시에 액세스할 수 있어야 합니다. 이를 통해, 새로운 기능을 시험해보는 개발자들의 트래픽을 유료 고객을 제공하는 fleet와 분리시킬 수 있습니다.
GitLab 인스턴스의 API
외부 클라이언트가 사용할 수 있는 로컬 GitLab 인스턴스의 API입니다. 예를 들어, Self-managed 인스턴스에 연결된 VSCode입니다.
이러한 버전은 크게 다를 수 있습니다. VSCode 확장은 개발자에 의해 최신 상태로 유지될 수 있습니다. 그러나 작업에 사용하는 GitLab 인스턴스는 소프트웨어 버전이 조금 뒤쳐진 상태로 유지될 수 있습니다. 따라서 클라이언트에 대한 안정성과 유연성 요구 사항이 AI 게이트웨이에 대해 적용됩니다.
최초 반복에서는 VSCode 확장과 웹 IDE가 보내는 현재 REST 페이로드를 유지하는 것을 고려할 수 있지만, 이를 적절한 GitLab 설치로 직접 보냅니다. GitLab-rails는 AI 게이트웨이에 대한 페이로드를 해석할 필요 없이 페이로드를 랩핑할 수 있습니다.
이렇게 하면 확장에서 시작된 요청을 GitLab 인스턴스가 AI 게이트웨이로 보내기 위해 페이로드 전체를 추가로 전달해야 합니다. 클라이언트의 새 버전의 변경 사항을 지원하기 위해 구버전의 GitLab 설치를 거쳐 최신 AI 게이트웨이로 이동할 수 있도록 이는 필요합니다.
토론: 이 첫 번째 반복에서 REST+JSON 방식을 사용하고 있습니다. 현재 VSCode 확장이 모델 게이트웨이와 통신하고 있는 방식입니다. 이는 현재 있는 페이로드를 랩핑하는 것으로 가기만 하면 되기 때문에 작은 반복을 거쳐 이러한 기존 페이로드를 랩핑할 수 있습니다. 이는 교차 버전 호환성의 추가적인 이점을 가지고 있습니다. 그러나 향후 반복이 REST+JSON을 사용해야 한다는 의미는 아닙니다. 각 기능이 자체 엔드포인트를 갖게 되므로 프로토콜도 다를 수 있습니다.
인증 및 권한 부여
GitLab은 최초의 권한 부여를 제공합니다. 사용자를 인증하고 사용자가 사용하려는 기능에 라이선스를 사용할 수 있는지 여부를 확인합니다. 이는 이미 GitLab에 내장된 인증, 정책 및 라이선스 확인을 통해 수행될 수 있습니다.
GitLab 인스턴스의 인증을 AI 게이트웨이로 위임하는 구체적인 메커니즘은 다음에서 논의되었습니다.
클라우드 커넥터 액세스 제어 문서에서 사용자 간의 신뢰 위임 방식에 대해 다루고 있습니다. (Cloud Connector access control documentation)
임베딩
임베딩은 모든 기능에 대해 단일 엔드포인트를 통해 요청할 수 있으며, 다음과 같은 요청을 통해 요청될 수 있습니다.
POST /internal/embeddings
{
"content": "The lazy fox and the jumping dog",
"content_type": "issue_title",
"metadata": {
"source": "GitLab EE",
"version": "16.3"
}
}
content_type
및 content
속성은 앞으로 적절한 것을 기반으로 다른 모델로부터 임베딩을 생성하는 데 사용될 수 있습니다.
응답에는 사용된 프로바이더와 모델 외에 임베딩 벡터가 포함됩니다. 예를 들면:
{
"response": [0.2, -1, ...],
"metadata": {
"identifier": "8badf00d",
"model": "text-embedding-ada-002",
"provider": "open_ai"
}
}
임베딩을 저장할 때는 모델 및 프로바이더 데이터를 반드시 포함해야 합니다. 임베딩이 프롬프트 생성에 사용되면, 페이로드에 그러한 메타데이터를 포함하여 임베딩의 품질을 판단할 수 있습니다.
배포
현재 AI-게이트웨이가 될 model-gateway가 gitlab-org/modelops/applied-ml/code-suggestions/ai-assist
프로젝트 리포지터리에서 배포되고 있습니다.
이는 Kubernetes 클러스터에 해당 프로젝트로 배포됩니다. 현재 엔지니어들이 직접 사용하는 스테이징 환경이 있습니다.
추후에는 Runway를 사용하여 배포될 것입니다. 그 때에는 프로덕션 및 스테이징 배포가 있을 것입니다. 스테이징 배포는 프로덕션 단계에 도달하는 배포를 중지시킬 수 있는 자동화된 QA 실행에 사용될 수 있을 것입니다.
더 나아가, 추가 테스트 전략이 &10563에서 논의 중입니다.
대체 솔루션
대체 솔루션에 대한 토의가 applied-ml/code-suggestions/ai-assist#161에서 이루어졌습니다.