Langchain-Chatchat 结合 Prometheus 实现 AI 服务可观测性

在企业级人工智能应用日益普及的今天,一个突出的矛盾逐渐显现:我们拥有了强大的本地化大模型能力,却常常“看不见”它的运行状态。尤其是在部署像 Langchain-Chatchat 这类集成了文档解析、向量检索和语言生成的复杂系统时,一旦出现响应延迟或服务中断,运维人员往往只能依赖用户反馈来被动响应。

这正是监控体系的价值所在。当我们将 Langchain-Chatchat 与 Prometheus 深度集成后,原本“黑盒”的 AI 服务变得透明可测——你能实时看到每秒有多少问答请求、GPU 显存是否接近阈值、某个提示词模板是否引发了异常延迟。这种从“感知问题”到“定位问题”的跃迁,正是现代 AIOps 的核心追求。

Langchain-Chatchat 本质上是一个基于 RAG(检索增强生成)架构的本地知识库系统。它允许企业在完全离线的环境中构建专属智能助手,尤其适用于金融、医疗等对数据安全要求极高的场景。其工作流程涵盖了文档加载、文本分块、向量化编码、相似性检索以及最终的回答生成。整个链条涉及多个组件协同工作,任何一个环节的性能波动都可能影响用户体验。

比如,在一次实际部署中,某企业的政策问答机器人突然变慢。初步排查并未发现 CPU 或内存占用异常,但通过 Prometheus 监控却发现 chatchat_request_duration_seconds 中的 P95 值飙升至 8 秒以上。进一步下钻发现,瓶颈并不在 LLM 推理阶段,而是出现在向量数据库的检索过程。原因很快被锁定:新上传的一批 PDF 文件含有大量扫描图像,OCR 解析后产生了冗余文本,导致索引膨胀。若无细粒度指标支撑,这类问题很难快速定位。

为了实现这样的可观测性,我们需要在 Langchain-Chatchat 服务中主动暴露关键指标。Python 生态下的 prometheus_client 库为此提供了轻量级解决方案。以下是一段典型的集成代码:

from prometheus_client import start_http_server, Counter, Histogram, Gauge
import time
import threading

# 定义核心监控指标
REQUEST_COUNT = Counter(
    'chatchat_requests_total', 
    'Total number of ChatChat API requests',
    ['method', 'endpoint']
)

REQUEST_DURATION = Histogram(
    'chatchat_request_duration_seconds',
    'Request latency in seconds',
    ['endpoint'],
    buckets=(0.1, 0.5, 1.0, 2.5, 5.0, 10.0)
)

GPU_MEMORY_USAGE = Gauge(
    'gpu_memory_used_mb',
    'Current GPU memory usage in MB'
)

ERROR_COUNT = Counter(
    'chatchat_errors_total',
    'Total number of errors in processing',
    ['type']
)

# 启动独立线程采集 GPU 使用情况
def monitor_gpu():
    try:
        import pynvml
        pynvml.nvmlInit()
        handle = pynvml.nvmlDeviceGetHandleByIndex(0)
        while True:
            mem_info = pynvml.nvmlDeviceGetMemoryInfo(handle)
            GPU_MEMORY_USAGE.set(mem_info.used / 1024 / 1024)  # 转换为 MB
            time.sleep(5)
    except Exception as e:
        pass  # 无 GPU 环境下静默处理

# 在服务启动时开启指标服务器
start_http_server(8000)
threading.Thread(target=monitor_gpu, daemon=True).start()

# 在实际处理逻辑中记录指标
def handle_question(question: str):
    REQUEST_COUNT.labels(method='POST', endpoint='/ask').inc()

    with REQUEST_DURATION.labels(endpoint='/ask').time():
        try:
            time.sleep(0.8)  # 模拟处理耗时
            return "这是一个测试回答。"
        except Exception as e:
            ERROR_COUNT.labels(type=type(e).__name__).inc()
            raise

这段代码不仅展示了如何定义计数器、直方图和仪表类指标,更体现了工程实践中的几个关键考量:

  • 直方图桶的选择 需结合业务预期。例如将 5 秒作为关键阈值之一,是因为大多数用户对超过该时长的响应会明显感知卡顿;
  • GPU 监控线程设为守护模式,确保主服务退出时不会因子线程阻塞而无法关闭;
  • 错误计数按异常类型分类,有助于区分是外部输入错误还是内部资源不足;
  • 所有监控逻辑均不阻塞主线程,避免因指标采集拖累服务性能。

