基于第三方集成的 AI 功能
极狐GitLab Duo 功能由 AI 模型和集成提供支持。本文档概述了在极狐GitLab 中使用 AI 功能进行开发的相关内容。
有关在开发环境中设置极狐GitLab Duo 许可的详细说明,请参阅极狐GitLab Duo 本地开发许可。
设置您的本地开发环境
这里列出了从一台全新的、未安装 GDK 的电脑开始,到完全具备 AI 开发能力所需完成的所有主要步骤。
准备您的 GDK
请按照极狐GitLab 开发套件中的说明,为本地开发目的设置极狐GitLab Duo。这些说明描述了如何在您的本地环境中满足前提条件,并设置核心后端组件。
更新现有的 GDK
如果您已经安装了 GDK,仍然必须参考极狐GitLab 开发套件说明来设置 DAP,包括正确的环境变量、NGINX、您的国内 SOTA 大模型密钥等。
运行 gitlab:duo:setup 任务
运行 gitlab:duo:setup Rake 任务,以播种一个测试群组和一个已启用极狐GitLab Duo 功能的项目。
这可以确保您的实例或群组拥有正确的许可证、设置和功能标志,以便在本地测试极狐GitLab Duo 功能。以下是几种选项。如果您不确定,请使用选项 1。
请务必从极狐GitLab Rails 根目录(通常为 /path/to/gdk/gitlab)运行 Rake 任务,而不是从 GDK 根目录。
-
JihuLab.com 模式
shellGITLAB_SIMULATE_SAAS=1 bundle exec 'rake gitlab:duo:setup'此操作会:
- 创建一个名为 gitlab-duo 的测试群组,其中包含一个名为 test 的项目
- 为该群组应用旗舰版许可证
- 为该群组设置极狐GitLab Duo Enterprise 席位
- 启用该群组的所有功能标志
- 更新群组设置以启用所有可用的极狐GitLab Duo 功能
或者,如果您想为该群组添加极狐GitLab Duo Pro 许可证(仅启用于部分功能),可以运行:
shellGITLAB_SIMULATE_SAAS=1 bundle exec 'rake gitlab:duo:setup[duo_pro]'要仅测试 Duo Core 功能,可以运行:
shellGITLAB_SIMULATE_SAAS=1 bundle exec 'rake gitlab:duo:setup[duo_core]' -
私有化部署模式
shellGITLAB_SIMULATE_SAAS=0 bundle exec 'rake gitlab:duo:setup'此操作会:
- 创建一个名为 gitlab-duo 的测试群组,其中包含一个名为 test 的项目
- 为实例应用旗舰版许可证
- 为实例设置极狐GitLab Duo Enterprise 席位
- 启用实例的所有功能标志
- 更新实例设置以启用所有可用的极狐GitLab Duo 功能
或者,如果您想为实例添加极狐GitLab Duo Pro 附加组件(仅启用于部分功能),可以运行:
shellGITLAB_SIMULATE_SAAS=0 bundle exec 'rake gitlab:duo:setup[duo_pro]'要仅测试 Duo Core 功能,可以运行:
shellGITLAB_SIMULATE_SAAS=0 bundle exec 'rake gitlab:duo:setup[duo_core]'
脚本无错误运行完成后,请转到 gitlab-duo/test,验证您是否能看到极狐GitLab Duo Chat。向 Chat 发送一个问题,确保没有错误。
故障排除
在大多数情况下,您只需运行 AI 服务脚本即可重置 GDK 环境变量,这通常足以修复出现的任何错误。
如果您收到错误 A9999,这是一个通用错误。最常见的原因是未按照 AI Gateway 安装说明中的描述正确设置 AI Gateway URL。 否则,请确保 gitlab-ai-gateway 仓库中的测试通过(使用 make test),并且 gdk tail gitlab-ai-gateway 没有返回错误。
A1003 更多是与权限相关,可能是国内 SOTA 大模型令牌无效/缺失,或者 gcloud 配置错误。
在 Agentic Chat 中,可能会发生身份验证错误,并且不会导致 A1003 错误。使用 gdk tail duo-workflow-service 确保工作流服务正常运行。如果您看到身份验证错误,则需要获取一个新的国内 SOTA 大模型密钥并重新运行 AI 设置脚本。
本地开发技巧
- 当响应在用户界面中显示时间过长时,请考虑通过运行 gdk restart rails-background-jobs 重启 Sidekiq。如果不起作用,请尝试 gdk kill 然后 gdk start。
- 或者,完全绕过 Sidekiq,同步运行服务。这有助于调试错误,因为 GraphQL 错误现在可在网络检查器中查看,而不是在 Sidekiq 日志中。为此,请在 Llm::CompletionWorker 类中临时修改 perform_for 方法,将 perform_async 改为 perform_inline。
- 测试模型选择时,将 export FETCH_MODEL_SELECTION_DATA_FROM_LOCAL=1 添加到您的 env.runit 文件中,这样您的 GDK 将从本地 AI Gateway 而不是云连接的 AIGW 获取模型信息。
功能开发(抽象层)
功能标志
对任何 AI 功能工作应用以下功能标志:
- 一个适用于所有其他 AI 功能的通用标志 (ai_global_switch)。它默认启用。
- 一个特定于该功能的标志。功能标志名称必须不同于许可功能名称。
有关所有功能标志及其使用方法的列表,请参阅功能标志跟踪史诗。
将功能标志推送到 AI Gateway
您可以将功能标志推送到 AI Gateway。这有助于逐步推出面向用户的更改,即使功能驻留在 AI Gateway 中也是如此。 请参阅以下示例:
ruby# 将功能标志状态推送到 AI Gateway。 Gitlab::AiGateway.push_feature_flag(:new_prompt_template, user)
之后,您可以在 AI Gateway 中通过以下方式使用功能标志状态:
python1from ai_gateway.feature_flags import is_feature_enabled 2 3# 检查功能标志“new_prompt_template”是否已启用。 4if is_feature_enabled('new_prompt_template'): 5 # 使用新提示模板构建提示 6else: 7 # 使用旧提示模板构建提示
重要提示:在清理步骤中,请先移除 AI Gateway 仓库中的功能标志,然后再移除 GitLab-Rails 仓库中的标志。 如果先在 GitLab-Rails 仓库中清理标志,AI Gateway 中的功能标志将立即被禁用(因为这是默认状态),从而可能导致意外行为。
重要提示:在 AI Gateway 中清理功能标志会立即将更改分发到所有极狐GitLab 实例,包括 JihuLab.com 和私有化部署。
技术细节:
- 当 push_feature_flag 针对已启用的功能标志运行时,该标志的名称会被缓存在当前上下文中,之后当 GitLab-Sidekiq/Rails 向 AI Gateway 发送请求时,会将其附加到 x-gitlab-enabled-feature-flags HTTP 头中。
- 当前端客户端(例如 LSP)请求 User JWT(UJWT)以进行直接 AI Gateway 通信时,极狐GitLab 会返回:
- 公共头(包括 x-gitlab-enabled-feature-flags)。
- 生成的 UJWT(1 小时过期)。
前端客户端必须在 UJWT 过期时重新生成它。后端更改(例如通过 ChatOps 更新功能标志)会导致头值过时。这些头值将在下次生成 UJWT 时刷新。
同样,我们也有 push_frontend_feature_flag 用于将功能标志推送到前端。
GraphQL API
要使用抽象层连接到 AI 提供商的 API,请使用一个名为 aiAction 的可扩展 GraphQL API。 input 接受键/值对,其中 key 是需要执行的操作。我们每次变更请求只允许一个 AI 操作。
变更示例:
graphqlmutation { aiAction(input: {summarizeComments: {resourceId: "gid://gitlab/Issue/52"}}) { clientMutationId } }
例如,假设我们要构建一个“解释代码”的操作。为此,我们使用一个新键 explainCode 扩展 input。变更如下所示:
graphql1mutation { 2 aiAction( 3 input: { 4 explainCode: { resourceId: "gid://gitlab/MergeRequest/52", code: "foo() { console.log() }" } 5 } 6 ) { 7 clientMutationId 8 } 9}
然后,GraphQL API 使用国内 SOTA 大模型客户端发送响应。
如何接收响应
向 AI 提供商的 API 请求在后台作业中处理。因此,我们不会保持请求处于活动状态,前端需要将请求与来自订阅的响应进行匹配。
要匹配 aiCompletionResponse 订阅上的响应,您可以向 aiAction 变更提供一个 clientSubscriptionId。
- clientSubscriptionId 应在每个功能内和页面内是唯一的,以免干扰其他 AI 功能。我们建议使用 UUID。
- 只有在 aiAction 变更中提供了 clientSubscriptionId 时,才会将其用于广播 aiCompletionResponse。
- 如果未提供 clientSubscriptionId,则 aiCompletionResponse 仅使用 userId 和 resourceId。
以下是一个总结评论的变更示例,我们在变更中提供了一个 randomId:
graphql1mutation { 2 aiAction( 3 input: { 4 summarizeComments: { resourceId: "gid://gitlab/Issue/52" } 5 clientSubscriptionId: "randomId" 6 } 7 ) { 8 clientMutationId 9 } 10}
然后,在我们的组件中,我们使用 userId、resourceId 和 clientSubscriptionId ("randomId") 监听 aiCompletionResponse:
graphql1subscription aiCompletionResponse( 2 $userId: UserID 3 $resourceId: AiModelID 4 $clientSubscriptionId: String 5) { 6 aiCompletionResponse( 7 userId: $userId 8 resourceId: $resourceId 9 clientSubscriptionId: $clientSubscriptionId 10 ) { 11 content 12 errors 13 } 14}
Chat 的订阅行为有所不同。
为了避免同时存在过多并发订阅,您还应该仅在发送变更后通过使用 skip() 来订阅该订阅。
澄清不同的 ID 参数
在使用 aiAction 变更时,有几个 ID 参数用于正确路由请求和响应。以下是每个参数的作用:
- user_id(必需)
- 用途:识别和验证请求用户
- 用于:权限检查、请求归属和响应路由
- 示例:gid://gitlab/User/123
- 注意:此 ID 由 GraphQL API 框架自动包含
- client_subscription_id(推荐用于流式传输或多个功能)
- 客户端生成的 UUID,用于跟踪特定的请求/响应对
- 当使用流式响应或当多个 AI 功能共享同一页面时必需
- 示例:"9f5dedb3-c58d-46e3-8197-73d653c71e69"
- 对于简单的、无流式传输的独立请求,可以省略
- resource_id(上下文相关 - 某些功能必需)
- 用途:引用为 AI 操作提供上下文的特定极狐GitLab 实体(项目、议题、合并请求)
- 用于:权限验证和上下文信息收集
- 实际示例:"gid://gitlab/Issue/164723626"
- 注意:某些功能可能不需要特定资源
- project_id(上下文相关 - 某些功能必需)
- 用途:标识 AI 操作的项目上下文
- 用于:项目特定权限检查和上下文
- 实际示例:"gid://gitlab/Project/278964"
- 注意:某些功能可能不需要特定项目
当前抽象层流程
下图以 VertexAI 为例。您可以使用不同的提供商。
Rendering chart...
为多个模型重用现有 AI 组件
我们努力为每个 LLM 优化 AI 组件,例如提示词、输入/输出解析器、工具/函数调用, 但是,为每个模型分化组件可能会增加维护开销。 因此,通常建议为多个模型重用现有组件,只要这不会降低功能质量即可。 以下是一些经验法则:
- 为多个模型迭代现有的提示词模板。除非对特定模型造成质量下降,否则不要引入新的模板。
- 为多个模型迭代现有的输入/输出解析器和工具/函数调用。除非对特定模型造成质量下降,否则不要引入新的解析器或调用。
- 如果检测到某个特定模型的质量下降,则应为该特定模型分化共享组件。
一个例子是,我们可以将针对国内 SOTA 大模型的特定 CoT 优化应用于其他模型(如 Mixtral),只要这不会导致质量下降。
监控
- 每个 AI 操作的错误率和响应延迟 apdex 可在 Sidekiq Service 仪表板的 SLI Detail: llm_completion 下找到。
- 花费的令牌、每个 AI 功能的使用情况和其他统计信息可在 periscope 仪表板上找到。
- AI Gateway 日志
- AI Gateway 指标
- 通过代理的功能使用仪表板