使用公开的 Terraform 模块 将 LangSmith 部署到 Azure。将部署作为代码进行管理,让您可以在不同订阅间对 LangSmith 环境进行版本控制、审查和复现,而无需在 Azure 门户中手动点击操作。 安装分两个阶段运行:
  1. 基础设施:Terraform 配置 AKS、PostgreSQL、Redis、Blob 存储、Key Vault、cert-manager、KEDA 和入口控制器。
  2. 应用程序:Helm 在集群上安装 LangSmith chart。
基础安装完成后,通过设置标志并重新部署,启用三个可选附加组件(LangSmith 部署、Agent Builder 以及 Insights 和 Polly)。

前提条件

所需工具

所需的 Azure RBAC

运行 Terraform 的身份在订阅上需要以下角色: Owner 角色包含以上两者。仅拥有 Contributor 权限是不够的,因为角色分配需要 User Access Administrator。

身份验证

您还需要一个 LangSmith 许可证密钥(联系销售),以及一个 dns_label(Azure 子域名,无需 DNS 配置)或自定义的 langsmith_domain。

快速入门

关于 make 目标、必需变量和常见约束的简明速查表,请参见 Azure 快速参考。
从零开始到运行 LangSmith 实例的最快路径:
或者一步完成步骤 5 到 7:
以下部分将详细说明每个阶段。

配置基础设施

Terraform 配置以下 Azure 资源:

克隆并配置

所有后续命令均在 modules/azure/ 目录下运行。运行 make help 可查看完整目标列表。 使用交互式向导生成 terraform.tfvars:
向导会运行一个包含 10 个部分的问题集,涵盖配置文件、订阅、命名、网络、AKS 规模、入口控制器、DNS/TLS、后端服务、Key Vault、规模配置文件和安全附加组件。每个部分都包含解释性背景信息、成本估算和权衡分析。重新运行是安全的;每个提示处都会预选现有值。按 Enter 键即可保留它们。 如果偏好手动编辑:
最低必需值:
集群内 ClickHouse 作为单个 Pod 运行,无复制或备份,仅适用于开发/概念验证。生产环境请使用 LangChain 托管 ClickHouse。
无论部署层级如何,Blob 存储始终是必需的。跟踪数据负载必须存储到 Azure Blob,绝不能存储到 ClickHouse。
所有变量请参见 Azure 变量参考。

引导密钥

setup-env.sh 会将内容写入 infra/secrets.auto.tfvars(已加入 gitignore,权限为 chmod 600)。Terraform 会自动读取此文件;无需在 shell 中导出。
  • 首次运行: 会提示输入 PostgreSQL 密码、LangSmith 许可证密钥、管理员密码和管理员电子邮件。会在本地生成 api_key_salt、jwt_secret 和四个 Fernet 加密密钥。
  • 后续运行: 会从 Azure Key Vault 读取六个生成的密钥(api_key_salt、jwt_secret 和四个 Fernet 密钥)。除非环境中设置了 LANGSMITH_PG_PASSWORD、LANGSMITH_LICENSE_KEY、LANGSMITH_ADMIN_PASSWORD 和 LANGSMITH_ADMIN_EMAIL,否则会重新提示输入 PostgreSQL 密码、许可证密钥、管理员密码和管理员电子邮件。
切勿提交 secrets.auto.tfvars。它已加入 gitignore。在任何机器上运行 make setup-env 即可重新生成。

预检

验证 Azure CLI 身份验证、活动订阅、11 个必需的资源提供程序、RBAC(Contributor + User Access Administrator)、terraform.tfvars 和 secrets.auto.tfvars 是否存在,以及 terraform/kubectl/helm 是否在 PATH 中。

应用

在新的订阅上配置 Azure 云基础需要 15 到 20 分钟。请勿中断应用过程。
首次部署时跳过 make plan。kubernetes_manifest 资源在 plan 阶段需要活动的集群 API,但该 API 尚不存在。make apply 会通过三个内部阶段处理资源顺序:Azure 基础设施(包括 AKS)→ Kubernetes 引导(命名空间、密钥、cert-manager、KEDA)→ ClusterIssuer 和其余清单。

