Skip to main content

llm-project-development

Build LLM-powered applications and pipelines using proven methodology - task-model fit analysis, pipeline architecture, structured outputs, file-based state, and cost estimation. Use when building AI features, data processing pipelines, agents, or any LLM-integrated system. Inspired by Karpathy's methodology and production case studies.

Informations de source

Dépôt
greyhaven-ai/claude-code-config
Dernière activité de la source
17 avril 2026 à 23:11
Langue détectée de SKILL.md
anglais
Étoiles
29
Forks
5

Options d'installation

Le prompt qui vérifie d'abord la source est sélectionné par défaut. Vous pouvez passer à une commande directe ou télécharger une copie locale.

Vérifiez les fichiers source

Lisez SKILL.md et les fichiers associés affichés par SkillsMP avant de décider de l'installer.

Explorateur de fichiers
10 fichiers

Affichage de SKILL.md

SKILL.md
Instructions source · Aperçu en lecture seule
name
llm-project-development
description
Build LLM-powered applications and pipelines using proven methodology - task-model fit analysis, pipeline architecture, structured outputs, file-based state, and cost estimation. Use when building AI features, data processing pipelines, agents, or any LLM-integrated system. Inspired by Karpathy's methodology and production case studies.
skills
["code-style","data-validation","prompt-engineering"]
allowed-tools
["Read","Write","MultiEdit","Bash","Grep","Glob","TodoWrite","WebFetch"]
# LLM Project Development Skill Build **production LLM applications** using proven methodology from Karpathy's HN Time Capsule, Vercel d0, Manus, and Anthropic's research. **Core principle**: Validate manually first, then build deterministic pipelines around the non-deterministic LLM core. ## Supporting Documentation All files under 500 lines per Anthropic best practices: - **[references/](references/)** - Methodology foundations - [case-studies.md](references/case-studies.md) - Karpathy, Vercel d0, Manus patterns - [pipeline-patterns.md](references/pipeline-patterns.md) - Python/TypeScript code patterns - [INDEX.md](references/INDEX.md) - Reference navigation - **[examples/](examples/)** - Grey Haven implementations - [tanstack-pipeline.md](examples/tanstack-pipeline.md) - TanStack Start example - [fastapi-pipeline.md](examples/fastapi-pipeline.md) - FastAPI backend example - [INDEX.md](examples/INDEX.md) - Examples navigation - **[templates/](templates/)** - Copy-paste starters - [pipeline-template.ts](templates/pipeline-template.ts) - TypeScript pipeline - [pipeline-template.py](templates/pipeline-template.py) - Python pipeline - **[checklists/](checklists/)** - Validation - [llm-project-checklist.md](checklists/llm-project-checklist.md) - Pre-launch checklist ## The Methodology ### Phase 1: Task-Model Fit Analysis **Before writing any code, determine if LLMs are the right tool.** #### LLM-Suited Tasks | Characteristic | Why LLMs Excel | Grey Haven Example | |----------------|----------------|-------------------| | **Synthesis over precision** | Combining context, not calculating | Summarizing tenant activity | | **Subjective judgment** | No single correct answer | Categorizing support tickets | | **Error tolerance** | Graceful degradation acceptable | Content recommendations | | **Human-like processing** | Natural language understanding | Chat-based tenant onboarding | | **Creative output** | Novel combinations required | Generating marketing copy | #### LLM-Unsuited Tasks (Use Traditional Code) | Characteristic | Why LLMs Fail | Better Approach | |----------------|---------------|-----------------| | **Precise computation** | Math errors, hallucinations | SQL queries, Python math | | **Real-time requirements** | Latency too high | Pre-computed indices | | **Deterministic output** | Need exact same result | Database lookups | | **Structured data lookup** | LLMs guess, don't retrieve | Drizzle/SQLModel queries | | **High-frequency calls** | Cost explodes | Caching, batching | #### The Manual Prototype Step **CRITICAL**: Before building automation, validate with the target model manually. ```markdown ## Manual Validation Checklist - [ ] Copy ONE real example into the LLM UI - [ ] Test with the EXACT model you'll use in production - [ ] Verify output quality meets requirements - [ ] Note edge cases and failure modes - [ ] Estimate cost per operation ## Example: Karpathy's Approach 1. Took ONE Hacker News thread 2. Pasted into ChatGPT with analysis prompt 3. Confirmed Opus 4.5 could do the task 4. THEN built automation pipeline ``` ### Phase 2: Pipeline Architecture **Design principle**: Deterministic stages wrapping one non-deterministic core. ``` ┌─────────────────────────────────────────────────────────────────┐ │ DETERMINISTIC │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ ACQUIRE │ → │ PREPARE │ → │ PROCESS │ → │ RENDER │ │ │ │ (fetch) │ │ (format) │ │ (LLM) │ │ (output) │ │ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │ ↑ ↑ ↑ ↑ │ │ Deterministic Deterministic NON-DETERMINISTIC Deterministic│ │ (retry safe) (retry safe) (cache results) (retry safe) │ └─────────────────────────────────────────────────────────────────┘ ``` #### Stage Details | Stage | Purpose | Grey Haven Implementation | |-------|---------|--------------------------| | **Acquire** | Get raw data | Drizzle queries, Firecrawl scraping, API calls | | **Prepare** | Format for LLM | Jinja templates, TypeScript string builders | | **Process** | LLM inference | Anthropic SDK, structured outputs | | **Parse** | Extract from response | Zod schemas, Pydantic models | | **Render** | Final output | React components, markdown, JSON | #### TypeScript Pipeline Example (TanStack Start) ```typescript // lib/pipelines/content-analyzer.ts import Anthropic from "@anthropic-ai/sdk"; import { z } from "zod"; import { existsSync, mkdirSync, writeFileSync, readFileSync } from "fs"; import { join } from "path"; // Stage 1: Schema definition const AnalysisSchema = z.object({ summary: z.string(), sentiment: z.enum(["positive", "neutral", "negative"]), topics: z.array(z.string()), action_items: z.array(z.string()), }); type Analysis = z.infer<typeof AnalysisSchema>; // Stage 2: Acquire - Get data from database async function acquire(tenant_id: string, content_id: string) { const content = await db.query.contents.findFirst({ where: and( eq(contents.tenant_id, tenant_id), eq(contents.id, content_id) ), }); if (!content) throw new Error(`Content ${content_id} not found`); return content; } // Stage 3: Prepare - Format prompt function prepare(content: Content): string { return `Analyze this content and provide structured output. CONTENT: ${content.body} Respond with JSON matching this schema: { "summary": "2-3 sentence summary", "sentiment": "positive" | "neutral" | "negative", "topics": ["topic1", "topic2"], "action_items": ["action1", "action2"] }`; } // Stage 4: Process - LLM call with caching async function process( prompt: string, cacheDir: string, cacheKey: string ): Promise<string> { const cachePath = join(cacheDir, `${cacheKey}.json`); // Check cache first if (existsSync(cachePath)) { return JSON.parse(readFileSync(cachePath, "utf-8")).response; } const client = new Anthropic(); const response = await client.messages.create({ model: "claude-sonnet-4-20250514", max_tokens: 1024, messages: [{ role: "user", content: prompt }], }); const text = response.content[0].type === "text" ? response.content[0].text : ""; // Cache result mkdirSync(cacheDir, { recursive: true }); writeFileSync(cachePath, JSON.stringify({ response: text, timestamp: new Date().toISOString() })); return text; } // Stage 5: Parse - Validate with Zod function parse(response: string): Analysis { const jsonMatch = response.match(/\{[\s\S]*\}/); if (!jsonMatch) throw new Error("No JSON found in response"); const parsed = JSON.parse(jsonMatch[0]); return AnalysisSchema.parse(parsed); } // Stage 6: Render - Save to database async function render( tenant_id: string, content_id: string, analysis: Analysis ) { await db.update(contents) .set({ analysis_summary: analysis.summary, analysis_sentiment: analysis.sentiment, analysis_topics: analysis.topics, updated_at: new Date(), }) .where(and( eq(contents.tenant_id, tenant_id), eq(contents.id, content_id) )); return analysis; } // Main pipeline function export async function analyzeContent( tenant_id: string, content_id: string ): Promise<Analysis> { const cacheDir = join(process.cwd(), ".cache", "analyses", tenant_id); const content = await acquire(tenant_id, content_id); const prompt = prepare(content); const response = await process(prompt, cacheDir, content_id); const analysis = parse(response); await render(tenant_id, content_id, analysis); return analysis; } ``` #### Python Pipeline Example (FastAPI) ```python # app/pipelines/content_analyzer.py from pathlib import Path from pydantic import BaseModel from anthropic import Anthropic import json class Analysis(BaseModel): summary: str sentiment: str # positive | neutral | negative topics: list[str] action_items: list[str] class ContentAnalyzerPipeline: def __init__(self, tenant_id: str, cache_dir: Path | None = None): self.tenant_id = tenant_id self.cache_dir = cache_dir or Path(".cache/analyses") / tenant_id self.client = Anthropic() async def acquire(self, content_id: str, db: AsyncSession) -> Content: """Stage 1: Get content from database.""" result = await db.execute( select(Content).where( Content.tenant_id == self.tenant_id, Content.id == content_id ) ) content = result.scalar_one_or_none() if not content: raise ValueError(f"Content {content_id} not found") return content def prepare(self, content: Content) -> str: """Stage 2: Format prompt.""" return f"""Analyze this content and provide structured output. CONTENT: {content.body} Respond with JSON: {{ "summary": "2-3 sentence summary", "sentiment": "positive" | "neutral" | "negative", "topics": ["topic1", "topic2"], "action_items": ["action1"] }}""" async def process(self, prompt: str, cache_key: str) -> str: """Stage 3: LLM call with file-based caching.""" cache_path = self.cache_dir / f"{cache_key}.json" # Check cache if cache_path.exists(): return json.loads(cache_path.read_text())["response"] response = self.client.messages.create( model="claude-sonnet-4-20250514", max_tokens=1024, messages=[{"role": "user", "content": prompt}] ) text = response.content[0].text # Cache result self.cache_dir.mkdir(parents=True, exist_ok=True) cache_path.write_text(json.dumps({ "response": text, "timestamp": datetime.utcnow().isoformat() })) return text def parse(self, response: str) -> Analysis: """Stage 4: Parse and validate with Pydantic.""" import re match = re.search(r'\{[\s\S]*\}', response) if not match: raise ValueError("No JSON found in response") return Analysis.model_validate_json(match.group()) async def render( self, content_id: str, analysis: Analysis, db: AsyncSession ) -> Analysis: """Stage 5: Save to database.""" await db.execute( update(Content) .where( Content.tenant_id == self.tenant_id, Content.id == content_id ) .values( analysis_summary=analysis.summary, analysis_sentiment=analysis.sentiment, analysis_topics=analysis.topics, updated_at=datetime.utcnow() ) ) await db.commit() return analysis async def run(self, content_id: str, db: AsyncSession) -> Analysis: """Execute full pipeline.""" content = await self.acquire(content_id, db) prompt = self.prepare(content) response = await self.process(prompt, content_id) analysis = self.parse(response) return await self.render(content_id, analysis, db) ``` ### Phase 3: File System as State Machine **Key insight from Karpathy**: File existence determines work state. ```python # Pipeline state management def get_pipeline_state(work_dir: Path, item_id: str) -> str: """Determine pipeline state from file existence.""" item_dir = work_dir / item_id if not item_dir.exists(): return "pending" if not (item_dir / "raw.json").exists(): return "acquired" if not (item_dir / "prepared.txt").exists(): return "prepared" if not (item_dir / "response.json").exists(): return "processed" if not (item_dir / "analysis.json").exists(): return "parsed" return "complete"
Voir sur GitHub
Ce SKILL.md est tres volumineux, SkillsMP affiche donc ici seulement la premiere section. Voir sur GitHub