系列目标 :30 天从 LangChain 入门到企业级部署
今日任务:暴露 RAG 指标 → 配置 Prometheus 采集 → 构建 Grafana 看板 → 设置智能告警!
📡 一、为什么 RAG 需要监控?
上线后的 RAG 系统如同"黑盒":
- ❌ 用户反馈"变慢了",但不知道哪一环出问题
- ❌ 向量库突然查不到结果,却无告警
- ❌ LLM 响应时间飙升,运维后知后觉
后果:
- 客户流失
- 内部效率下降
- 故障排查耗时数小时
💡 今天,我们就为 RAG 装上"仪表盘"和"警报器" !
🧱 二、RAG 监控四大核心维度
表格
| 维度 | 关键指标 | 作用 |
|---|---|---|
| 1. 可用性 | 请求成功率、错误率 | 系统是否活着? |
| 2. 性能 | P50/P95 延迟(Embedding/检索/生成) | 用户体验如何? |
| 3. 质量 | 检索命中率、空结果率 | 回答准不准? |
| 4. 资源 | CPU/GPU、内存、QPS | 是否需要扩容? |
✅ 所有指标通过 Prometheus 采集,Grafana 可视化
🛠️ 三、动手实践 1:在 FastAPI 中暴露指标
步骤 1:安装依赖
pip install prometheus-client starlette-prometheus
步骤 2:集成指标埋点
python
# day29_rag_monitoring.py
from prometheus_client import Counter, Histogram, start_http_server
from starlette_prometheus import PrometheusMiddleware
from fastapi import FastAPI, Request
import time
app = FastAPI()
# 启动 Prometheus 指标端点(默认 /metrics)
start_http_server(8001) # 单独端口,避免业务干扰
app.add_middleware(PrometheusMiddleware)
# 自定义指标
REQUEST_COUNT = Counter("rag_requests_total", "Total RAG requests", ["status"])
LATENCY_EMBEDDING = Histogram("rag_embedding_seconds", "Embedding generation latency")
LATENCY_RETRIEVE = Histogram("rag_retrieve_seconds", "Vector retrieval latency")
LATENCY_GENERATE = Histogram("rag_generate_seconds", "LLM generation latency")
EMPTY_RESULT_COUNT = Counter("rag_empty_results_total", "Count of empty retrieval results")
@app.post("/rag")
async def rag_api(request: Request):
query = (await request.json())["query"]
try:
# 1. Embedding
with LATENCY_EMBEDDING.time():
emb = embeddings.embed_query(query)
# 2. 检索
with LATENCY_RETRIEVE.time():
docs = vectorstore.similarity_search_by_vector(emb, k=3)
if not docs:
EMPTY_RESULT_COUNT.inc()
raise ValueError("未找到相关文档")
# 3. 生成
context = "\n".join([d.page_content for d in docs])
with LATENCY_GENERATE.time():
answer = llm.invoke(f"根据内容回答:{context}\n\n问题:{query}").content
REQUEST_COUNT.labels(status="success").inc()
return {"answer": answer}
except Exception as e:
REQUEST_COUNT.labels(status="error").inc()
raise
✅ 指标自动暴露于
http://localhost:8001/metrics
📈 四、动手实践 2:配置 Prometheus 采集
创建 prometheus.yml
yaml
# prometheus.yml
global:
scrape_interval: 15s
scrape_configs:
- job_name: "rag-service"
static_configs:
- targets: ["host.docker.internal:8001"] # 若用 Docker
启动 Prometheus(Docker)
bash
docker run -d \
--name=prometheus \
-p 9090:9090 \
-v $(pwd)/prometheus.yml:/etc/prometheus/prometheus.yml \
prom/prometheus
✅ 访问
http://localhost:9090查看指标
🖥️ 五、动手实践 3:构建 Grafana 看板
步骤 1:启动 Grafana
css
docker run -d --name=grafana -p 3000:3000 grafana/grafana
步骤 2:配置数据源
- 登录
http://localhost:3000(admin/admin) - Add data source → Prometheus → URL:
http://host.docker.internal:9090
步骤 3:导入/创建看板
关键 Panel 查询示例:
表格
| 面板 | Prometheus 查询 |
|---|---|
| 请求速率 | rate(rag_requests_total[5m]) |
| 成功率 | rate(rag_requests_total{status="success"}[5m]) / rate(rag_requests_total[5m]) |
| P95 延迟(总) | histogram_quantile(0.95, sum(rate(rag_embedding_seconds_bucket[5m])) by (le)) + ... |
| 空结果率 | rate(rag_empty_results_total[5m]) / rate(rag_requests_total[5m]) |
💡 可导出 JSON 模板复用(文末提供)
🔔 六、动手实践 4:设置智能告警
在 Prometheus 中配置告警规则
yaml
# alert.rules.yml
groups:
- name: rag-alerts
rules:
- alert: HighErrorRate
expr: rate(rag_requests_total{status="error"}[5m]) / rate(rag_requests_total[5m]) > 0.1
for: 2m
labels:
severity: warning
annotations:
summary: "RAG 错误率过高 ({{ $value | humanizePercentage }})"
- alert: HighLatency
expr: histogram_quantile(0.95, rate(rag_generate_seconds_bucket[5m])) > 2.0
for: 5m
labels:
severity: critical
annotations:
summary: "LLM 生成延迟过高 (P95 > 2s)"
- alert: EmptyResultsSpiking
expr: rate(rag_empty_results_total[5m]) > 0.5 # 每分钟 >30 次空结果
for: 3m
labels:
severity: warning
annotations:
summary: "检索空结果激增,可能知识库缺失"
更新 prometheus.yml 引入规则:
makefile
rule_files:
- "alert.rules.yml"
配置 Alertmanager(通知到企业微信/钉钉)
yaml
# alertmanager.yml
route:
receiver: 'dingtalk'
receivers:
- name: 'dingtalk'
webhook_configs:
- url: 'http://your-dingtalk-bot-url' # 替换为实际 webhook
✅ 支持邮件、Slack、飞书、企业微信等
📊 七、高级监控:业务质量指标
除了技术指标,还需监控业务效果:
csharp
# 在评估流水线(Day 26)中增加指标
from prometheus_client import Gauge
RAG_ACCURACY = Gauge("rag_accuracy_score", "Daily automated accuracy score")
def run_daily_eval():
score = evaluate_rag_accuracy() # 来自 Day 26
RAG_ACCURACY.set(score)
if score < 0.85:
# 触发自定义告警(或写入日志供 Prometheus 采集)
logger.error("RAG 准确率低于阈值!")
💡 将 准确率、忠实度 纳入监控体系,实现"技术+业务"双视角
⚠️ 八、注意事项 & 最佳实践
表格
| 问题 | 建议 |
|---|---|
| 指标爆炸 | 只采集关键路径,避免高基数标签 |
| 延迟计算不准 | 使用 Histogram 而非 Summary |
| 告警疲劳 | 设置合理阈值 + 持续时间(for) |
| 本地开发无 Docker | 用 host.docker.internal 或直接 localhost |
| 敏感信息泄露 | /metrics 接口加鉴权(Nginx Basic Auth) |
💡 生产建议:
- 每个微服务独立指标前缀(如
rag_service_)- 保留 30 天指标数据
- 每周 Review 告警有效性
📦 九、配套资源
bash
langchain-30-days/
└── day29/
├── rag_with_metrics.py # 带埋点的 FastAPI 服务
├── prometheus.yml # 采集配置
├── alert.rules.yml # 告警规则
└── grafana-dashboard.json # 看板模板(可导入)
🔗 点击下载 Grafana 看板模板(示例 ID)
📝 十、今日小结
- ✅ 理解了 RAG 监控的四大核心维度
- ✅ 学会了用 Prometheus Client 埋点
- ✅ 配置了 Prometheus 采集 与 Grafana 可视化
- ✅ 设置了 错误率、延迟、空结果 三大关键告警
- ✅ 将 业务质量指标 纳入监控体系
🎯 明日预告:Day 30 ------ 终章!RAG 项目打包部署:Docker + CI/CD + 文档,交付企业级解决方案!