集群凭据和 Kubernetes 密钥

make apply 完成后,获取集群凭据并将密钥推送到集群:
make k8s-secrets 从 Key Vault 读取 8 个密钥,并创建或更新 langsmith-config-secret。可以安全地重新运行;它使用 --dry-run=client | kubectl apply 来原地更新。

验证基础设施

部署 LangSmith

使用两种受支持的部署路径之一:

Helm 路径(推荐)

生成 Helm 值

make init-values 读取 terraform output 和 terraform.tfvars,并生成包含所有已填充字段的 helm/values/values-overrides.yaml:
  • config.hostname,您的 FQDN(来自 dns_label 或 langsmith_domain)。
  • config.initialOrgAdminEmail,第一个组织管理员账户。
  • config.existingSecretName: langsmith-config-secret,密钥引用。
  • config.blobStorage,存储账户名称 + 容器 + 工作负载标识客户端 ID。
  • 8 个 ServiceAccount 的工作负载标识注解(backend, platform-backend, queue, ingest-queue, host-backend, listener, agent-builder-tool-server, agent-builder-trigger-server)。
  • Ingress + TLS 配置块(cert-manager 注解、TLS 密钥名称)。
  • PostgreSQL 和 Redis 外部密钥引用(当 postgres_source = "external" / redis_source = "external" 时)。
还会将规模配置覆盖和任何启用的附加组件覆盖从 helm/values/examples/ 复制到 helm/values/。
管理员电子邮件读取自 terraform.tfvars 中的 langsmith_admin_email(在 make setup-env 期间设置),并自动写入 values-overrides.yaml。无需手动编辑。

部署

make deploy 执行以下操作:
  1. 验证 values-overrides.yaml 是否存在。
  2. 通过 az aks get-credentials 刷新 kubeconfig。
  3. 使用 service.beta.kubernetes.io/azure-dns-label-name 对 LoadBalancer 服务进行注解,这是 Azure 将 DNS 标签分配给公共 IP 所必需的。
  4. 如果 tls_certificate_source = "letsencrypt",则创建 letsencrypt-prod cert-manager ClusterIssuer(幂等操作)。
  5. 运行预检(工具、集群连接性、Helm 仓库)。
  6. 验证 langsmith-config-secret 是否存在;如果缺失,则从 Key Vault 自动创建。
  7. 构建并记录值链。
  8. 在继续之前,自动恢复任何卡在 pending-upgrade 状态的 Helm 发布。
  9. 运行 helm upgrade --install langsmith langchain/langsmith --timeout 20m。
  10. 等待核心部署完成滚动更新。
  11. 使用工作负载标识客户端 ID 对 langsmith-ksa ServiceAccount 进行注解。
  12. 打印访问 URL 和登录凭据位置。
为什么是 --timeout 20m?langsmith-backend-auth-bootstrap Job 作为安装后钩子运行数据库迁移和组织初始化。首次安装时最多需要 5 分钟。如果没有较长的超时时间,即使安装最终成功,Helm 也可能报告失败。
在另一个终端监视 Pod:
如果您已完成 Helm 路径,请跳至 验证部署。以下的 Terraform 路径是 Helm 路径的替代方案,而非额外步骤。

Terraform 路径

当您希望 Helm 发布、Kubernetes 密钥和工作负载标识 ServiceAccount 由 Terraform 状态管理时,使用此路径。
app/terraform.tfvars 中的功能标志:
通过 Terraform 端到端部署(基础设施 + 应用程序):

验证部署

预期的 Pod 状态(约 5 分钟后全部为 Running):
打开 https://<HOSTNAME> 并使用来自 Key Vault 的管理员电子邮件和密码登录:

值链

