技能创建器
skill-creator
创建、改进和评估自定义技能,把专业流程转化为可重复使用的 AI 能力。
django-recommender-search-backend-patterns【数据与研究】Django backend patterns for recommendation services (AWS Personalize, Databricks Model Serving, internal microservices) and OpenSearch-backed search/feed endpoints. Covers fan-out orchestration (asyncio.gather, deadline propagation, partial results, async client reuse), external service protection (timeouts, circuit breakers, jittered retry, bulkhead…
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
Implementation patterns for a Django backend serving mixed-results recommendations (Personalize / Databricks / microservice fan-out) and OpenSearch-backed search/feeds. 48 rules across 8 categories, ordered by execution lifecycle impact — earlier categories cascade through everything downstream.
This is the backend peer of the react-fetch-cache-patterns skill. React handles client-side waterfalls and caching; this skill handles server-side fan-out, downstream protection, OpenSearch query design, and ML-blend orchestration.
| # | Category | Impact | Prefix | Rules |
|---|---|---|---|---|
| 1 | Fan-out Orchestration | CRITICAL | orch- | 8 |
| 2 | External Service Protection | CRITICAL | protect- | 7 |
| 3 | OpenSearch Query Patterns | CRITICAL | search- | 8 |
| 4 | Result Blending & Personalization | HIGH | blend- | 5 |
| 5 | Caching Strategy | HIGH | cache- | 5 |
| 6 | Resilience & Partial Results | HIGH | resilience- | 5 |
| 7 | Async & Concurrency | MEDIUM-HIGH | async- | 5 |
| 8 | API Response Design | MEDIUM | api- | 5 |
orch-parallel-fanout-asyncio-gather — Use asyncio.gather for independent downstream calls; never await sequentiallyorch-return-exceptions-on-fanout — return_exceptions=True so one failure doesn't poison the whole gatherorch-propagate-request-deadline — Pass a deadline through every downstream call to bound whole-request latencyorch-reuse-async-clients — One httpx.AsyncClient per downstream at module scope; never per-requestorch-bounded-fanout-concurrency — Cap per-request fan-out with asyncio.Semaphore to protect the poolorch-no-blocking-in-async-view — Never block the event loop with sync ORM/IO in async viewsorch-avoid-await-in-loop — for item in items: await ... is serial; use asyncio.gather with comprehensionorch-batch-with-bulk-endpoint — Bulk endpoint over N parallel calls; DataLoader pattern for batchersprotect-per-downstream-timeout-budget — Different timeouts per service matched to each downstream's p99protect-circuit-breaker-per-downstream — One breaker per downstream so failures stay isolatedprotect-jittered-retry-backoff — Full-jitter exponential backoff to prevent thundering-herd recoveryprotect-no-retry-on-4xx — Skip retry on 4xx and non-idempotent failures; distinguish connect vs read errorsprotect-bulkhead-connection-pool — One connection pool per downstream so one slow service doesn't starve othersprotect-client-side-rate-limit — Token bucket toward each downstream to stay under their quotaprotect-honor-retry-after-header — Parse Retry-After (seconds or HTTP-date) on 429/503search-use-search-after-not-from — search_after cursor instead of from/size for any paginated endpointsearch-filter-source-fields — Restrict _source to fields you render; use docvalue_fields for sortablesearch-bool-filter-vs-must — Non-scoring clauses in filter (cacheable), scoring clauses in mustsearch-function-score-for-blending — Use function_score to blend personalization signals in-enginesearch-stable-tiebreaker-sort — Always end sort with _id (or unique numeric field) for stable cursorssearch-alias-for-blue-green-reindex — Query through aliases; never direct index namessearch-enable-request-cache — request_cache=true for hit-returning queries; canonicalize request bodysearch-shard-aware-routing — Use routing keys to limit per-query shard fan-outblend-normalize-scores-across-sources — Min-max or RRF normalize before blending Personalize/Databricks/OpenSearchblend-mmr-for-diversity — Maximal Marginal Relevance to avoid monocultures in top-Kblend-dedup-across-sources — Canonical item ID dedup; bonus for cross-source corroborationblend-cold-start-fallback — Popular/editorial fallback for new users; tiered personalizationblend-anonymous-vs-personalized-paths — Cheap segment-keyed cache for anon traffic; ML only for logged-incache-redis-with-stampede-protection — SETNX lock + jittered TTL + probabilistic early refreshcache-version-on-model-deploy — Bake model version into cache keys; no flush needed on retraincache-segment-keyed-isolation — Include auth/role/locale/segment in keys to prevent cross-context leakagecache-two-tier-process-and-redis — Process LRU in front of Redis for the hottest keyscache-negative-results — Cache absences and empty results with shorter TTLresilience-partial-response-envelope — partial: true + sources_used + failed_sources in responseresilience-serve-stale-from-redis — Two TTLs (fresh + stale); serve stale on origin failureresilience-default-ranking-fallback — Precomputed default ranking when all ML sources are downresilience-per-source-observability — Tag every downstream call with structured source/outcome metadataresilience-degrade-search-gracefully — Tier 1 → tier 2 → tier 3 fallback for OpenSearch outagesasync-sync-to-async-orm — Use Django 4.1+ async ORM (aget, afilter) or sync_to_async with thread_sensitive=Trueasync-worker-model-uvicorn-vs-gunicorn — Run ASGI (uvicorn or gunicorn+UvicornWorker) for true async concurrencyasync-fire-and-forget-with-create-task — create_task for analytics/audit; add error handler; hold task referencesasync-context-vars-for-request-scope — contextvars.ContextVar for per-request state; not threading.localasync-cancel-on-client-disconnect — Check await request.is_disconnected(); propagate cancellationapi-cursor-pagination-in-drf — Cursor pagination over page-number; opaque base64 cursorsapi-serializer-perf-select-related — select_related/prefetch_related/only to eliminate N+1api-etag-and-cache-control-headers — ETag + Cache-Control + Vary for CDN/client reuseapi-compression-and-payload-shaping — gzip/brotli; sparse fieldsets; msgpack for internal APIsapi-throttle-per-user-and-endpoint — DRF throttle classes per user/anon and per expensive endpointFive ready-to-adapt Python templates under assets/templates/:
| Template | Purpose |
|---|---|
fanout_recommender_service.py.template | Async fan-out client to Personalize/Databricks/microservice with per-downstream circuit breaker, bounded timeout, partial-result return |
opensearch_search_view.py.template | DRF view + OpenSearch search_after cursor + function_score blending + _source filtering |
result_blender.py.template | Score normalization + MMR diversity + canonical-ID dedup + cold-start fallback |
redis_cache_with_stampede.py.template | Stampede-safe cached function decorator with SETNX lock and jittered TTL |
degraded_response.py.template | Partial-results envelope with per-source status flags + tier-based fallback |
| File | Description |
|---|---|
| references/_sections.md | Category definitions, ordering, impact rationale, tier definitions |
| assets/templates/_template.md | Template for authoring new rules |
| metadata.json | Version, references, abstract |
react-fetch-cache-patterns — Client-side peer covering React data fetching/caching (Suspense, query libraries, prefetch)io-bound-data-processing — Python async patterns for batch and pipeline workloadsinngest-nextjs-patterns — Workflow patterns for server-side step functions