关于 rag-architect
rag-architect 是用于规划和评估检索增强生成系统的技能。它引导从业者完成向量存储设计、分块、检索和评估,并提供按主题划分的参考指南与实现示例。
主要功能
- 01RAG 需求与架构流程
- 02向量存储和模式设计指导
- 03分块策略设计
- 04混合检索与重排指导
- 05检索评估与迭代
适用场景
- 01选择向量数据库和索引方案
- 02规划文档分块及元数据
- 03设计混合检索和重排
- 04在接入 LLM 前衡量检索质量
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ jeffallan/ claude-skills --skill rag-architect安装后在 Claude Code 中输入/rag-architect确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/chunking-strategies.mdembedding-models.mdrag-evaluation.mdretrieval-optimization.mdvector-databases.md详细介绍
RAG 架构师
核心工作流
- 需求分析 — 明确检索需求、延迟限制、准确率要求和规模
- 向量存储设计 — 选择数据库、设计架构、制定索引策略和分片方案
- 分块策略 — 文档拆分、重叠、语义边界、元数据增强
- 检索流程 — 选择嵌入模型、转换查询、混合搜索、重排序
- 评估与迭代 — 跟踪指标、调试检索、持续优化
每个步骤完成后,都要先验证再继续(参见下方检查点)。
参考指南
根据上下文加载详细指南:
| 主题 | 参考资料 | 加载时机 |
|---|---|---|
| 向量数据库 | references/vector-databases.md | 比较 Pinecone、Weaviate、Chroma、pgvector、Qdrant 时 |
| 嵌入模型 | references/embedding-models.md | 选择嵌入模型、微调或权衡维度时 |
| 分块策略 | references/chunking-strategies.md | 拆分文档、设置重叠或进行语义分块时 |
| 检索优化 | references/retrieval-optimization.md | 进行混合搜索、重排序、查询扩展或筛选时 |
| RAG 评估 | references/rag-evaluation.md | 评估指标、评估框架或检索调试时 |
实现示例
1. 文档分块
from langchain.text_splitter import RecursiveCharacterTextSplitter
# Evaluate chunk_size on your domain data — never use 512 blindly
splitter = RecursiveCharacterTextSplitter(
chunk_size=800,
chunk_overlap=100,
separators=["\n\n", "\n", ". ", " "],
)
chunks = splitter.create_documents(
texts=[doc.page_content for doc in raw_docs],
metadatas=[{"source": doc.metadata["source"], "timestamp": doc.metadata.get("timestamp")} for doc in raw_docs],
)
检查点: assert all(c.metadata.get("source") for c in chunks), "Missing source metadata"
2. 生成嵌入并建立索引
from openai import OpenAI
import qdrant_client
from qdrant_client.models import VectorParams, Distance, PointStruct
client = OpenAI()
qdrant = qdrant_client.QdrantClient("localhost", port=6333)
# Create collection
qdrant.recreate_collection(
collection_name="knowledge_base",
vectors_config=VectorParams(size=1536, distance=Distance.COSINE),
)
def embed_chunks(chunks: list[str], model: str = "text-embedding-3-small") -> list[list[float]]:
response = client.embeddings.create(input=chunks, model=model)
return [r.embedding for r in response.data]
# Idempotent upsert with deduplication via deterministic IDs
import hashlib, uuid
points = []
for i, chunk in enumerate(chunks):
doc_id = str(uuid.UUID(hashlib.md5(chunk.page_content.encode()).hexdigest()))
embedding = embed_chunks([chunk.page_content])[0]
points.append(PointStruct(id=doc_id, vector=embedding, payload=chunk.metadata))
qdrant.upsert(collection_name="knowledge_base", points=points)
检查点: assert qdrant.count("knowledge_base").count == len(set(p.id for p in points)), "Deduplication failed"
3. 混合搜索(向量 + BM25)
from qdrant_client.models import Filter, FieldCondition, MatchValue, SparseVector
from rank_bm25 import BM25Okapi
def hybrid_search(query: str, tenant_id: str, top_k: int = 20) -> list:
# Dense retrieval
query_embedding = embed_chunks([query])[0]
tenant_filter = Filter(must=[FieldCondition(key="tenant_id", match=MatchValue(value=tenant_id))])
dense_results = qdrant.search(
collection_name="knowledge_base",
query_vector=query_embedding,
query_filter=tenant_filter,
limit=top_k,
)
# Sparse retrieval (BM25)
corpus = [r.payload.get("text", "") for r in dense_results]
bm25 = BM25Okapi([doc.split() for doc in corpus])
bm25_scores = bm25.get_scores(query.split())
# Reciprocal Rank Fusion
ranked = sorted(
zip(dense_results, bm25_scores),
key=lambda x: 0.6 * x[0].score + 0.4 * x[1],
reverse=True,
)
return [r for r, _ in ranked[:top_k]]
检查点: assert len(hybrid_search("test query", tenant_id="demo")) > 0, "Hybrid search returned no results"
4. 对前 K 个结果进行重排序
从环境变量或密钥管理器中加载提供商 API 密钥;切勿将其提交到源代码中。
import os
import cohere
co = cohere.Client(os.environ["COHERE_API_KEY"])
def rerank(query: str, results: list, top_n: int = 5) -> list:
docs = [r.payload.get("text", "") for r in results]
reranked = co.rerank(query=query, documents=docs, top_n=top_n, model="rerank-english-v3.0")
return [results[r.index] for r in reranked.results]
5. 检索评估
# Run precision@k and recall@k against a labeled evaluation set
# python evaluate.py --metrics precision@10 recall@10 mrr --collection knowledge_base
from ragas import evaluate
from ragas.metrics import context_precision, context_recall, faithfulness, answer_relevancy
from datasets import Dataset
eval_dataset = Dataset.from_dict({
"question": questions,
"contexts": retrieved_contexts,
"answer": generated_answers,
"ground_truth": ground_truth_answers,
})
results = evaluate(eval_dataset, metrics=[context_precision, context_recall, faithfulness, answer_relevancy])
print(results)
检查点: 在进入大模型集成阶段之前,目标为 context_precision >= 0.7 且 context_recall >= 0.6。
约束
必须做到
- 在确定采用某个嵌入模型前,先使用领域数据评估多个模型
- 在生产系统中实现混合搜索(向量 + 关键词)
- 为多租户或特定领域的检索添加元数据筛选器
- 衡量检索指标(precision@k、recall@k、MRR、NDCG)
- 将上下文传递给大模型前,对前 k 个结果进行重排序
- 实现支持去重的幂等摄取(使用确定性 ID)
- 持续监控检索延迟和质量
- 对嵌入模型进行版本管理,并规划模型迁移
必须避免
- 未使用领域数据评估就采用默认分块大小(512)
- 跳过元数据增强(来源、时间戳、章节)
- 忽视检索质量指标,只关注大模型输出质量
- 未经预处理或清理就存储原始文档
- 在复杂的多领域检索中仅使用余弦相似度
- 未使用接近生产环境规模的数据进行测试就部署
- 忽略边界情况的处理(结果为空、文档格式异常)
- 将嵌入模型与应用代码紧密耦合
输出模板
设计 RAG 架构时,请提供:
- 系统架构图(摄取流程 + 检索流程)
- 向量数据库选择及权衡分析
- 分块策略示例及其理由
- 检索流程设计(查询 → 结果流)
- 评估计划,包括指标、基准和通过/失败阈值
由 @jeffallan 维护;他是 Synergetic Solutions 的首席顾问。
评论
支持 Markdown