make deploy 按以下顺序应用 Helm 值文件(最后的文件在冲突时生效):
helm/values/ 中的所有文件都已加入 gitignore(是生成的或包含实时密钥)。源模板位于 helm/values/examples/ 中,由 make init-values 复制。

日常运维

启用附加组件

每个附加组件都受 infra/terraform.tfvars 中的一个标志控制。设置该标志,重新运行 make init-values 以重新生成值,然后重新运行 make deploy。

LangSmith 部署

启用 LangSmith 部署,这使您可以直接从 LangSmith UI 部署和管理代理作为 API 服务器。这会增加三个新的 Pod。

先扩展节点池

在启用之前,将 default_node_pool_min_count 至少增加到 5。operator 会按需生成代理部署 Pod,并需要节点余量:
如果节点容量不足,operator 生成的代理 Pod 将无限期保持 Pending 状态。请先扩展节点池,然后再启用。

应用、重新生成值、部署

make init-values 将 LangSmith 部署附加组件覆盖 (langsmith-values-agent-deploys.yaml) 追加到值链中。它会自动注入:
config.deployment.url 必须包含 https://。 缺少协议会导致 operator 部署的代理无限期卡在 DEPLOYING 状态。该 URL 由 make init-values 自动注入。不要在覆盖文件中手动设置;下次运行时会被覆盖。
config.deployment.enabled: true 是必需的。 仅设置 config.deployment.url 而没有 enabled: true 会导致 chart 静默跳过创建 listener 和 operator。不会报错,它们永远不会出现。

验证

预期:langsmith-host-backend、langsmith-listener 和 langsmith-operator 全部为 Running。Pod 总数:约 20 个 Running + 3 个 Completed 的 Job。 KEDA 已随基础设施一同安装。启用 enable_deployments = true 后,operator 会为每个代理部署的工作队列创建 KEDA ScaledObject 资源。工作 Pod 在空闲时缩放至零,并根据 Redis 队列深度进行扩展。

Agent Builder

提供从 LangSmith UI 对 LangGraph 代理进行可视化的 AI 辅助创建和管理。无需运行 terraform apply;只需执行 make init-values && make deploy。 前提条件: 已启用 LangSmith 部署(enable_deployments = true)。在未启用的情况下启用 Agent Builder 会导致预检错误。 启用:
make init-values 将 Agent Builder 附加组件覆盖 (langsmith-values-agent-builder.yaml) 追加到值链中。该覆盖启用 Agent Builder UI 及其支持服务,设置 backend.agentBootstrap.enabled: true(注册 Agent Builder 为 LangSmith 部署并创建所需 ConfigMap 的安装后 Job),并设置保守的代理工作 Pod 资源(1 到 2 CPU,512 MiB 到 1 GiB 内存),而不是 chart 默认的 4 到 8 GiB 内存。 验证:
预期:3 个静态 Pod(tool-server, trigger-server, bootstrap Job)+ 4 个动态 Pod。总计:约 26 个 Pod。执行 make deploy 后,LangSmith UI 导航中会出现 Agent Builder 部分。
在 agentBootstrap 完成后重启前端。 agentBootstrap Job 会创建前端读取 Polly UI 所需的 langsmith-polly-config ConfigMap。如果前端在 bootstrap 完成时正在运行,Polly 会显示“无法连接到 LangGraph 服务器”。修复方法:
加密密钥从 langsmith-config-secret 读取。 不要在 values-overrides.yaml 中内联设置 config.agentBuilder.encryptionKey。Chart 通过 existingSecretName 从 langsmith-config-secret 读取它。内联设置会覆盖密钥引用并导致不匹配。
langsmith-agent-builder-tool-server 和 langsmith-agent-builder-trigger-server 都需要工作负载标识来访问 Azure Blob 存储。它们的联合凭据已在 modules/k8s-cluster/main.tf 中预注册;无需额外设置。

Insights 和 Polly

