mirror of
https://github.com/BagelHole/DevOps-Security-Agent-Skills.git
synced 2026-08-22 12:49:53 +02:00
Add 12 AI infrastructure and LLM operations skills
New skills covering hot-topic AI engineering subjects: Local AI Infrastructure: - vllm-server: High-throughput LLM serving with PagedAttention, tensor parallelism, quantization - llm-inference-scaling: KEDA-based GPU autoscaling for LLM inference on Kubernetes - rag-infrastructure: Production RAG with hybrid search, reranking, and embedding pipelines - llm-fine-tuning: QLoRA/LoRA fine-tuning with Axolotl, DeepSpeed ZeRO-3, and DPO alignment Infrastructure: - gpu-server-management: NVIDIA driver setup, MIG partitioning, DCGM monitoring - vector-database-ops: Qdrant, Weaviate, pgvector for production AI search - llm-gateway: LiteLLM-based API gateway with rate limiting, virtual keys, fallback routing DevOps/AI: - llm-cost-optimization: Model right-sizing, prompt/semantic caching, batch API, break-even analysis - llm-caching: Multi-layer exact + semantic + provider caching to cut costs 30-70% - ai-pipeline-orchestration: Prefect/Airflow/Dagster for RAG ingestion and training workflows Orchestration: - model-serving-kubernetes: KServe + Triton with canary deployments and GPU autoscaling Security: - ai-security-hardening: Prompt injection defense, PII scrubbing, model weight verification https://claude.ai/code/session_011MN1C4PrkCeg2Qmi7q1ZUe
This commit is contained in:
@@ -0,0 +1,285 @@
|
||||
---
|
||||
name: vector-database-ops
|
||||
description: Deploy, manage, and optimize vector databases for AI applications. Covers Qdrant, Weaviate, pgvector, and Pinecone — collection management, indexing strategies, backup, and performance tuning for production RAG and semantic search workloads.
|
||||
license: MIT
|
||||
metadata:
|
||||
author: devops-skills
|
||||
version: "1.0"
|
||||
---
|
||||
|
||||
# Vector Database Operations
|
||||
|
||||
Run production vector databases for AI-powered search, RAG, and recommendation systems.
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
Use this skill when:
|
||||
- Setting up a vector database for a RAG or semantic search application
|
||||
- Choosing between Qdrant, Weaviate, pgvector, or Pinecone
|
||||
- Managing collections, indexes, and data migrations
|
||||
- Optimizing query performance and indexing for production loads
|
||||
- Implementing multi-tenant vector search with namespace isolation
|
||||
|
||||
## Vector Database Comparison
|
||||
|
||||
| Database | Best For | Hosting | Filtering | Scale |
|
||||
|----------|----------|---------|-----------|-------|
|
||||
| **Qdrant** | High-performance, rich filtering, self-hosted | Self / Cloud | Excellent | Very High |
|
||||
| **Weaviate** | Schema-first, hybrid search, multi-modal | Self / Cloud | Good | High |
|
||||
| **pgvector** | Already on Postgres, simple use cases | Self | Good | Medium |
|
||||
| **Pinecone** | Zero-ops managed, serverless | Managed only | Good | Very High |
|
||||
| **Chroma** | Local dev, prototyping | Self only | Basic | Low-Medium |
|
||||
|
||||
## Qdrant — Production Deployment
|
||||
|
||||
```bash
|
||||
# Docker (single node)
|
||||
docker run -d \
|
||||
--name qdrant \
|
||||
-p 6333:6333 \
|
||||
-p 6334:6334 \
|
||||
-v $(pwd)/qdrant-data:/qdrant/storage \
|
||||
qdrant/qdrant:latest
|
||||
|
||||
# With custom config
|
||||
docker run -d \
|
||||
--name qdrant \
|
||||
-p 6333:6333 \
|
||||
-v $(pwd)/qdrant-data:/qdrant/storage \
|
||||
-v $(pwd)/qdrant-config.yaml:/qdrant/config/production.yaml \
|
||||
qdrant/qdrant:latest
|
||||
```
|
||||
|
||||
```yaml
|
||||
# qdrant-config.yaml
|
||||
storage:
|
||||
storage_path: /qdrant/storage
|
||||
on_disk_payload: true # store payload on disk (saves RAM)
|
||||
|
||||
service:
|
||||
max_request_size_mb: 32
|
||||
|
||||
hnsw_index:
|
||||
m: 16 # graph connections per node
|
||||
ef_construct: 100 # accuracy vs build time trade-off
|
||||
full_scan_threshold: 10000 # switch to brute force below this
|
||||
|
||||
quantization:
|
||||
scalar:
|
||||
type: int8
|
||||
quantile: 0.99
|
||||
always_ram: true # keep quantized index in RAM
|
||||
|
||||
telemetry_disabled: true
|
||||
```
|
||||
|
||||
## Qdrant Collection Management
|
||||
|
||||
```python
|
||||
from qdrant_client import QdrantClient
|
||||
from qdrant_client.models import (
|
||||
Distance, VectorParams, HnswConfigDiff,
|
||||
ScalarQuantizationConfig, ScalarType, QuantizationConfig
|
||||
)
|
||||
|
||||
client = QdrantClient("http://localhost:6333")
|
||||
|
||||
# Create optimized collection
|
||||
client.create_collection(
|
||||
collection_name="documents",
|
||||
vectors_config=VectorParams(
|
||||
size=1536, # OpenAI ada-002 / text-embedding-3-small
|
||||
distance=Distance.COSINE,
|
||||
on_disk=True, # save RAM — vectors stored on disk
|
||||
),
|
||||
hnsw_config=HnswConfigDiff(
|
||||
m=32, # higher = better recall, more RAM
|
||||
ef_construct=200,
|
||||
on_disk=False, # keep HNSW graph in RAM for speed
|
||||
),
|
||||
quantization_config=QuantizationConfig(
|
||||
scalar=ScalarQuantizationConfig(
|
||||
type=ScalarType.INT8,
|
||||
quantile=0.99,
|
||||
always_ram=True,
|
||||
)
|
||||
),
|
||||
)
|
||||
|
||||
# Create payload index for fast filtering
|
||||
client.create_payload_index(
|
||||
collection_name="documents",
|
||||
field_name="tenant_id",
|
||||
field_schema="keyword",
|
||||
)
|
||||
client.create_payload_index(
|
||||
collection_name="documents",
|
||||
field_name="created_at",
|
||||
field_schema="datetime",
|
||||
)
|
||||
|
||||
# Collection info
|
||||
info = client.get_collection("documents")
|
||||
print(f"Vectors: {info.vectors_count}, Status: {info.status}")
|
||||
```
|
||||
|
||||
## Qdrant Filtered Search
|
||||
|
||||
```python
|
||||
from qdrant_client.models import Filter, FieldCondition, MatchValue, Range
|
||||
|
||||
# Tenant-isolated search (multi-tenant RAG)
|
||||
results = client.query_points(
|
||||
collection_name="documents",
|
||||
query=query_embedding,
|
||||
query_filter=Filter(
|
||||
must=[
|
||||
FieldCondition(key="tenant_id", match=MatchValue(value="acme-corp")),
|
||||
FieldCondition(key="doc_type", match=MatchValue(value="contract")),
|
||||
],
|
||||
should=[
|
||||
FieldCondition(key="created_at", range=Range(gte="2024-01-01")),
|
||||
],
|
||||
),
|
||||
limit=10,
|
||||
with_payload=True,
|
||||
)
|
||||
```
|
||||
|
||||
## pgvector — PostgreSQL Extension
|
||||
|
||||
```sql
|
||||
-- Enable extension
|
||||
CREATE EXTENSION IF NOT EXISTS vector;
|
||||
|
||||
-- Create table with vector column
|
||||
CREATE TABLE documents (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
content TEXT NOT NULL,
|
||||
embedding VECTOR(1536),
|
||||
metadata JSONB DEFAULT '{}',
|
||||
tenant_id TEXT NOT NULL,
|
||||
created_at TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Create HNSW index (faster queries, more memory)
|
||||
CREATE INDEX ON documents
|
||||
USING hnsw (embedding vector_cosine_ops)
|
||||
WITH (m = 16, ef_construction = 64);
|
||||
|
||||
-- Create IVFFlat index (less memory, slower build)
|
||||
-- CREATE INDEX ON documents
|
||||
-- USING ivfflat (embedding vector_cosine_ops)
|
||||
-- WITH (lists = 100);
|
||||
|
||||
-- Semantic search with metadata filtering
|
||||
SELECT id, content, metadata,
|
||||
1 - (embedding <=> $1::vector) AS similarity
|
||||
FROM documents
|
||||
WHERE tenant_id = 'acme-corp'
|
||||
AND metadata->>'doc_type' = 'contract'
|
||||
ORDER BY embedding <=> $1::vector
|
||||
LIMIT 10;
|
||||
```
|
||||
|
||||
```bash
|
||||
# Deploy pgvector via Docker
|
||||
docker run -d \
|
||||
--name pgvector \
|
||||
-e POSTGRES_PASSWORD=secret \
|
||||
-e POSTGRES_DB=vectordb \
|
||||
-p 5432:5432 \
|
||||
-v pgvector-data:/var/lib/postgresql/data \
|
||||
pgvector/pgvector:pg16
|
||||
```
|
||||
|
||||
## Weaviate Deployment
|
||||
|
||||
```yaml
|
||||
# docker-compose for Weaviate
|
||||
services:
|
||||
weaviate:
|
||||
image: semitechnologies/weaviate:latest
|
||||
ports:
|
||||
- "8080:8080"
|
||||
- "50051:50051"
|
||||
environment:
|
||||
QUERY_DEFAULTS_LIMIT: 25
|
||||
AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: "false"
|
||||
AUTHENTICATION_APIKEY_ENABLED: "true"
|
||||
AUTHENTICATION_APIKEY_ALLOWED_KEYS: "${WEAVIATE_API_KEY}"
|
||||
AUTHENTICATION_APIKEY_USERS: "admin"
|
||||
PERSISTENCE_DATA_PATH: /var/lib/weaviate
|
||||
ENABLE_MODULES: text2vec-openai,generative-openai
|
||||
OPENAI_APIKEY: "${OPENAI_API_KEY}"
|
||||
CLUSTER_HOSTNAME: node1
|
||||
volumes:
|
||||
- weaviate-data:/var/lib/weaviate
|
||||
restart: unless-stopped
|
||||
|
||||
volumes:
|
||||
weaviate-data:
|
||||
```
|
||||
|
||||
## Backup and Restore
|
||||
|
||||
```bash
|
||||
# Qdrant — snapshot backup
|
||||
curl -X POST "http://localhost:6333/collections/documents/snapshots"
|
||||
# Download snapshot
|
||||
curl -O "http://localhost:6333/collections/documents/snapshots/documents-snapshot.snapshot"
|
||||
# Restore
|
||||
curl -X POST "http://localhost:6333/collections/documents/snapshots/recover" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"location": "/qdrant/snapshots/documents-snapshot.snapshot"}'
|
||||
|
||||
# pgvector — standard pg_dump
|
||||
pg_dump -h localhost -U postgres -d vectordb \
|
||||
--table=documents --format=custom > documents-backup.dump
|
||||
|
||||
# Restore
|
||||
pg_restore -h localhost -U postgres -d vectordb documents-backup.dump
|
||||
```
|
||||
|
||||
## Performance Tuning
|
||||
|
||||
```python
|
||||
# Qdrant — optimize collection after bulk load
|
||||
client.update_collection(
|
||||
collection_name="documents",
|
||||
optimizer_config={"indexing_threshold": 0}, # force indexing now
|
||||
)
|
||||
|
||||
# Wait for optimization to complete
|
||||
import time
|
||||
while True:
|
||||
info = client.get_collection("documents")
|
||||
if info.status.value == "green":
|
||||
break
|
||||
time.sleep(5)
|
||||
print(f"Optimizing... segments: {info.segments_count}")
|
||||
```
|
||||
|
||||
## Common Issues
|
||||
|
||||
| Issue | Cause | Fix |
|
||||
|-------|-------|-----|
|
||||
| Slow queries | No HNSW index built yet | Wait for indexing; check `status == green` |
|
||||
| High RAM usage | Vectors in memory | Enable `on_disk=True` for vectors |
|
||||
| Poor recall | Low `ef` search param | Increase `ef` in search request (at query time) |
|
||||
| pgvector slow | Using IVFFlat without vacuum | Run `VACUUM ANALYZE documents` |
|
||||
| Weaviate OOM | Too many objects | Enable async indexing; increase heap |
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Use cosine distance for normalized embeddings; dot product for unnormalized.
|
||||
- Always create payload indexes on filter fields (`tenant_id`, `doc_type`).
|
||||
- For datasets >10M vectors, use `on_disk` vectors + `always_ram` quantization.
|
||||
- Benchmark with your actual query patterns before choosing IVFFlat vs HNSW.
|
||||
- Snapshot before any bulk delete or migration operation.
|
||||
|
||||
## Related Skills
|
||||
|
||||
- [rag-infrastructure](../../local-ai/rag-infrastructure/) - Full RAG pipeline
|
||||
- [databases](../databases/) - General database management
|
||||
- [postgresql](../postgresql/) - pgvector host database ops
|
||||
Reference in New Issue
Block a user