Langfuse

  • 简要说明

    • 官方文档 https://langfuse.com/docs,不懂问AI助手 https://langfuse.com/docs/ask-ai
    Langfuse 是一个开源的可观测性和分析平台,专为由大型语言模型(LLM)驱动的应用而设计。我们的使命是帮助开发人员和组织构建并改进 LLM 应用程序。为此,我们通过先进的跟踪和分析模块深入了解模型的成本、质量和延迟

10.1 架构及组件

  • 介绍如下

    • v3架构
    • 组件说明
    # 主要容器
    Langfuse Web: 提供UI界面和API服务的主要Web应用
    Langfuse Worker: 异步处理事件的worker
    # 存储组件
    Postgres: 用于事务性工作负载的主数据库
    Redis: 用于队列和缓存操作的内存数据存储
    S3/Blob Store: 用于持久化存储传入事件、多模态输入和大型导出的对象存储
    Clickhouse: 用于存储追踪、观察和评分的高性能OLAP数据库
    • 组件要求
    # 版本要求
    Postgres: 至少需要12版本
    Redis: 至少需要7版本,必须配置maxmemory-policy=noeviction
    S3: 需要兼容S3的blob存储
    # 配置要求(生产)
    所有容器至少配置2 CPU和4GB RAM
    Langfuse Web容器至少部署两个实例以实现高可用
    当CPU使用率超过50%时进行自动扩容
    • v2架构

10.2 环境变量说明

  • 主要环境变量及其含义【可以选择性地配置这些变量】

    • 数据库相关
    # DATABASE_URL (必需)
    PostgreSQL数据库的连接字符串
    # DIRECT_URL
    用于数据库迁移的 PostgreSQL 连接字符串,默认值为 DATABASE_URL 的值
    如果你在 DATABASE_URL 上使用连接池,则需要为迁移设置单独的 DIRECT_URL
    对于大型部署,建议为数据库用户配置较长的超时时间,因为迁移可能需要较长时间完成
    # SHADOW_DATABASE_URL
    当数据库用户缺少 CREATE DATABASE 权限时必须配置此变量,用于创建一个影子数据库用于数据库迁移操作
    • 认证相关
    # NEXTAUTH_URL (必需)
    部署URL,如https://yourdomain.com
    # NEXTAUTH_SECRET (必需)
    用于验证登录会话cookie,用于对JWT令牌进行签名的随机字符串
    # SALT (必需)
    用于API密钥的哈希处理
    设置要求:必须使用至少256位熵的随机字符串,可以通过以下命令生成: openssl rand -base64 32
    # ENCRYPTION_KEY (必需)
    用于加密敏感数据的密钥,用于加密敏感数据
    用途包括:1、加密存储在 Langfuse 中的 LLM API 凭证 2、加密集成凭证(例如 PostHog)
    设置要求:必须是256位(64个字符)的十六进制格式,可以通过命令生成: openssl rand -hex 32
    • 基础配置
    # PORT (必需)
    服务器监听端口,默认3000
    # HOSTNAME (必需)
    默认值为 localhost,生产环境中需要设置为 0.0.0.0 才能从容器外部访问
    # LANGFUSE_CSP_ENFORCE_HTTPS
    默认值为 false,当设置为 true 时,会设置 CSP (Content Security Policy) 头,只允许 HTTPS 连接
    • 组织和项目配置
    # LANGFUSE_DEFAULT_ORG_ID
    为新用户配置默认组织ID
    # LANGFUSE_DEFAULT_ORG_ROLE
    用户在默认组织中的角色,可选值为 OWNER, ADMIN, MEMBER, VIEWER
    # LANGFUSE_DEFAULT_PROJECT_ID
    为新用户配置默认项目
    # LANGFUSE_DEFAULT_PROJECT_ROLE
    用户在默认项目中的角色,可选值为 OWNER, ADMIN, MEMBER, VIEWER
    # 以使用 LANGFUSE_INIT_* 环境变量来自动初始化这些资源,也可再界面中再配置
    LANGFUSE_INIT_ORG_ID
    LANGFUSE_INIT_ORG_NAME
    LANGFUSE_INIT_PROJECT_ID
    LANGFUSE_INIT_PROJECT_NAME
    # 公钥以 lf_pk_ 开头,私钥以 lf_sk_ 开头
    LANGFUSE_INIT_PROJECT_PUBLIC_KEY
    LANGFUSE_INIT_PROJECT_SECRET_KEY
    LANGFUSE_INIT_USER_EMAIL
    LANGFUSE_INIT_USER_NAME 
    LANGFUSE_INIT_USER_PASSWORD
    • 邮件配置
    # smtp://username:password@smtp.server.com:port?tls.rejectUnauthorized=false
    # 当用户名是邮箱地址时,需要对特殊字符@进行URL编码为%40,其他处包含特殊字符一样处理
    SMTP_CONNECTION_URL: SMTP服务器连接配置
    EMAIL_FROM_ADDRESS: 发件人地址
    • S3存储配置
    # 事件上传配置
    LANGFUSE_S3_EVENT_UPLOAD_BUCKET: 存储事件信息的桶名称(必需)1
    LANGFUSE_S3_EVENT_UPLOAD_PREFIX: 在桶内存储事件的子路径前缀,默认为桶根目录。如果提供,必须以 / 结尾
    LANGFUSE_S3_EVENT_UPLOAD_REGION: 存储桶所在的区域
    LANGFUSE_S3_EVENT_UPLOAD_ENDPOINT: 用于上传事件的终端节点
    LANGFUSE_S3_EVENT_UPLOAD_ACCESS_KEY_ID: 访问密钥,必须具有List、Get和Put权限
    LANGFUSE_S3_EVENT_UPLOAD_SECRET_ACCESS_KEY: 访问密钥的密码
    LANGFUSE_S3_EVENT_UPLOAD_FORCE_PATH_STYLE: 是否强制使用路径样式请求,MinIO需要
    # 媒体上传配置
    LANGFUSE_S3_MEDIA_UPLOAD_ENABLED: 是否启用S3媒体上传功能,默认为false
    LANGFUSE_S3_MEDIA_UPLOAD_BUCKET: 存储媒体文件的桶名称(必需)
    LANGFUSE_S3_MEDIA_UPLOAD_PREFIX: 在桶内存储媒体的子路径前缀,默认为桶根目录。如果提供,必须以 / 结尾
    LANGFUSE_S3_MEDIA_UPLOAD_REGION: 存储桶所在的区域
    LANGFUSE_S3_MEDIA_UPLOAD_ENDPOINT: 用于上传媒体文件的终端节点
    LANGFUSE_S3_MEDIA_UPLOAD_ACCESS_KEY_ID: 访问密钥,必须具有List、Get和Put权限
    LANGFUSE_S3_MEDIA_UPLOAD_SECRET_ACCESS_KEY: 访问密钥的密码
    LANGFUSE_S3_MEDIA_UPLOAD_FORCE_PATH_STYLE: 是否强制使用路径样式请求,MinIO需要此设置
    • 日志配置
    LANGFUSE_LOG_LEVEL: 日志级别,可选trace/debug/info/warn/error/fatal
    LANGFUSE_LOG_FORMAT: 日志格式,可选text/json
    • 其他配置
    TELEMETRY_ENABLED:用于报告基本的使用统计信息,默认true
    LANGFUSE_ENABLE_EXPERIMENTAL_FEATURES: 特性标志(feature flag)被启用,用户可以访问实验性功能
    LANGFUSE_AUTO_POSTGRES_MIGRATION_DISABLED: 设置为true禁用自动数据库迁移
    DB_EXPORT_PAGE_SIZE: 用于调整流式导出到S3时的页面大小,以避免内存问题。默认值为 1000,可以根据需要调整页面大小以优化性能

