InfoGrab DocsInfoGrab Docs

GitLab Duo Chat

요약

GitLab Duo Chat은 소프트웨어 개발 수명 주기(Software Development Lifecycle, SDLC) 전반에 걸쳐 아이디에이션·창작 작업과 학습 작업에 AI를 활용하여 사용자가 더 빠르고 효율적으로 작업할 수 있도록 지원하는 것을 목표로 합니다.

GitLab Duo Chat은 소프트웨어 개발 수명 주기(Software Development Lifecycle, SDLC) 전반에 걸쳐 아이디에이션·창작 작업과 학습 작업에 AI를 활용하여 사용자가 더 빠르고 효율적으로 작업할 수 있도록 지원하는 것을 목표로 합니다.

ChatGitLab Duo 오퍼링의 일부입니다.

Chat은 다양한 질문에 답하고 특정 작업을 수행할 수 있습니다. 이는 프롬프트도구의 도움으로 이루어집니다.

Chat 인터페이스에서 사용자가 질문하면, GitLab은 GraphQL 요청을 Rails 백엔드에 전송합니다. Rails 백엔드는 AI Gateway를 통해 대형 언어 모델(Large Language Model, LLM)에 지시를 전송합니다.

Chat 기여에 가장 적합한 유스케이스는 무엇인가요?#

저희는 대형 언어 모델(LLM)이 주도하는 사용자AI 간의 대화형 상호작용으로 이점을 얻을 수 있는 모든 유스케이스와 워크플로에 Chat을 활용하고자 합니다. 일반적으로 이에 해당하는 것들은 다음과 같습니다:

  • 일회성 상호작용보다 반복을 통해 더 효과적이고 효율적으로 해결할 수 있는 창작·아이디에이션 작업 및 학습 작업.

  • 일반적으로 일회성 상호작용으로 충족될 수 있지만 정제가 필요하거나 대화로 이어질 수 있는 작업.

  • 후자 중에는 AI가 처음에는 정확하지 않을 수 있지만 사용자가 AI에게 더 정확히 원하는 것을 알려줌으로써 쉽게 방향을 수정할 수 있는 작업이 포함됩니다. 예를 들어, "이 코드를 설명해줘"는 대부분의 경우 만족스러운 답변을 제공하는 일반적인 질문이지만, 때로는 사용자가 추가적인 질문을 할 수 있습니다.

  • 사용자와 AI 모두 반복적으로 같은 내용을 말할 필요가 없도록 대화 기록의 혜택을 받는 작업.

Chat은 컨텍스트를 인식하고 궁극적으로 사용자가 접근할 수 있는 GitLab의 모든 리소스에 접근하는 것을 목표로 합니다. 초기에는 개별 이슈와 에픽의 내용, 그리고 GitLab 문서로 제한되었으나, 이후 코드 선택 및 코드 파일과 같은 추가 컨텍스트가 더해졌습니다. 현재 취약점 컨텍스트와 파이프라인 job 컨텍스트가 개발 중이어서, 사용자가 이러한 컨텍스트에 대해 질문할 수 있게 될 예정입니다.

전체 DevSecOps 도메인에 걸쳐 컨텍스트 인식을 확장하고, 그에 따라 창작·아이디에이션·학습 유스케이스를 확장하기 위해, GitLab Duo Chat 팀은 다른 GitLab 팀과 더 넓은 커뮤니티로부터 Chat 플랫폼에 대한 기여를 환영합니다. 이들이 가속화할 유스케이스와 워크플로의 전문가들입니다.

독립형 AI 기능으로 구현하는 것이 더 나은 유스케이스는 무엇인가요?#

독립형 AI 기능으로, 또는 적어도 독립형 AI 기능으로도 구현하는 것이 더 나은 유스케이스는 무엇인가요?

  • AI를 기존 워크플로에 깊이 통합하여 가속화할 수 있는 범위가 좁게 정해진 작업.

  • AI와의 대화에서 이점을 얻을 수 없는 작업.

좀 더 구체적으로 설명하기 위해 예시를 들겠습니다.

변경 내용을 기반으로 커밋 메시지를 생성하는 것은 커밋 메시지 작성 워크플로에 통합하는 것이 가장 좋습니다.

  • AI 없이는 커밋 메시지 작성에 10초가 걸릴 수 있습니다.

  • IDE의 커밋 메시지 필드에 AI가 생성한 커밋 메시지를 자동으로 채워 넣으면, 이 작업을 1초로 줄일 수 있습니다.

커밋 메시지 작성에 Chat을 사용하면 직접 작성하는 것보다 오래 걸릴 수 있습니다. 사용자는 Chat 창으로 전환하고, 요청을 입력한 다음 결과를 커밋 메시지 필드에 복사해야 합니다.

그렇다고 해서 Chat이 커밋 메시지를 작성할 수 없다거나, 그러지 못하도록 방지한다는 의미는 아닙니다. Chat에 커밋 컨텍스트가 있다면(커밋 메시지 작성 이외의 이유로 어느 시점에 추가될 수 있음), 사용자는 커밋 메시지 작성을 포함하여 이 커밋 내용으로 무엇이든 요청할 수 있습니다. 하지만 시간만 낭비하게 될 것이므로, 사용자가 Chat으로 그렇게 할 가능성은 거의 없습니다. 참고: 사용자가 작성한 프롬프트로 Chat에서 생성된 커밋 메시지와 전용 커밋 메시지 생성 기능의 정적 프롬프트로 생성된 커밋 메시지는 다를 수 있습니다.

GitLab Duo Chat 설정#

GitLab Duo Chat을 로컬에서 설정하려면 AI 기능에 대한 일반 설정 지침을 따르세요.

GitLab Duo Chat 작업하기#

프롬프트는 GitLab Duo Chat 시스템의 가장 중요한 부분입니다. 프롬프트는 특정 작업을 수행하기 위해 LLM에 전송하는 지시 사항입니다.

현재 프롬프트의 상태는 수 주에 걸친 반복의 결과물입니다. 현재 도구의 프롬프트를 변경하려면 기능 플래그 뒤에 배치해야 합니다.

새로운 프롬프트나 업데이트된 프롬프트가 있다면, 상당한 경험을 갖고 있는 GitLab Duo Chat 팀 구성원에게 리뷰를 요청하세요.

문제 해결#

로컬에서 Chat 작업 중 오류가 발생할 수 있습니다. 가장 일반적인 문제들은 이 섹션에 문서화되어 있습니다. 문서화되지 않은 이슈를 발견한 경우, 해결책을 찾은 후 이 섹션에 문서화해야 합니다.

문제 해결책
GitLab UI에 Chat 버튼이 없습니다. 사용자가 Premium 또는 Ultimate 라이선스를 보유하고 Chat이 활성화된 그룹에 속해 있는지 확인하세요.
Chat이 "Forbidden by auth provider" 오류로 응답합니다. 백엔드가 LLM에 접근할 수 없습니다. AI Gateway가 올바르게 설정되어 있는지 확인하세요.
UI에 요청이 나타나는 데 너무 오래 걸립니다. gdk restart rails-background-jobs를 실행하여 Sidekiq를 재시작하는 것을 고려하세요. 그래도 해결되지 않으면 gdk killgdk start를 시도하세요. 또는 Sidekiq를 완전히 우회할 수 있습니다. 그러려면 Llm::CompletionWorker.perform_async 구문을 임시로 Llm::CompletionWorker.perform_inline으로 변경하세요.
GDK가 non-SaaS 모드로 실행될 때 GitLab UI에 Chat 버튼이 없습니다. 클라우드 커넥터 액세스 토큰 레코드가 없거나 시트가 할당되지 않았습니다. 클라우드 커넥터 액세스 레코드를 생성하려면, rails 콘솔에서 다음 코드를 실행하세요: FactoryBot.create(:cloud_connector_access).

자세한 내용은 Chat이 문제 해결을 돕기 위해 전송하는 GitLab Duo Chat 에러 코드 해석을 참조하세요.

GitLab Duo Chat에 기여하기#

코드 관점에서 Chat은 다른 AI 기능과 유사하게 구현됩니다. GitLab AI 추상화 레이어에 대해 자세히 읽어보세요.

Chat 기능은 사용자 질문과 관련 컨텍스트를 AI Gateway에 전송하는 zero-shot 에이전트를 사용하며, AI Gateway는 프롬프트를 구성하고 대형 언어 모델에 요청을 전송합니다.

대형 언어 모델은 직접 답변할 수 있는지, 아니면 정의된 도구 중 하나를 사용해야 하는지 결정합니다.

각 도구에는 해당 도구를 사용하여 정보를 수집하는 방법을 대형 언어 모델에 제공하는 자체 프롬프트가 있습니다. 도구들은 자급자족적으로 설계되어 대형 언어 모델과의 여러 번 왕복 요청을 피합니다.

도구들이 필요한 정보를 수집한 후, 정보는 zero-shot 에이전트에 반환되며, 에이전트는 사용자의 질문에 최종 답변을 제공하기에 충분한 정보가 수집되었는지 대형 언어 모델에 질의합니다.

새 도구 추가하기#

새 도구를 추가하려면 AI Gateway와 Rails Monolith 모두에 변경 사항을 추가해야 합니다. 주요 chat 프롬프트는 AI Gateway에 저장되고 조합됩니다. Rails 측은 프롬프트의 필요한 파라미터를 조합하여 AI Gateway에 전송하는 역할을 합니다. AI Gateway는 Chat 프롬프트를 조합하고 사용자의 구독 및 애드온에 따라 사용 가능한 Chat 도구를 선택하는 역할을 합니다.

LLM이 사용할 도구를 선택하면, 해당 도구는 Rails 측에서 실행됩니다. 도구들은 AI Gateway에 요청을 보낼 때 다른 엔드포인트를 사용합니다. 새 도구를 추가할 때, AI Gateway는 다양한 버전을 가진 다양한 클라이언트와 GitLab 애플리케이션과 함께 작동한다는 점을 고려해야 합니다. 즉, 이전 버전의 GitLab은 새 도구에 대해 알지 못합니다. 새 도구를 추가하고 싶다면 GitLab Duo Chat 팀에 문의하세요. 저희는 이 문제에 대한 장기적인 해결책을 마련하고 있습니다.

AI Gateway 변경 사항#

  • ai_gateway/chat/tools/gitlab.py에 도구에 대한 새 클래스를 생성합니다. 이 클래스에는 다음 속성들이 포함되어야 합니다:

    name - 도구의 이름

    • 도구가 다루는 GitLab resource

    • 도구가 수행하는 작업에 대한 description

    • 질문과 원하는 답변에 대한 example

  • ai_gateway/chat/tools/gitlab.py__all__ 도구 목록에 도구를 추가합니다.

  • 적절한 Unit Primitive와 함께 ai_gateway/chat/toolset.pyDuoChatToolsRegistry에 도구 클래스를 추가합니다.

  • 변경 사항에 대한 테스트를 추가합니다.

Rails Monolith 변경 사항#

  • ee/lib/gitlab/llm/chain/tools/ 폴더에 도구 파일을 생성합니다. 기존 도구인 issue_reader 또는 epic_reader를 템플릿으로 사용하세요.

  • 도구가 정보를 수집하는 방법에 대한 대형 언어 모델 지시 사항을 포함하는 도구 클래스를 작성합니다 - 이 도구가 사용하는 주요 프롬프트입니다.

  • 대형 언어 모델의 응답을 파싱하여 chat 에이전트에 반환하는 코드를 도구에 구현합니다.

  • 에이전트가 알 수 있도록 ee/lib/gitlab/llm/completions/chat.rbtools 배열에 새 도구 이름을 추가합니다.

통합 테스트#

대형 언어 모델에 실제 요청을 보내는 RSpec 테스트를 사용하여 프롬프트를 테스트하고 반복합니다.

  • 프롬프트는 시행착오가 필요하며, LLM 작업의 비결정론적 특성은 예상치 못한 결과를 초래할 수 있습니다.

  • Anthropic은 프롬프트 작업에 대한 훌륭한 가이드를 제공합니다.

  • 프롬프트 작업에 대한 GitLab 가이드.

핵심은 프롬프트와 도구 설명을 통해 대형 언어 모델에 적절하게 지시하고, 도구가 자급자족적으로 유지되며, 응답이 zero-shot 에이전트에 반환되도록 하는 것입니다. 프롬프트에 대한 시행착오를 통해, 새 도구를 추가함으로써 Chat 기능의 역량을 확장할 수 있습니다.

이 주제를 다루는 짧은 동영상들을 활용할 수 있습니다.

멀티 스레드 대화 작업하기#

GitLab Duo Chat 대화와 상호작용하는 기능을 구축하는 경우, 스레드 작동 방식을 이해해야 합니다.

GitLab Duo Chat은 여러 대화를 지원합니다. 각 대화는 여러 메시지를 포함하는 스레드로 표현됩니다. 스레드의 중요한 속성은 다음과 같습니다:

  • id: id는 스레드에 답글을 달 때 필요합니다.

  • conversation_type: 사용 가능한 다양한 GitLab Duo Chat 대화 유형을 구분할 수 있습니다. 스레드 대화 유형 목록을 참조하세요.

