{"id":"rag-architect","name":"rag-architect","summary":"文書のチャンク化、埋め込み生成、ベクターストアの設定、ハイブリッド検索パイプラインの構築、リランク付けの適用、検索品質の評価を通じて、本番レベルのRAGシステムを設計・実装します。","body":"# RAG Architect\n\n## Core Workflow\n\n1. **Requirements Analysis** — Identify retrieval needs, latency constraints, accuracy requirements, and scale\n2. **Vector Store Design** — Select database, schema design, indexing strategy, sharding approach\n3. **Chunking Strategy** — Document splitting, overlap, semantic boundaries, metadata enrichment\n4. **Retrieval Pipeline** — Embedding selection, query transformation, hybrid search, reranking\n5. **Evaluation & Iteration** — Metrics tracking, retrieval debugging, continuous optimization\n\nFor each step, validate before moving on (see checkpoints below).\n\n## Reference Guide\n\nLoad detailed guidance based on context:\n\n| Topic | Reference | Load When |\n|-------|-----------|-----------|\n| Vector Databases | `references/vector-databases.md` | Comparing Pinecone, Weaviate, Chroma, pgvector, Qdrant |\n| Embedding Models | `references/embedding-models.md` | Selecting embeddings, fine-tuning, dimension trade-offs |\n| Chunking Strategies | `references/chunking-strategies.md` | Document splitting, overlap, semantic chunking |\n| Retrieval Optimization | `references/retrieval-optimization.md` | Hybrid search, reranking, query expansion, filtering |\n| RAG Evaluation | `references/rag-evaluation.md` | Metrics, evaluation frameworks, debugging retrieval |\n\n## Implementation Examples\n\n### 1. Chunking Documents\n\n```python\nfrom langchain.text_splitter import RecursiveCharacterTextSplitter\n\n# Evaluate chunk_size on your domain data — never use 512 blindly\nsplitter = RecursiveCharacterTextSplitter(\n    chunk_size=800,\n    chunk_overlap=100,\n    separators=[\"\\n\\n\", \"\\n\", \". \", \" \"],\n)\n\nchunks = splitter.create_documents(\n    texts=[doc.page_content for doc in raw_docs],\n    metadatas=[{\"source\": doc.metadata[\"source\"], \"timestamp\": doc.metadata.get(\"timestamp\")} for doc in raw_docs],\n)\n```\n\n**Checkpoint:** `assert all(c.metadata.get(\"source\") for c in chunks), \"Missing source metadata\"`\n\n### 2. Generating Embeddings & Indexing\n\n```python\nfrom openai import OpenAI\nimport qdrant_client\nfrom qdrant_client.models import VectorParams, Distance, PointStruct\n\nclient = OpenAI()\nqdrant = qdrant_client.QdrantClient(\"localhost\", port=6333)\n\n# Create collection\nqdrant.recreate_collection(\n    collection_name=\"knowledge_base\",\n    vectors_config=VectorParams(size=1536, distance=Distance.COSINE),\n)\n\ndef embed_chunks(chunks: list[str], model: str = \"text-embedding-3-small\") -> list[list[float]]:\n    response = client.embeddings.create(input=chunks, model=model)\n    return [r.embedding for r in response.data]\n\n# Idempotent upsert with deduplication via deterministic IDs\nimport hashlib, uuid\n\npoints = []\nfor i, chunk in enumerate(chunks):\n    doc_id = str(uuid.UUID(hashlib.md5(chunk.page_content.encode()).hexdigest()))\n    embedding = embed_chunks([chunk.page_content])[0]\n    points.append(PointStruct(id=doc_id, vector=embedding, payload=chunk.metadata))\n\nqdrant.upsert(collection_name=\"knowledge_base\", points=points)\n```\n\n**Checkpoint:** `assert qdrant.count(\"knowledge_base\").count == len(set(p.id for p in points)), \"Deduplication failed\"`\n\n### 3. Hybrid Search (Vector + BM25)\n\n```python\nfrom qdrant_client.models import Filter, FieldCondition, MatchValue, SparseVector\nfrom rank_bm25 import BM25Okapi\n\ndef hybrid_search(query: str, tenant_id: str, top_k: int = 20) -> list:\n    # Dense retrieval\n    query_embedding = embed_chunks([query])[0]\n    tenant_filter = Filter(must=[FieldCondition(key=\"tenant_id\", match=MatchValue(value=tenant_id))])\n    dense_results = qdrant.search(\n        collection_name=\"knowledge_base\",\n        query_vector=query_embedding,\n        query_filter=tenant_filter,\n        limit=top_k,\n    )\n\n    # Sparse retrieval (BM25)\n    corpus = [r.payload.get(\"text\", \"\") for r in dense_results]\n    bm25 = BM25Okapi([doc.split() for doc in corpus])\n    bm25_scores = bm25.get_scores(query.split())\n\n    # Reciprocal Rank Fusion\n    ranked = sorted(\n        zip(dense_results, bm25_scores),\n        key=lambda x: 0.6 * x[0].score + 0.4 * x[1],\n        reverse=True,\n    )\n    return [r for r, _ in ranked[:top_k]]\n```\n\n**Checkpoint:** `assert len(hybrid_search(\"test query\", tenant_id=\"demo\")) > 0, \"Hybrid search returned no results\"`\n\n### 4. Reranking Top-K Results\n\nLoad provider API keys from environment variables or a secrets manager; never commit them to source code.\n\n```python\nimport os\n\nimport cohere\n\nco = cohere.Client(os.environ[\"COHERE_API_KEY\"])\n\ndef rerank(query: str, results: list, top_n: int = 5) -> list:\n    docs = [r.payload.get(\"text\", \"\") for r in results]\n    reranked = co.rerank(query=query, documents=docs, top_n=top_n, model=\"rerank-english-v3.0\")\n    return [results[r.index] for r in reranked.results]\n```\n\n### 5. Retrieval Evaluation\n\n```python\n# Run precision@k and recall@k against a labeled evaluation set\n# python evaluate.py --metrics precision@10 recall@10 mrr --collection knowledge_base\n\nfrom ragas import evaluate\nfrom ragas.metrics import context_precision, context_recall, faithfulness, answer_relevancy\nfrom datasets import Dataset\n\neval_dataset = Dataset.from_dict({\n    \"question\": questions,\n    \"contexts\": retrieved_contexts,\n    \"answer\": generated_answers,\n    \"ground_truth\": ground_truth_answers,\n})\n\nresults = evaluate(eval_dataset, metrics=[context_precision, context_recall, faithfulness, answer_relevancy])\nprint(results)\n```\n\n**Checkpoint:** Target `context_precision >= 0.7` and `context_recall >= 0.6` before moving to LLM integration.\n\n## Constraints\n\n### MUST DO\n- Evaluate multiple embedding models on your domain data before committing\n- Implement hybrid search (vector + keyword) for production systems\n- Add metadata filters for multi-tenant or domain-specific retrieval\n- Measure retrieval metrics (precision@k, recall@k, MRR, NDCG)\n- Use reranking for top-k results before passing context to LLM\n- Implement idempotent ingestion with deduplication (deterministic IDs)\n- Monitor retrieval latency and quality over time\n- Version embeddings and plan for model migration\n\n### MUST NOT DO\n- Use default chunk size (512) without evaluation on your domain data\n- Skip metadata enrichment (source, timestamp, section)\n- Ignore retrieval quality metrics in favor of only LLM output quality\n- Store raw documents without preprocessing/cleaning\n- Use cosine similarity alone for complex multi-domain retrieval\n- Deploy without testing on production-like data volumes\n- Forget to handle edge cases (empty results, malformed docs)\n- Couple the embedding model tightly to application code\n\n## Output Templates\n\nWhen designing RAG architecture, deliver:\n1. System architecture diagram (ingestion + retrieval pipelines)\n2. Vector database selection with trade-off analysis\n3. Chunking strategy with examples and rationale\n4. Retrieval pipeline design (query → results flow)\n5. Evaluation plan with metrics, benchmarks, and pass/fail thresholds\n\n[Documentation](https://jeffallan.github.io/claude-skills/skills/data-ml/rag-architect/)","author":"@Jeffallan","ownerProfile":null,"authorContacts":null,"sourceUrl":"https://github.com/Jeffallan/claude-skills/tree/main/skills/rag-architect","license":"MIT","category":"document","lang":"en","tokens":1626,"stars":0,"calls30d":2,"claimed":false,"visibility":"public","origin":"crawler","version":"0.1.0","createdAt":"2026-08-22","updatedAt":"2026-08-22","files":[{"path":"references/chunking-strategies.md","size":25083,"sha256":"1b732310ebf7b5e64c5abef46b13a11614f1c3dc331c214389f2643504a9a809"},{"path":"references/embedding-models.md","size":15330,"sha256":"a840774bb2f5a635f454ccf7f2e9da72725552382ebf2a2b412b0d578f6bb8c8"},{"path":"references/rag-evaluation.md","size":24288,"sha256":"de20bdaa8180b00bdd931dd79870926f747de4dafc1c0a66a64609293a8131e0"},{"path":"references/retrieval-optimization.md","size":21922,"sha256":"caca467d9b0b2b0d3beba5e77f3333bd23f05c971a5dc101084293aa3d66df86"},{"path":"references/vector-databases.md","size":14257,"sha256":"2782da946dee97da4dfa796aaee62852a7d0b92b8d713a7d8350fb7733ab63cc"}],"requires":{"mcp":[],"tools":[]},"safety":{"flags":[{"code":"code.eval","kind":"dangerous-code","where":"references/chunking-strategies.md:737","excerpt":"eval(","message":"evaluates code at runtime","severity":"warn"}],"scannedAt":"2026-08-22","hasScripts":false,"networkEndpoints":["jeffallan.github.io","your-cluster.qdrant.io","your-cluster.weaviate.network"]}}