10.3 Kubernetes&v2

  • 操作说明

    • 本节主要介绍如何在 Kubernetes 集群中交付 Langfuse v2 版本
    • 由于 v3 版本正处于频繁开发迭代中,所以生产环境交付暂不建议
    • v2 相对于 v3 部署相对简单,只涉及到 postgress 。v3 版本架构做了很大调整,拆分出很多组件
    • 如何交付到 kubernetes 集群可以参考官方文档
    https://github.com/Hkanfshujian/langfuse-k8s/tree/main/examples

10.3.1 Secret

  • 操作如下

    • 在官方给出的示例中,使用的是ConfigMap,这里更推荐使用 Secret 的方式

    • secrets_langfuse.yaml

    apiVersion: v1
    kind: Secret
    metadata:
    name: dify-credentials
    namespace: dify
    data:
    # 注意:所有配置项值需转成base64编码格式
    # check Base64 online https://base64.us/ 
    # NEXTAUTH_SECRET hukanfa688
    langfuse-nextauth-secret: aHVrYW5mYTY4OA==
    # SALT openssl rand -base64 32 随机生成: sDPU5Qyqg4K24jbs1iuLdL864SR2rHMkvzDBEVB2a1c=
    langfuse-salt: c0RQVTVReXFnNEsyNGpiczFpdUxkTDg2NFNSMnJITWt2ekRCRVZCMmExYz0=
    type: Opaque