기능에 자체 대화 유형이 필요한 경우, GitLab Duo Chat 팀에 문의하세요.

기능에서 GraphQL API를 직접 호출해야 하는 경우, 다음 쿼리와 뮤테이션을 사용할 수 있으며, 이 때 반드시 conversation_type을 지정해야 합니다.

모든 chat 대화에는 관리자가 제어하는 보존 기간이 있습니다. 기본 보존 기간은 마지막 답글로부터 30일입니다.

개발자 리소스#

디버깅#

전체 요청에 대한 더 많은 인사이트를 얻으려면 Gitlab::Llm::Logger 파일을 사용하여 로그를 디버그하세요. 프로덕션 환경의 기본 로깅 레벨은 INFO이며, 개인 식별 정보가 포함될 수 있는 데이터를 로깅하는 데 사용해서는 안 됩니다.

추상화 레이어의 AI 요청과 관련된 디버깅 메시지를 추적하려면 다음을 사용할 수 있습니다:

export LLM_DEBUG=1
gdk start
tail -f log/llm.log

프로덕션 환경에서 디버깅#

프로덕션 환경에서의 디버깅 및 문제 해결과 관련된 모든 정보는 GitLab Duo Chat On-Call Runbook에 수집되어 있습니다.

LangSmith를 사용한 트레이싱#

트레이싱은 LLM 애플리케이션의 동작을 이해하는 강력한 도구입니다. LangSmith는 최고 수준의 트레이싱 기능을 갖추고 있으며, GitLab Duo Chat과 통합되어 있습니다. 트레이싱은 다음과 같은 문제를 추적하는 데 도움이 됩니다:

  • GitLab Duo Chat이 처음인데 내부에서 무슨 일이 일어나는지 이해하고 싶습니다.

  • 예상치 못한 답변을 받았을 때 어디서 정확히 프로세스가 실패했는지.

  • 어느 프로세스가 지연의 병목 지점이었는지.

  • 모호한 질문에 어떤 도구가 사용되었는지.

트레이싱은 대규모 데이터셋으로 GitLab Duo Chat을 실행하는 평가에 특히 유용합니다. LangSmith 통합은 GitLab Centralized Evaluation Framework(CEF)를 포함한 모든 도구와 함께 작동합니다.

LangSmith로 트레이싱 사용하기#

Tracing is available in Development and Testing environment only.

It's not available in Production environment.

  • LangSmith에 접근하여 계정을 생성합니다.

    Lumos를 통해 접근 권한을 요청하세요.

    • Editor 권한을 위한 접근 요청을 생성하세요 (템플릿: LangSmith_Access_Request).
  • API 키를 생성합니다 (API 키를 어디서 생성하는지 주의하세요 - 개인 네임스페이스 또는 GL 네임스페이스에서 생성할 수 있습니다).

  • GDK에서 다음 환경 변수를 설정합니다.

    gdk.yml에서 정의할 수 있습니다:

# on your gdk.yml
env:
  LANGCHAIN_TRACING_V2: 'true'
  LANGCHAIN_API_KEY: '<your-api-key>'
  LANGCHAIN_PROJECT: '<your-project-name>'
  LANGCHAIN_ENDPOINT: 'https://api.smith.langchain.com'
  GITLAB_RAILS_RACK_TIMEOUT: '180' # Extending puma timeout for using LangSmith with CEF as the evaluation tool.

또는 터미널에서 직접 export합니다:

export LANGCHAIN_TRACING_V2=true
export LANGCHAIN_API_KEY='<your-api-key>'
export LANGCHAIN_PROJECT='<your-project-name>'
export LANGCHAIN_ENDPOINT='https://api.smith.langchain.com'
export GITLAB_RAILS_RACK_TIMEOUT=180 # Extending puma timeout for using LangSmith with CEF as the evaluation tool.

프로젝트 이름은 LangSmith의 기존 프로젝트 또는 새 프로젝트입니다. 환경 변수에 새 이름을 입력하면 충분합니다 - 요청 중에 프로젝트가 생성됩니다.

  • GDK를 재시작합니다.

  • Chat에 질문을 합니다.

  • LangSmith 페이지 > Projects > [프로젝트 이름]에서 프로젝트를 확인합니다. 'Runs' 탭에 최근 요청이 표시되어야 합니다.

LangSmith 트레이스 공유하기 (내부 팀 멤버용)#

웹 브라우저의 전체 URL을 복사하여 팀 멤버와 직접 트레이스 URL을 공유할 수 있습니다. 이는 LangSmith UI에 있는 "share" 트레이스 기능 대신 트레이스를 공유하는 권장 방법입니다. 트레이스를 공개적으로 공유하면 OKTA를 통한 LangSmith 접근 권한이 없는 사람도 링크를 통해 접근할 수 있게 됩니다. 트레이스에는 CI 토큰과 같은 민감한 정보가 포함되어 있습니다.

한 번의 클릭으로 머지 리퀘스트 평가하기#

CEF를 사용하여 머지 리퀘스트를 평가하려면, Evaluation Runner(내부 전용)를 사용할 수 있습니다. 머지 리퀘스트에서 평가 실행 지침을 따르세요.

머지 리퀘스트의 회귀 방지#

GitLab Duo Chat 또는 관련 컴포넌트를 변경할 때, 머지 리퀘스트의 품질 저하와 버그를 감지하기 위해 회귀 평가기를 실행해야 합니다. 도구 실행 및 슬래시 명령을 포함하여 모든 GitLab Duo Chat 실행 패턴을 다룹니다.

회귀 평가기를 실행하려면, 머지 리퀘스트에서 평가를 실행하고 회귀 평가기의 실행 버튼을 클릭하세요. 이후 머지 리퀘스트의 평가 결과를 master와 비교할 수 있습니다. LangSmith 비교 페이지에서 품질 저하와 버그가 없는지 확인하세요.

비교 결과 해석에 대한 엄격한 가이드라인은 없지만, 고려해야 할 몇 가지 유용한 팁이 있습니다:

  • 저하된 점수의 수가 향상된 점수의 수를 초과하는 경우, 머지 리퀘스트가 품질 저하를 일으켰을 수 있습니다.

  • 평가 중에 오류가 발생하는 예시가 있는 경우, 머지 리퀘스트에 잠재적인 버그가 있을 수 있습니다.

이러한 시나리오 중 하나라도 해당한다면, 추가 조사를 권장합니다:

  • 일일 평가 결과와 결과를 비교하세요. 예를 들어, 어제와 그제의 일일 평가를 살펴보세요.

  • 이러한 일일 평가에서 유사한 패턴이 관찰된다면, 머지 리퀘스트를 머지해도 안전할 가능성이 높습니다. 그러나 패턴이 다르다면, 머지 리퀘스트가 예상치 못한 변경을 일으켰을 수 있습니다.

최소한 다음 환경에서 회귀 평가기를 실행할 것을 강력히 권장합니다:

환경 평가 파이프라인 이름
GitLab Self-Managed 및 널리 채택된 커스텀 모델 duo-chat regression sm: [bedrock_mistral_8x7b_instruct]
GitLab.com 및 GitLab Duo Enterprise 애드온 duo-chat regression .com: [duo_enterprise]
GitLab.com 및 GitLab Duo Pro 애드온 duo-chat regression .com: [duo_pro]

또한, 특정 범위에 대한 더 포괄적인 데이터셋을 보유한 gitlab-docs와 같은 다른 평가기를 실행할 수 있습니다. 자세한 내용은 사용 가능한 평가 파이프라인을 참조하세요.

회귀 데이터셋에 예시 추가하기#

새 기능을 도입하거나 사용자로부터 회귀 보고를 받은 경우, 적용 범위를 확장하기 위해 회귀 데이터셋에 새 예시를 추가해야 합니다. 회귀 데이터셋에 예시를 추가하려면 이 섹션을 따르세요.

자세한 내용은 회귀 평가기 가이드라인을 참조하세요.

GitLab Duo Chat Self-managed 엔드 투 엔드 테스트#

머지 리퀘스트에서 엔드 투 엔드 테스트는 AI Gateway의 latest 버전과 통합된 GitLab Linux 패키지 인스턴스를 사용하여 GitLab Self-Managed 인스턴스의 GitLab Duo Chat 기능을 실행합니다. AI Gateway 인스턴스는 목(mock) 응답을 반환하도록 구성됩니다. 테스트 결과를 보려면 e2e:test-on-omnibus-ee 하위 파이프라인을 열고 ai-gateway job을 확인하세요.

ai-gateway job은 클라우드 라이선스를 활성화한 후 테스트 사용자에게 GitLab Duo Pro 시트를 할당하고, 그 다음 테스트가 실행됩니다.

자세한 내용은 AiGateway 시나리오를 참조하세요.

클라이언트 측 관찰 가능성#

Duo Agentic Chat은 모니터링과 분류를 지원하기 위해 클라이언트 측 오류를 Sentry에 보고합니다.

Sentry 오류 캡처#

Sentry를 직접 호출하는 대신 ee/app/assets/javascripts/ai/duo_agentic_chat/observability/sentry_utils.jscaptureExceptionForDuoChat 래퍼를 사용하세요. 이 래퍼는 모든 예외에 feature_category: 'duo_chat' 태그를 자동으로 추가합니다. 호출자는 추가 태그를 추가할 수 있지만 feature_category를 재정의할 수 없습니다.

import { captureExceptionForDuoChat } from '../observability/sentry_utils';

// Report an error with no extra context.
captureExceptionForDuoChat(new Error('Something went wrong'));

// Report an error with extra metadata.
captureExceptionForDuoChat(error, { extra: { info, component: 'MyComponent' } });

프론트엔드에서 Duo Chat 통합하기#

두 가지 공유 Vue 컴포넌트 중 하나를 사용하여 기능에 Duo Chat 통합을 추가할 수 있습니다. 두 컴포넌트 모두 현재 사용자에게 Duo Chat이 사용 가능한지 확인하고, 사용 불가능한 경우 아무것도 렌더링하지 않습니다.

  • DuoChatQuickAction (ee/app/assets/javascripts/ai/shared/widgets/duo_chat_quick_action.vue): Duo Chat을 열고 프롬프트를 전송하는 버튼을 렌더링합니다. 댓글 요약이나 리소스 설명 같은 특정 Duo Chat 작업을 페이지에서 트리거하려는 경우 사용하세요.

  • OpenAgenticChatButton (ee/app/assets/javascripts/ai/shared/widgets/open_agentic_chat_button.vue): 프롬프트를 자동으로 전송하지 않고 특정 에이전트가 미리 선택된 상태로 Duo Chat을 여는 버튼을 렌더링합니다. 커스텀 에이전트와 하나 이상의 프롬프트 제안을 포함한 Duo Chat을 열고 싶을 때 사용하세요.

사전 정의된 프롬프트로 Duo Chat 열기 (DuoChatQuickAction)#

DuoChatQuickAction을 사용하여 Duo Chat을 열고 사전 정의된 프롬프트를 전송하는 버튼을 추가하세요. 이 컴포넌트는 사용자의 현재 chat 모드(Classic 또는 Agentic)를 존중하고 각 모드에 맞는 프롬프트를 전송합니다.

컴포넌트 위치: ee/app/assets/javascripts/ai/shared/widgets/duo_chat_quick_action.vue.

Props#