两个功能,都需要 LangSmith 部署。它们彼此独立;可以只启用其中一个。
  • Insights: AI 驱动的跟踪分析(Clio)。揭示 LangSmith 跟踪中的模式和异常。Clio 在首次 UI 调用时通过 operator 部署为动态的 LangGraph 部署。不添加新的静态 Pod。
  • Polly: AI 驱动的评估和监控代理。作为动态的 LangGraph 部署运行,由 operator 管理。该覆盖启用 Polly(顶层 polly.enabled: true);operator 管理其资源。
无需运行 terraform apply;只需执行 make init-values && make deploy。
启用其中一个:
make init-values 根据 terraform.tfvars 中的 clickhouse_source 追加附加组件覆盖:
  • clickhouse_source = "in-cluster",生成一个最小覆盖(仅顶层 insights.enabled: true)。Helm chart 在内部管理 ClickHouse。
  • clickhouse_source = "external",生成一个包含 clickhouse.external.enabled: true 和 langsmith-clickhouse 密钥引用的完整覆盖。部署前请使用 ClickHouse 主机和凭据创建此密钥。
对于集群内 ClickHouse,请勿手动复制 Insights 示例文件。 示例文件 helm/values/examples/langsmith-values-insights.yaml 包含 clickhouse.external.enabled: true 和 existingSecretName: langsmith-clickhouse。在使用集群内 ClickHouse 时手动复制它会导致 CreateContainerConfigError,因为该密钥不存在。始终使用 make init-values 生成正确的文件。
验证:
加密密钥在首次启用后绝不能更改。 insights_encryption_key 和 polly_encryption_key 在首次启用后绝不能更改。更改其中任何一个都会永久损坏所有现有加密数据。无法恢复。这些密钥存储在 Key Vault 中,永远不会自动轮换。
在首次启用 Polly 后重启前端。 如果启用后 Polly UI 显示“无法连接到 LangGraph 服务器”,则是因为前端在 bootstrap ConfigMap 准备好之前就已启动。修复方法:

附加组件摘要

入口控制器

在 make apply 之前,在 terraform.tfvars 中设置 ingress_controller。完整的 TLS 兼容性矩阵,请参见 Azure 模块仓库 中的 INGRESS_CONTROLLERS.md。
letsencrypt(HTTP-01)仅适用于 nginx、istio(自托管)和 envoy-gateway。istio-addon 不会创建 IngressClass,因此 ACME 求解器无法接收流量。使用 agic 时,Application Gateway 会重写 ACME 挑战路径,导致 HTTP-01 求解器失败。对于这两种情况,请使用带有自定义域名的 dns01,或对于仅 HTTP 场景使用 none。

DNS 和 TLS

dns_label 为您提供一个免费的 Azure 子域名 <label>.<region>.cloudapp.azure.com,无需域名注册或 DNS 区域。deploy.sh 会自动对正确的 LoadBalancer 服务进行注解。 快速入门默认值(HTTP,零配置):
使用 Let’s Encrypt 添加 HTTPS(nginx、自托管 istio 或 envoy-gateway):
自定义域名 + DNS-01(适用于所有控制器,可在防火墙后工作):
dns01 流程:
  1. make apply 创建 Azure DNS 区域并输出 4 个名称服务器。
  2. 在您的域名注册商处,为子域名添加指向这 4 个名称服务器的 NS 记录。
  3. 验证:dig NS langsmith.mycompany.com @8.8.8.8。
  4. make deploy 通过 DNS-01 自动颁发证书(工作负载标识将 TXT 记录写入 Azure DNS)。
  5. 获取负载均衡器 IP,将 ingress_ip = "<ip>" 添加到 terraform.tfvars,然后运行 make apply(创建 A 记录)。
  6. make status 会准确显示每个阶段需要添加的 NS 和 A 记录。
为什么是 NS 记录而不是 CNAME: cert-manager 必须向区域写入 TXT 记录以证明所有权。这要求 Azure DNS 对该子域具有权威性,而 NS 授权授予了该权限。CNAME 只是对流量的别名,不转移 DNS 权限;DNS-01 挑战会失败。

后续步骤