10.3.2 Deployment

  • 操作如下

    • 本示例在官方原基础上额外增加了滚动部署策略、资源限制、健康检查接口等配置

    • deployment_langfuse.yaml

    apiVersion: apps/v1
    kind: Deployment
    metadata:
    name: dify-langfuse
    namespace: dify
    spec:
    replicas: 1
    selector:
      matchLabels:
        app: langfuse
    strategy:
      rollingUpdate:
        maxSurge: 50%
        maxUnavailable: 0
      type: RollingUpdate
    template:
      metadata:
        labels:
          app: langfuse
      spec:
        imagePullSecrets:
        - name: public-docker-registry
        containers:
          - name: dify-langfuse
            image: registry.xxx.com/langfuse:2
            imagePullPolicy: Always
            env:
              - name: NODE_ENV
                value: 'production'
              - name: HOSTNAME
                value: '0.0.0.0'
              - name: DATABASE_URL
                valueFrom:
                  secretKeyRef:
                    name: dify-credentials
                    key: langfuse-db-url
              - name: NEXTAUTH_URL
                value: 'https://langfuse.xxx.com'
              - name: NEXTAUTH_SECRET
                valueFrom:
                  secretKeyRef:
                    name: dify-credentials
                    key: langfuse-nextauth-secret
              - name: SALT
                valueFrom:
                  secretKeyRef:
                    name: dify-credentials
                    key: langfuse-salt
              - name: TELEMETRY_ENABLED
                value: 'true'
              - name: NEXT_PUBLIC_SIGN_UP_DISABLED
                value: 'false'
              - name: LANGFUSE_ENABLE_EXPERIMENTAL_FEATURES
                value: 'false'
            ports:
              - name: http
                containerPort: 3000
            resources:
              requests:
                cpu: 200m
                memory: 256Mi
              limits:
                cpu: 1000m
                memory: 1Gi
            startupProbe:
              httpGet:
                port: http
                path: /api/public/health
              failureThreshold: 60
              periodSeconds: 10
            livenessProbe:
              httpGet:
                port: http
                path: /api/public/health
              periodSeconds: 10
              failureThreshold: 60
            readinessProbe:
              httpGet:
                port: http
                path: /api/public/ready
              periodSeconds: 10
              failureThreshold: 60 
    
    ---
    
    apiVersion: v1
    kind: Service
    metadata:
    name: dify-langfuse
    namespace: dify
    spec:
    selector:
      app: langfuse
    ports:
      - protocol: TCP
        port: 3000
        targetPort: 3000
    type: ClusterIP
    clusterIP: None

10.3.3 配置默认组织和项目

  • 操作如下

    • 通过前面步骤运行项目后,访问https://langfuse.xxx.com先注册一个账号,其将被视为管理员用户
    • 注意,并不是第一个注册的账号就是管理员账号。而是通过后续设置一些限制后,新建的账号将受到一定限制限制
    • 使用新建的账号创建默认组织和默认项目,之后到数据库中查询相应的组织id和项目id
    select * from organizations 
    select * from projects
    • 最后在deployment_langfuse.yaml 中加入以下环境变量即可
              - name: LANGFUSE_DEFAULT_ORG_ID
                value: 'cm4grf68e0001mlh0eynntd1v'
              - name: LANGFUSE_DEFAULT_ORG_ROLE
                value: 'VIEWER'
              - name: LANGFUSE_DEFAULT_PROJECT_ID
                value: 'cm4grfstq0006mlh0dhp2xegt'
              - name: LANGFUSE_DEFAULT_PROJECT_ROLE
                value: 'VIEWER'
    • 后续如有新用户注册,将自动归属到默认的组织和项目,并且只拥有给定的 VIEWER 权限

10.3.4 配置邮件

  • 操作如下

    • 邮件这块配置主要用于忘记登陆密码时,可以通过邮件找回
    • secrets_langfuse.yaml 新增邮件配置
    # SMTP_CONNECTION_URL 用户名是邮箱则@符号需转成url编码为%40,链接 smtp://example%40xxx.com:Ql123456@smtp.xxx.com:587?tls.rejectUnauthorized=false
    langfuse-smtp-url: c210cDovL2V4YW1wbGUlNDB4eHguY29tOlFsMTIzNDU2QHNtdHAueHh4LmNvbTo1ODc/dGxzLnJlamVjdFVuYXV0aG9yaXplZD1mYWxzZQ==
    # EMAIL_FROM_ADDRESS 发件人 example@xxx.com
    langfuse-smtp-sender: ZXhhbXBsZUB4eHguY29t
    • deployment_langfuse.yaml 新增邮件配置
              - name: EMAIL_FROM_ADDRESS
                valueFrom:
                  secretKeyRef:
                    name: dify-credentials
                    key: langfuse-smtp-sender
              - name: SMTP_CONNECTION_URL
                valueFrom:
                  secretKeyRef:
                    name: dify-credentials
                    key: langfuse-smtp-url
    • 推送邮件如下图所示