系列目标 :30 天从 LangChain 入门到企业级部署
今日任务:理解 RAG 评估维度 → 接入 TruLens → 构建自动化评估流水线!
📊 一、为什么需要 RAG 评估?
很多团队部署 RAG 后只做"人工抽查":
- "AI 回答看起来挺对"
- "用户没投诉,应该没问题"
但隐藏风险巨大:
- ❌ 幻觉:编造政策条款
- ❌ 漏检:未召回关键文档
- ❌ 偏差:只引用过时版本
后果:
客服误导客户、员工执行错误流程、法律合规风险......
解决方案:
✅ 系统化评估 ------ 用数据说话,持续优化!
💡 今天,我们就用 TruLens + 自定义规则 + 人工校验 三重机制,构建 RAG 质量看板!
🧪 二、RAG 评估三大核心维度
表格
| 维度 | 说明 | 评估方法 |
|---|---|---|
| 检索质量(Retrieval) | 召回的文档是否相关? | Hit Rate, MRR, Recall@K |
| 生成质量(Generation) | 回答是否准确、无幻觉? | Faithfulness, Answer Relevance |
| 端到端效果(End-to-End) | 用户问题是否被正确解决? | Custom QA Pairs, Human Eval |
🔑 关键指标:
- Faithfulness(忠实度) :回答是否仅基于检索结果?
- Answer Relevance(答案相关性) :是否直接回答用户问题?
- Context Relevance(上下文相关性) :检索结果是否与问题相关?
🛠️ 三、动手实践 1:用 TruLens 自动评估
步骤 1:安装 TruLens
ini
pip install trulens-eval==0.30.0
⚠️ 注意:TruLens 目前对中文支持有限,需配合英文 LLM 或自定义反馈函数。
步骤 2:封装 RAG 应用为 TruLens App
python
# day26_rag_evaluation.py
from trulens_eval import Tru, Feedback, Select
from trulens_eval.feedback import Groundedness, AnswerRelevance, ContextRelevance
from trulens_eval.feedback.provider import OpenAI # 中文可用 Ollama 替代(见下文)
from langchain_ollama import ChatOllama
from langchain_milvus import Milvus
from langchain_ollama import OllamaEmbeddings
from langchain.chains import RetrievalQA
# 初始化 RAG(复用 Day 25)
embeddings = OllamaEmbeddings(model="nomic-embed-text")
vectorstore = Milvus(
embedding_function=embeddings,
connection_args={"host": "localhost", "port": "19530"},
collection_name="company_knowledge"
)
llm = ChatOllama(model="qwen:7b", temperature=0)
rag_chain = RetrievalQA.from_chain_type(
llm=llm,
retriever=vectorstore.as_retriever(k=3)
)
# 封装为 callable
def rag_app(question: str) -> dict:
return rag_chain({"query": question})
步骤 3:定义反馈函数(适配中文)
由于 TruLens 默认依赖 OpenAI,我们自定义中文反馈:
ini
from trulens_eval.feedback import Feedback
from langchain_ollama import ChatOllama
eval_llm = ChatOllama(model="qwen:7b", temperature=0)
# 自定义 Faithfulness(忠实度):回答是否基于上下文?
f_faithfulness = Feedback(
eval_llm.invoke,
name="Faithfulness"
).on_input().on(
Select.RecordCalls.retrieve.call.rets # 检索结果
).on_output() # 回答
# Prompt 模板(中文)
faithfulness_prompt = """
你是一个评估专家。请判断以下回答是否完全基于提供的上下文,没有编造信息。
上下文:
{context}
回答:
{output}
请仅回答"是"或"否"。
"""
# 在实际调用中拼接(简化版)
def custom_faithfulness(input, context, output):
prompt = faithfulness_prompt.format(
context="\n".join([doc.page_content for doc in context]),
output=output
)
response = eval_llm.invoke(prompt).content.strip()
return 1.0 if "是" in response else 0.0
💡 更推荐:直接用规则+关键词匹配(见下节),避免 LLM 评估 LLM 的偏差。
🧮 四、动手实践 2:自定义规则评估(更可靠!)
场景:公司政策问答,有标准答案
python
# 准备测试集(黄金标准)
test_cases = [
{
"question": "员工年假最多多少天?",
"ground_truth": "15天",
"must_contain": ["15", "年假"],
"must_not_contain": ["20", "30"]
},
{
"question": "病假需要提供什么证明?",
"ground_truth": "二级以上医院诊断证明",
"must_contain": ["医院", "证明"]
}
]
def evaluate_rag(rag_chain, test_cases):
results = []
for case in test_cases:
output = rag_chain({"query": case["question"]})["result"]
# 规则1:必须包含关键词
contains_required = all(w in output for w in case.get("must_contain", []))
contains_forbidden = any(w in output for w in case.get("must_not_contain", []))
# 规则2:与标准答案语义相似(可用 Sentence-BERT)
from sentence_transformers import util
emb1 = embeddings.embed_query(output)
emb2 = embeddings.embed_query(case["ground_truth"])
similarity = util.cos_sim(emb1, emb2).item()
score = 1.0 if (contains_required and not contains_forbidden and similarity > 0.7) else 0.0
results.append({
"question": case["question"],
"answer": output,
"score": score,
"similarity": similarity
})
return results
# 执行评估
results = evaluate_rag(rag_chain, test_cases)
for r in results:
print(f"Q: {r['question']}\nA: {r['answer']}\n✅ Pass: {r['score']}\n")
✅ 优势:
- 不依赖额外 LLM
- 可解释性强
- 适合合规/金融等高要求场景
👥 五、动手实践 3:人工评估模板(不可或缺!)
自动化无法覆盖所有场景,需定期人工抽检:
markdown
## RAG 人工评估表
| 问题 | AI 回答 | 检索片段 | 评分(1-5) | 问题类型 |
|------|--------|--------|------------|--------|
| 员工如何申请远程办公? | 需邮件直属领导... | [片段1: 远程办公流程] | 5 | 流程类 |
| 年假能跨年吗? | 可以累计至次年3月 | [片段2: 年假不可跨年] | 1 | 事实错误 |
**评分标准**:
- 5:完全正确,引用准确
- 3:部分正确,有小瑕疵
- 1:错误/幻觉/无关
💡 建议:
- 每周抽样 50 条线上 query
- 标注"问题类型"(事实/流程/数值)
- 计算各类型准确率
📈 六、构建评估流水线(CI/CD 集成)
ini
# eval_pipeline.py
def run_daily_evaluation():
# 1. 加载最新测试集
test_cases = load_test_cases_from_db()
# 2. 运行自动化评估
auto_results = evaluate_rag(rag_chain, test_cases)
# 3. 计算通过率
pass_rate = sum(r["score"] for r in auto_results) / len(auto_results)
# 4. 若 <90%,触发告警
if pass_rate < 0.9:
send_alert(f"RAG 质量下降!当前通过率: {pass_rate:.2%}")
# 5. 保存结果到数据库(供看板展示)
save_evaluation_results(auto_results)
✅ 集成到 GitLab CI / Airflow,实现每日自动质检!
⚠️ 七、注意事项 & 最佳实践
表格
| 陷阱 | 建议 |
|---|---|
| 用同一 LLM 评估自己 | 改用规则/更强模型/人工 |
| 测试集太简单 | 覆盖边界案例(如模糊问、错别字) |
| 忽略检索阶段 | 单独评估 Recall@K(如 80% 问题 Top-3 有答案) |
| 无版本对比 | 保留历史评估结果,监控退化 |
| 只看平均分 | 分维度(事实/流程/数值)统计 |
💡 生产建议:
- 建立"RAG 质量看板"(Grafana)
- 对低分问题自动加入知识库待办
- 新文档入库后触发回归测试
📦 八、配套代码结构
bash
langchain-30-days/
└── day26/
├── rag_eval_trulens.py # TruLens 示例(英文为主)
├── rag_eval_custom_rules.py # 自定义规则评估(推荐)
└── human_eval_template.csv # 人工评估模板
📝 九、今日小结
- ✅ 理解了 RAG 评估的三大维度与核心指标
- ✅ 学会了用 TruLens 做基础自动化评估
- ✅ 掌握了自定义规则评估(更可靠、适合中文)
- ✅ 设计了人工评估模板与抽检流程
- ✅ 构建了可集成 CI/CD 的评估流水线
🎯 明日预告:Day 27 ------ RAG 安全加固!防止提示注入、数据泄露与越权访问!