Prop Type Required Description
buttonText String Yes 버튼에 표시되는 라벨.
resourceId String Yes 리소스의 GraphQL 글로벌 ID (예: gid://gitlab/Issue/1). Duo Chat에 관련 객체의 컨텍스트를 제공하는 데 사용됩니다.
trackingInfo Object Yes 트래킹 메타데이터. 적어도 두 단어를 포함하는 snake_case의 label 키가 필요합니다 (예: { label: 'issue_view_summary' }).
command Object Yes agenticPrompt (Agentic 모드용 자연어 프롬프트) 또는 agent (에이전트 객체)를 포함해야 합니다.
classicQuickAction String No Classic Chat 모드에서 전송할 슬래시 명령 (예: '/summarize_comments'). 기본값은 null입니다.
buttonOptions Object No 기본 GlButton에 전달되는 추가 props (예: { size: 'small' }).

Events#

Event Payload Description
duo-tool-completed { name, args } agentic 도구가 완료될 때 발생합니다. name은 도구 이름이고, args는 도구 출력값입니다.

예시#

// app/assets/javascripts/my_feature/components/my_component.vue
import { DUO_CHAT_QUICK_ACTION_SUMMARIZE, DUO_CHAT_AGENT_PLANNER } from '~/ai/constants';
import { s__ } from '~/locale';

export default {
  name: 'MyComponent',
  components: {
    DuoChatQuickAction: () => import('ee_component/ai/shared/widgets/duo_chat_quick_action.vue'),
  },
  inject: {
    resourceGlobalId: { default: null },
    noteableType: { default: '' },
  },
  computed: {
    summarizeTracking() {
      return { label: 'my_feature_view_summary', property: this.noteableType };
    },
  },
  buttonOptions: { size: 'small' },
  classicQuickAction: DUO_CHAT_QUICK_ACTION_SUMMARIZE,
  summarizeCommand: {
    agent: { name: DUO_CHAT_AGENT_PLANNER },
    agenticPrompt: s__('AI|Summarize the comments on this issue.'),
  },
};
<duo-chat-quick-action
  v-if="resourceGlobalId"
  :button-text="s__('AISummary|View summary')"
  :resource-id="resourceGlobalId"
  :tracking-info="summarizeTracking"
  :classic-quick-action="$options.classicQuickAction"
  :command="$options.summarizeCommand"
  :button-options="$options.buttonOptions"
/>

프롬프트 제안이 있는 Duo Chat 열기 (OpenAgenticChatButton)#

OpenAgenticChatButton을 사용하여 커스텀 에이전트가 미리 선택되고 Duo Agentic Chat의 빈 상태 UI에 표시되는 하나 이상의 프롬프트 제안이 있는 Duo Chat을 여는 버튼을 추가하세요.

컴포넌트 위치: ee/app/assets/javascripts/ai/shared/widgets/open_agentic_chat_button.vue.

Props#

Prop Type Required Description
buttonText String Yes 버튼에 표시되는 라벨.
resourceId String Yes 리소스의 GraphQL 글로벌 ID. 스트리밍 응답을 바인딩하는 데 사용됩니다.
agent Object Yes 미리 선택할 에이전트, 이름으로 식별됩니다 (예: { name: 'My Feature Assistant' }).
welcomeMessage String No 사용자가 타이핑하기 전 빈 상태 패널에 표시되는 메시지.
predefinedPrompts Array No 빈 상태에 표시되는 제안 칩.
buttonOptions Object No 기본 GlButton에 전달되는 추가 props.

Events#

Event Payload Description
tool-completed { name, args } 에이전트의 도구가 완료될 때 발생합니다. name은 도구 이름이고, args는 도구 출력값입니다.

예시: Duo Chat을 사용하여 웹 폼을 채우는 기능 구현#

구현에는 세 가지 부분이 있습니다:

  • 사용자로부터 정보를 수집하고 컴포넌트가 사용할 수 있는 구조화된 데이터를 반환하는 자체 도구가 있는 커스텀 에이전트. 각 에이전트는 자체 도구를 정의해야 합니다 - 공유 범용 도구는 없습니다.

  • 해당 에이전트가 미리 선택되고 몇 가지 프롬프트 제안이 있는 Duo Chat을 여는 버튼.

  • 도구 완료 이벤트를 수신하고 결과를 적용하는 컴포넌트.

Step 1: 도구가 있는 커스텀 에이전트 생성#

duo_workflow_service/agent_platform/v1/flows/configs/ 아래의 AI Gateway 리포지터리에 플로우 구성을 생성합니다. 에이전트에 대한 자체 도구를 정의해야 합니다. 여기서 선택하는 도구 이름이 Step 3에서 프론트엔드에서 수신 대기할 이름입니다.

전체 에이전트 생성 프로세스는 foundational_chat_agents.md를 참조하세요.

Step 2: 컴포넌트에 버튼 추가#

OpenAgenticChatButton을 가져오고 에이전트, 환영 메시지, 사전 정의된 프롬프트를 컴포넌트 수준 상수로 정의합니다.

// ee/app/assets/javascripts/my_feature/components/my_component.vue
import OpenAgenticChatButton from 'ee/ai/shared/widgets/open_agentic_chat_button.vue';
import { convertToGraphQLId } from '~/graphql_shared/utils';
import { TYPENAME_USER } from '~/graphql_shared/constants';
import { s__, __ } from '~/locale';

const AGENT = { name: __('My Feature Assistant') };
const TOOL_NAME = 'my_feature_tool';
const WELCOME_MESSAGE = s__('MyFeature|I can help you configure this feature.');
const PREDEFINED_PROMPTS = [
  s__('MyFeature|Enable read access to repositories.'),
  s__('MyFeature|Set up CI/CD pipeline permissions.'),
];

export default {
  name: 'MyComponent',
  components: { OpenAgenticChatButton },
  computed: {
    resourceId() {
      return convertToGraphQLId(TYPENAME_USER, window.gon?.current_user_id);
    },
  },
  methods: {
    handleToolCompleted({ name, args } = {}) {
      if (name !== TOOL_NAME || !args || typeof args !== 'object') return;

      // Apply the tool output to your component
      this.myField = args.my_field;
    },
  },
  AGENT,
  WELCOME_MESSAGE,
  PREDEFINED_PROMPTS,
};
<open-agentic-chat-button
  :button-text="__('Configure with Duo')"
  :resource-id="resourceId"
  :agent="$options.AGENT"
  :welcome-message="$options.WELCOME_MESSAGE"
  :predefined-prompts="$options.PREDEFINED_PROMPTS"
  @tool-completed="handleToolCompleted"
/>

predefinedPrompts는 chat 패널이 비어 있을 때 제안 칩으로 표시되는 문자열 배열입니다. welcomeMessage를 사용하여 에이전트가 할 수 있는 일을 사용자에게 설명하세요. 둘 다 선택 사항이지만 첫 번째 프롬프트까지의 시간을 줄이기 위해 권장합니다.

Step 3: 도구 완료 이벤트 처리#

에이전트의 도구가 완료되면, OpenAgenticChatButtontool-completed 이벤트를 발생시킵니다. 페이로드는 { name, args } 형태를 가지며, name은 도구 이름이고 args는 도구가 반환한 인수의 객체입니다.

모든 도구 완료가 동일한 이벤트를 통해 브로드캐스트되므로, 페이로드에 따라 작업하기 전에 name이 에이전트 구성에서 정의된 도구 이름과 일치하는지 확인하세요.

const TOOL_NAME = 'my_feature_tool'; // Must match the tool name in your agent config

methods: {
  handleToolCompleted({ name, args } = {}) {
    if (name !== TOOL_NAME || !args || typeof args !== 'object') return;

    // Apply the tool output to your component
    this.myField = args.my_field;
  },
},

이벤트 페이로드의 형태는 다음과 같습니다:

{
  name: 'my_feature_tool', // tool name as defined in your agent config
  args: {
    // fields defined by your tool
    my_field: 'value',
  }
}

완전한 실제 예시는 ee/app/assets/javascripts/personal_access_tokens/components/create_granular_token/ask_dap_permissions.vue를 참조하세요.

알려진 제한 사항#

  • 에이전트는 자체 도구를 구현해야 합니다. AI Catalog 에이전트는 이 패턴에 도구를 공유할 수 없습니다. (ai-assist#2113)

  • 커스텀 질문은 에이전트 YAML에 정의할 수 없으며, 호출하는 컴포넌트에 하드코딩되어야 합니다. (GitLab#594533)

  • 특정 페이지를 위해 생성된 에이전트는 여전히 사이트 전체의 foundational 에이전트로 선택 가능합니다.

  • 스트리밍 응답은 지원되지 않습니다.

  • 에이전트는 기존 폼 필드 값을 읽지 않습니다.

GraphQL 구독#

Chat의 GraphQL 구독은 사용자 중심이기 때문에 약간 다르게 동작합니다. 사용자는 여러 브라우저 탭에서, 또는 IDE에서도 Chat을 열 수 있습니다. 따라서 클라이언트를 동기화 상태로 유지하기 위해 여러 클라이언트에 메시지를 브로드캐스트해야 합니다. chat 액션이 있는 aiAction 뮤테이션은 다음과 같이 동작합니다:

  • 모든 완전한 Chat 메시지(사용자의 메시지 포함)는 userId, aiAction: "chat"을 식별자로 브로드캐스트됩니다.

  • 스트리밍된 Chat 메시지의 청크는 뮤테이션의 clientSubscriptionId를 식별자로 브로드캐스트됩니다.

Vue 컴포넌트에서 GraphQL 구독 예시:

  • 완전한 Chat 메시지
import aiResponseSubscription from 'ee/graphql_shared/subscriptions/ai_completion_response.subscription.graphql';
[...]

apollo: {
 $subscribe: {
   aiCompletionResponse: {
     query: aiResponseSubscription,
     variables() {
       return {
         userId, // for example "gid://gitlab/User/1"
         aiAction: 'CHAT',
       };
     },
     result({ data }) {
       // handle data.aiCompletionResponse
     },
     error(err) {
       // handle error
     },
   },
 },
  • 스트리밍된 Chat 메시지
import aiResponseSubscription from 'ee/graphql_shared/subscriptions/ai_completion_response.subscription.graphql';
[...]

apollo: {
 $subscribe: {
   aiCompletionResponseStream: {
     query: aiResponseSubscription,
     variables() {
       return {
         aiAction: 'CHAT',
         userId, // for example "gid://gitlab/User/1"
         clientSubscriptionId // randomly generated identifier for every message
         htmlResponse: false, // important to bypass HTML processing on every chunk
       };
     },
     result({ data }) {
       // handle data.aiCompletionResponse
     },
     error(err) {
       // handle error
     },
   },
 },

clientSubscriptionId는 모든 요청에 대해 고유해야 합니다. clientSubscriptionId를 재사용하면 구독 응답에 여러 원치 않는 부작용이 발생합니다.

GitLab Duo Chat GraphQL 쿼리#

mutation {
  aiAction(
    input: {
      chat: {
        resourceId: "gid://gitlab/User/1",
        content: "Hello"
      }
    }
  ){
    requestId
    errors
  }
}
  • 다음 쿼리를 실행하여 응답을 가져오세요:
query {
  aiMessages {
    nodes {
      requestId
      content
      role
      timestamp
      chunkId
      errors
    }
  }
}

응답을 가져올 수 없는 경우, graphql_json.log, sidekiq_json.log, llm.log 또는 modelgateway_debug.log에 오류 정보가 포함되어 있는지 확인하세요.

GitLab Duo Chat 대화 스레드 GraphQL 쿼리#

대화 스레드에서 메시지 조회#

특정 스레드에서 메시지를 검색하려면 스레드 ID와 함께 aiMessages 쿼리를 사용하세요:

query {
  aiMessages(threadId: "gid://gitlab/Ai::Conversation::Thread/1") {
    nodes {
      requestId
      content
      role
      timestamp
      chunkId
      errors
    }
  }
}

새 대화 스레드 시작#

aiAction 뮤테이션에 threadId를 포함하지 않으면 새 스레드가 생성됩니다:

mutation {
  aiAction(input: {
    chat: {
      content: "This will create a new conversation thread"
    },
    conversationType: DUO_CHAT
  })
  {
    requestId
    errors
    threadId  # This will contain the ID of the newly created thread
  }
}

기존 대화 스레드에 새 메시지 생성#

기존 스레드에 메시지를 추가하려면 aiAction 뮤테이션에 threadId를 포함하세요:

mutation {
  aiAction(input: {
    chat: {
      content: "this is another message in the same thread"
    },
    conversationType: DUO_CHAT,
    threadId: "gid://gitlab/Ai::Conversation::Thread/1",
  })
  {
    requestId
    errors
    threadId
  }
}

프로덕션과 유사한 환경에서 GitLab Duo Chat 테스트#

GitLab Duo Chat은 StagingStaging Ref GitLab 환경에서 활성화되어 있습니다.

GitLab Duo Chat은 현재 Premium 및 Ultimate 티어 그룹의 구성원에게만 제공되므로, GitLab 팀 멤버에게는 Staging Ref가 변경 사항을 테스트하기 더 쉬운 장소일 수 있습니다. Staging Ref에서 자신을 인스턴스 Admin으로 만들 수 있으므로, Admin으로서 테스트용 라이선스 그룹을 쉽게 생성할 수 있기 때문입니다.

중요한 테스트 고려 사항#

A user who has a seat in multiple groups with different tiers of GitLab Duo add-on gets the highest tier experience across the entire instance.

테스트 계정이 더 높은 티어 애드온의 시트를 가지고 있는 경우, 다양한 GitLab Duo 애드온 간의 기능 분리를 테스트하는 것은 불가능합니다. 다양한 티어를 올바르게 테스트하려면, 테스트할 각 티어마다 별도의 테스트 계정을 생성하세요.

Staging 테스트 그룹#

staging에서의 테스트를 간소화하기 위해, 적절한 라이선스와 애드온이 구성된 여러 사전 설정 그룹이 생성되었습니다:

그룹 GitLab Duo 애드온 GitLab 라이선스
duo_pro_gitlab_premium Pro Premium
duo_pro_gitlab_ultimate Pro Ultimate
duo_enterprise_gitlab_ultimate Enterprise Ultimate

이 그룹에 Owner로 추가되려면 Slack의 #g_duo_chat 채널에 요청하세요. Owner로 추가된 후, 보조 계정을 Developer 권한으로 그룹에 추가하고 GitLab Duo 애드온 시트를 할당할 수 있습니다. 그런 다음 Developer 사용자로 로그인하여 GitLab Duo Chat에 대한 접근 제어를 테스트할 수 있습니다.

라이브 환경에서의 GitLab Duo Chat 엔드 투 엔드 테스트#

GitLab Duo Chat 엔드 투 엔드 테스트는 StagingProduction GitLab 환경에 대해 지속적으로 실행됩니다.

이 테스트들은 예약된 파이프라인에서 실행되며, 엔드 투 엔드 사용자 경험이 올바르게 작동하는지 확인합니다. 결과는 #e2e-run-staging#e2e-run-production Slack 채널에서 볼 수 있습니다. 파이프라인은 아래에서 찾을 수 있으며, #s_developer_experience에서 접근 권한을 요청할 수 있습니다:

제품 분석#

기능이 어떻게 사용되는지 더 잘 이해하기 위해, 각 프로덕션 사용자 입력 메시지는 LLM과 Ruby를 사용하여 분석되며, 분석 결과는 Snowplow 이벤트로 추적됩니다.

분석은 최신 iglu 스키마에 정의된 속성을 포함할 수 있습니다.

  • 카테고리와 상세 카테고리는 제품 관리자와 제품 디자이너에 의해 사전 정의되었습니다. 실제 사용자 질문을 볼 수 없기 때문입니다. 누락되거나 혼란스러운 카테고리가 있다고 판단되면 변경할 수 있습니다. 정의를 편집하려면 AI Gatewaymonolith 모두에서 categories.xml을 업데이트하세요.

  • 캡처되는 속성 목록은 labels.xml에서 찾을 수 있습니다.

다음은 아직 구현되지 않은 것들입니다:

is_proper_sentence

  • 다음은 더 이상 사용되지 않습니다:

number_of_questions_in_history

  • length_of_questions_in_history

  • time_since_first_question

각 질문 카테고리 및 상세 카테고리에 대한 요청 수와 사용자 수는 이 Tableau 대시보드에서 확인할 수 있습니다(GitLab 팀 멤버 전용).

access_duo_classic_chat 정책 작동 방식#

이 표는 다양한 컨텍스트에서 access_duo_classic_chat 정책이 true를 반환하기 위한 요구 사항을 설명합니다.

GitLab.com Dedicated 또는 GitLab Self-Managed 모든 인스턴스
프로젝트 또는 그룹 외부 사용자의 경우 (user.can?(:access_duo_classic_chat)) 사용자는 duo_features_enabled 그룹 설정이 활성화된 Premium 또는 Ultimate 티어의 적어도 하나의 그룹에 속해야 합니다. - 인스턴스가 Premium 또는 Ultimate 티어에 있어야 합니다. - 인스턴스에 duo_features_enabled 설정이 활성화되어 있어야 합니다.
그룹 컨텍스트의 사용자의 경우 (user.can?(:access_duo_classic_chat, group)) - 사용자는 experiment_and_beta_features 그룹 설정이 활성화된 Premium 또는 Ultimate 티어의 적어도 하나의 그룹에 속해야 합니다. - 그룹의 루트 상위 그룹이 Premium 또는 Ultimate 티어에 있고 그룹에 duo_features_enabled 설정이 활성화되어 있어야 합니다. - 인스턴스가 Premium 또는 Ultimate 티어에 있어야 합니다. - 인스턴스에 duo_features_enabled 설정이 활성화되어 있어야 합니다. 사용자는 그룹에 대해 최소한 읽기 권한이 있어야 합니다.
프로젝트 컨텍스트의 사용자의 경우 (user.can?(:access_duo_classic_chat, project)) - 사용자는 experiment_and_beta_features 그룹 설정이 활성화된 Premium 또는 Ultimate 티어의 적어도 하나의 그룹에 속해야 합니다. - 프로젝트의 루트 상위 그룹이 Premium 또는 Ultimate 티어에 있고 프로젝트에 duo_features_enabled 설정이 활성화되어 있어야 합니다. - 인스턴스가 Ultimate 티어에 있어야 합니다. - 인스턴스에 duo_features_enabled 설정이 활성화되어 있어야 합니다. 사용자는 프로젝트에 대해 최소한 읽기 권한이 있어야 합니다.

(Deprecated) 이슈 및 에픽 실험#

This section is deprecated in favor of the [development seed file](/19.1/development/development_seed_files/#seed-project-and-group-resources-for-gitlab-duo).

평가 프레임워크를 사용하려는 경우(평가 문서에 설명된 대로), 이 Rake 작업을 사용하여 필요한 그룹과 프로젝트를 가져올 수 있습니다:

GITLAB_SIMULATE_SAAS=1 bundle exec 'rake gitlab:duo:setup_evaluation[<test-group-name>]'

하위 그룹 가져오기에 필요한 그룹을 생성하기 위해 "saas" 모드가 필요한 Setup 클래스(ee/lib/gitlab/duo/developments/setup.rb 아래)를 사용하기 때문에, GITLAB_SIMULATE_SAAS=1을 설정해야 합니다. 이는 가져오기를 성공적으로 완료하기 위한 것이며, 원하는 경우 이후에 GITLAB_SIMULATE_SAAS=0으로 다시 전환할 수 있습니다.

(Deprecated) 에픽 및 이슈 픽스처#

This section is deprecated in favor of the [development seed file](/19.1/development/development_seed_files/#seed-project-and-group-resources-for-gitlab-duo).

픽스처는 GitLab이 소유한 프로젝트와 그룹의 공개 이슈 및 에픽의 복제본입니다. 샘플링 시 내부 노트는 제외되었습니다. 픽스처는 canonical gitlab 리포지터리에 커밋되어 있습니다. 픽스처를 생성하는 데 사용된 스니펫을 참조하세요.

Chat 프롬프트 구성 방법#

모든 Chat 요청은 GitLab GraphQL API로 처리됩니다. 그리고 현재는 서드파티 LLM을 위한 프롬프트가 GitLab 코드베이스에 하드코딩되어 있습니다.

하지만 Chat 프롬프트를 변경하려는 경우, 단일 파일에서 문자열을 찾는 것만큼 단순하지 않습니다. Chat 프롬프트 구성은 많은 단계를 거쳐 프롬프트가 조합되기 때문에 따라가기 어렵습니다. 다음은 Chat 프롬프트 구성 흐름입니다:

  • GraphQL AI Mutation에 API 요청이 이루어집니다. 요청에는 사용자 Chat 입력이 포함됩니다. (코드)

  • GraphQL 뮤테이션은 Llm::ExecuteMethodService#execute를 호출합니다. (코드)

  • Llm::ExecuteMethodService#executechat 메서드가 GraphQL API로 전송되었음을 감지하고 Llm::ChatService#execute를 호출합니다. (코드)

  • Llm::ChatService#executeLlm::BaseService(ChatService의 기본 클래스)에 정의된 schedule_completion_worker를 호출합니다. (코드)

  • schedule_completion_worker는 job을 비동기적으로 큐에 넣는 Llm::CompletionWorker.perform_for를 호출합니다. (코드)

  • job이 실행될 때 Llm::CompletionWorker#perform이 호출됩니다. 사용자 입력과 기타 메시지 컨텍스트를 역직렬화하여 Llm::Internal::CompletionService#execute로 전달합니다. (코드)

  • Llm::Internal::CompletionService#executeGitlab::Llm::CompletionsFactory#completion!을 호출하고, 원래 GraphQL 요청에서 ai_action을 가져와 Gitlab::Llm::Completions::Chat의 새 인스턴스를 초기화하고 execute를 호출합니다. (코드)

  • Gitlab::Llm::Completions::Chat#executeGitlab::Duo::Chat::ReactExecutor를 호출합니다. (코드)

  • Gitlab::Duo::Chat::ReactExecutor#execute#step_forward를 호출하고, 이는 Gitlab::Duo::Chat::StepExecutor#step을 호출합니다. (코드)

  • Gitlab::Duo::Chat::StepExecutor#stepGitlab::Duo::Chat::StepExecutor#perform_agent_request를 호출하고, AI Gateway /v2/chat/agent/ 엔드포인트에 요청을 전송합니다. (코드)

  • AI Gateway /v2/chat/agent 엔드포인트는 api.v2.agent.chat.agent.chat 함수에서 요청을 받습니다. (코드)

  • api.v2.agent.chat.agent.chatgl_agent_remote_executor_factory를 통해 GLAgentRemoteExecutor를 생성합니다 (코드).

    GLAgentRemoteExecutor 생성 시 다음 파라미터가 전달됩니다:

    tools_registry - 사용 가능한 모든 도구의 레지스트리. 팩토리를 통해 전달됩니다 (코드)

    • agent - 선택된 LLM 모델, 프롬프트 템플릿 등을 포함한 프롬프트 정보를 래핑하는 ReActAgent 객체
  • api.v2.agent.chat.agent.chatGLAgentRemoteExecutor.on_behalf를 호출하며, 오류 발생 시 가능한 한 빨리 예외를 발생시키기 위해 사용자 도구를 미리 가져옵니다 (코드).

  • api.v2.agent.chat.agent.chatGLAgentRemoteExecutor.stream을 호출합니다 (코드).

  • GLAgentRemoteExecutor.stream은 메시지와 사용 가능한 도구 목록과 같은 입력으로 agent(ReActAgent 인스턴스)에서 astream을 호출합니다 (코드).

  • ReActAgent는 사용 가능한 도구를 시스템 프롬프트 템플릿에 삽입하여 프롬프트를 구성합니다 (코드).

  • ReActAgent.astream은 LLM 모델에 호출을 전송합니다 (코드)

  • LLM 응답이 Rails에 반환됩니다 (코드 경로: ReActAgent.astream -> GLAgentRemoteExecutor.stream -> api.v2.agent.chat.agent.chat -> Rails)

  • 이제 AI Gateway에 첫 번째 요청을 완료했습니다. LLM이 첫 번째 요청의 답변이 최종적이라고 판단하면, Rails는 답변을 파싱하고 Gitlab::Llm::Completions::Chat에 의한 추가 응답 처리를 위해 반환합니다.

  • 답변이 최종적이지 않은 경우, 첫 번째 LLM 요청의 "thoughts"와 "picked tools"가 파싱된 다음 관련 도구 클래스가 호출됩니다. (코드 | 도구 클래스 예시)

    도구 실행기 클래스는 Concerns::AiDependent를 포함하고 request 메서드를 사용합니다. (코드)

  • request 메서드는 Llm::Completions::Chatcontext에 주입된 ai_request 인스턴스를 사용합니다. Chat의 경우 이것은 Gitlab::Llm::Chain::Requests::AiGateway입니다. (코드)

  • 도구는 use_ai_gateway_agent_prompt=true를 나타냅니다 (코드).

    이를 통해 ai_request/v1/prompts/chat 엔드포인트에 프롬프트를 전송합니다 (코드).

  • AI Gateway /v1/prompts/chat 엔드포인트는 api.v1.prompts.invoke에서 요청을 받습니다 (코드).

  • api.v1.prompts.invoke는 도구 프롬프트 레지스트리에서 올바른 도구 프롬프트를 가져옵니다 (코드).

  • 프롬프트는 스트림 또는 비스트리밍 호출로 호출됩니다.

  • 도구 답변이 최종적이지 않으면, 응답은 agent_scratchpad에 추가되고 Gitlab::Duo::Chat::ReactExecutor의 루프가 다시 시작되어 요청에 추가 컨텍스트를 더합니다. 최종 답변이 나올 때까지 최대 10번 반복합니다. (코드)

GitLab Duo Chat 에러 코드 해석#

GitLab Duo Chat에는 디버깅을 돕기 위한 지정된 의미를 가진 에러 코드가 있습니다.

모든 GitLab Duo Chat 에러 코드 목록은 GitLab Duo Chat 문제 해결 문서를 참조하세요.

GitLab Duo Chat 개발 시, 오류 반환 시 이러한 에러 코드를 포함하고 특히 사용자 대면 오류의 경우 문서화하세요.

에러 코드 형식#

에러 코드는 <레이어 식별자><네 자리 시리즈 번호> 형식을 따릅니다.

예를 들어:

  • M1001: monolith 레이어의 네트워크 통신 오류.

  • G2005: AI Gateway 레이어의 데이터 형식/처리 오류.

  • A3010: 서드파티 API의 인증 또는 데이터 접근 권한 오류.

에러 코드 레이어 식별자#

코드 레이어
M Monolith
G AI Gateway
A 서드파티 API

에러 시리즈#

시리즈 유형
1000 네트워크 통신 오류
2000 데이터 형식/처리 오류
3000 인증 및/또는 데이터 접근 권한 오류
4000 코드 실행 예외
5000 잘못된 구성 또는 잘못된 파라미터 오류
6000 의미론적 또는 추론 오류 (모델이 이해하지 못하거나 환각을 일으킴)

GitLab Duo Chat

GitLab v19.1
원문 보기
요약

GitLab Duo Chat은 소프트웨어 개발 수명 주기(Software Development Lifecycle, SDLC) 전반에 걸쳐 아이디에이션·창작 작업과 학습 작업에 AI를 활용하여 사용자가 더 빠르고 효율적으로 작업할 수 있도록 지원하는 것을 목표로 합니다.

GitLab Duo Chat은 소프트웨어 개발 수명 주기(Software Development Lifecycle, SDLC) 전반에 걸쳐 아이디에이션·창작 작업과 학습 작업에 AI를 활용하여 사용자가 더 빠르고 효율적으로 작업할 수 있도록 지원하는 것을 목표로 합니다.

ChatGitLab Duo 오퍼링의 일부입니다.

Chat은 다양한 질문에 답하고 특정 작업을 수행할 수 있습니다. 이는 프롬프트도구의 도움으로 이루어집니다.

Chat 인터페이스에서 사용자가 질문하면, GitLab은 GraphQL 요청을 Rails 백엔드에 전송합니다. Rails 백엔드는 AI Gateway를 통해 대형 언어 모델(Large Language Model, LLM)에 지시를 전송합니다.

Chat 기여에 가장 적합한 유스케이스는 무엇인가요?#

저희는 대형 언어 모델(LLM)이 주도하는 사용자AI 간의 대화형 상호작용으로 이점을 얻을 수 있는 모든 유스케이스와 워크플로에 Chat을 활용하고자 합니다. 일반적으로 이에 해당하는 것들은 다음과 같습니다:

  • 일회성 상호작용보다 반복을 통해 더 효과적이고 효율적으로 해결할 수 있는 창작·아이디에이션 작업 및 학습 작업.

  • 일반적으로 일회성 상호작용으로 충족될 수 있지만 정제가 필요하거나 대화로 이어질 수 있는 작업.

  • 후자 중에는 AI가 처음에는 정확하지 않을 수 있지만 사용자가 AI에게 더 정확히 원하는 것을 알려줌으로써 쉽게 방향을 수정할 수 있는 작업이 포함됩니다. 예를 들어, "이 코드를 설명해줘"는 대부분의 경우 만족스러운 답변을 제공하는 일반적인 질문이지만, 때로는 사용자가 추가적인 질문을 할 수 있습니다.

  • 사용자와 AI 모두 반복적으로 같은 내용을 말할 필요가 없도록 대화 기록의 혜택을 받는 작업.

Chat은 컨텍스트를 인식하고 궁극적으로 사용자가 접근할 수 있는 GitLab의 모든 리소스에 접근하는 것을 목표로 합니다. 초기에는 개별 이슈와 에픽의 내용, 그리고 GitLab 문서로 제한되었으나, 이후 코드 선택 및 코드 파일과 같은 추가 컨텍스트가 더해졌습니다. 현재 취약점 컨텍스트와 파이프라인 job 컨텍스트가 개발 중이어서, 사용자가 이러한 컨텍스트에 대해 질문할 수 있게 될 예정입니다.

전체 DevSecOps 도메인에 걸쳐 컨텍스트 인식을 확장하고, 그에 따라 창작·아이디에이션·학습 유스케이스를 확장하기 위해, GitLab Duo Chat 팀은 다른 GitLab 팀과 더 넓은 커뮤니티로부터 Chat 플랫폼에 대한 기여를 환영합니다. 이들이 가속화할 유스케이스와 워크플로의 전문가들입니다.

독립형 AI 기능으로 구현하는 것이 더 나은 유스케이스는 무엇인가요?#

독립형 AI 기능으로, 또는 적어도 독립형 AI 기능으로도 구현하는 것이 더 나은 유스케이스는 무엇인가요?

  • AI를 기존 워크플로에 깊이 통합하여 가속화할 수 있는 범위가 좁게 정해진 작업.

  • AI와의 대화에서 이점을 얻을 수 없는 작업.

좀 더 구체적으로 설명하기 위해 예시를 들겠습니다.

변경 내용을 기반으로 커밋 메시지를 생성하는 것은 커밋 메시지 작성 워크플로에 통합하는 것이 가장 좋습니다.

  • AI 없이는 커밋 메시지 작성에 10초가 걸릴 수 있습니다.

  • IDE의 커밋 메시지 필드에 AI가 생성한 커밋 메시지를 자동으로 채워 넣으면, 이 작업을 1초로 줄일 수 있습니다.

커밋 메시지 작성에 Chat을 사용하면 직접 작성하는 것보다 오래 걸릴 수 있습니다. 사용자는 Chat 창으로 전환하고, 요청을 입력한 다음 결과를 커밋 메시지 필드에 복사해야 합니다.

그렇다고 해서 Chat이 커밋 메시지를 작성할 수 없다거나, 그러지 못하도록 방지한다는 의미는 아닙니다. Chat에 커밋 컨텍스트가 있다면(커밋 메시지 작성 이외의 이유로 어느 시점에 추가될 수 있음), 사용자는 커밋 메시지 작성을 포함하여 이 커밋 내용으로 무엇이든 요청할 수 있습니다. 하지만 시간만 낭비하게 될 것이므로, 사용자가 Chat으로 그렇게 할 가능성은 거의 없습니다. 참고: 사용자가 작성한 프롬프트로 Chat에서 생성된 커밋 메시지와 전용 커밋 메시지 생성 기능의 정적 프롬프트로 생성된 커밋 메시지는 다를 수 있습니다.

GitLab Duo Chat 설정#

GitLab Duo Chat을 로컬에서 설정하려면 AI 기능에 대한 일반 설정 지침을 따르세요.

GitLab Duo Chat 작업하기#

프롬프트는 GitLab Duo Chat 시스템의 가장 중요한 부분입니다. 프롬프트는 특정 작업을 수행하기 위해 LLM에 전송하는 지시 사항입니다.

현재 프롬프트의 상태는 수 주에 걸친 반복의 결과물입니다. 현재 도구의 프롬프트를 변경하려면 기능 플래그 뒤에 배치해야 합니다.

새로운 프롬프트나 업데이트된 프롬프트가 있다면, 상당한 경험을 갖고 있는 GitLab Duo Chat 팀 구성원에게 리뷰를 요청하세요.

문제 해결#

로컬에서 Chat 작업 중 오류가 발생할 수 있습니다. 가장 일반적인 문제들은 이 섹션에 문서화되어 있습니다. 문서화되지 않은 이슈를 발견한 경우, 해결책을 찾은 후 이 섹션에 문서화해야 합니다.

문제 해결책
GitLab UI에 Chat 버튼이 없습니다. 사용자가 Premium 또는 Ultimate 라이선스를 보유하고 Chat이 활성화된 그룹에 속해 있는지 확인하세요.
Chat이 "Forbidden by auth provider" 오류로 응답합니다. 백엔드가 LLM에 접근할 수 없습니다. AI Gateway가 올바르게 설정되어 있는지 확인하세요.
UI에 요청이 나타나는 데 너무 오래 걸립니다. gdk restart rails-background-jobs를 실행하여 Sidekiq를 재시작하는 것을 고려하세요. 그래도 해결되지 않으면 gdk killgdk start를 시도하세요. 또는 Sidekiq를 완전히 우회할 수 있습니다. 그러려면 Llm::CompletionWorker.perform_async 구문을 임시로 Llm::CompletionWorker.perform_inline으로 변경하세요.
GDK가 non-SaaS 모드로 실행될 때 GitLab UI에 Chat 버튼이 없습니다. 클라우드 커넥터 액세스 토큰 레코드가 없거나 시트가 할당되지 않았습니다. 클라우드 커넥터 액세스 레코드를 생성하려면, rails 콘솔에서 다음 코드를 실행하세요: FactoryBot.create(:cloud_connector_access).

자세한 내용은 Chat이 문제 해결을 돕기 위해 전송하는 GitLab Duo Chat 에러 코드 해석을 참조하세요.

GitLab Duo Chat에 기여하기#

코드 관점에서 Chat은 다른 AI 기능과 유사하게 구현됩니다. GitLab AI 추상화 레이어에 대해 자세히 읽어보세요.

Chat 기능은 사용자 질문과 관련 컨텍스트를 AI Gateway에 전송하는 zero-shot 에이전트를 사용하며, AI Gateway는 프롬프트를 구성하고 대형 언어 모델에 요청을 전송합니다.

대형 언어 모델은 직접 답변할 수 있는지, 아니면 정의된 도구 중 하나를 사용해야 하는지 결정합니다.

각 도구에는 해당 도구를 사용하여 정보를 수집하는 방법을 대형 언어 모델에 제공하는 자체 프롬프트가 있습니다. 도구들은 자급자족적으로 설계되어 대형 언어 모델과의 여러 번 왕복 요청을 피합니다.

도구들이 필요한 정보를 수집한 후, 정보는 zero-shot 에이전트에 반환되며, 에이전트는 사용자의 질문에 최종 답변을 제공하기에 충분한 정보가 수집되었는지 대형 언어 모델에 질의합니다.

새 도구 추가하기#

새 도구를 추가하려면 AI Gateway와 Rails Monolith 모두에 변경 사항을 추가해야 합니다. 주요 chat 프롬프트는 AI Gateway에 저장되고 조합됩니다. Rails 측은 프롬프트의 필요한 파라미터를 조합하여 AI Gateway에 전송하는 역할을 합니다. AI Gateway는 Chat 프롬프트를 조합하고 사용자의 구독 및 애드온에 따라 사용 가능한 Chat 도구를 선택하는 역할을 합니다.

LLM이 사용할 도구를 선택하면, 해당 도구는 Rails 측에서 실행됩니다. 도구들은 AI Gateway에 요청을 보낼 때 다른 엔드포인트를 사용합니다. 새 도구를 추가할 때, AI Gateway는 다양한 버전을 가진 다양한 클라이언트와 GitLab 애플리케이션과 함께 작동한다는 점을 고려해야 합니다. 즉, 이전 버전의 GitLab은 새 도구에 대해 알지 못합니다. 새 도구를 추가하고 싶다면 GitLab Duo Chat 팀에 문의하세요. 저희는 이 문제에 대한 장기적인 해결책을 마련하고 있습니다.

AI Gateway 변경 사항#

  • ai_gateway/chat/tools/gitlab.py에 도구에 대한 새 클래스를 생성합니다. 이 클래스에는 다음 속성들이 포함되어야 합니다:

    name - 도구의 이름

    • 도구가 다루는 GitLab resource

    • 도구가 수행하는 작업에 대한 description

    • 질문과 원하는 답변에 대한 example

  • ai_gateway/chat/tools/gitlab.py__all__ 도구 목록에 도구를 추가합니다.

  • 적절한 Unit Primitive와 함께 ai_gateway/chat/toolset.pyDuoChatToolsRegistry에 도구 클래스를 추가합니다.

  • 변경 사항에 대한 테스트를 추가합니다.

Rails Monolith 변경 사항#

  • ee/lib/gitlab/llm/chain/tools/ 폴더에 도구 파일을 생성합니다. 기존 도구인 issue_reader 또는 epic_reader를 템플릿으로 사용하세요.

  • 도구가 정보를 수집하는 방법에 대한 대형 언어 모델 지시 사항을 포함하는 도구 클래스를 작성합니다 - 이 도구가 사용하는 주요 프롬프트입니다.

  • 대형 언어 모델의 응답을 파싱하여 chat 에이전트에 반환하는 코드를 도구에 구현합니다.

  • 에이전트가 알 수 있도록 ee/lib/gitlab/llm/completions/chat.rbtools 배열에 새 도구 이름을 추가합니다.

통합 테스트#

대형 언어 모델에 실제 요청을 보내는 RSpec 테스트를 사용하여 프롬프트를 테스트하고 반복합니다.

  • 프롬프트는 시행착오가 필요하며, LLM 작업의 비결정론적 특성은 예상치 못한 결과를 초래할 수 있습니다.

  • Anthropic은 프롬프트 작업에 대한 훌륭한 가이드를 제공합니다.

  • 프롬프트 작업에 대한 GitLab 가이드.

핵심은 프롬프트와 도구 설명을 통해 대형 언어 모델에 적절하게 지시하고, 도구가 자급자족적으로 유지되며, 응답이 zero-shot 에이전트에 반환되도록 하는 것입니다. 프롬프트에 대한 시행착오를 통해, 새 도구를 추가함으로써 Chat 기능의 역량을 확장할 수 있습니다.

이 주제를 다루는 짧은 동영상들을 활용할 수 있습니다.

멀티 스레드 대화 작업하기#

GitLab Duo Chat 대화와 상호작용하는 기능을 구축하는 경우, 스레드 작동 방식을 이해해야 합니다.

GitLab Duo Chat은 여러 대화를 지원합니다. 각 대화는 여러 메시지를 포함하는 스레드로 표현됩니다. 스레드의 중요한 속성은 다음과 같습니다:

  • id: id는 스레드에 답글을 달 때 필요합니다.

  • conversation_type: 사용 가능한 다양한 GitLab Duo Chat 대화 유형을 구분할 수 있습니다. 스레드 대화 유형 목록을 참조하세요.

기능에 자체 대화 유형이 필요한 경우, GitLab Duo Chat 팀에 문의하세요.

기능에서 GraphQL API를 직접 호출해야 하는 경우, 다음 쿼리와 뮤테이션을 사용할 수 있으며, 이 때 반드시 conversation_type을 지정해야 합니다.

모든 chat 대화에는 관리자가 제어하는 보존 기간이 있습니다. 기본 보존 기간은 마지막 답글로부터 30일입니다.

개발자 리소스#

디버깅#

전체 요청에 대한 더 많은 인사이트를 얻으려면 Gitlab::Llm::Logger 파일을 사용하여 로그를 디버그하세요. 프로덕션 환경의 기본 로깅 레벨은 INFO이며, 개인 식별 정보가 포함될 수 있는 데이터를 로깅하는 데 사용해서는 안 됩니다.

추상화 레이어의 AI 요청과 관련된 디버깅 메시지를 추적하려면 다음을 사용할 수 있습니다:

export LLM_DEBUG=1
gdk start
tail -f log/llm.log

프로덕션 환경에서 디버깅#

프로덕션 환경에서의 디버깅 및 문제 해결과 관련된 모든 정보는 GitLab Duo Chat On-Call Runbook에 수집되어 있습니다.

LangSmith를 사용한 트레이싱#

트레이싱은 LLM 애플리케이션의 동작을 이해하는 강력한 도구입니다. LangSmith는 최고 수준의 트레이싱 기능을 갖추고 있으며, GitLab Duo Chat과 통합되어 있습니다. 트레이싱은 다음과 같은 문제를 추적하는 데 도움이 됩니다:

  • GitLab Duo Chat이 처음인데 내부에서 무슨 일이 일어나는지 이해하고 싶습니다.

  • 예상치 못한 답변을 받았을 때 어디서 정확히 프로세스가 실패했는지.

  • 어느 프로세스가 지연의 병목 지점이었는지.

  • 모호한 질문에 어떤 도구가 사용되었는지.

트레이싱은 대규모 데이터셋으로 GitLab Duo Chat을 실행하는 평가에 특히 유용합니다. LangSmith 통합은 GitLab Centralized Evaluation Framework(CEF)를 포함한 모든 도구와 함께 작동합니다.

LangSmith로 트레이싱 사용하기#

Tracing is available in Development and Testing environment only.

It's not available in Production environment.

  • LangSmith에 접근하여 계정을 생성합니다.

    Lumos를 통해 접근 권한을 요청하세요.

    • Editor 권한을 위한 접근 요청을 생성하세요 (템플릿: LangSmith_Access_Request).
  • API 키를 생성합니다 (API 키를 어디서 생성하는지 주의하세요 - 개인 네임스페이스 또는 GL 네임스페이스에서 생성할 수 있습니다).

  • GDK에서 다음 환경 변수를 설정합니다.

    gdk.yml에서 정의할 수 있습니다:

# on your gdk.yml
env:
  LANGCHAIN_TRACING_V2: 'true'
  LANGCHAIN_API_KEY: '<your-api-key>'
  LANGCHAIN_PROJECT: '<your-project-name>'
  LANGCHAIN_ENDPOINT: 'https://api.smith.langchain.com'
  GITLAB_RAILS_RACK_TIMEOUT: '180' # Extending puma timeout for using LangSmith with CEF as the evaluation tool.

또는 터미널에서 직접 export합니다:

export LANGCHAIN_TRACING_V2=true
export LANGCHAIN_API_KEY='<your-api-key>'
export LANGCHAIN_PROJECT='<your-project-name>'
export LANGCHAIN_ENDPOINT='https://api.smith.langchain.com'
export GITLAB_RAILS_RACK_TIMEOUT=180 # Extending puma timeout for using LangSmith with CEF as the evaluation tool.

프로젝트 이름은 LangSmith의 기존 프로젝트 또는 새 프로젝트입니다. 환경 변수에 새 이름을 입력하면 충분합니다 - 요청 중에 프로젝트가 생성됩니다.

  • GDK를 재시작합니다.

  • Chat에 질문을 합니다.

  • LangSmith 페이지 > Projects > [프로젝트 이름]에서 프로젝트를 확인합니다. 'Runs' 탭에 최근 요청이 표시되어야 합니다.

LangSmith 트레이스 공유하기 (내부 팀 멤버용)#

웹 브라우저의 전체 URL을 복사하여 팀 멤버와 직접 트레이스 URL을 공유할 수 있습니다. 이는 LangSmith UI에 있는 "share" 트레이스 기능 대신 트레이스를 공유하는 권장 방법입니다. 트레이스를 공개적으로 공유하면 OKTA를 통한 LangSmith 접근 권한이 없는 사람도 링크를 통해 접근할 수 있게 됩니다. 트레이스에는 CI 토큰과 같은 민감한 정보가 포함되어 있습니다.

한 번의 클릭으로 머지 리퀘스트 평가하기#

CEF를 사용하여 머지 리퀘스트를 평가하려면, Evaluation Runner(내부 전용)를 사용할 수 있습니다. 머지 리퀘스트에서 평가 실행 지침을 따르세요.

머지 리퀘스트의 회귀 방지#

GitLab Duo Chat 또는 관련 컴포넌트를 변경할 때, 머지 리퀘스트의 품질 저하와 버그를 감지하기 위해 회귀 평가기를 실행해야 합니다. 도구 실행 및 슬래시 명령을 포함하여 모든 GitLab Duo Chat 실행 패턴을 다룹니다.

회귀 평가기를 실행하려면, 머지 리퀘스트에서 평가를 실행하고 회귀 평가기의 실행 버튼을 클릭하세요. 이후 머지 리퀘스트의 평가 결과를 master와 비교할 수 있습니다. LangSmith 비교 페이지에서 품질 저하와 버그가 없는지 확인하세요.

비교 결과 해석에 대한 엄격한 가이드라인은 없지만, 고려해야 할 몇 가지 유용한 팁이 있습니다:

  • 저하된 점수의 수가 향상된 점수의 수를 초과하는 경우, 머지 리퀘스트가 품질 저하를 일으켰을 수 있습니다.

  • 평가 중에 오류가 발생하는 예시가 있는 경우, 머지 리퀘스트에 잠재적인 버그가 있을 수 있습니다.

이러한 시나리오 중 하나라도 해당한다면, 추가 조사를 권장합니다:

  • 일일 평가 결과와 결과를 비교하세요. 예를 들어, 어제와 그제의 일일 평가를 살펴보세요.

  • 이러한 일일 평가에서 유사한 패턴이 관찰된다면, 머지 리퀘스트를 머지해도 안전할 가능성이 높습니다. 그러나 패턴이 다르다면, 머지 리퀘스트가 예상치 못한 변경을 일으켰을 수 있습니다.

최소한 다음 환경에서 회귀 평가기를 실행할 것을 강력히 권장합니다:

환경 평가 파이프라인 이름
GitLab Self-Managed 및 널리 채택된 커스텀 모델 duo-chat regression sm: [bedrock_mistral_8x7b_instruct]
GitLab.com 및 GitLab Duo Enterprise 애드온 duo-chat regression .com: [duo_enterprise]
GitLab.com 및 GitLab Duo Pro 애드온 duo-chat regression .com: [duo_pro]

또한, 특정 범위에 대한 더 포괄적인 데이터셋을 보유한 gitlab-docs와 같은 다른 평가기를 실행할 수 있습니다. 자세한 내용은 사용 가능한 평가 파이프라인을 참조하세요.

회귀 데이터셋에 예시 추가하기#

새 기능을 도입하거나 사용자로부터 회귀 보고를 받은 경우, 적용 범위를 확장하기 위해 회귀 데이터셋에 새 예시를 추가해야 합니다. 회귀 데이터셋에 예시를 추가하려면 이 섹션을 따르세요.

자세한 내용은 회귀 평가기 가이드라인을 참조하세요.

GitLab Duo Chat Self-managed 엔드 투 엔드 테스트#

머지 리퀘스트에서 엔드 투 엔드 테스트는 AI Gateway의 latest 버전과 통합된 GitLab Linux 패키지 인스턴스를 사용하여 GitLab Self-Managed 인스턴스의 GitLab Duo Chat 기능을 실행합니다. AI Gateway 인스턴스는 목(mock) 응답을 반환하도록 구성됩니다. 테스트 결과를 보려면 e2e:test-on-omnibus-ee 하위 파이프라인을 열고 ai-gateway job을 확인하세요.

ai-gateway job은 클라우드 라이선스를 활성화한 후 테스트 사용자에게 GitLab Duo Pro 시트를 할당하고, 그 다음 테스트가 실행됩니다.

자세한 내용은 AiGateway 시나리오를 참조하세요.

클라이언트 측 관찰 가능성#

Duo Agentic Chat은 모니터링과 분류를 지원하기 위해 클라이언트 측 오류를 Sentry에 보고합니다.

Sentry 오류 캡처#

Sentry를 직접 호출하는 대신 ee/app/assets/javascripts/ai/duo_agentic_chat/observability/sentry_utils.jscaptureExceptionForDuoChat 래퍼를 사용하세요. 이 래퍼는 모든 예외에 feature_category: 'duo_chat' 태그를 자동으로 추가합니다. 호출자는 추가 태그를 추가할 수 있지만 feature_category를 재정의할 수 없습니다.

import { captureExceptionForDuoChat } from '../observability/sentry_utils';

// Report an error with no extra context.
captureExceptionForDuoChat(new Error('Something went wrong'));

// Report an error with extra metadata.
captureExceptionForDuoChat(error, { extra: { info, component: 'MyComponent' } });

프론트엔드에서 Duo Chat 통합하기#

두 가지 공유 Vue 컴포넌트 중 하나를 사용하여 기능에 Duo Chat 통합을 추가할 수 있습니다. 두 컴포넌트 모두 현재 사용자에게 Duo Chat이 사용 가능한지 확인하고, 사용 불가능한 경우 아무것도 렌더링하지 않습니다.

  • DuoChatQuickAction (ee/app/assets/javascripts/ai/shared/widgets/duo_chat_quick_action.vue): Duo Chat을 열고 프롬프트를 전송하는 버튼을 렌더링합니다. 댓글 요약이나 리소스 설명 같은 특정 Duo Chat 작업을 페이지에서 트리거하려는 경우 사용하세요.

  • OpenAgenticChatButton (ee/app/assets/javascripts/ai/shared/widgets/open_agentic_chat_button.vue): 프롬프트를 자동으로 전송하지 않고 특정 에이전트가 미리 선택된 상태로 Duo Chat을 여는 버튼을 렌더링합니다. 커스텀 에이전트와 하나 이상의 프롬프트 제안을 포함한 Duo Chat을 열고 싶을 때 사용하세요.

사전 정의된 프롬프트로 Duo Chat 열기 (DuoChatQuickAction)#

DuoChatQuickAction을 사용하여 Duo Chat을 열고 사전 정의된 프롬프트를 전송하는 버튼을 추가하세요. 이 컴포넌트는 사용자의 현재 chat 모드(Classic 또는 Agentic)를 존중하고 각 모드에 맞는 프롬프트를 전송합니다.

컴포넌트 위치: ee/app/assets/javascripts/ai/shared/widgets/duo_chat_quick_action.vue.

Props#

Prop Type Required Description
buttonText String Yes 버튼에 표시되는 라벨.
resourceId String Yes 리소스의 GraphQL 글로벌 ID (예: gid://gitlab/Issue/1). Duo Chat에 관련 객체의 컨텍스트를 제공하는 데 사용됩니다.
trackingInfo Object Yes 트래킹 메타데이터. 적어도 두 단어를 포함하는 snake_case의 label 키가 필요합니다 (예: { label: 'issue_view_summary' }).
command Object Yes agenticPrompt (Agentic 모드용 자연어 프롬프트) 또는 agent (에이전트 객체)를 포함해야 합니다.
classicQuickAction String No Classic Chat 모드에서 전송할 슬래시 명령 (예: '/summarize_comments'). 기본값은 null입니다.
buttonOptions Object No 기본 GlButton에 전달되는 추가 props (예: { size: 'small' }).

Events#

Event Payload Description
duo-tool-completed { name, args } agentic 도구가 완료될 때 발생합니다. name은 도구 이름이고, args는 도구 출력값입니다.

예시#

// app/assets/javascripts/my_feature/components/my_component.vue
import { DUO_CHAT_QUICK_ACTION_SUMMARIZE, DUO_CHAT_AGENT_PLANNER } from '~/ai/constants';
import { s__ } from '~/locale';

export default {
  name: 'MyComponent',
  components: {
    DuoChatQuickAction: () => import('ee_component/ai/shared/widgets/duo_chat_quick_action.vue'),
  },
  inject: {
    resourceGlobalId: { default: null },
    noteableType: { default: '' },
  },
  computed: {
    summarizeTracking() {
      return { label: 'my_feature_view_summary', property: this.noteableType };
    },
  },
  buttonOptions: { size: 'small' },
  classicQuickAction: DUO_CHAT_QUICK_ACTION_SUMMARIZE,
  summarizeCommand: {
    agent: { name: DUO_CHAT_AGENT_PLANNER },
    agenticPrompt: s__('AI|Summarize the comments on this issue.'),
  },
};
<duo-chat-quick-action
  v-if="resourceGlobalId"
  :button-text="s__('AISummary|View summary')"
  :resource-id="resourceGlobalId"
  :tracking-info="summarizeTracking"
  :classic-quick-action="$options.classicQuickAction"
  :command="$options.summarizeCommand"
  :button-options="$options.buttonOptions"
/>

프롬프트 제안이 있는 Duo Chat 열기 (OpenAgenticChatButton)#

OpenAgenticChatButton을 사용하여 커스텀 에이전트가 미리 선택되고 Duo Agentic Chat의 빈 상태 UI에 표시되는 하나 이상의 프롬프트 제안이 있는 Duo Chat을 여는 버튼을 추가하세요.

컴포넌트 위치: ee/app/assets/javascripts/ai/shared/widgets/open_agentic_chat_button.vue.

Props#

Prop Type Required Description
buttonText String Yes 버튼에 표시되는 라벨.
resourceId String Yes 리소스의 GraphQL 글로벌 ID. 스트리밍 응답을 바인딩하는 데 사용됩니다.
agent Object Yes 미리 선택할 에이전트, 이름으로 식별됩니다 (예: { name: 'My Feature Assistant' }).
welcomeMessage String No 사용자가 타이핑하기 전 빈 상태 패널에 표시되는 메시지.
predefinedPrompts Array No 빈 상태에 표시되는 제안 칩.
buttonOptions Object No 기본 GlButton에 전달되는 추가 props.

Events#

Event Payload Description
tool-completed { name, args } 에이전트의 도구가 완료될 때 발생합니다. name은 도구 이름이고, args는 도구 출력값입니다.

예시: Duo Chat을 사용하여 웹 폼을 채우는 기능 구현#

구현에는 세 가지 부분이 있습니다:

  • 사용자로부터 정보를 수집하고 컴포넌트가 사용할 수 있는 구조화된 데이터를 반환하는 자체 도구가 있는 커스텀 에이전트. 각 에이전트는 자체 도구를 정의해야 합니다 - 공유 범용 도구는 없습니다.

  • 해당 에이전트가 미리 선택되고 몇 가지 프롬프트 제안이 있는 Duo Chat을 여는 버튼.

  • 도구 완료 이벤트를 수신하고 결과를 적용하는 컴포넌트.

Step 1: 도구가 있는 커스텀 에이전트 생성#

duo_workflow_service/agent_platform/v1/flows/configs/ 아래의 AI Gateway 리포지터리에 플로우 구성을 생성합니다. 에이전트에 대한 자체 도구를 정의해야 합니다. 여기서 선택하는 도구 이름이 Step 3에서 프론트엔드에서 수신 대기할 이름입니다.

전체 에이전트 생성 프로세스는 foundational_chat_agents.md를 참조하세요.

Step 2: 컴포넌트에 버튼 추가#

OpenAgenticChatButton을 가져오고 에이전트, 환영 메시지, 사전 정의된 프롬프트를 컴포넌트 수준 상수로 정의합니다.

// ee/app/assets/javascripts/my_feature/components/my_component.vue
import OpenAgenticChatButton from 'ee/ai/shared/widgets/open_agentic_chat_button.vue';
import { convertToGraphQLId } from '~/graphql_shared/utils';
import { TYPENAME_USER } from '~/graphql_shared/constants';
import { s__, __ } from '~/locale';

const AGENT = { name: __('My Feature Assistant') };
const TOOL_NAME = 'my_feature_tool';
const WELCOME_MESSAGE = s__('MyFeature|I can help you configure this feature.');
const PREDEFINED_PROMPTS = [
  s__('MyFeature|Enable read access to repositories.'),
  s__('MyFeature|Set up CI/CD pipeline permissions.'),
];

export default {
  name: 'MyComponent',
  components: { OpenAgenticChatButton },
  computed: {
    resourceId() {
      return convertToGraphQLId(TYPENAME_USER, window.gon?.current_user_id);
    },
  },
  methods: {
    handleToolCompleted({ name, args } = {}) {
      if (name !== TOOL_NAME || !args || typeof args !== 'object') return;

      // Apply the tool output to your component
      this.myField = args.my_field;
    },
  },
  AGENT,
  WELCOME_MESSAGE,
  PREDEFINED_PROMPTS,
};
<open-agentic-chat-button
  :button-text="__('Configure with Duo')"
  :resource-id="resourceId"
  :agent="$options.AGENT"
  :welcome-message="$options.WELCOME_MESSAGE"
  :predefined-prompts="$options.PREDEFINED_PROMPTS"
  @tool-completed="handleToolCompleted"
/>

predefinedPrompts는 chat 패널이 비어 있을 때 제안 칩으로 표시되는 문자열 배열입니다. welcomeMessage를 사용하여 에이전트가 할 수 있는 일을 사용자에게 설명하세요. 둘 다 선택 사항이지만 첫 번째 프롬프트까지의 시간을 줄이기 위해 권장합니다.

Step 3: 도구 완료 이벤트 처리#

에이전트의 도구가 완료되면, OpenAgenticChatButtontool-completed 이벤트를 발생시킵니다. 페이로드는 { name, args } 형태를 가지며, name은 도구 이름이고 args는 도구가 반환한 인수의 객체입니다.

모든 도구 완료가 동일한 이벤트를 통해 브로드캐스트되므로, 페이로드에 따라 작업하기 전에 name이 에이전트 구성에서 정의된 도구 이름과 일치하는지 확인하세요.

const TOOL_NAME = 'my_feature_tool'; // Must match the tool name in your agent config

methods: {
  handleToolCompleted({ name, args } = {}) {
    if (name !== TOOL_NAME || !args || typeof args !== 'object') return;

    // Apply the tool output to your component
    this.myField = args.my_field;
  },
},

이벤트 페이로드의 형태는 다음과 같습니다:

{
  name: 'my_feature_tool', // tool name as defined in your agent config
  args: {
    // fields defined by your tool
    my_field: 'value',
  }
}

완전한 실제 예시는 ee/app/assets/javascripts/personal_access_tokens/components/create_granular_token/ask_dap_permissions.vue를 참조하세요.

알려진 제한 사항#

  • 에이전트는 자체 도구를 구현해야 합니다. AI Catalog 에이전트는 이 패턴에 도구를 공유할 수 없습니다. (ai-assist#2113)

  • 커스텀 질문은 에이전트 YAML에 정의할 수 없으며, 호출하는 컴포넌트에 하드코딩되어야 합니다. (GitLab#594533)

  • 특정 페이지를 위해 생성된 에이전트는 여전히 사이트 전체의 foundational 에이전트로 선택 가능합니다.

  • 스트리밍 응답은 지원되지 않습니다.

  • 에이전트는 기존 폼 필드 값을 읽지 않습니다.

GraphQL 구독#

Chat의 GraphQL 구독은 사용자 중심이기 때문에 약간 다르게 동작합니다. 사용자는 여러 브라우저 탭에서, 또는 IDE에서도 Chat을 열 수 있습니다. 따라서 클라이언트를 동기화 상태로 유지하기 위해 여러 클라이언트에 메시지를 브로드캐스트해야 합니다. chat 액션이 있는 aiAction 뮤테이션은 다음과 같이 동작합니다:

  • 모든 완전한 Chat 메시지(사용자의 메시지 포함)는 userId, aiAction: "chat"을 식별자로 브로드캐스트됩니다.

  • 스트리밍된 Chat 메시지의 청크는 뮤테이션의 clientSubscriptionId를 식별자로 브로드캐스트됩니다.

Vue 컴포넌트에서 GraphQL 구독 예시:

  • 완전한 Chat 메시지
import aiResponseSubscription from 'ee/graphql_shared/subscriptions/ai_completion_response.subscription.graphql';
[...]

apollo: {
 $subscribe: {
   aiCompletionResponse: {
     query: aiResponseSubscription,
     variables() {
       return {
         userId, // for example "gid://gitlab/User/1"
         aiAction: 'CHAT',
       };
     },
     result({ data }) {
       // handle data.aiCompletionResponse
     },
     error(err) {
       // handle error
     },
   },
 },
  • 스트리밍된 Chat 메시지
import aiResponseSubscription from 'ee/graphql_shared/subscriptions/ai_completion_response.subscription.graphql';
[...]

apollo: {
 $subscribe: {
   aiCompletionResponseStream: {
     query: aiResponseSubscription,
     variables() {
       return {
         aiAction: 'CHAT',
         userId, // for example "gid://gitlab/User/1"
         clientSubscriptionId // randomly generated identifier for every message
         htmlResponse: false, // important to bypass HTML processing on every chunk
       };
     },
     result({ data }) {
       // handle data.aiCompletionResponse
     },
     error(err) {
       // handle error
     },
   },
 },

clientSubscriptionId는 모든 요청에 대해 고유해야 합니다. clientSubscriptionId를 재사용하면 구독 응답에 여러 원치 않는 부작용이 발생합니다.

GitLab Duo Chat GraphQL 쿼리#

mutation {
  aiAction(
    input: {
      chat: {
        resourceId: "gid://gitlab/User/1",
        content: "Hello"
      }
    }
  ){
    requestId
    errors
  }
}
  • 다음 쿼리를 실행하여 응답을 가져오세요:
query {
  aiMessages {
    nodes {
      requestId
      content
      role
      timestamp
      chunkId
      errors
    }
  }
}

응답을 가져올 수 없는 경우, graphql_json.log, sidekiq_json.log, llm.log 또는 modelgateway_debug.log에 오류 정보가 포함되어 있는지 확인하세요.

GitLab Duo Chat 대화 스레드 GraphQL 쿼리#

대화 스레드에서 메시지 조회#

특정 스레드에서 메시지를 검색하려면 스레드 ID와 함께 aiMessages 쿼리를 사용하세요:

query {
  aiMessages(threadId: "gid://gitlab/Ai::Conversation::Thread/1") {
    nodes {
      requestId
      content
      role
      timestamp
      chunkId
      errors
    }
  }
}

새 대화 스레드 시작#

aiAction 뮤테이션에 threadId를 포함하지 않으면 새 스레드가 생성됩니다:

mutation {
  aiAction(input: {
    chat: {
      content: "This will create a new conversation thread"
    },
    conversationType: DUO_CHAT
  })
  {
    requestId
    errors
    threadId  # This will contain the ID of the newly created thread
  }
}

기존 대화 스레드에 새 메시지 생성#

기존 스레드에 메시지를 추가하려면 aiAction 뮤테이션에 threadId를 포함하세요:

mutation {
  aiAction(input: {
    chat: {
      content: "this is another message in the same thread"
    },
    conversationType: DUO_CHAT,
    threadId: "gid://gitlab/Ai::Conversation::Thread/1",
  })
  {
    requestId
    errors
    threadId
  }
}

프로덕션과 유사한 환경에서 GitLab Duo Chat 테스트#

GitLab Duo Chat은 StagingStaging Ref GitLab 환경에서 활성화되어 있습니다.

GitLab Duo Chat은 현재 Premium 및 Ultimate 티어 그룹의 구성원에게만 제공되므로, GitLab 팀 멤버에게는 Staging Ref가 변경 사항을 테스트하기 더 쉬운 장소일 수 있습니다. Staging Ref에서 자신을 인스턴스 Admin으로 만들 수 있으므로, Admin으로서 테스트용 라이선스 그룹을 쉽게 생성할 수 있기 때문입니다.

중요한 테스트 고려 사항#

A user who has a seat in multiple groups with different tiers of GitLab Duo add-on gets the highest tier experience across the entire instance.

테스트 계정이 더 높은 티어 애드온의 시트를 가지고 있는 경우, 다양한 GitLab Duo 애드온 간의 기능 분리를 테스트하는 것은 불가능합니다. 다양한 티어를 올바르게 테스트하려면, 테스트할 각 티어마다 별도의 테스트 계정을 생성하세요.

Staging 테스트 그룹#

staging에서의 테스트를 간소화하기 위해, 적절한 라이선스와 애드온이 구성된 여러 사전 설정 그룹이 생성되었습니다:

그룹 GitLab Duo 애드온 GitLab 라이선스
duo_pro_gitlab_premium Pro Premium
duo_pro_gitlab_ultimate Pro Ultimate
duo_enterprise_gitlab_ultimate Enterprise Ultimate

이 그룹에 Owner로 추가되려면 Slack의 #g_duo_chat 채널에 요청하세요. Owner로 추가된 후, 보조 계정을 Developer 권한으로 그룹에 추가하고 GitLab Duo 애드온 시트를 할당할 수 있습니다. 그런 다음 Developer 사용자로 로그인하여 GitLab Duo Chat에 대한 접근 제어를 테스트할 수 있습니다.

라이브 환경에서의 GitLab Duo Chat 엔드 투 엔드 테스트#

GitLab Duo Chat 엔드 투 엔드 테스트는 StagingProduction GitLab 환경에 대해 지속적으로 실행됩니다.

이 테스트들은 예약된 파이프라인에서 실행되며, 엔드 투 엔드 사용자 경험이 올바르게 작동하는지 확인합니다. 결과는 #e2e-run-staging#e2e-run-production Slack 채널에서 볼 수 있습니다. 파이프라인은 아래에서 찾을 수 있으며, #s_developer_experience에서 접근 권한을 요청할 수 있습니다:

제품 분석#

기능이 어떻게 사용되는지 더 잘 이해하기 위해, 각 프로덕션 사용자 입력 메시지는 LLM과 Ruby를 사용하여 분석되며, 분석 결과는 Snowplow 이벤트로 추적됩니다.

분석은 최신 iglu 스키마에 정의된 속성을 포함할 수 있습니다.

  • 카테고리와 상세 카테고리는 제품 관리자와 제품 디자이너에 의해 사전 정의되었습니다. 실제 사용자 질문을 볼 수 없기 때문입니다. 누락되거나 혼란스러운 카테고리가 있다고 판단되면 변경할 수 있습니다. 정의를 편집하려면 AI Gatewaymonolith 모두에서 categories.xml을 업데이트하세요.

  • 캡처되는 속성 목록은 labels.xml에서 찾을 수 있습니다.

다음은 아직 구현되지 않은 것들입니다:

is_proper_sentence

  • 다음은 더 이상 사용되지 않습니다:

number_of_questions_in_history

  • length_of_questions_in_history

  • time_since_first_question

각 질문 카테고리 및 상세 카테고리에 대한 요청 수와 사용자 수는 이 Tableau 대시보드에서 확인할 수 있습니다(GitLab 팀 멤버 전용).

access_duo_classic_chat 정책 작동 방식#

이 표는 다양한 컨텍스트에서 access_duo_classic_chat 정책이 true를 반환하기 위한 요구 사항을 설명합니다.

GitLab.com Dedicated 또는 GitLab Self-Managed 모든 인스턴스
프로젝트 또는 그룹 외부 사용자의 경우 (user.can?(:access_duo_classic_chat)) 사용자는 duo_features_enabled 그룹 설정이 활성화된 Premium 또는 Ultimate 티어의 적어도 하나의 그룹에 속해야 합니다. - 인스턴스가 Premium 또는 Ultimate 티어에 있어야 합니다. - 인스턴스에 duo_features_enabled 설정이 활성화되어 있어야 합니다.
그룹 컨텍스트의 사용자의 경우 (user.can?(:access_duo_classic_chat, group)) - 사용자는 experiment_and_beta_features 그룹 설정이 활성화된 Premium 또는 Ultimate 티어의 적어도 하나의 그룹에 속해야 합니다. - 그룹의 루트 상위 그룹이 Premium 또는 Ultimate 티어에 있고 그룹에 duo_features_enabled 설정이 활성화되어 있어야 합니다. - 인스턴스가 Premium 또는 Ultimate 티어에 있어야 합니다. - 인스턴스에 duo_features_enabled 설정이 활성화되어 있어야 합니다. 사용자는 그룹에 대해 최소한 읽기 권한이 있어야 합니다.
프로젝트 컨텍스트의 사용자의 경우 (user.can?(:access_duo_classic_chat, project)) - 사용자는 experiment_and_beta_features 그룹 설정이 활성화된 Premium 또는 Ultimate 티어의 적어도 하나의 그룹에 속해야 합니다. - 프로젝트의 루트 상위 그룹이 Premium 또는 Ultimate 티어에 있고 프로젝트에 duo_features_enabled 설정이 활성화되어 있어야 합니다. - 인스턴스가 Ultimate 티어에 있어야 합니다. - 인스턴스에 duo_features_enabled 설정이 활성화되어 있어야 합니다. 사용자는 프로젝트에 대해 최소한 읽기 권한이 있어야 합니다.

(Deprecated) 이슈 및 에픽 실험#

This section is deprecated in favor of the [development seed file](/19.1/development/development_seed_files/#seed-project-and-group-resources-for-gitlab-duo).

평가 프레임워크를 사용하려는 경우(평가 문서에 설명된 대로), 이 Rake 작업을 사용하여 필요한 그룹과 프로젝트를 가져올 수 있습니다:

GITLAB_SIMULATE_SAAS=1 bundle exec 'rake gitlab:duo:setup_evaluation[<test-group-name>]'

하위 그룹 가져오기에 필요한 그룹을 생성하기 위해 "saas" 모드가 필요한 Setup 클래스(ee/lib/gitlab/duo/developments/setup.rb 아래)를 사용하기 때문에, GITLAB_SIMULATE_SAAS=1을 설정해야 합니다. 이는 가져오기를 성공적으로 완료하기 위한 것이며, 원하는 경우 이후에 GITLAB_SIMULATE_SAAS=0으로 다시 전환할 수 있습니다.

(Deprecated) 에픽 및 이슈 픽스처#

This section is deprecated in favor of the [development seed file](/19.1/development/development_seed_files/#seed-project-and-group-resources-for-gitlab-duo).

픽스처는 GitLab이 소유한 프로젝트와 그룹의 공개 이슈 및 에픽의 복제본입니다. 샘플링 시 내부 노트는 제외되었습니다. 픽스처는 canonical gitlab 리포지터리에 커밋되어 있습니다. 픽스처를 생성하는 데 사용된 스니펫을 참조하세요.

Chat 프롬프트 구성 방법#

모든 Chat 요청은 GitLab GraphQL API로 처리됩니다. 그리고 현재는 서드파티 LLM을 위한 프롬프트가 GitLab 코드베이스에 하드코딩되어 있습니다.

하지만 Chat 프롬프트를 변경하려는 경우, 단일 파일에서 문자열을 찾는 것만큼 단순하지 않습니다. Chat 프롬프트 구성은 많은 단계를 거쳐 프롬프트가 조합되기 때문에 따라가기 어렵습니다. 다음은 Chat 프롬프트 구성 흐름입니다:

  • GraphQL AI Mutation에 API 요청이 이루어집니다. 요청에는 사용자 Chat 입력이 포함됩니다. (코드)

  • GraphQL 뮤테이션은 Llm::ExecuteMethodService#execute를 호출합니다. (코드)

  • Llm::ExecuteMethodService#executechat 메서드가 GraphQL API로 전송되었음을 감지하고 Llm::ChatService#execute를 호출합니다. (코드)

  • Llm::ChatService#executeLlm::BaseService(ChatService의 기본 클래스)에 정의된 schedule_completion_worker를 호출합니다. (코드)

  • schedule_completion_worker는 job을 비동기적으로 큐에 넣는 Llm::CompletionWorker.perform_for를 호출합니다. (코드)

  • job이 실행될 때 Llm::CompletionWorker#perform이 호출됩니다. 사용자 입력과 기타 메시지 컨텍스트를 역직렬화하여 Llm::Internal::CompletionService#execute로 전달합니다. (코드)

  • Llm::Internal::CompletionService#executeGitlab::Llm::CompletionsFactory#completion!을 호출하고, 원래 GraphQL 요청에서 ai_action을 가져와 Gitlab::Llm::Completions::Chat의 새 인스턴스를 초기화하고 execute를 호출합니다. (코드)

  • Gitlab::Llm::Completions::Chat#executeGitlab::Duo::Chat::ReactExecutor를 호출합니다. (코드)

  • Gitlab::Duo::Chat::ReactExecutor#execute#step_forward를 호출하고, 이는 Gitlab::Duo::Chat::StepExecutor#step을 호출합니다. (코드)

  • Gitlab::Duo::Chat::StepExecutor#stepGitlab::Duo::Chat::StepExecutor#perform_agent_request를 호출하고, AI Gateway /v2/chat/agent/ 엔드포인트에 요청을 전송합니다. (코드)

  • AI Gateway /v2/chat/agent 엔드포인트는 api.v2.agent.chat.agent.chat 함수에서 요청을 받습니다. (코드)

  • api.v2.agent.chat.agent.chatgl_agent_remote_executor_factory를 통해 GLAgentRemoteExecutor를 생성합니다 (코드).

    GLAgentRemoteExecutor 생성 시 다음 파라미터가 전달됩니다:

    tools_registry - 사용 가능한 모든 도구의 레지스트리. 팩토리를 통해 전달됩니다 (코드)

    • agent - 선택된 LLM 모델, 프롬프트 템플릿 등을 포함한 프롬프트 정보를 래핑하는 ReActAgent 객체
  • api.v2.agent.chat.agent.chatGLAgentRemoteExecutor.on_behalf를 호출하며, 오류 발생 시 가능한 한 빨리 예외를 발생시키기 위해 사용자 도구를 미리 가져옵니다 (코드).

  • api.v2.agent.chat.agent.chatGLAgentRemoteExecutor.stream을 호출합니다 (코드).

  • GLAgentRemoteExecutor.stream은 메시지와 사용 가능한 도구 목록과 같은 입력으로 agent(ReActAgent 인스턴스)에서 astream을 호출합니다 (코드).

  • ReActAgent는 사용 가능한 도구를 시스템 프롬프트 템플릿에 삽입하여 프롬프트를 구성합니다 (코드).

  • ReActAgent.astream은 LLM 모델에 호출을 전송합니다 (코드)

  • LLM 응답이 Rails에 반환됩니다 (코드 경로: ReActAgent.astream -> GLAgentRemoteExecutor.stream -> api.v2.agent.chat.agent.chat -> Rails)

  • 이제 AI Gateway에 첫 번째 요청을 완료했습니다. LLM이 첫 번째 요청의 답변이 최종적이라고 판단하면, Rails는 답변을 파싱하고 Gitlab::Llm::Completions::Chat에 의한 추가 응답 처리를 위해 반환합니다.

  • 답변이 최종적이지 않은 경우, 첫 번째 LLM 요청의 "thoughts"와 "picked tools"가 파싱된 다음 관련 도구 클래스가 호출됩니다. (코드 | 도구 클래스 예시)

    도구 실행기 클래스는 Concerns::AiDependent를 포함하고 request 메서드를 사용합니다. (코드)

  • request 메서드는 Llm::Completions::Chatcontext에 주입된 ai_request 인스턴스를 사용합니다. Chat의 경우 이것은 Gitlab::Llm::Chain::Requests::AiGateway입니다. (코드)

  • 도구는 use_ai_gateway_agent_prompt=true를 나타냅니다 (코드).

    이를 통해 ai_request/v1/prompts/chat 엔드포인트에 프롬프트를 전송합니다 (코드).

  • AI Gateway /v1/prompts/chat 엔드포인트는 api.v1.prompts.invoke에서 요청을 받습니다 (코드).

  • api.v1.prompts.invoke는 도구 프롬프트 레지스트리에서 올바른 도구 프롬프트를 가져옵니다 (코드).

  • 프롬프트는 스트림 또는 비스트리밍 호출로 호출됩니다.

  • 도구 답변이 최종적이지 않으면, 응답은 agent_scratchpad에 추가되고 Gitlab::Duo::Chat::ReactExecutor의 루프가 다시 시작되어 요청에 추가 컨텍스트를 더합니다. 최종 답변이 나올 때까지 최대 10번 반복합니다. (코드)

GitLab Duo Chat 에러 코드 해석#

GitLab Duo Chat에는 디버깅을 돕기 위한 지정된 의미를 가진 에러 코드가 있습니다.

모든 GitLab Duo Chat 에러 코드 목록은 GitLab Duo Chat 문제 해결 문서를 참조하세요.

GitLab Duo Chat 개발 시, 오류 반환 시 이러한 에러 코드를 포함하고 특히 사용자 대면 오류의 경우 문서화하세요.

에러 코드 형식#

에러 코드는 <레이어 식별자><네 자리 시리즈 번호> 형식을 따릅니다.

예를 들어:

  • M1001: monolith 레이어의 네트워크 통신 오류.

  • G2005: AI Gateway 레이어의 데이터 형식/처리 오류.

  • A3010: 서드파티 API의 인증 또는 데이터 접근 권한 오류.

에러 코드 레이어 식별자#

코드 레이어
M Monolith
G AI Gateway
A 서드파티 API

에러 시리즈#

시리즈 유형
1000 네트워크 통신 오류
2000 데이터 형식/처리 오류
3000 인증 및/또는 데이터 접근 권한 오류
4000 코드 실행 예외
5000 잘못된 구성 또는 잘못된 파라미터 오류
6000 의미론적 또는 추론 오류 (모델이 이해하지 못하거나 환각을 일으킴)