这些指标随后会被 Prometheus 主动拉取。典型的配置如下:

scrape_configs:
  - job_name: 'chatchat'
    static_configs:
      - targets: ['langchain-chatchat-host:8000']

Prometheus 每隔 15 秒访问一次目标实例的 /metrics 接口,获取当前状态并存入其内置的时间序列数据库(TSDB)。相比传统的推模式监控工具(如 Zabbix),这种拉取机制更适合云原生环境,尤其便于与容器编排平台集成。

采集到的数据可通过 PromQL 进行灵活查询。例如:

# 计算过去5分钟内的平均QPS
rate(chatchat_requests_total[5m])

# 查看P95延迟
histogram_quantile(0.95, sum(rate(chatchat_request_duration_seconds_bucket[5m])) by (le))

# 检测CUDA内存溢出趋势
increase(chatchat_errors_total{type="CUDAOutOfMemory"}[1h])

这些查询结果可进一步导入 Grafana,构建出直观的可视化仪表盘。一张典型的监控面板通常包含以下几个维度:

  • 请求流量:展示 QPS 趋势,识别高峰时段;
  • 响应延迟分布:使用热力图或直方图呈现不同区间的请求占比;
  • 错误率变化:叠加显示各类异常的增长情况;
  • 资源使用:包括 GPU 显存、CPU 利用率、内存占用等系统级指标。

更重要的是,我们可以基于这些数据设置智能告警规则。例如:

groups:
  - name: chatchat.rules
    rules:
      - alert: HighLatency
        expr: histogram_quantile(0.95, rate(chatchat_request_duration_seconds_bucket[5m])) > 5
        for: 3m
        labels:
          severity: warning
        annotations:
          summary: "高延迟告警"
          description: "Chatchat 服务 P95 延迟已持续3分钟超过5秒"

这条规则意味着:如果连续三次采样(即 45 秒内)的 P95 延迟均高于 5 秒,则触发告警。之所以设定“for 3m”,是为了避免瞬时抖动造成误报,体现了告警设计中的稳定性思维。

当然,在落地过程中也需注意一些常见陷阱。最典型的是“高基数问题”——如果给指标添加过多标签(如把 user_id 或完整 URL 作为标签),会导致时间序列数量爆炸式增长,严重影响 Prometheus 的存储与查询性能。因此建议:

  • 标签应仅用于具有有限取值集合的维度,如 method, endpoint, error_type
  • 避免使用连续变量或唯一标识符作为标签;
  • 定期审查指标命名规范,统一前缀(如 chatchat_)以防止冲突。

另一个容易被忽视的点是安全性。默认暴露的 /metrics 接口可能泄露系统信息,因此在生产环境中应通过反向代理限制访问来源,或启用 Basic Auth 认证。对于高度敏感的环境,甚至可以考虑仅在内网开放该端口,并通过 VPC 内部网络完成抓取。

从架构上看,完整的监控链路如下所示:

+------------------+       +---------------------+
|   用户客户端      |<----->| Langchain-Chatchat   |
| (Web / API)      |       | - Flask/FastAPI      |
|                  |       | - LangChain pipeline |
+------------------+       | - Embedding & LLM    |
                           | - /metrics endpoint  |
                           +----------+-----------+
                                      |
                                      | HTTP Pull
                                      v
                           +----------+-----------+
                           |   Prometheus Server  |
                           | - Scrapes /metrics   |
                           | - Stores TSDB        |
                           | - Runs alerts        |
                           +----------+-----------+
                                      |
                                      | Query
                                      v
                           +----------+-----------+
                           |     Grafana           |
                           | - Dashboards          |
                           | - Visualizations      |
                           +-----------------------+

在这个体系中,Langchain-Chatchat 不再只是一个“能用”的问答系统,而是成为一个具备自我诊断能力的智能服务节点。每一次提问都被转化为可分析的数据点,每一次性能波动都有迹可循。

展望未来,随着更多企业将 LLM 技术融入日常运营,这种“智能服务 + 专业监控”的组合将成为标配。我们不仅要让 AI “会说话”,更要让它“能体检”。只有这样,才能真正实现从实验性项目到生产级系统的跨越。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