3v324v23 commited on
Commit
4aed5f4
·
0 Parent(s):

feat: initial release of Multiverse AI Studio

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .agents/AGENTS.md +84 -0
  2. .gitignore +22 -0
  3. Dockerfile +35 -0
  4. README.md +148 -0
  5. REPORT.md +116 -0
  6. TRAE-Skills/LICENSE +64 -0
  7. TRAE-Skills/README.md +240 -0
  8. TRAE-Skills/ai_engineering/AI_Agent_Design_Patterns.md +99 -0
  9. TRAE-Skills/ai_engineering/AI_Agents_LangGraph.md +232 -0
  10. TRAE-Skills/ai_engineering/AI_Experiment_Tracking.md +640 -0
  11. TRAE-Skills/ai_engineering/AI_Model_Evaluation.md +107 -0
  12. TRAE-Skills/ai_engineering/AI_Model_Serving.md +503 -0
  13. TRAE-Skills/ai_engineering/AI_Monitoring_Observability.md +536 -0
  14. TRAE-Skills/ai_engineering/AI_Pipeline_Automation.md +562 -0
  15. TRAE-Skills/ai_engineering/AI_Safety_Ethics.md +379 -0
  16. TRAE-Skills/ai_engineering/AI_Testing_Evaluation.md +400 -0
  17. TRAE-Skills/ai_engineering/Chain_of_Thought_Prompting.md +169 -0
  18. TRAE-Skills/ai_engineering/Computer_Vision_Object_Detection.md +95 -0
  19. TRAE-Skills/ai_engineering/Data_Drift_Detection.md +84 -0
  20. TRAE-Skills/ai_engineering/Distributed_Training_Horovod.md +82 -0
  21. TRAE-Skills/ai_engineering/Embedding_Techniques.md +108 -0
  22. TRAE-Skills/ai_engineering/Federated_Learning.md +387 -0
  23. TRAE-Skills/ai_engineering/Fine_Tuning_Custom_Models.md +237 -0
  24. TRAE-Skills/ai_engineering/Fine_tuning_Basics.md +85 -0
  25. TRAE-Skills/ai_engineering/Function_Calling.md +280 -0
  26. TRAE-Skills/ai_engineering/Generative_AI_Image_Synthesis.md +96 -0
  27. TRAE-Skills/ai_engineering/LLM_Caching_Strategies.md +259 -0
  28. TRAE-Skills/ai_engineering/LLM_Function_Calling_Advanced.md +234 -0
  29. TRAE-Skills/ai_engineering/LLM_Operations.md +507 -0
  30. TRAE-Skills/ai_engineering/LangChain_Basics.md +103 -0
  31. TRAE-Skills/ai_engineering/Local_LLM_Running_Ollama.md +94 -0
  32. TRAE-Skills/ai_engineering/ML_Model_Quantization.md +85 -0
  33. TRAE-Skills/ai_engineering/MultiModal_AI.md +333 -0
  34. TRAE-Skills/ai_engineering/Natural_Language_to_SQL.md +152 -0
  35. TRAE-Skills/ai_engineering/OpenAI_API_Integration.md +142 -0
  36. TRAE-Skills/ai_engineering/Prompt_Engineering_Basics.md +130 -0
  37. TRAE-Skills/ai_engineering/RAG_System_Architecture.md +110 -0
  38. TRAE-Skills/ai_engineering/Recommender_Systems_Collaborative_Filtering.md +198 -0
  39. TRAE-Skills/ai_engineering/Reinforcement_Learning_Basics.md +335 -0
  40. TRAE-Skills/ai_engineering/Speech_to_Text_Whisper.md +88 -0
  41. TRAE-Skills/ai_engineering/Stream_Responses.md +321 -0
  42. TRAE-Skills/ai_engineering/Structured_Output_Parsing.md +301 -0
  43. TRAE-Skills/ai_engineering/Time_Series_Forecasting.md +94 -0
  44. TRAE-Skills/ai_engineering/Time_Series_Forecasting_LSTM.md +233 -0
  45. TRAE-Skills/ai_engineering/Token_Optimization.md +245 -0
  46. TRAE-Skills/ai_engineering/Vector_Database_Setup.md +97 -0
  47. TRAE-Skills/ai_engineering/Vector_Databases_Pinecone_Weaviate.md +220 -0
  48. TRAE-Skills/architecture/API_Gateway_Pattern.md +488 -0
  49. TRAE-Skills/architecture/Adapter_Pattern_TypeScript.md +87 -0
  50. TRAE-Skills/architecture/Authentication_Strategy_Selection.md +12 -0
.agents/AGENTS.md ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Multiverse AI Studio — Agent Rules
2
+
3
+ ## User Learning Style
4
+
5
+ This project is a **learning-first** environment. The user is building AND learning simultaneously.
6
+ These rules apply to every interaction in this workspace.
7
+
8
+ ---
9
+
10
+ ### Rule 1 — Always Write Explanatory Comments
11
+
12
+ Every piece of code written must include comments that explain:
13
+ - **What** the code does (the obvious)
14
+ - **Why** it does it that way (the reasoning)
15
+ - **How** it fits into the larger pipeline (the context)
16
+
17
+ Do not write bare code. If a newcomer cannot understand the code from the comments alone, add more.
18
+
19
+ Example style:
20
+ ```python
21
+ # We use ThreadPoolExecutor here because model inference is CPU/GPU-bound
22
+ # (blocking), not I/O-bound. asyncio alone can't parallelize blocking work —
23
+ # it needs a thread pool to offload heavy computation without blocking the
24
+ # FastAPI event loop.
25
+ executor = ThreadPoolExecutor(max_workers=2)
26
+ ```
27
+
28
+ ---
29
+
30
+ ### Rule 2 — Pause and Explain at Every Phase Step
31
+
32
+ When implementing any phase step:
33
+ 1. **Before coding** — briefly explain what is about to be built and why it exists in the pipeline.
34
+ 2. **After coding** — explain what was just built, point to the key lines, and explain any non-obvious decisions.
35
+ 3. **Invite doubts** — always end with an open invitation: *"Any questions before we move on?"* or similar.
36
+
37
+ Do not chain multiple phase steps together without pausing.
38
+
39
+ ---
40
+
41
+ ### Rule 3 — Take and Resolve Doubts Before Proceeding
42
+
43
+ If the user asks a question mid-phase:
44
+ - Stop what you are doing.
45
+ - Answer the question fully.
46
+ - Check if the answer raised new questions.
47
+ - Only resume coding once the user signals they are ready.
48
+
49
+ Never skip past a doubt to "keep momentum."
50
+
51
+ ---
52
+
53
+ ### Rule 4 — User Workflow (READ THIS CAREFULLY)
54
+
55
+ The user's development workflow is:
56
+
57
+ ```
58
+ AI Studio (Google)
59
+ ↓ generates initial code scaffold
60
+ TRAE
61
+ ↓ organizes, structures, and assembles the codebase
62
+ Antigravity (this agent)
63
+ ↓ reviews, compares against implementation plan, checks quality
64
+ ```
65
+
66
+ **Antigravity's role in this project is a REVIEWER and TEACHER — not the primary code generator.**
67
+
68
+ When the user brings code for review:
69
+ - Compare it against the implementation plan phase by phase.
70
+ - Check that the model wrapper interface (`initialize/generate/cleanup`) is respected.
71
+ - Check that Stop & Review gate criteria are met.
72
+ - Explain what is correct, what could be improved, and why.
73
+ - Never silently fix things — always explain what was wrong and what the fix does.
74
+
75
+ ---
76
+
77
+ ### Rule 5 — Explain Tradeoffs, Not Just Solutions
78
+
79
+ Whenever a technical decision is made (or reviewed), explain:
80
+ - What alternatives existed
81
+ - Why this choice was made
82
+ - What the tradeoff is
83
+
84
+ This prepares the user to defend decisions in interviews and discussions.
.gitignore ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Generated AI outputs - these are large, binary, and regenerated on demand
2
+ generated_assets/
3
+
4
+ # Python cache files - automatically generated, not source code
5
+ __pycache__/
6
+ *.pyc
7
+
8
+ # Environment secrets - NEVER commit API keys or tokens to git
9
+ .env
10
+
11
+ # Node.js dependencies - large directory, installed via npm install
12
+ node_modules/
13
+
14
+ # Next.js build artifacts - generated automatically on build
15
+ .next/
16
+
17
+ # macOS system files - OS-specific, not part of the project
18
+ .DS_Store
19
+
20
+ # Python package metadata - generated during packaging
21
+ *.egg-info/
22
+ test_apple.png
Dockerfile ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Stage 1: Build the React frontend
2
+ FROM node:18-alpine AS frontend-builder
3
+ WORKDIR /app/frontend
4
+ COPY frontend/package*.json ./
5
+ RUN npm install
6
+ COPY frontend/ ./
7
+ RUN npm run build
8
+
9
+ # Stage 2: Serve using Python FastAPI
10
+ FROM python:3.10-slim
11
+ WORKDIR /app
12
+
13
+ # Install system dependencies
14
+ # - git: needed for certain pip dependencies
15
+ # - libsndfile1: needed for SciPy audio file writes
16
+ # - ffmpeg: needed for imageio video compilations
17
+ RUN apt-get update && apt-get install -y \
18
+ git \
19
+ libsndfile1 \
20
+ ffmpeg \
21
+ && rm -rf /var/lib/apt/lists/*
22
+
23
+ # Copy backend requirements first to leverage Docker build cache
24
+ COPY backend/requirements.txt ./backend/requirements.txt
25
+ RUN pip install --no-cache-dir -r backend/requirements.txt
26
+
27
+ # Copy source code and frontend build output
28
+ COPY backend ./backend
29
+ COPY --from=frontend-builder /app/frontend/dist ./frontend/dist
30
+
31
+ # Expose port 7860 (Hugging Face Spaces default container port)
32
+ EXPOSE 7860
33
+
34
+ # Start uvicorn server on port 7860, binding to all interfaces
35
+ CMD ["python", "-m", "uvicorn", "backend.main:app", "--host", "0.0.0.0", "--port", "7860"]
README.md ADDED
@@ -0,0 +1,148 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Multiverse AI Studio
2
+
3
+ A portfolio-grade, full-stack generative AI application that chains five Hugging Face models into a unified, coherent multimedia pipeline. A single human prompt is expanded into specialized instructions to generate a **base visual scene**, estimate its **3D depth geometry**, synthesize an **ambient background soundscape**, and render a **cinematic video** anchoring the visual track.
4
+
5
+ Designed with a strict focus on system architecture, event-loop safety, memory management, and smooth user experience.
6
+
7
+ ---
8
+
9
+ ## 🏗️ System Architecture
10
+
11
+ ### 1. Model Pipeline Flow
12
+ Every stage in the pipeline consumes something meaningful from the previous step. The visual assets (depth and video) are conditioned on the generated image, ensuring visual cohesion.
13
+
14
+ ```mermaid
15
+ graph TD
16
+ A[User Prompt] -->|POST /api/generate| B(Prompt Expansion LLM)
17
+ B -->|image_prompt| C(Image Generation Service)
18
+ B -->|audio_prompt| D(Audio Generation Service)
19
+ C -->|RGB Image| E(Depth Estimation Service)
20
+ C -->|RGB Image| F(Video Generation Service)
21
+ E -->|Depth Map| F
22
+ D -->|Audio Track| G[Final Coherent Scene]
23
+ F -->|MP4 Stream| G
24
+
25
+ style C fill:#4f46e5,stroke:#333,stroke-width:2px,color:#fff
26
+ style E fill:#ec4899,stroke:#333,stroke-width:2px,color:#fff
27
+ style F fill:#db2777,stroke:#333,stroke-width:2px,color:#fff
28
+ ```
29
+
30
+ ### 2. Event-Loop & Threading Execution Flow
31
+ ML model inference is CPU/GPU-bound and blocking. To prevent blocking FastAPI's main asynchronous event loop, all inferences are offloaded to a background thread pool.
32
+
33
+ ```
34
+ Browser FastAPI Route Background Worker Job Store
35
+ │ │ │ │
36
+ │── POST /generate ──────>│ │ │
37
+ │ (prompt payload) │── Create Job (UUID) ───────────────────────────────>│ (QUEUED)
38
+ │ │── Schedule run_pipeline ──>│ │
39
+ │<── Return job_id ───────│ │ │
40
+ │ │ │── Update Stage ────────>│ (EXPANDING...)
41
+ │ │ │── Run Prompt LLM │
42
+ │ │ │── Run Image Gen │
43
+ │ │ │── Update Asset (img) ──>│ (Image URL)
44
+ │ │ │── Run Depth Est │
45
+ │ │ │── Update Asset (depth) ─>│ (Depth URL)
46
+ │ │ │── Run Audio/Video │
47
+ │ │ │── Update final state ──>│ (COMPLETED)
48
+ │ │ │ │
49
+ │── GET /result/{id} ────>│────────────────────────────────────────────────────>│
50
+ │<── Returns assets ──────│<────────────────────────────────────────────────────│
51
+ ```
52
+
53
+ ---
54
+
55
+ ## ⚡ Key Features
56
+
57
+ * **Progressive Polling & Rendering**: The frontend polls `/api/result/{job_id}`. Completed assets (like the base image) are rendered on the screen *immediately* while downstream stages are still processing.
58
+ * **Granular Memory/VRAM Management**: Chaining 5 heavy models sequentially can cause VRAM Out-of-Memory (OOM) crashes. Each model wrapper implements a strict `cleanup()` method that deletes pipeline instances, runs garbage collection (`gc.collect()`), and flushes PyTorch's CUDA memory cache (`torch.cuda.empty_cache()`) before loading the next stage.
59
+ * **Stage Error Isolation**: Wrap-around try/except boundaries guarantee that a single failed stage (e.g., depth map or audio timeout) does not crash the entire pipeline. The server flags a `PARTIAL_FAILURE` and delivers all other successfully compiled assets.
60
+ * **Interactive CSS Depth Slider**: Features a custom swipable comparison slider built using CSS `clip-path` polygon slicing for smooth 60fps comparisons between the visual base image and its calculated depth map.
61
+ * **Custom Media Players**: Custom glassmorphic React components for audio and video playback, including a dynamic pulsing audio waveform visualizer.
62
+
63
+ ---
64
+
65
+ ## ⚙️ Project Setup
66
+
67
+ ### Prerequisites
68
+ * Python 3.10+
69
+ * Node.js 18+
70
+ * Hugging Face Access Token (for gated model downloads and Inference API)
71
+
72
+ ### 1. Environment Configuration
73
+ Create a `.env` file in the project root:
74
+ ```env
75
+ HF_TOKEN=your_huggingface_access_token_here
76
+ MOCK_INFERENCE=False
77
+ FORCE_CPU_INFERENCE=False
78
+ ```
79
+
80
+ #### Environment Variables Explained:
81
+ * `HF_TOKEN`: Your Hugging Face user access token (required for querying the cloud image generation API and downloading gated local models).
82
+ * `MOCK_INFERENCE`:
83
+ * `True` (Default DX): Bypasses all local and cloud model execution, returning mock visual, audio, and video assets in 1 second. Useful for testing UI components on any computer.
84
+ * `False` (Hybrid Production): Connects to the cloud and local machine learning models for real generation.
85
+ * `FORCE_CPU_INFERENCE`:
86
+ * `False` (Safe Fallback): If running `MOCK_INFERENCE=False` on a **CPU-only machine**, the backend will run cloud image generation and local depth maps, but will automatically bypass the heavy `MusicGen` and `i2vgen-xl` local models to prevent RAM exhaustion.
87
+ * `True` (Force CPU): Forces the backend to download, load, and execute the full MusicGen and Video models locally on your CPU. *Warning: MusicGen takes 2–5 minutes, and i2vgen-xl takes 20–45 minutes on CPU.*
88
+
89
+ ---
90
+
91
+ ## 🚀 GPU & Production Execution Setup
92
+ If you want to run the **complete, real local PyTorch pipelines** (audio and video) on a GPU-enabled developer machine:
93
+
94
+ 1. **Install CUDA-enabled PyTorch**: Ensure your virtual environment is using a GPU-compiled version of PyTorch:
95
+ ```bash
96
+ pip install torch --index-url https://download.pytorch.org/whl/cu121
97
+ ```
98
+ 2. **Configure environment**: Open your `.env` file and set:
99
+ ```env
100
+ HF_TOKEN=your_real_huggingface_token
101
+ MOCK_INFERENCE=False
102
+ FORCE_CPU_INFERENCE=False
103
+ ```
104
+ 3. **Launch**: Run uvicorn. The backend will automatically detect the GPU (`cuda`), log the status, and run the real local Hugging Face and Diffusers pipelines at maximum speed.
105
+
106
+ ### 2. Backend Installation
107
+ ```bash
108
+ # Navigate to the backend directory
109
+ cd backend
110
+
111
+ # Create a virtual environment
112
+ python -m venv venv
113
+ source venv/bin/activate # On Windows: venv\Scripts\activate
114
+
115
+ # Install dependencies
116
+ pip install -r requirements.txt
117
+
118
+ # Start the development server
119
+ python -m uvicorn main:app --host 127.0.0.1 --port 8000 --reload
120
+ ```
121
+ The backend health check is available at `http://127.0.0.1:8000/api/health`.
122
+
123
+ ### 3. Frontend Installation
124
+ ```bash
125
+ # Navigate to the frontend directory
126
+ cd frontend
127
+
128
+ # Install packages
129
+ npm install
130
+
131
+ # Start the Vite React development server
132
+ npm run dev
133
+ ```
134
+ Open `http://localhost:3000` to access the Multiverse AI Studio interface.
135
+
136
+ ---
137
+
138
+ ## 📈 Engineering Decisions & Tradeoffs
139
+
140
+ For a detailed analysis of our engineering decisions (such as choosing client polling over WebSockets, utilising an in-memory job store instead of Celery/Redis, and enforcing the BaseModel wrapper abstraction), please refer to the dedicated **[Tradeoffs and Decisions Report](file:///c:\AI Native founder\AI_Engineering\Projects\Multiverse_AI_Studio\docs\decisions\tradeoffs.md)**.
141
+
142
+ ---
143
+
144
+ ## 🚀 Future Roadmap
145
+
146
+ * **Server-Sent Events (SSE)**: Migrate the progressive rendering polling system to standard Server-Sent Events to push updates in real-time without client request overhead.
147
+ * **Persistent Database storage**: Replace the volatile in-memory dictionary with SQLite or PostgreSQL to keep user history across restarts.
148
+ * **Muxed Video Audio**: Integrate system FFmpeg binaries to merge (mux) the Stage 4 ambient soundscape directly into the Stage 5 MP4 video container.
REPORT.md ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Multiverse AI Studio - Development Report
2
+
3
+ ## Overview
4
+ This report summarizes all the work done on the Multiverse AI Studio project so far.
5
+
6
+ ---
7
+
8
+ ## Table of Contents
9
+ 1. [Backend Improvements](#backend-improvements)
10
+ 2. [Frontend Updates](#frontend-updates)
11
+ 3. [Files Modified](#files-modified)
12
+ 4. [New Files Created](#new-files-created)
13
+
14
+ ---
15
+
16
+ ## Backend Improvements
17
+
18
+ ### 1. Fixed Module Import Issues
19
+ All Python files in the backend were updated to use relative imports to avoid `ModuleNotFoundError` when running the server.
20
+ - Example changes:
21
+ - `from models.base import BaseModel` → `from .base import BaseModel`
22
+ - `from config import HF_TOKEN` → `from ..config import HF_TOKEN`
23
+
24
+ ### 2. Added Error Handling to Model Methods
25
+ Every model wrapper's `generate()` and `initialize()` methods now include try/except blocks to gracefully handle failures (like Out-of-Memory errors, API failures, etc.).
26
+ - Models updated:
27
+ - `PromptExpander` (already had good error handling)
28
+ - `ImageGenerator`
29
+ - `DepthEstimator`
30
+ - `AudioGenerator`
31
+ - `VideoGenerator`
32
+ - `execute_model_sync` in `pipeline.py` now also handles initialization errors
33
+
34
+ ### 3. Added Scene Description Support
35
+ - Added `set_job_scene_description` to `job_store.py`
36
+ - Updated `pipeline.py` to save the expanded scene description
37
+ - Updated `/api/result/{job_id}` in `routes.py` to return `scene_description`
38
+ - Updated backend `config.py` (no changes needed, but it's there)
39
+ - Added `scene_description` to `JobResult` in frontend API client
40
+
41
+ ### 4. Improved Job Store
42
+ - Added `scene_description` field to job state
43
+ - Added `error_at` timestamp for better error tracking
44
+
45
+ ### 5. Backend Startup Fixes
46
+ - `main.py` now loads dotenv before importing config
47
+ - `main.py` creates `OUTPUT_DIR` before mounting static files to avoid startup crashes
48
+
49
+ ---
50
+
51
+ ## Frontend Updates
52
+
53
+ ### 1. Centralized API Client
54
+ Created `frontend/src/lib/api.ts` to handle all API calls with:
55
+ - Proper base URL (`http://localhost:8000/api`)
56
+ - Type definitions for API responses
57
+ - Asset URL fixing (prepends backend base URL to relative paths)
58
+
59
+ ### 2. Updated Pages
60
+ - **Home.tsx**: Now uses `generateAssets` from API client instead of direct fetch
61
+ - **Studio.tsx**:
62
+ - Now uses `getJobStatus` and `getJobResult` from API client
63
+ - Added collapsible panel to show the scene description
64
+ - Added error state for pipeline stages
65
+ - Added red error indicator and error message display
66
+
67
+ ### 3. Added Types
68
+ - `JobStatus` interface
69
+ - `JobResult` interface (includes `scene_description`)
70
+
71
+ ---
72
+
73
+ ## Files Modified
74
+
75
+ ### Backend
76
+ - [`backend/main.py`](file:///c:\AI Native founder\AI_Engineering\Projects\Multiverse_AI_Studio\backend\main.py)
77
+ - [`backend/config.py`](file:///c:\AI Native founder\AI_Engineering\Projects\Multiverse_AI_Studio\backend\config.py)
78
+ - [`backend/api/routes.py`](file:///c:\AI Native founder\AI_Engineering\Projects\Multiverse_AI_Studio\backend\api\routes.py)
79
+ - [`backend/services/pipeline.py`](file:///c:\AI Native founder\AI_Engineering\Projects\Multiverse_AI_Studio\backend\services\pipeline.py)
80
+ - [`backend/utils/job_store.py`](file:///c:\AI Native founder\AI_Engineering\Projects\Multiverse_AI_Studio\backend\utils\job_store.py)
81
+ - [`backend/utils/file_manager.py`](file:///c:\AI Native founder\AI_Engineering\Projects\Multiverse_AI_Studio\backend\utils\file_manager.py)
82
+ - [`backend/models/prompt_expander.py`](file:///c:\AI Native founder\AI_Engineering\Projects\Multiverse_AI_Studio\backend\models\prompt_expander.py)
83
+ - [`backend/models/image_generator.py`](file:///c:\AI Native founder\AI_Engineering\Projects\Multiverse_AI_Studio\backend\models\image_generator.py)
84
+ - [`backend/models/depth_estimator.py`](file:///c:\AI Native founder\AI_Engineering\Projects\Multiverse_AI_Studio\backend\models\depth_estimator.py)
85
+ - [`backend/models/audio_generator.py`](file:///c:\AI Native founder\AI_Engineering\Projects\Multiverse_AI_Studio\backend\models\audio_generator.py)
86
+ - [`backend/models/video_generator.py`](file:///c:\AI Native founder\AI_Engineering\Projects\Multiverse_AI_Studio\backend\models\video_generator.py)
87
+
88
+ ### Frontend
89
+ - [`frontend/src/pages/Home.tsx`](file:///c:\AI Native founder\AI_Engineering\Projects\Multiverse_AI_Studio\frontend\src\pages\Home.tsx)
90
+ - [`frontend/src/pages/Studio.tsx`](file:///c:\AI Native founder\AI_Engineering\Projects\Multiverse_AI_Studio\frontend\src\pages\Studio.tsx)
91
+
92
+ ---
93
+
94
+ ## New Files Created
95
+
96
+ ### Backend
97
+ - [`backend/api/__init__.py`](file:///c:\AI Native founder\AI_Engineering\Projects\Multiverse_AI_Studio\backend\api\__init__.py) (empty)
98
+ - [`backend/services/__init__.py`](file:///c:\AI Native founder\AI_Engineering\Projects\Multiverse_AI_Studio\backend\services\__init__.py) (empty)
99
+ - [`backend/utils/__init__.py`](file:///c:\AI Native founder\AI_Engineering\Projects\Multiverse_AI_Studio\backend\utils\__init__.py) (empty)
100
+ - [`backend/models/__init__.py`](file:///c:\AI Native founder\AI_Engineering\Projects\Multiverse_AI_Studio\backend\models\__init__.py) (empty)
101
+
102
+ ### Frontend
103
+ - [`frontend/src/lib/api.ts`](file:///c:\AI Native founder\AI_Engineering\Projects\Multiverse_AI_Studio\frontend\src\lib\api.ts)
104
+
105
+ ### Project Root
106
+ - [`.gitignore`](file:///c:\AI Native founder\AI_Engineering\Projects\Multiverse_AI_Studio\.gitignore)
107
+ - [`TRAE-Skills/`](file:///c:\AI Native founder\AI_Engineering\Projects\Multiverse_AI_Studio\TRAE-Skills) (cloned repo)
108
+ - [`REPORT.md`](file:///c:\AI Native founder\AI_Engineering\Projects\Multiverse_AI_Studio\REPORT.md) (this file!)
109
+
110
+ ---
111
+
112
+ ## Next Steps
113
+ - Test the full pipeline end-to-end
114
+ - Add model download caching
115
+ - Add more comprehensive error handling in frontend
116
+ - Deploy to production
TRAE-Skills/LICENSE ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ TRAE Skills License Agreement
2
+ Version 1.0
3
+
4
+ Copyright (c) 2026 HighMark-IT
5
+
6
+ 1. GRANT OF RIGHTS
7
+
8
+ You are granted a non-exclusive, royalty-free right to use, copy, modify, and distribute this software and its associated documentation files (the "Software") for personal, educational, and commercial purposes, subject to the conditions outlined in this License.
9
+
10
+ 2. CONDITIONS AND RESTRICTIONS
11
+
12
+ A. Proper Attribution Required
13
+ - You MUST include clear attribution to this repository (https://github.com/HighMark-31/TRAE-Agents) and its author (HighMark-IT) in any derivative work, product, or project that incorporates or uses the Software or its agent structures.
14
+ - Attribution must be visible and accessible to end users.
15
+
16
+ B. No Republication of Original Agents
17
+ - You MAY NOT republish, redistribute, or present the original agents or substantially unmodified versions of them as your own public collection, product suite, or template library.
18
+ - You cannot claim ownership of the "TRAE Agents" collection, the specific agent names, or the overall ecosystem as originally created in this repository.
19
+ - Minor modifications (e.g., parameter tweaks, prompt rewording) do not constitute a new original work and remain subject to this restriction.
20
+
21
+ C. Prohibited Agent Rebranding
22
+ - You MAY NOT use the names "TRAE Agents", "TRAE-Agents", or the specific agent names (e.g., "General Coordinator", "Code Optimizer", "Security Sentinel") as if they were your original creation or branding.
23
+ - You must create distinctly different naming and branding if you publish agent collections based on this work.
24
+
25
+ D. Original Works Permitted
26
+ - Creating your own agents or agent frameworks INSPIRED BY this project is permitted, provided they are:
27
+ 1. Materially different in structure, purpose, or implementation
28
+ 2. Given original names and branding
29
+ 3. Properly attributed to this repository as inspiration
30
+
31
+ 3. COMMERCIAL USE
32
+
33
+ You are permitted to use the Software in commercial products and services, provided that:
34
+ - You maintain proper attribution to this repository
35
+ - You do not republish the original agent collection as your own
36
+ - You do not claim ownership of the TRAE Agents ecosystem
37
+
38
+ 4. MODIFICATIONS AND DERIVATIVES
39
+
40
+ You may modify the Software for your own use. If you distribute modified versions, you must:
41
+ - Clearly mark modifications as your own
42
+ - Maintain attribution to the original work
43
+ - Not present near-identical versions as original creations
44
+
45
+ 5. NO WARRANTY
46
+
47
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
48
+
49
+ 6. ENFORCEMENT
50
+
51
+ Breach of conditions outlined in Section 2 may result in:
52
+ - Cease and desist notices
53
+ - Requests for content removal from public platforms
54
+ - Legal action to enforce compliance with this License
55
+
56
+ 7. SEVERABILITY
57
+
58
+ If any provision of this License is found to be unenforceable, the remaining provisions shall remain in full force and effect.
59
+
60
+ 8. GOVERNING LAW
61
+
62
+ This License is governed by applicable copyright and intellectual property laws. The Copyright holder reserves the right to modify these terms with notice.
63
+
64
+ By using this Software, you acknowledge that you have read, understood, and agree to be bound by all terms of this License.
TRAE-Skills/README.md ADDED
@@ -0,0 +1,240 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div align="center">
2
+
3
+ ### ✨ The Ultimate AI Skill Library for Modern Development ✨
4
+
5
+ </div>
6
+
7
+ # [TRAE](https://www.trae.ai/) Skills Collection
8
+
9
+ **_The Largest, Most Complete, and Popular Collection of TRAE Skills._**
10
+
11
+ A powerful collection of **expert-level TRAE Skills**, designed to standardize and elevate every stage of modern software development.
12
+ These skills act as a knowledge base for agents, enabling them to generate production-ready code, follow best practices, and handle complex architectural tasks across multiple stacks.
13
+
14
+ Perfect for developers, engineers, and teams seeking **consistency, quality, and expert-level output** in every interaction.
15
+
16
+
17
+ ---
18
+
19
+ [![Star the project](https://img.shields.io/badge/⭐_Star_the_Project-black?style=for-the-badge)](https://github.com/HighMark-31/TRAE-Skills/stargazers) ![Visitors](https://visitor-badge.laobi.icu/badge?page_id=HighMark-31.TRAE-Skills)
20
+
21
+ ---
22
+
23
+ ## 📍 Skill List
24
+
25
+ | Category | Skill Name | Info | View |
26
+ | :--- | :--- | :--- | :--- |
27
+ | **🔹 ️ Frontend** | Accessibility Audit | [ℹ️](./frontend/Accessibility_Audit.md) | [👆 View](./frontend/Accessibility_Audit.md) |
28
+ | | API Data Fetching (TanStack) | [ℹ️](./frontend/API_Data_Fetching_TanStack.md) | [👆 View](./frontend/API_Data_Fetching_TanStack.md) |
29
+ | | Authentication Strategy Selection | [ℹ️](./architecture/Authentication_Strategy_Selection.md) | [👆 View](./architecture/Authentication_Strategy_Selection.md) |
30
+ | | BFF Pattern Implementation | [ℹ️](./architecture/BFF_Pattern_Implementation.md) | [👆 View](./architecture/BFF_Pattern_Implementation.md) |
31
+ | | Code Review Security Checklist | [ℹ️](./security/Code_Review_Security.md) | [👆 View](./security/Code_Review_Security.md) |
32
+ | | Custom React Hook Creation | [ℹ️](./frontend/Custom_React_Hook_Creation.md) | [👆 View](./frontend/Custom_React_Hook_Creation.md) |
33
+ | | Database Selection (SQL vs NoSQL) | [ℹ️](./architecture/Database_Selection_SQL_vs_NoSQL.md) | [👆 View](./architecture/Database_Selection_SQL_vs_NoSQL.md) |
34
+ | | E2E Testing (Playwright) | [ℹ️](./testing/E2E_Testing_Playwright.md) | [👆 View](./testing/E2E_Testing_Playwright.md) |
35
+ | | Event Driven Architecture | [ℹ️](./architecture/Event_Driven_Architecture_Basics.md) | [👆 View](./architecture/Event_Driven_Architecture_Basics.md) |
36
+ | | Form Handling (ReactHookForm) | [ℹ️](./frontend/Form_Handling_ReactHookForm.md) | [👆 View](./frontend/Form_Handling_ReactHookForm.md) |
37
+ | | Frontend Error Boundary | [ℹ️](./frontend/Frontend_Error_Boundary.md) | [👆 View](./frontend/Frontend_Error_Boundary.md) |
38
+ | | Frontend-Backend Communication | [ℹ️](./architecture/Frontend_Backend_Communication_Patterns.md) | [👆 View](./architecture/Frontend_Backend_Communication_Patterns.md) |
39
+ | | Global State (Redux Toolkit) | [ℹ️](./frontend/Global_State_Management_Redux.md) | [👆 View](./frontend/Global_State_Management_Redux.md) |
40
+ | | Input Validation (Zod) | [ℹ️](./security/Input_Validation_Zod.md) | [👆 View](./security/Input_Validation_Zod.md) |
41
+ | | Internationalization (i18n) | [ℹ️](./frontend/Internationalization_i18n.md) | [👆 View](./frontend/Internationalization_i18n.md) |
42
+ | | JWT Authentication | [ℹ️](./security/JWT_Authentication.md) | [👆 View](./security/JWT_Authentication.md) |
43
+ | | Microservices vs Monolith | [ℹ️](./architecture/Microservices_vs_Monolith_Decision.md) | [👆 View](./architecture/Microservices_vs_Monolith_Decision.md) |
44
+ | | Multi-Tenancy Architecture | [ℹ️](./architecture/Multi_Tenancy_Architecture.md) | [👆 View](./architecture/Multi_Tenancy_Architecture.md) |
45
+ | | Rate Limiting (Redis) | [ℹ️](./security/Rate_Limiting_Redis.md) | [👆 View](./security/Rate_Limiting_Redis.md) |
46
+ | | RBAC Implementation | [ℹ️](./security/RBAC_Implementation.md) | [👆 View](./security/RBAC_Implementation.md) |
47
+ | | React Component Optimization | [ℹ️](./frontend/React_Component_Optimization.md) | [👆 View](./frontend/React_Component_Optimization.md) |
48
+ | | Responsive UI (Tailwind) | [ℹ️](./frontend/Responsive_UI_Design_Tailwind.md) | [👆 View](./frontend/Responsive_UI_Design_Tailwind.md) |
49
+ | | REST vs GraphQL Selection | [ℹ️](./architecture/REST_vs_GraphQL_Selection.md) | [👆 View](./architecture/REST_vs_GraphQL_Selection.md) |
50
+ | | Route Protection (React Router) | [ℹ️](./frontend/Route_Protection_React_Router.md) | [👆 View](./frontend/Route_Protection_React_Router.md) |
51
+ | | Scaling Strategies | [ℹ️](./architecture/Scaling_Strategies_Horizontal_vs_Vertical.md) | [👆 View](./architecture/Scaling_Strategies_Horizontal_vs_Vertical.md) |
52
+ | | Secure Env Var Handling | [ℹ️](./security/Secure_Env_Var_Handling.md) | [👆 View](./security/Secure_Env_Var_Handling.md) |
53
+ | | Serverless Architecture | [ℹ️](./architecture/Serverless_Architecture_Considerations.md) | [👆 View](./architecture/Serverless_Architecture_Considerations.md) |
54
+ | | SSR vs CSR Decision | [ℹ️](./architecture/SSR_vs_CSR_Decision_Matrix.md) | [👆 View](./architecture/SSR_vs_CSR_Decision_Matrix.md) |
55
+ | | Stack Selection Criteria | [ℹ️](./architecture/Stack_Selection_Criteria.md) | [👆 View](./architecture/Stack_Selection_Criteria.md) |
56
+ | | Unit Test Generation (Jest) | [ℹ️](./testing/Unit_Test_Generation_Jest.md) | [👆 View](./testing/Unit_Test_Generation_Jest.md) |
57
+ | **💻 Backend** | API REST Endpoint Design | [ℹ️](./backend/API_REST_Endpoint_Design.md) | [👆 View](./backend/API_REST_Endpoint_Design.md) |
58
+ | | API Versioning Strategies | [ℹ️](./backend/API_Versioning_Strategies.md) | [👆 View](./backend/API_Versioning_Strategies.md) |
59
+ | | Background Jobs with BullMQ | [ℹ️](./backend/Background_Jobs_BullMQ.md) | [👆 View](./backend/Background_Jobs_BullMQ.md) |
60
+ | | Caching Strategy (Redis) | [ℹ️](./backend/Caching_Strategy_Redis.md) | [👆 View](./backend/Caching_Strategy_Redis.md) |
61
+ | | Database Locking Strategies | [ℹ️](./backend/Database_Locking_Strategies.md) | [👆 View](./backend/Database_Locking_Strategies.md) |
62
+ | | Database Schema Migration | [ℹ️](./backend/Database_Schema_Migration.md) | [👆 View](./backend/Database_Schema_Migration.md) |
63
+ | | Database Seeding | [ℹ️](./backend/Database_Seeding.md) | [👆 View](./backend/Database_Seeding.md) |
64
+ | | Error Handling (Express) | [ℹ️](./backend/Error_Handling_Express.md) | [👆 View](./backend/Error_Handling_Express.md) |
65
+ | | Express Middleware Creation | [ℹ️](./backend/Express_Middleware_Creation.md) | [👆 View](./backend/Express_Middleware_Creation.md) |
66
+ | | Feature Flag Implementation | [ℹ️](./backend/Feature_Flag_Implementation.md) | [👆 View](./backend/Feature_Flag_Implementation.md) |
67
+ | | File Storage (S3/MinIO) | [ℹ️](./backend/File_Storage_S3_MinIO.md) | [👆 View](./backend/File_Storage_S3_MinIO.md) |
68
+ | | File Upload Handling | [ℹ️](./backend/File_Upload_Handling.md) | [👆 View](./backend/File_Upload_Handling.md) |
69
+ | | GraphQL Schema Design | [ℹ️](./backend/GraphQL_Schema_Design.md) | [👆 View](./backend/GraphQL_Schema_Design.md) |
70
+ | | gRPC Service Implementation | [ℹ️](./backend/gRPC_Service_Implementation.md) | [👆 View](./backend/gRPC_Service_Implementation.md) |
71
+ | | Handling Distributed Transactions (Sagas) | [ℹ️](./backend/Distributed_Transactions_Sagas.md) | [👆 View](./backend/Distributed_Transactions_Sagas.md) |
72
+ | | Health Check Endpoint | [ℹ️](./backend/Health_Check_Endpoint.md) | [👆 View](./backend/Health_Check_Endpoint.md) |
73
+ | | Implementing OAuth2 Providers | [ℹ️](./backend/OAuth2_Provider_Implementation.md) | [👆 View](./backend/OAuth2_Provider_Implementation.md) |
74
+ | | Implementing Search (Elasticsearch) | [ℹ️](./backend/Elasticsearch_Integration.md) | [👆 View](./backend/Elasticsearch_Integration.md) |
75
+ | | Logger Configuration (Winston) | [ℹ️](./backend/Logger_Configuration_Winston.md) | [👆 View](./backend/Logger_Configuration_Winston.md) |
76
+ | | Message Queue Implementation | [ℹ️](./backend/Message_Queue_Implementation.md) | [👆 View](./backend/Message_Queue_Implementation.md) |
77
+ | | Microservice Communication | [ℹ️](./backend/Microservice_Communication.md) | [👆 View](./backend/Microservice_Communication.md) |
78
+ | | MongoDB Aggregation Pipeline | [ℹ️](./backend/MongoDB_Aggregation.md) | [👆 View](./backend/MongoDB_Aggregation.md) |
79
+ | | Multi-factor Authentication (MFA) | [ℹ️](./backend/MFA_Implementation.md) | [👆 View](./backend/MFA_Implementation.md) |
80
+ | | Node.js Stream Processing | [ℹ️](./backend/Nodejs_Streams.md) | [👆 View](./backend/Nodejs_Streams.md) |
81
+ | | Pagination Implementation | [ℹ️](./backend/Pagination_Implementation.md) | [👆 View](./backend/Pagination_Implementation.md) |
82
+ | | PostgreSQL Indexing Strategies | [ℹ️](./backend/PostgreSQL_Indexing.md) | [👆 View](./backend/PostgreSQL_Indexing.md) |
83
+ | | Prisma Schema Design | [ℹ️](./backend/Prisma_Schema_Design.md) | [👆 View](./backend/Prisma_Schema_Design.md) |
84
+ | | Redis Data Structures | [ℹ️](./backend/Redis_Data_Structures.md) | [👆 View](./backend/Redis_Data_Structures.md) |
85
+ | | Refactoring Legacy Controller | [ℹ️](./backend/Refactoring_Legacy_Controller.md) | [👆 View](./backend/Refactoring_Legacy_Controller.md) |
86
+ | | Role-Based Access Control (Advanced) | [ℹ️](./backend/Advanced_RBAC.md) | [👆 View](./backend/Advanced_RBAC.md) |
87
+ | | Session Management Best Practices | [ℹ️](./backend/Session_Management_Best_Practices.md) | [👆 View](./backend/Session_Management_Best_Practices.md) |
88
+ | | Soft Delete Implementation | [ℹ️](./backend/Soft_Delete_Implementation.md) | [👆 View](./backend/Soft_Delete_Implementation.md) |
89
+ | | SQL Query Optimization | [ℹ️](./backend/SQL_Query_Optimization.md) | [👆 View](./backend/SQL_Query_Optimization.md) |
90
+ | | Swagger Documentation | [ℹ️](./backend/Swagger_Documentation.md) | [👆 View](./backend/Swagger_Documentation.md) |
91
+ | | Transaction Management | [ℹ️](./backend/Transaction_Management.md) | [👆 View](./backend/Transaction_Management.md) |
92
+ | | TypeORM Entity Relations | [ℹ️](./backend/TypeORM_Relations.md) | [👆 View](./backend/TypeORM_Relations.md) |
93
+ | | Webhooks Implementation | [ℹ️](./backend/Webhooks_Implementation.md) | [👆 View](./backend/Webhooks_Implementation.md) |
94
+ | | WebSocket Implementation | [ℹ️](./backend/WebSocket_Implementation.md) | [👆 View](./backend/WebSocket_Implementation.md) |
95
+ | | Real-time Data Processing (Kafka) | [ℹ️](./backend/Real-time_Data_Processing_Kafka.md) | [👆 View](./backend/Real-time_Data_Processing_Kafka.md) |
96
+ | | Real-time GraphQL Subscriptions | [ℹ️](./backend/GraphQL_Subscriptions_Realtime.md) | [👆 View](./backend/GraphQL_Subscriptions_Realtime.md) |
97
+ | | WebSocket Scalability (Socket.io) | [ℹ️](./backend/WebSocket_Scalability_SocketIO.md) | [👆 View](./backend/WebSocket_Scalability_SocketIO.md) |
98
+ | | Type-Safe APIs with tRPC | [ℹ️](./backend/Type_Safe_APIs_tRPC.md) | [👆 View](./backend/Type_Safe_APIs_tRPC.md) |
99
+ | | Serverless Streaming & Webhooks at Scale | [ℹ️](./backend/Serverless_Streaming_Webhooks.md) | [👆 View](./backend/Serverless_Streaming_Webhooks.md) |
100
+ | **🖥️ Frontend** | Browser Storage (LocalStorage/IndexedDB) | [ℹ️](./frontend/Browser_Storage.md) | [👆 View](./frontend/Browser_Storage.md) |
101
+ | | Canvas/WebGL Basics (Three.js) | [ℹ️](./frontend/Canvas_Threejs_Basics.md) | [👆 View](./frontend/Canvas_Threejs_Basics.md) |
102
+ | | CSS Grid vs Flexbox Guide | [ℹ️](./frontend/CSS_Grid_vs_Flexbox.md) | [👆 View](./frontend/CSS_Grid_vs_Flexbox.md) |
103
+ | | Dark Mode Implementation | [ℹ️](./frontend/Dark_Mode_Implementation.md) | [👆 View](./frontend/Dark_Mode_Implementation.md) |
104
+ | | Handling Large Lists (Virtualization) | [ℹ️](./frontend/Handling_Large_Lists_Virtualization.md) | [👆 View](./frontend/Handling_Large_Lists_Virtualization.md) |
105
+ | | Mobile-First Design Principles | [ℹ️](./frontend/Mobile_First_Design.md) | [👆 View](./frontend/Mobile_First_Design.md) |
106
+ | | Next.js App Router Migration | [ℹ️](./frontend/Nextjs_App_Router.md) | [👆 View](./frontend/Nextjs_App_Router.md) |
107
+ | | Optimizing Web Vitals | [ℹ️](./frontend/Web_Vitals_Optimization.md) | [👆 View](./frontend/Web_Vitals_Optimization.md) |
108
+ | | PWA Implementation | [ℹ️](./frontend/PWA_Implementation.md) | [👆 View](./frontend/PWA_Implementation.md) |
109
+ | | React Context vs Zustand | [ℹ️](./frontend/React_Context_vs_Zustand.md) | [👆 View](./frontend/React_Context_vs_Zustand.md) |
110
+ | | Storybook Component Documentation | [ℹ️](./frontend/Storybook_Component_Documentation.md) | [👆 View](./frontend/Storybook_Component_Documentation.md) |
111
+ | | SVG Animation Techniques | [ℹ️](./frontend/SVG_Animation_Techniques.md) | [👆 View](./frontend/SVG_Animation_Techniques.md) |
112
+ | | Testing React Components (RTL) | [ℹ️](./frontend/React_Testing_Library.md) | [👆 View](./frontend/React_Testing_Library.md) |
113
+ | | Web Workers for Heavy Computation | [ℹ️](./frontend/Web_Workers.md) | [👆 View](./frontend/Web_Workers.md) |
114
+ | | Advanced WebGL with Three.js | [ℹ️](./frontend/WebGL_Advanced_Threejs.md) | [👆 View](./frontend/WebGL_Advanced_Threejs.md) |
115
+ | | Advanced Web Animations with Framer Motion | [ℹ️](./frontend/Web_Animations_Framer_Motion.md) | [👆 View](./frontend/Web_Animations_Framer_Motion.md) |
116
+ | **📱 Mobile** | App Store Deployment Guide | [ℹ️](./mobile/App_Store_Deployment_Guide.md) | [👆 View](./mobile/App_Store_Deployment_Guide.md) |
117
+ | | Mobile Device Features | [ℹ️](./mobile/Mobile_Device_Features.md) | [👆 View](./mobile/Mobile_Device_Features.md) |
118
+ | | Mobile UI Styling (NativeWind) | [ℹ️](./mobile/Mobile_UI_Styling_NativeWind.md) | [👆 View](./mobile/Mobile_UI_Styling_NativeWind.md) |
119
+ | | Offline-First Mobile Architecture | [ℹ️](./mobile/Offline_First_Mobile_Architecture.md) | [👆 View](./mobile/Offline_First_Mobile_Architecture.md) |
120
+ | | Push Notifications Setup | [ℹ️](./mobile/Push_Notifications_Setup.md) | [👆 View](./mobile/Push_Notifications_Setup.md) |
121
+ | | React Native Navigation | [ℹ️](./mobile/React_Native_Navigation.md) | [👆 View](./mobile/React_Native_Navigation.md) |
122
+ | | React Native Reanimated | [ℹ️](./mobile/React_Native_Reanimated.md) | [👆 View](./mobile/React_Native_Reanimated.md) |
123
+ | | React Native Setup (Expo) | [ℹ️](./mobile/React_Native_Setup_Expo.md) | [👆 View](./mobile/React_Native_Setup_Expo.md) |
124
+ | | Biometric Authentication (Expo) | [ℹ️](./mobile/Biometric_Authentication_Expo.md) | [👆 View](./mobile/Biometric_Authentication_Expo.md) |
125
+ | | Deep Linking (React Navigation) | [ℹ️](./mobile/Deep_Linking_React_Navigation.md) | [👆 View](./mobile/Deep_Linking_React_Navigation.md) |
126
+ | | Flutter Advanced State Management | [ℹ️](./mobile/Flutter_Advanced_State_Management.md) | [👆 View](./mobile/Flutter_Advanced_State_Management.md) |
127
+ | | React Native Performance Optimization | [ℹ️](./mobile/React_Native_Performance_Optimization.md) | [👆 View](./mobile/React_Native_Performance_Optimization.md) |
128
+ | **🔧 DevOps** | Ansible Playbook Creation | [ℹ️](./devops/Ansible_Playbook_Creation.md) | [👆 View](./devops/Ansible_Playbook_Creation.md) |
129
+ | | Automated Database Backups | [ℹ️](./devops/Automated_Database_Backups.md) | [👆 View](./devops/Automated_Database_Backups.md) |
130
+ | | AWS Lambda Function Design | [ℹ️](./devops/AWS_Lambda_Function_Design.md) | [👆 View](./devops/AWS_Lambda_Function_Design.md) |
131
+ | | AWS Secrets Manager Integration | [ℹ️](./devops/AWS_Secrets_Manager_Integration.md) | [👆 View](./devops/AWS_Secrets_Manager_Integration.md) |
132
+ | | Azure Functions Basics | [ℹ️](./devops/Azure_Functions_Basics.md) | [👆 View](./devops/Azure_Functions_Basics.md) |
133
+ | | Blue/Green Deployment | [ℹ️](./devops/Blue_Green_Deployment_Strategy.md) | [👆 View](./devops/Blue_Green_Deployment_Strategy.md) |
134
+ | | Chaos Engineering Basics | [ℹ️](./devops/Chaos_Engineering_Basics.md) | [👆 View](./devops/Chaos_Engineering_Basics.md) |
135
+ | | CI Pipeline (GitHub Actions) | [ℹ️](./devops/CI_Pipeline_GitHub_Actions.md) | [👆 View](./devops/CI_Pipeline_GitHub_Actions.md) |
136
+ | | Cost Optimization (AWS/Cloud) | [ℹ️](./devops/Cost_Optimization_Cloud.md) | [👆 View](./devops/Cost_Optimization_Cloud.md) |
137
+ | | Dependency Update Audit | [ℹ️](./devops/Dependency_Update_Audit.md) | [👆 View](./devops/Dependency_Update_Audit.md) |
138
+ | | Docker Containerization (Node) | [ℹ️](./devops/Docker_Containerization_Node.md) | [👆 View](./devops/Docker_Containerization_Node.md) |
139
+ | | Git Branching Strategy | [ℹ️](./devops/Git_Branching_Strategy.md) | [👆 View](./devops/Git_Branching_Strategy.md) |
140
+ | | Google Cloud Run Deployment | [ℹ️](./devops/Google_Cloud_Run_Deployment.md) | [👆 View](./devops/Google_Cloud_Run_Deployment.md) |
141
+ | | Infrastructure as Code (Terraform) | [ℹ️](./devops/Infrastructure_as_Code_Terraform.md) | [👆 View](./devops/Infrastructure_as_Code_Terraform.md) |
142
+ | | K8s Deployment Manifests | [ℹ️](./devops/Kubernetes_Deployment_Manifests.md) | [👆 View](./devops/Kubernetes_Deployment_Manifests.md) |
143
+ | | Log Aggregation (ELK) | [ℹ️](./devops/Log_Aggregation_ELK.md) | [👆 View](./devops/Log_Aggregation_ELK.md) |
144
+ | | Monitoring with Datadog | [ℹ️](./devops/Monitoring_with_Datadog.md) | [👆 View](./devops/Monitoring_with_Datadog.md) |
145
+ | | Nginx Reverse Proxy Setup | [ℹ️](./devops/Nginx_Reverse_Proxy_Setup.md) | [👆 View](./devops/Nginx_Reverse_Proxy_Setup.md) |
146
+ | | Prometheus & Grafana Monitoring | [ℹ️](./devops/Prometheus_Grafana_Monitoring.md) | [👆 View](./devops/Prometheus_Grafana_Monitoring.md) |
147
+ | | Sentry Error Tracking Setup | [ℹ️](./devops/Sentry_Error_Tracking.md) | [👆 View](./devops/Sentry_Error_Tracking.md) |
148
+ | | Serverless Framework Setup | [ℹ️](./devops/Serverless_Framework_Setup.md) | [👆 View](./devops/Serverless_Framework_Setup.md) |
149
+ | | SSL/TLS Setup (Certbot) | [ℹ️](./devops/SSL_TLS_Certbot_Setup.md) | [👆 View](./devops/SSL_TLS_Certbot_Setup.md) |
150
+ | | Terraform Best Practices (Advanced) | [ℹ️](./devops/Terraform_Advanced.md) | [👆 View](./devops/Terraform_Advanced.md) |
151
+ | | Docker Swarm Orchestration | [ℹ️](./devops/Docker_Swarm_Orchestration.md) | [👆 View](./devops/Docker_Swarm_Orchestration.md) |
152
+ | | Kubernetes Helm Charts | [ℹ️](./devops/Kubernetes_Helm_Charts.md) | [👆 View](./devops/Kubernetes_Helm_Charts.md) |
153
+ | | Edge Computing with Vercel & Cloudflare Workers | [ℹ️](./devops/Edge_Computing_Vercel_Cloudflare.md) | [👆 View](./devops/Edge_Computing_Vercel_Cloudflare.md) |
154
+ | **🛡️ Security** | Content Security Policy (CSP) Setup | [ℹ️](./security/Content_Security_Policy_CSP.md) | [👆 View](./security/Content_Security_Policy_CSP.md) |
155
+ | | CSRF Protection Strategies | [ℹ️](./security/CSRF_Protection_Strategies.md) | [👆 View](./security/CSRF_Protection_Strategies.md) |
156
+ | | Dependency Vulnerability Scanning | [ℹ️](./security/Dependency_Vulnerability_Scanning.md) | [👆 View](./security/Dependency_Vulnerability_Scanning.md) |
157
+ | | OWASP Top 10 Mitigation | [ℹ️](./security/OWASP_Top_10_Mitigation.md) | [👆 View](./security/OWASP_Top_10_Mitigation.md) |
158
+ | | Secret Scanning in CI/CD | [ℹ️](./security/Secret_Scanning_CI_CD.md) | [👆 View](./security/Secret_Scanning_CI_CD.md) |
159
+ | | XSS Prevention Guide | [ℹ️](./security/XSS_Prevention_Guide.md) | [👆 View](./security/XSS_Prevention_Guide.md) |
160
+ | | CORS Configuration Best Practices | [ℹ️](./security/CORS_Configuration_Best_Practices.md) | [👆 View](./security/CORS_Configuration_Best_Practices.md) |
161
+ | | SQL Injection Prevention | [ℹ️](./security/SQL_Injection_Prevention.md) | [👆 View](./security/SQL_Injection_Prevention.md) |
162
+ | | OAuth2 & OIDC Implementation | [ℹ️](./security/OAuth2_OIDC_Implementation.md) | [👆 View](./security/OAuth2_OIDC_Implementation.md) |
163
+ | | Password Hashing Best Practices | [ℹ️](./security/Password_Hashing_Best_Practices.md) | [👆 View](./security/Password_Hashing_Best_Practices.md) |
164
+ | | Multi-factor Authentication (MFA) | [ℹ️](./backend/MFA_Implementation.md) | [👆 View](./backend/MFA_Implementation.md) |
165
+ | | API Security Penetration Testing | [ℹ️](./security/API_Security_Penetration_Testing.md) | [👆 View](./security/API_Security_Penetration_Testing.md) |
166
+ | | Zero Trust Architecture Implementation | [ℹ️](./security/Zero_Trust_Architecture.md) | [👆 View](./security/Zero_Trust_Architecture.md) |
167
+ | **🧪 Testing** | API Integration Testing (Supertest) | [ℹ️](./testing/API_Integration_Testing_Supertest.md) | [👆 View](./testing/API_Integration_Testing_Supertest.md) |
168
+ | | Visual Regression Testing (Playwright) | [ℹ️](./testing/Visual_Regression_Testing_Playwright.md) | [👆 View](./testing/Visual_Regression_Testing_Playwright.md) |
169
+ | | Load & Performance Testing (k6) | [ℹ️](./testing/Load_Testing_k6.md) | [👆 View](./testing/Load_Testing_k6.md) |
170
+ | | Contract Testing (Pact) | [ℹ️](./testing/Consumer_Driven_Contract_Testing_Pact.md) | [👆 View](./testing/Consumer_Driven_Contract_Testing_Pact.md) |
171
+ | | Mutation Testing (Stryker) | [ℹ️](./testing/Mutation_Testing_Stryker.md) | [👆 View](./testing/Mutation_Testing_Stryker.md) |
172
+ | | Automated Accessibility Testing (Axe-core) | [ℹ️](./testing/Automated_Accessibility_Testing_Axe.md) | [👆 View](./testing/Automated_Accessibility_Testing_Axe.md) |
173
+ | | Snapshot Testing (Jest) | [ℹ️](./testing/Snapshot_Testing_Jest.md) | [👆 View](./testing/Snapshot_Testing_Jest.md) |
174
+ | | Test-Driven Development (TDD) | [ℹ️](./testing/Test_Driven_Development_TDD.md) | [👆 View](./testing/Test_Driven_Development_TDD.md) |
175
+ | | Component Testing (RTL) | [ℹ️](./testing/Component_Testing_React_Testing_Library.md) | [👆 View](./testing/Component_Testing_React_Testing_Library.md) |
176
+ | | Mocking External Services (Jest) | [ℹ️](./testing/Mocking_External_Services_Jest.md) | [👆 View](./testing/Mocking_External_Services_Jest.md) |
177
+ | | Test Coverage & Quality (Istanbul) | [ℹ️](./testing/Test_Coverage_Quality_Istanbul.md) | [👆 View](./testing/Test_Coverage_Quality_Istanbul.md) |
178
+ | | Performance Testing with Lighthouse | [ℹ️](./testing/Performance_Testing_Lighthouse.md) | [👆 View](./testing/Performance_Testing_Lighthouse.md) |
179
+ | | Advanced End-to-End Testing with Playwright | [ℹ️](./testing/End-to-End_Testing_Playwright_Advanced.md) | [👆 View](./testing/End-to-End_Testing_Playwright_Advanced.md) |
180
+ | **🤖 AI Engineering** | AI Agent Design Patterns | [ℹ️](./ai_engineering/AI_Agent_Design_Patterns.md) | [👆 View](./ai_engineering/AI_Agent_Design_Patterns.md) |
181
+ | | AI Model Evaluation | [ℹ️](./ai_engineering/AI_Model_Evaluation.md) | [👆 View](./ai_engineering/AI_Model_Evaluation.md) |
182
+ | | Fine-tuning Basics | [ℹ️](./ai_engineering/Fine_tuning_Basics.md) | [👆 View](./ai_engineering/Fine_tuning_Basics.md) |
183
+ | | LangChain Basics | [ℹ️](./ai_engineering/LangChain_Basics.md) | [👆 View](./ai_engineering/LangChain_Basics.md) |
184
+ | | Local LLM Running (Ollama) | [ℹ️](./ai_engineering/Local_LLM_Running_Ollama.md) | [👆 View](./ai_engineering/Local_LLM_Running_Ollama.md) |
185
+ | | OpenAI API Integration | [ℹ️](./ai_engineering/OpenAI_API_Integration.md) | [👆 View](./ai_engineering/OpenAI_API_Integration.md) |
186
+ | | Prompt Engineering Basics | [ℹ️](./ai_engineering/Prompt_Engineering_Basics.md) | [👆 View](./ai_engineering/Prompt_Engineering_Basics.md) |
187
+ | | RAG System Architecture | [ℹ️](./ai_engineering/RAG_System_Architecture.md) | [👆 View](./ai_engineering/RAG_System_Architecture.md) |
188
+ | | Speech-to-Text Implementation (Whisper) | [ℹ️](./ai_engineering/Speech_to_Text_Whisper.md) | [👆 View](./ai_engineering/Speech_to_Text_Whisper.md) |
189
+ | | Vector Database Setup | [ℹ️](./ai_engineering/Vector_Database_Setup.md) | [👆 View](./ai_engineering/Vector_Database_Setup.md) |
190
+ | | ML Model Quantization | [ℹ️](./ai_engineering/ML_Model_Quantization.md) | [👆 View](./ai_engineering/ML_Model_Quantization.md) |
191
+ | | Time Series Forecasting | [ℹ️](./ai_engineering/Time_Series_Forecasting.md) | [👆 View](./ai_engineering/Time_Series_Forecasting.md) |
192
+ | | Distributed Training (Horovod) | [ℹ️](./ai_engineering/Distributed_Training_Horovod.md) | [👆 View](./ai_engineering/Distributed_Training_Horovod.md) |
193
+ | | Computer Vision Object Detection | [ℹ️](./ai_engineering/Computer_Vision_Object_Detection.md) | [👆 View](./ai_engineering/Computer_Vision_Object_Detection.md) |
194
+ | | Data Drift Detection | [ℹ️](./ai_engineering/Data_Drift_Detection.md) | [👆 View](./ai_engineering/Data_Drift_Detection.md) |
195
+ | | Generative AI Image Synthesis | [ℹ️](./ai_engineering/Generative_AI_Image_Synthesis.md) | [👆 View](./ai_engineering/Generative_AI_Image_Synthesis.md) |
196
+ | | Natural Language to SQL (NL2SQL) | [ℹ️](./ai_engineering/Natural_Language_to_SQL.md) | [👆 View](./ai_engineering/Natural_Language_to_SQL.md) |
197
+ | | AI Agents with LangGraph | [ℹ️](./ai_engineering/AI_Agents_LangGraph.md) | [👆 View](./ai_engineering/AI_Agents_LangGraph.md) |
198
+ | | Advanced Vector Databases (Pinecone & Weaviate) | [ℹ️](./ai_engineering/Vector_Databases_Pinecone_Weaviate.md) | [👆 View](./ai_engineering/Vector_Databases_Pinecone_Weaviate.md) |
199
+ | | Time Series Forecasting with LSTM | [ℹ️](./ai_engineering/Time_Series_Forecasting_LSTM.md) | [👆 View](./ai_engineering/Time_Series_Forecasting_LSTM.md) |
200
+ | | Recommender Systems with Collaborative Filtering | [ℹ️](./ai_engineering/Recommender_Systems_Collaborative_Filtering.md) | [👆 View](./ai_engineering/Recommender_Systems_Collaborative_Filtering.md) |
201
+ | **🏗️ Architecture** | Adapter Pattern in TypeScript | [ℹ️](./architecture/Adapter_Pattern_TypeScript.md) | [👆 View](./architecture/Adapter_Pattern_TypeScript.md) |
202
+ | | Clean Architecture in Node.js | [ℹ️](./architecture/Clean_Architecture_Node.md) | [👆 View](./architecture/Clean_Architecture_Node.md) |
203
+ | | CQRS Pattern Implementation | [ℹ️](./architecture/CQRS_Pattern_Implementation.md) | [👆 View](./architecture/CQRS_Pattern_Implementation.md) |
204
+ | | Domain-Driven Design (DDD) Basics | [ℹ️](./architecture/Domain_Driven_Design_Basics.md) | [👆 View](./architecture/Domain_Driven_Design_Basics.md) |
205
+ | | CQRS Implementation | [ℹ️](./architecture/CQRS_Implementation.md) | [👆 View](./architecture/CQRS_Implementation.md) |
206
+ | | Event Sourcing Pattern | [ℹ️](./architecture/Event_Sourcing_Pattern.md) | [👆 View](./architecture/Event_Sourcing_Pattern.md) |
207
+ | **📦 Code Mgmt** | Branch Protection Rules | [ℹ️](./code_management/Branch_Protection_Rules.md) | [👆 View](./code_management/Branch_Protection_Rules.md) |
208
+ | | Code Review Guidelines | [ℹ️](./code_management/Code_Review_Guidelines.md) | [👆 View](./code_management/Code_Review_Guidelines.md) |
209
+ | | Dead Code Elimination | [ℹ️](./code_management/Dead_Code_Elimination.md) | [👆 View](./code_management/Dead_Code_Elimination.md) |
210
+ | | ESLint & Prettier Setup | [ℹ️](./code_management/ESLint_Prettier_Setup.md) | [👆 View](./code_management/ESLint_Prettier_Setup.md) |
211
+ | | Git Commit Convention | [ℹ️](./code_management/Git_Commit_Convention_Conventional_Commits.md) | [👆 View](./code_management/Git_Commit_Convention_Conventional_Commits.md) |
212
+ | | Git Hooks (Husky) | [ℹ️](./code_management/Git_Hooks_Husky.md) | [👆 View](./code_management/Git_Hooks_Husky.md) |
213
+ | | Managing Technical Debt | [ℹ️](./code_management/Managing_Technical_Debt.md) | [👆 View](./code_management/Managing_Technical_Debt.md) |
214
+ | | Monorepo Setup (Turborepo) | [ℹ️](./code_management/Monorepo_Setup_Turborepo.md) | [👆 View](./code_management/Monorepo_Setup_Turborepo.md) |
215
+ | | NPM Scripts Automation | [ℹ️](./code_management/Npm_Scripts_Automation.md) | [👆 View](./code_management/Npm_Scripts_Automation.md) |
216
+ | | Semantic Versioning | [ℹ️](./code_management/Semantic_Versioning_Strategy.md) | [👆 View](./code_management/Semantic_Versioning_Strategy.md) |
217
+ | | Git Workflow Strategies | [ℹ️](./code_management/Git_Workflow_Strategies.md) | [👆 View](./code_management/Git_Workflow_Strategies.md) |
218
+ | | Advanced Dependency Management (Dependabot/Renovate) | [ℹ️](./code_management/Advanced_Dependency_Management_Dependabot_Renovate.md) | [👆 View](./code_management/Advanced_Dependency_Management_Dependabot_Renovate.md) |
219
+ | | Code Documentation Standards (JSDoc/TSDoc) | [ℹ️](./code_management/Code_Documentation_Standards_JSDoc_TSDoc.md) | [👆 View](./code_management/Code_Documentation_Standards_JSDoc_TSDoc.md) |
220
+ | | Pull Request Templates & Standard Operating Procedure | [ℹ️](./code_management/Pull_Request_Templates_SOP.md) | [👆 View](./code_management/Pull_Request_Templates_SOP.md) |
221
+ | | Repository Structure & Organization | [ℹ️](./code_management/Repository_Structure_Organization.md) | [👆 View](./code_management/Repository_Structure_Organization.md) |
222
+ | | Dependency Pinning & Reproducible Builds | [ℹ️](./code_management/Dependency_Pinning_Reproducible_Builds.md) | [👆 View](./code_management/Dependency_Pinning_Reproducible_Builds.md) |
223
+ | | Git Rebase, Merge & Squash Guidelines | [ℹ️](./code_management/Git_Rebase_Merge_Squash_Guidelines.md) | [👆 View](./code_management/Git_Rebase_Merge_Squash_Guidelines.md) |
224
+ | | Pre-Commit & Pre-Push Hooks Automation | [ℹ️](./code_management/Pre-Commit_Pre-Push_Hooks_Automation.md) | [👆 View](./code_management/Pre-Commit_Pre-Push_Hooks_Automation.md) |
225
+ | | CHANGELOG Conventional Changelog Auto-Generation | [ℹ️](./code_management/CHANGELOG_Conventional_Changelog_Auto_Generation.md) | [👆 View](./code_management/CHANGELOG_Conventional_Changelog_Auto_Generation.md) |
226
+ | | Repository Archiving & Legacy Code Retirement | [ℹ️](./code_management/Repository_Archiving_Legacy_Code_Retirement.md) | [👆 View](./code_management/Repository_Archiving_Legacy_Code_Retirement.md) |
227
+ | **📝 Docs** | ADR Records | [ℹ️](./documentation/Architectural_Decision_Records_ADR.md) | [👆 View](./documentation/Architectural_Decision_Records_ADR.md) |
228
+ | | API Documentation | [ℹ️](./documentation/API_Documentation_Best_Practices.md) | [👆 View](./documentation/API_Documentation_Best_Practices.md) |
229
+ | | API Design Guidelines (REST) | [ℹ️](./documentation/API_Design_Guidelines_REST.md) | [👆 View](./documentation/API_Design_Guidelines_REST.md) |
230
+ | | Changelog Maintenance | [ℹ️](./documentation/Changelog_Maintenance.md) | [👆 View](./documentation/Changelog_Maintenance.md) |
231
+ | | Code Comments | [ℹ️](./documentation/Code_Comments_Best_Practices.md) | [👆 View](./documentation/Code_Comments_Best_Practices.md) |
232
+ | | Component Documentation (Storybook) | [ℹ️](./documentation/Component_Documentation_Storybook.md) | [👆 View](./documentation/Component_Documentation_Storybook.md) |
233
+ | | Contributing Guidelines | [ℹ️](./documentation/Contributing_Guidelines_CONTRIBUTING.md) | [👆 View](./documentation/Contributing_Guidelines_CONTRIBUTING.md) |
234
+ | | Diagramming with Mermaid.js | [ℹ️](./documentation/Diagramming_Mermaid_JS.md) | [👆 View](./documentation/Diagramming_Mermaid_JS.md) |
235
+ | | Effective User Documentation | [ℹ️](./documentation/Effective_User_Documentation.md) | [👆 View](./documentation/Effective_User_Documentation.md) |
236
+ | | Project Onboarding | [ℹ️](./documentation/Project_Onboarding_Guide.md) | [👆 View](./documentation/Project_Onboarding_Guide.md) |
237
+ | | Technical Spec Writing (RFC) | [ℹ️](./documentation/Technical_Spec_Writing.md) | [👆 View](./documentation/Technical_Spec_Writing.md) |
238
+ | | User Manual Creation | [ℹ️](./documentation/User_Manual_Creation.md) | [👆 View](./documentation/User_Manual_Creation.md) |
239
+ | | User Story Mapping | [ℹ️](./documentation/User_Story_Mapping.md) | [👆 View](./documentation/User_Story_Mapping.md) |
240
+ | | Writing Effective README | [ℹ️](./documentation/Writing_Effective_README.md) | [👆 View](./documentation/Writing_Effective_README.md) |
TRAE-Skills/ai_engineering/AI_Agent_Design_Patterns.md ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Skill: AI Agent Design Patterns
2
+
3
+ ## Purpose
4
+ To structure autonomous AI systems that can reason, plan, and execute tools to solve complex, multi-step problems using patterns like ReAct and Multi-Agent orchestration.
5
+
6
+ ## When to Use
7
+ - When the task requires multiple distinct steps (e.g., "Find the price of BTC and email me the summary").
8
+ - When the LLM needs to interact with the outside world (APIs, Databases, Web Search).
9
+ - When the workflow is non-linear and depends on intermediate results.
10
+
11
+ ## Procedure
12
+
13
+ ### 1. Tool Definition (Zod-based)
14
+ Define the tools your agent can use with clear descriptions.
15
+
16
+ ```typescript
17
+ import { z } from "zod";
18
+ import { tool } from "@langchain/core/tools";
19
+
20
+ const searchTool = tool(
21
+ async ({ query }) => {
22
+ // Implement search logic here
23
+ return `Results for ${query}...`;
24
+ },
25
+ {
26
+ name: "web_search",
27
+ description: "Search the web for current events or technical info.",
28
+ schema: z.object({
29
+ query: z.string(),
30
+ }),
31
+ }
32
+ );
33
+ ```
34
+
35
+ ### 2. The ReAct Agent Pattern
36
+ Implement the Reasoning + Acting loop.
37
+
38
+ ```typescript
39
+ import { ChatOpenAI } from "@langchain/openai";
40
+ import { createReactAgent } from "@langchain/langgraph/prebuilt";
41
+ import { MemorySaver } from "@langchain/langgraph";
42
+
43
+ const model = new ChatOpenAI({ modelName: "gpt-4o" });
44
+ const tools = [searchTool];
45
+ const checkpointer = new MemorySaver();
46
+
47
+ const app = createReactAgent({
48
+ llm: model,
49
+ tools,
50
+ checkpointSaver: checkpointer,
51
+ });
52
+
53
+ // Usage
54
+ const result = await app.invoke(
55
+ { messages: [{ role: "user", content: "What is the current price of Ethereum?" }] },
56
+ { configurable: { thread_id: "user_1" } }
57
+ );
58
+ ```
59
+
60
+ ### 3. Multi-Agent Orchestration (Hand-off)
61
+ Structure specialized agents that pass tasks to each other.
62
+
63
+ ```typescript
64
+ // Conceptual LangGraph Flow:
65
+ // 1. Router Agent -> Decides if it's a "Coding" or "Writing" task.
66
+ // 2. Coder Agent -> Generates code.
67
+ // 3. Reviewer Agent -> Reviews code. If errors, sends back to Coder.
68
+ // 4. Final Output.
69
+ ```
70
+
71
+ ### 4. Guardrails & Safety
72
+ Implement safety checks for tool execution.
73
+
74
+ ```typescript
75
+ const safeExecute = (action: string) => {
76
+ const forbidden = ["rm -rf", "delete", "drop table"];
77
+ if (forbidden.some(word => action.includes(word))) {
78
+ throw new Error("Safety violation: forbidden command.");
79
+ }
80
+ };
81
+ ```
82
+
83
+ ### 5. State Management
84
+ Maintain the conversation and tool execution state.
85
+
86
+ ```typescript
87
+ // Use LangGraph state to keep track of:
88
+ // - messages
89
+ // - tool_outputs
90
+ // - current_step
91
+ ```
92
+
93
+ ## Constraints
94
+ - **Infinite Loops**: Always set a `maxIterations` or recursion limit.
95
+ - **Context Bloat**: Agents generate a lot of tokens. Prune history or use summarization for long tasks.
96
+ - **Tool Descriptions**: The agent's performance is 90% dependent on how well you describe the tools. Be extremely precise.
97
+
98
+ ## Expected Output
99
+ A robust agentic system capable of autonomous problem solving by effectively utilizing provided tools.
TRAE-Skills/ai_engineering/AI_Agents_LangGraph.md ADDED
@@ -0,0 +1,232 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Skill: Building AI Agents with LangGraph
2
+
3
+ ## Purpose
4
+ To build stateful, multi-agent, and agentic systems using LangGraph for complex workflows (reasoning, tool use, multi-step tasks).
5
+
6
+ ## When to Use
7
+ - When building customer support agents that use multiple tools
8
+ - For research assistants that can browse, analyze, and summarize
9
+ - When creating multi-agent collaboration systems
10
+ - For building RAG with reasoning loops
11
+ - When you need agentic workflows with human-in-the-loop
12
+
13
+ ## Procedure
14
+
15
+ ### 1. Basic LangGraph Agent
16
+ Create a simple agent with tools.
17
+
18
+ ```python
19
+ from typing import Annotated, Literal, TypedDict
20
+ from langchain_openai import ChatOpenAI
21
+ from langchain_core.tools import tool
22
+ from langgraph.graph import StateGraph, START, END
23
+ from langgraph.graph.message import add_messages
24
+ from langgraph.prebuilt import ToolNode
25
+
26
+ # Define tools
27
+ @tool
28
+ def search_web(query: str) -> str:
29
+ """Search the web for a query."""
30
+ return f"Search results for '{query}': LangGraph is a library for building stateful agents."
31
+
32
+ @tool
33
+ def calculate(expression: str) -> str:
34
+ """Calculate a mathematical expression."""
35
+ try:
36
+ return str(eval(expression))
37
+ except:
38
+ return "Invalid expression"
39
+
40
+ tools = [search_web, calculate]
41
+
42
+ # Define state
43
+ class AgentState(TypedDict):
44
+ messages: Annotated[list, add_messages]
45
+
46
+ # Initialize model
47
+ llm = ChatOpenAI(model="gpt-4o", temperature=0)
48
+ llm_with_tools = llm.bind_tools(tools)
49
+
50
+ # Define nodes
51
+ def agent_node(state: AgentState):
52
+ response = llm_with_tools.invoke(state["messages"])
53
+ return {"messages": [response]}
54
+
55
+ tool_node = ToolNode(tools)
56
+
57
+ # Define conditional edge
58
+ def should_continue(state: AgentState) -> Literal["tools", END]:
59
+ last_message = state["messages"][-1]
60
+ if last_message.tool_calls:
61
+ return "tools"
62
+ return END
63
+
64
+ # Build graph
65
+ graph = StateGraph(AgentState)
66
+ graph.add_node("agent", agent_node)
67
+ graph.add_node("tools", tool_node)
68
+ graph.add_edge(START, "agent")
69
+ graph.add_conditional_edges("agent", should_continue)
70
+ graph.add_edge("tools", "agent")
71
+
72
+ app = graph.compile()
73
+
74
+ # Run agent
75
+ result = app.invoke({"messages": [("user", "What's 25 * 4 + 10? Also, tell me about LangGraph.")]})
76
+ print(result["messages"][-1].content)
77
+ ```
78
+
79
+ ### 2. Multi-Agent Collaboration
80
+ Build a team of specialized agents.
81
+
82
+ ```python
83
+ from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
84
+ from langgraph.graph import StateGraph, START, END
85
+
86
+ # Define specialized agents
87
+ researcher_prompt = ChatPromptTemplate.from_messages([
88
+ ("system", "You are a researcher. Use the search tool to find information."),
89
+ MessagesPlaceholder(variable_name="messages")
90
+ ])
91
+
92
+ writer_prompt = ChatPromptTemplate.from_messages([
93
+ ("system", "You are a writer. Take research and write a concise summary."),
94
+ MessagesPlaceholder(variable_name="messages")
95
+ ])
96
+
97
+ reviewer_prompt = ChatPromptTemplate.from_messages([
98
+ ("system", "You are a reviewer. Check the summary and improve it if needed."),
99
+ MessagesPlaceholder(variable_name="messages")
100
+ ])
101
+
102
+ class TeamState(TypedDict):
103
+ messages: Annotated[list, add_messages]
104
+ current_agent: str
105
+ final_summary: str
106
+
107
+ def researcher_node(state: TeamState):
108
+ researcher_llm = researcher_prompt | llm_with_tools
109
+ response = researcher_llm.invoke(state["messages"])
110
+ return {"messages": [response], "current_agent": "researcher"}
111
+
112
+ def writer_node(state: TeamState):
113
+ writer_llm = writer_prompt | llm
114
+ response = writer_llm.invoke(state["messages"])
115
+ return {"messages": [response], "current_agent": "writer", "final_summary": response.content}
116
+
117
+ def reviewer_node(state: TeamState):
118
+ reviewer_llm = reviewer_prompt | llm
119
+ response = reviewer_llm.invoke(state["messages"])
120
+ return {"messages": [response], "current_agent": "reviewer", "final_summary": response.content}
121
+
122
+ def route_team(state: TeamState) -> Literal["researcher", "writer", "reviewer", END]:
123
+ if not state["current_agent"]:
124
+ return "researcher"
125
+ elif state["current_agent"] == "researcher":
126
+ return "writer"
127
+ elif state["current_agent"] == "writer":
128
+ return "reviewer"
129
+ return END
130
+
131
+ team_graph = StateGraph(TeamState)
132
+ team_graph.add_node("researcher", researcher_node)
133
+ team_graph.add_node("writer", writer_node)
134
+ team_graph.add_node("reviewer", reviewer_node)
135
+ team_graph.add_conditional_edges(START, route_team)
136
+ team_graph.add_conditional_edges("researcher", route_team)
137
+ team_graph.add_conditional_edges("writer", route_team)
138
+
139
+ team_app = team_graph.compile()
140
+
141
+ # Run team
142
+ result = team_app.invoke({"messages": [("user", "Research LangGraph and write a summary.")]})
143
+ print("Final Summary:", result["final_summary"])
144
+ ```
145
+
146
+ ### 3. Human-in-the-Loop (HITL)
147
+ Add human approval steps.
148
+
149
+ ```python
150
+ from langgraph.checkpoint.memory import MemorySaver
151
+
152
+ class HITLState(TypedDict):
153
+ messages: Annotated[list, add_messages]
154
+ approved: bool
155
+
156
+ def agent_node_with_approval(state: HITLState):
157
+ if not state.get("approved", False):
158
+ # Wait for human approval (interrupt)
159
+ pass
160
+ response = llm_with_tools.invoke(state["messages"])
161
+ return {"messages": [response]}
162
+
163
+ checkpointer = MemorySaver()
164
+
165
+ hitl_graph = StateGraph(HITLState)
166
+ hitl_graph.add_node("agent", agent_node_with_approval)
167
+ hitl_graph.add_edge(START, "agent")
168
+ hitl_graph.add_conditional_edges("agent", should_continue)
169
+ hitl_graph.add_edge("tools", "agent")
170
+
171
+ hitl_app = hitl_graph.compile(checkpointer=checkpointer, interrupt_before=["agent"])
172
+
173
+ config = {"configurable": {"thread_id": "1"}}
174
+
175
+ # Initial run (interrupts before agent)
176
+ initial_result = hitl_app.invoke({"messages": [("user", "Approve this action?")]}, config)
177
+
178
+ # Human approves
179
+ human_approved_state = hitl_app.update_state(config, {"approved": True})
180
+
181
+ # Continue execution
182
+ final_result = hitl_app.invoke(None, config)
183
+ ```
184
+
185
+ ### 4. RAG Agent with LangGraph
186
+ Build an agent that does RAG with reasoning.
187
+
188
+ ```python
189
+ from langchain_community.vectorstores import InMemoryVectorStore
190
+ from langchain_openai import OpenAIEmbeddings
191
+ from langchain_core.documents import Document
192
+
193
+ # Sample documents
194
+ documents = [
195
+ Document(page_content="LangGraph is for building stateful agents.", metadata={"source": "doc1"}),
196
+ Document(page_content="Agents can use tools and have memory.", metadata={"source": "doc2"})
197
+ ]
198
+
199
+ vector_store = InMemoryVectorStore.from_documents(documents, OpenAIEmbeddings())
200
+ retriever = vector_store.as_retriever(k=2)
201
+
202
+ @tool
203
+ def retrieve_documents(query: str) -> str:
204
+ """Retrieve relevant documents from the knowledge base."""
205
+ docs = retriever.invoke(query)
206
+ return "\n\n".join([f"Source: {d.metadata['source']}\n{d.page_content}" for d in docs])
207
+
208
+ rag_tools = [retrieve_documents]
209
+ rag_llm = llm.bind_tools(rag_tools)
210
+
211
+ # RAG agent graph
212
+ rag_graph = StateGraph(AgentState)
213
+ rag_graph.add_node("agent", lambda s: {"messages": [rag_llm.invoke(s["messages"])]})
214
+ rag_graph.add_node("tools", ToolNode(rag_tools))
215
+ rag_graph.add_edge(START, "agent")
216
+ rag_graph.add_conditional_edges("agent", should_continue)
217
+ rag_graph.add_edge("tools", "agent")
218
+
219
+ rag_app = rag_graph.compile()
220
+
221
+ result = rag_app.invoke({"messages": [("user", "What is LangGraph used for?")]})
222
+ print(result["messages"][-1].content)
223
+ ```
224
+
225
+ ## Best Practices
226
+ - **State Design**: Keep state minimal and typed
227
+ - **Tool Design**: Make tools with clear, specific descriptions
228
+ - **Error Handling**: Add fallback edges for failures
229
+ - **Checkpoints**: Use checkpoints for long-running workflows
230
+ - **Evaluation**: Test agent workflows with LangSmith
231
+ - **Cost**: Limit tool calls to control costs
232
+ - **Human-in-the-Loop**: Add approval steps for high-stakes actions
TRAE-Skills/ai_engineering/AI_Experiment_Tracking.md ADDED
@@ -0,0 +1,640 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Skill: AI Experiment Tracking
2
+
3
+ ## Purpose
4
+ To systematically track machine learning experiments, including hyperparameters, metrics, artifacts, and results for reproducibility and optimization.
5
+
6
+ ## When to Use
7
+ - When running multiple ML experiments with different configurations
8
+ - When comparing model performance across different approaches
9
+ - When needing to reproduce experimental results
10
+ - When optimizing hyperparameters and model architectures
11
+
12
+ ## Procedure
13
+
14
+ ### 1. Experiment Tracking Framework
15
+ Create a comprehensive experiment tracking system.
16
+
17
+ ```python
18
+ import json
19
+ import logging
20
+ from datetime import datetime
21
+ from typing import Any, Dict, List, Optional
22
+ from pathlib import Path
23
+ import hashlib
24
+ import pandas as pd
25
+ import matplotlib.pyplot as plt
26
+
27
+ class ExperimentTracker:
28
+ """Track machine learning experiments."""
29
+
30
+ def __init__(self, project_name: str, base_dir: str = "./experiments"):
31
+ self.project_name = project_name
32
+ self.base_dir = Path(base_dir)
33
+ self.project_dir = self.base_dir / project_name
34
+ self.project_dir.mkdir(parents=True, exist_ok=True)
35
+
36
+ self.current_experiment = None
37
+ self.logger = logging.getLogger(f"ExperimentTracker.{project_name}")
38
+
39
+ # Initialize experiment registry
40
+ self.registry_file = self.project_dir / "experiments_registry.json"
41
+ self._init_registry()
42
+
43
+ def _init_registry(self):
44
+ """Initialize experiments registry."""
45
+ if not self.registry_file.exists():
46
+ self._save_registry({"experiments": [], "total": 0})
47
+
48
+ def _load_registry(self) -> Dict[str, Any]:
49
+ """Load experiments registry."""
50
+ with open(self.registry_file, 'r') as f:
51
+ return json.load(f)
52
+
53
+ def _save_registry(self, registry: Dict[str, Any]):
54
+ """Save experiments registry."""
55
+ with open(self.registry_file, 'w') as f:
56
+ json.dump(registry, f, indent=2)
57
+
58
+ def start_experiment(self, name: str, description: str = "", tags: List[str] = None) -> str:
59
+ """Start a new experiment."""
60
+ experiment_id = self._generate_experiment_id(name)
61
+
62
+ experiment = {
63
+ "id": experiment_id,
64
+ "name": name,
65
+ "description": description,
66
+ "tags": tags or [],
67
+ "start_time": datetime.now().isoformat(),
68
+ "end_time": None,
69
+ "status": "running",
70
+ "hyperparameters": {},
71
+ "metrics": {},
72
+ "artifacts": [],
73
+ "metadata": {}
74
+ }
75
+
76
+ # Create experiment directory
77
+ experiment_dir = self.project_dir / experiment_id
78
+ experiment_dir.mkdir(exist_ok=True)
79
+
80
+ # Update registry
81
+ registry = self._load_registry()
82
+ registry["experiments"].append(experiment)
83
+ registry["total"] += 1
84
+ self._save_registry(registry)
85
+
86
+ self.current_experiment = experiment
87
+ self.logger.info(f"Started experiment: {name} (ID: {experiment_id})")
88
+
89
+ return experiment_id
90
+
91
+ def log_hyperparameters(self, params: Dict[str, Any]):
92
+ """Log hyperparameters for current experiment."""
93
+ if not self.current_experiment:
94
+ raise ValueError("No active experiment. Call start_experiment() first.")
95
+
96
+ self.current_experiment["hyperparameters"].update(params)
97
+ self._update_current_experiment()
98
+ self.logger.info(f"Logged hyperparameters: {params}")
99
+
100
+ def log_metrics(self, metrics: Dict[str, float], step: Optional[int] = None):
101
+ """Log metrics for current experiment."""
102
+ if not self.current_experiment:
103
+ raise ValueError("No active experiment. Call start_experiment() first.")
104
+
105
+ if step is not None:
106
+ if "metric_history" not in self.current_experiment:
107
+ self.current_experiment["metric_history"] = {}
108
+
109
+ for metric_name, value in metrics.items():
110
+ if metric_name not in self.current_experiment["metric_history"]:
111
+ self.current_experiment["metric_history"][metric_name] = []
112
+
113
+ self.current_experiment["metric_history"][metric_name].append({
114
+ "step": step,
115
+ "value": value,
116
+ "timestamp": datetime.now().isoformat()
117
+ })
118
+
119
+ self.current_experiment["metrics"].update(metrics)
120
+ self._update_current_experiment()
121
+ self.logger.info(f"Logged metrics: {metrics}")
122
+
123
+ def log_artifact(self, artifact_path: str, artifact_type: str = "file"):
124
+ """Log an artifact for current experiment."""
125
+ if not self.current_experiment:
126
+ raise ValueError("No active experiment. Call start_experiment() first.")
127
+
128
+ import shutil
129
+ experiment_dir = self.project_dir / self.current_experiment["id"]
130
+ artifact_name = Path(artifact_path).name
131
+ dest_path = experiment_dir / "artifacts" / artifact_name
132
+
133
+ # Create artifacts directory
134
+ dest_path.parent.mkdir(exist_ok=True)
135
+
136
+ # Copy artifact
137
+ shutil.copy2(artifact_path, dest_path)
138
+
139
+ artifact_info = {
140
+ "name": artifact_name,
141
+ "type": artifact_type,
142
+ "original_path": artifact_path,
143
+ "stored_path": str(dest_path),
144
+ "timestamp": datetime.now().isoformat()
145
+ }
146
+
147
+ self.current_experiment["artifacts"].append(artifact_info)
148
+ self._update_current_experiment()
149
+ self.logger.info(f"Logged artifact: {artifact_name}")
150
+
151
+ def end_experiment(self, status: str = "completed"):
152
+ """End the current experiment."""
153
+ if not self.current_experiment:
154
+ raise ValueError("No active experiment to end.")
155
+
156
+ self.current_experiment["end_time"] = datetime.now().isoformat()
157
+ self.current_experiment["status"] = status
158
+ self._update_current_experiment()
159
+
160
+ self.logger.info(f"Ended experiment: {self.current_experiment['name']} (status: {status})")
161
+ self.current_experiment = None
162
+
163
+ def _update_current_experiment(self):
164
+ """Update current experiment in registry."""
165
+ if not self.current_experiment:
166
+ return
167
+
168
+ registry = self._load_registry()
169
+ for i, exp in enumerate(registry["experiments"]):
170
+ if exp["id"] == self.current_experiment["id"]:
171
+ registry["experiments"][i] = self.current_experiment
172
+ break
173
+
174
+ self._save_registry(registry)
175
+
176
+ def _generate_experiment_id(self, name: str) -> str:
177
+ """Generate unique experiment ID."""
178
+ timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
179
+ name_hash = hashlib.md5(name.encode()).hexdigest()[:8]
180
+ return f"exp_{timestamp}_{name_hash}"
181
+
182
+ def get_experiment(self, experiment_id: str) -> Optional[Dict[str, Any]]:
183
+ """Get experiment by ID."""
184
+ registry = self._load_registry()
185
+ for exp in registry["experiments"]:
186
+ if exp["id"] == experiment_id:
187
+ return exp
188
+ return None
189
+
190
+ def list_experiments(self, status: Optional[str] = None, tags: Optional[List[str]] = None) -> List[Dict[str, Any]]:
191
+ """List experiments with optional filtering."""
192
+ registry = self._load_registry()
193
+ experiments = registry["experiments"]
194
+
195
+ if status:
196
+ experiments = [exp for exp in experiments if exp["status"] == status]
197
+
198
+ if tags:
199
+ experiments = [exp for exp in experiments if any(tag in exp["tags"] for tag in tags)]
200
+
201
+ return experiments
202
+
203
+ def compare_experiments(self, experiment_ids: List[str]) -> pd.DataFrame:
204
+ """Compare experiments side by side."""
205
+ experiments = []
206
+ for exp_id in experiment_ids:
207
+ exp = self.get_experiment(exp_id)
208
+ if exp:
209
+ experiments.append(exp)
210
+
211
+ if not experiments:
212
+ return pd.DataFrame()
213
+
214
+ comparison_data = []
215
+ for exp in experiments:
216
+ row = {
217
+ "id": exp["id"],
218
+ "name": exp["name"],
219
+ "status": exp["status"],
220
+ **exp["hyperparameters"],
221
+ **exp["metrics"]
222
+ }
223
+ comparison_data.append(row)
224
+
225
+ return pd.DataFrame(comparison_data)
226
+ ```
227
+
228
+ ### 2. Automated Hyperparameter Logging
229
+ Automatically track hyperparameters.
230
+
231
+ ```python
232
+ from functools import wraps
233
+
234
+ def track_hyperparameters(tracker: ExperimentTracker):
235
+ """Decorator to automatically track function parameters as hyperparameters."""
236
+ def decorator(func):
237
+ @wraps(func)
238
+ def wrapper(*args, **kwargs):
239
+ # Extract hyperparameters from function arguments
240
+ import inspect
241
+ sig = inspect.signature(func)
242
+ bound_args = sig.bind(*args, **kwargs)
243
+ bound_args.apply_defaults()
244
+
245
+ # Log all parameters as hyperparameters
246
+ params = dict(bound_args.arguments)
247
+ # Remove self parameter if present
248
+ params.pop('self', None)
249
+ params.pop('tracker', None)
250
+
251
+ tracker.log_hyperparameters(params)
252
+
253
+ return func(*args, **kwargs)
254
+ return wrapper
255
+ return decorator
256
+
257
+ # Usage
258
+ # @track_hyperparameters(tracker)
259
+ # def train_model(learning_rate, batch_size, epochs, model_type):
260
+ # # Training code here
261
+ # pass
262
+ ```
263
+
264
+ ### 3. Metrics Visualization
265
+ Create visualizations for experiment comparison.
266
+
267
+ ```python
268
+ class ExperimentVisualizer:
269
+ """Visualize experiment results."""
270
+
271
+ def __init__(self, tracker: ExperimentTracker):
272
+ self.tracker = tracker
273
+
274
+ def plot_metric_comparison(self, metric_name: str, top_n: int = 10):
275
+ """Plot metric comparison across experiments."""
276
+ experiments = self.tracker.list_experiments(status="completed")
277
+
278
+ # Filter experiments that have the metric
279
+ valid_experiments = [
280
+ exp for exp in experiments
281
+ if metric_name in exp["metrics"]
282
+ ]
283
+
284
+ if not valid_experiments:
285
+ print(f"No experiments found with metric: {metric_name}")
286
+ return
287
+
288
+ # Sort by metric value
289
+ valid_experiments.sort(key=lambda x: x["metrics"][metric_name])
290
+
291
+ # Take top N
292
+ top_experiments = valid_experiments[:top_n]
293
+
294
+ # Create plot
295
+ plt.figure(figsize=(12, 6))
296
+ names = [exp["name"] for exp in top_experiments]
297
+ values = [exp["metrics"][metric_name] for exp in top_experiments]
298
+
299
+ plt.bar(range(len(names)), values)
300
+ plt.xticks(range(len(names)), names, rotation=45, ha='right')
301
+ plt.ylabel(metric_name)
302
+ plt.title(f'{metric_name} Comparison (Top {top_n})')
303
+ plt.tight_layout()
304
+
305
+ # Save plot
306
+ output_path = self.tracker.project_dir / f"{metric_name}_comparison.png"
307
+ plt.savefig(output_path)
308
+ plt.close()
309
+
310
+ print(f"Plot saved to: {output_path}")
311
+
312
+ def plot_training_curves(self, experiment_id: str, metric_name: str):
313
+ """Plot training curves for a specific experiment."""
314
+ exp = self.tracker.get_experiment(experiment_id)
315
+
316
+ if not exp or "metric_history" not in exp:
317
+ print(f"No metric history found for experiment: {experiment_id}")
318
+ return
319
+
320
+ if metric_name not in exp["metric_history"]:
321
+ print(f"Metric {metric_name} not found in experiment history")
322
+ return
323
+
324
+ # Extract data
325
+ history = exp["metric_history"][metric_name]
326
+ steps = [entry["step"] for entry in history]
327
+ values = [entry["value"] for entry in history]
328
+
329
+ # Create plot
330
+ plt.figure(figsize=(10, 6))
331
+ plt.plot(steps, values, marker='o')
332
+ plt.xlabel("Step")
333
+ plt.ylabel(metric_name)
334
+ plt.title(f'{metric_name} Training Curve - {exp["name"]}')
335
+ plt.grid(True)
336
+
337
+ # Save plot
338
+ output_path = self.tracker.project_dir / f"{experiment_id}_{metric_name}_curve.png"
339
+ plt.savefig(output_path)
340
+ plt.close()
341
+
342
+ print(f"Training curve saved to: {output_path}")
343
+
344
+ def create_experiment_report(self, experiment_id: str) -> str:
345
+ """Create a comprehensive experiment report."""
346
+ exp = self.tracker.get_experiment(experiment_id)
347
+
348
+ if not exp:
349
+ return f"Experiment not found: {experiment_id}"
350
+
351
+ report = f"""
352
+ Experiment Report
353
+ {'=' * 50}
354
+
355
+ Name: {exp['name']}
356
+ ID: {exp['id']}
357
+ Status: {exp['status']}
358
+ Description: {exp['description']}
359
+
360
+ Timeline:
361
+ - Started: {exp['start_time']}
362
+ - Ended: {exp['end_time'] or 'Running'}
363
+
364
+ Tags: {', '.join(exp['tags']) if exp['tags'] else 'None'}
365
+
366
+ Hyperparameters:
367
+ """
368
+ for param, value in exp['hyperparameters'].items():
369
+ report += f"- {param}: {value}\n"
370
+
371
+ report += f"\nFinal Metrics:\n"
372
+ for metric, value in exp['metrics'].items():
373
+ report += f"- {metric}: {value}\n"
374
+
375
+ if exp['artifacts']:
376
+ report += f"\nArtifacts ({len(exp['artifacts'])}):\n"
377
+ for artifact in exp['artifacts']:
378
+ report += f"- {artifact['name']} ({artifact['type']})\n"
379
+
380
+ return report
381
+ ```
382
+
383
+ ### 4. Model Artifact Management
384
+ Manage model artifacts and versions.
385
+
386
+ ```python
387
+ import joblib
388
+ import pickle
389
+
390
+ class ModelArtifactManager:
391
+ """Manage model artifacts with versioning."""
392
+
393
+ def __init__(self, tracker: ExperimentTracker):
394
+ self.tracker = tracker
395
+ self.artifacts_dir = tracker.project_dir / "artifacts"
396
+ self.artifacts_dir.mkdir(exist_ok=True)
397
+
398
+ def save_model(self, model, model_name: str, framework: str = "sklearn"):
399
+ """Save model and log as artifact."""
400
+ timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
401
+ artifact_filename = f"{model_name}_{timestamp}.joblib"
402
+ artifact_path = self.artifacts_dir / artifact_filename
403
+
404
+ # Save model
405
+ if framework == "sklearn":
406
+ joblib.dump(model, artifact_path)
407
+ elif framework == "pickle":
408
+ with open(artifact_path, 'wb') as f:
409
+ pickle.dump(model, f)
410
+ else:
411
+ raise ValueError(f"Unsupported framework: {framework}")
412
+
413
+ # Log artifact
414
+ self.tracker.log_artifact(str(artifact_path), artifact_type="model")
415
+
416
+ return artifact_path
417
+
418
+ def load_model(self, artifact_path: str):
419
+ """Load model from artifact."""
420
+ if artifact_path.endswith('.joblib'):
421
+ return joblib.load(artifact_path)
422
+ elif artifact_path.endswith('.pkl'):
423
+ with open(artifact_path, 'rb') as f:
424
+ return pickle.load(f)
425
+ else:
426
+ raise ValueError(f"Unsupported artifact format: {artifact_path}")
427
+
428
+ def compare_model_versions(self, model_name: str) -> pd.DataFrame:
429
+ """Compare different versions of a model."""
430
+ experiments = self.tracker.list_experiments()
431
+
432
+ model_versions = []
433
+ for exp in experiments:
434
+ for artifact in exp['artifacts']:
435
+ if artifact['name'].startswith(model_name) and artifact['type'] == 'model':
436
+ model_versions.append({
437
+ 'experiment_id': exp['id'],
438
+ 'experiment_name': exp['name'],
439
+ 'artifact_name': artifact['name'],
440
+ 'created': artifact['timestamp'],
441
+ **exp['metrics']
442
+ })
443
+
444
+ return pd.DataFrame(model_versions)
445
+ ```
446
+
447
+ ### 5. Experiment Analysis and Insights
448
+ Analyze experiments to derive insights.
449
+
450
+ ```python
451
+ class ExperimentAnalyzer:
452
+ """Analyze experiments to provide insights."""
453
+
454
+ def __init__(self, tracker: ExperimentTracker):
455
+ self.tracker = tracker
456
+
457
+ def find_best_experiment(self, metric_name: str, higher_is_better: bool = True) -> Optional[Dict[str, Any]]:
458
+ """Find the best performing experiment for a given metric."""
459
+ experiments = self.tracker.list_experiments(status="completed")
460
+
461
+ valid_experiments = [
462
+ exp for exp in experiments
463
+ if metric_name in exp["metrics"]
464
+ ]
465
+
466
+ if not valid_experiments:
467
+ return None
468
+
469
+ if higher_is_better:
470
+ best_exp = max(valid_experiments, key=lambda x: x["metrics"][metric_name])
471
+ else:
472
+ best_exp = min(valid_experiments, key=lambda x: x["metrics"][metric_name])
473
+
474
+ return best_exp
475
+
476
+ def analyze_hyperparameter_importance(self, metric_name: str) -> pd.DataFrame:
477
+ """Analyze the importance of hyperparameters on a metric."""
478
+ experiments = self.tracker.list_experiments(status="completed")
479
+
480
+ valid_experiments = [
481
+ exp for exp in experiments
482
+ if metric_name in exp["metrics"]
483
+ ]
484
+
485
+ if not valid_experiments:
486
+ return pd.DataFrame()
487
+
488
+ # Create analysis data
489
+ analysis_data = []
490
+ for exp in valid_experiments:
491
+ row = {
492
+ "experiment_id": exp["id"],
493
+ "experiment_name": exp["name"],
494
+ "metric_value": exp["metrics"][metric_name]
495
+ }
496
+ # Add all hyperparameters
497
+ row.update(exp["hyperparameters"])
498
+ analysis_data.append(row)
499
+
500
+ df = pd.DataFrame(analysis_data)
501
+
502
+ # Calculate correlations for numeric hyperparameters
503
+ numeric_cols = df.select_dtypes(include=['number']).columns
504
+ if len(numeric_cols) > 1:
505
+ correlations = df[numeric_cols].corr()['metric_value'].sort_values(ascending=False)
506
+ return correlations
507
+
508
+ return df
509
+
510
+ def generate_experiment_summary(self) -> str:
511
+ """Generate a summary of all experiments."""
512
+ experiments = self.tracker.list_experiments()
513
+
514
+ summary = f"""
515
+ Experiment Summary for {self.tracker.project_name}
516
+ {'=' * 60}
517
+
518
+ Total Experiments: {len(experiments)}
519
+
520
+ Status Breakdown:
521
+ """
522
+ status_counts = {}
523
+ for exp in experiments:
524
+ status = exp["status"]
525
+ status_counts[status] = status_counts.get(status, 0) + 1
526
+
527
+ for status, count in sorted(status_counts.items()):
528
+ summary += f"- {status}: {count}\n"
529
+
530
+ if status_counts.get("completed", 0) > 0:
531
+ summary += f"\nCompleted Experiments: {status_counts['completed']}\n"
532
+ summary += "Best performing experiments by common metrics:\n"
533
+
534
+ common_metrics = {}
535
+ for exp in experiments:
536
+ if exp["status"] == "completed":
537
+ for metric in exp["metrics"].keys():
538
+ if metric not in common_metrics:
539
+ common_metrics[metric] = []
540
+ common_metrics[metric].append((exp["name"], exp["metrics"][metric]))
541
+
542
+ for metric, values in common_metrics.items():
543
+ best = max(values, key=lambda x: x[1])
544
+ summary += f"- {metric}: {best[0]} ({best[1]:.4f})\n"
545
+
546
+ return summary
547
+ ```
548
+
549
+ ### 6. Complete Example Usage
550
+ Demonstrate complete experiment tracking workflow.
551
+
552
+ ```python
553
+ def example_experiment_tracking():
554
+ """Demonstrate complete experiment tracking."""
555
+
556
+ # Initialize tracker
557
+ tracker = ExperimentTracker(project_name="sentiment_analysis")
558
+
559
+ # Start experiment
560
+ exp_id = tracker.start_experiment(
561
+ name="random_forest_baseline",
562
+ description="Random Forest baseline model for sentiment analysis",
563
+ tags=["baseline", "random_forest"]
564
+ )
565
+
566
+ # Log hyperparameters
567
+ tracker.log_hyperparameters({
568
+ "model_type": "random_forest",
569
+ "n_estimators": 100,
570
+ "max_depth": 10,
571
+ "min_samples_split": 2,
572
+ "learning_rate": None
573
+ })
574
+
575
+ # Simulate training and log metrics
576
+ import numpy as np
577
+ for epoch in range(10):
578
+ # Simulate training
579
+ train_loss = 1.0 - (epoch * 0.08)
580
+ val_loss = 1.0 - (epoch * 0.07) + np.random.normal(0, 0.05)
581
+
582
+ tracker.log_metrics({
583
+ "train_loss": train_loss,
584
+ "val_loss": val_loss,
585
+ "epoch": epoch
586
+ }, step=epoch)
587
+
588
+ # Log final metrics
589
+ tracker.log_metrics({
590
+ "train_accuracy": 0.92,
591
+ "val_accuracy": 0.87,
592
+ "test_accuracy": 0.85,
593
+ "f1_score": 0.84,
594
+ "precision": 0.86,
595
+ "recall": 0.82
596
+ })
597
+
598
+ # Save model artifact
599
+ artifact_manager = ModelArtifactManager(tracker)
600
+ import joblib
601
+ dummy_model = {"model": "dummy_model", "accuracy": 0.85}
602
+ joblib.dump(dummy_model, "dummy_model.joblib")
603
+ artifact_manager.save_model(dummy_model, "sentiment_model")
604
+
605
+ # End experiment
606
+ tracker.end_experiment(status="completed")
607
+
608
+ # Create visualizations
609
+ visualizer = ExperimentVisualizer(tracker)
610
+ visualizer.plot_metric_comparison("test_accuracy")
611
+ visualizer.plot_training_curves(exp_id, "train_loss")
612
+
613
+ # Generate report
614
+ report = visualizer.create_experiment_report(exp_id)
615
+ print(report)
616
+
617
+ # Analyze experiments
618
+ analyzer = ExperimentAnalyzer(tracker)
619
+ best_exp = analyzer.find_best_experiment("test_accuracy")
620
+ print(f"\nBest experiment: {best_exp['name']} with accuracy {best_exp['metrics']['test_accuracy']}")
621
+
622
+ summary = analyzer.generate_experiment_summary()
623
+ print(summary)
624
+
625
+ # Usage
626
+ if __name__ == "__main__":
627
+ logging.basicConfig(level=logging.INFO)
628
+ example_experiment_tracking()
629
+ ```
630
+
631
+ ## Constraints
632
+ - **Storage Space**: Experiment artifacts can consume significant storage
633
+ - **Performance**: Extensive logging may impact training performance
634
+ - **Reproducibility**: Ensure complete environment capture for true reproducibility
635
+ - **Scalability**: Consider scalability for large numbers of experiments
636
+ - **Privacy**: Be careful with sensitive data in experiment logs
637
+ - **Organization**: Maintain consistent naming and tagging conventions
638
+
639
+ ## Expected Output
640
+ Comprehensive experiment tracking system that captures all aspects of ML experiments, enables detailed comparison and analysis, and provides insights for model optimization.
TRAE-Skills/ai_engineering/AI_Model_Evaluation.md ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Skill: AI Model Evaluation
2
+
3
+ ## Purpose
4
+ To systematically assess the performance, accuracy, and safety of LLM outputs using quantitative metrics and "LLM-as-a-Judge" patterns, ensuring production readiness.
5
+
6
+ ## When to Use
7
+ - Before deploying any LLM application to production.
8
+ - When comparing different models (e.g., GPT-4o vs. Claude 3.5 Sonnet) or prompt versions.
9
+ - To detect regressions after updating prompts or RAG knowledge bases.
10
+
11
+ ## Procedure
12
+
13
+ ### 1. Define the Evaluation Dataset (Golden Set)
14
+ Create a `tests.json` file containing inputs and expected outputs.
15
+
16
+ ```json
17
+ [
18
+ {
19
+ "input": "What is the return policy?",
20
+ "expected": "You can return items within 30 days.",
21
+ "context": "Our policy allows returns for 30 days from purchase date."
22
+ }
23
+ ]
24
+ ```
25
+
26
+ ### 2. Implementation with Promptfoo (CLI)
27
+ Promptfoo is a popular tool for running batch evaluations.
28
+
29
+ ```bash
30
+ # Install
31
+ npm install -g promptfoo
32
+
33
+ # Initialize
34
+ promptfoo init
35
+ ```
36
+
37
+ Configure `promptfooconfig.yaml`:
38
+ ```yaml
39
+ prompts:
40
+ - "Answer this question using the context: {{context}}. Question: {{input}}"
41
+
42
+ providers:
43
+ - openai:gpt-4o
44
+
45
+ tests:
46
+ - vars:
47
+ input: "What is the return policy?"
48
+ context: "30-day return policy applies."
49
+ assert:
50
+ - type: icontains
51
+ value: "30 days"
52
+ - type: llm-rubric
53
+ value: "Does not mention unrelated topics"
54
+ ```
55
+
56
+ ### 3. RAG Evaluation (Ragas/DeepEval)
57
+ For RAG systems, evaluate the three-way relationship: Question, Context, and Answer.
58
+
59
+ ```typescript
60
+ import { rce } from "deepeval"; // Conceptual example
61
+
62
+ async function evaluateRag(query: string, retrievalContext: string, output: string) {
63
+ // 1. Faithfulness: Is the answer grounded in the context?
64
+ // 2. Answer Relevance: Does it answer the query?
65
+ // 3. Context Precision: Was the retrieved context relevant?
66
+ }
67
+ ```
68
+
69
+ ### 4. Custom LLM-as-a-Judge Script
70
+ Use a stronger model to grade your target model.
71
+
72
+ ```typescript
73
+ async function gradeOutput(question: string, answer: string, reference: string) {
74
+ const graderPrompt = `
75
+ You are an impartial judge. Grade the student's answer based on the reference.
76
+ Question: ${question}
77
+ Reference: ${reference}
78
+ Student Answer: ${answer}
79
+
80
+ Provide a score from 1-10 and a brief explanation.
81
+ Output JSON: { "score": number, "explanation": string }
82
+ `;
83
+
84
+ // Call GPT-4 with JSON mode enabled
85
+ }
86
+ ```
87
+
88
+ ### 5. Continuous Integration (CI)
89
+ Integrate evaluation into your GitHub Actions to prevent regressions.
90
+
91
+ ```yaml
92
+ # .github/workflows/ai-eval.yml
93
+ jobs:
94
+ evaluate:
95
+ runs-on: ubuntu-latest
96
+ steps:
97
+ - uses: actions/checkout@v4
98
+ - run: npx promptfoo eval
99
+ ```
100
+
101
+ ## Constraints
102
+ - **Bias**: LLM judges tend to prefer longer answers or answers from the same provider. Use diverse judges (OpenAI + Anthropic).
103
+ - **Cost**: Running evaluations on 1000s of rows can be expensive. Use `gpt-4o-mini` for simpler checks.
104
+ - **Reference Accuracy**: A "Golden Set" is only as good as the human-verified reference answers.
105
+
106
+ ## Expected Output
107
+ A detailed report (HTML/JSON) showing pass/fail status, accuracy percentages, and regression analysis.
TRAE-Skills/ai_engineering/AI_Model_Serving.md ADDED
@@ -0,0 +1,503 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Skill: AI Model Serving
2
+
3
+ ## Purpose
4
+ To deploy and serve machine learning models in production environments with proper scaling, monitoring, and API integration.
5
+
6
+ ## When to Use
7
+ - When deploying ML models to production
8
+ - When building ML-powered APIs and services
9
+ - When implementing real-time inference systems
10
+ - When scaling ML services for production traffic
11
+
12
+ ## Procedure
13
+
14
+ ### 1. Model Server Setup
15
+ Create a production-ready model server.
16
+
17
+ ```python
18
+ from fastapi import FastAPI, HTTPException, BackgroundTasks
19
+ from fastapi.middleware.cors import CORSMiddleware
20
+ from pydantic import BaseModel, Field
21
+ from typing import List, Optional, Dict, Any
22
+ import joblib
23
+ import logging
24
+ import time
25
+ from datetime import datetime
26
+ import asyncio
27
+ from prometheus_client import Counter, Histogram, generate_latest
28
+ import numpy as np
29
+
30
+ # Define request/response models
31
+ class PredictionRequest(BaseModel):
32
+ model_name: str = Field(..., description="Name of the model to use")
33
+ model_version: str = Field(default="latest", description="Version of the model")
34
+ input_data: Dict[str, Any] = Field(..., description="Input data for prediction")
35
+ preprocessing: Optional[Dict[str, Any]] = Field(default=None, description="Preprocessing options")
36
+ postprocessing: Optional[Dict[str, Any]] = Field(default=None, description="Postprocessing options")
37
+
38
+ class PredictionResponse(BaseModel):
39
+ prediction: Any
40
+ model_name: str
41
+ model_version: str
42
+ prediction_time: float
43
+ timestamp: str
44
+ metadata: Optional[Dict[str, Any]] = None
45
+
46
+ class HealthResponse(BaseModel):
47
+ status: str
48
+ models_loaded: List[str]
49
+ uptime_seconds: float
50
+ version: str
51
+
52
+ # Create FastAPI app
53
+ app = FastAPI(
54
+ title="ML Model Serving API",
55
+ description="Production ML model inference server",
56
+ version="1.0.0"
57
+ )
58
+
59
+ # Add CORS middleware
60
+ app.add_middleware(
61
+ CORSMiddleware,
62
+ allow_origins=["*"],
63
+ allow_credentials=True,
64
+ allow_methods=["*"],
65
+ allow_headers=["*"],
66
+ )
67
+
68
+ # Prometheus metrics
69
+ prediction_counter = Counter('predictions_total', 'Total predictions', ['model_name', 'status'])
70
+ prediction_duration = Histogram('prediction_duration_seconds', 'Prediction duration', ['model_name'])
71
+
72
+ class ModelServer:
73
+ """Production model server."""
74
+
75
+ def __init__(self, model_registry_path: str = "./models"):
76
+ self.model_registry_path = model_registry_path
77
+ self.loaded_models = {}
78
+ self.model_metadata = {}
79
+ self.start_time = time.time()
80
+ self.logger = logging.getLogger("ModelServer")
81
+
82
+ # Load model registry
83
+ self._load_model_registry()
84
+
85
+ def _load_model_registry(self):
86
+ """Load model registry."""
87
+ import json
88
+ registry_path = f"{self.model_registry_path}/model_registry.json"
89
+ try:
90
+ with open(registry_path, 'r') as f:
91
+ self.model_registry = json.load(f)
92
+ except FileNotFoundError:
93
+ self.model_registry = {"models": [], "current": None}
94
+ self.logger.warning("Model registry not found, starting with empty registry")
95
+
96
+ def load_model(self, model_name: str, version: str = "latest"):
97
+ """Load model into memory."""
98
+ model_key = f"{model_name}_{version}"
99
+
100
+ if model_key in self.loaded_models:
101
+ return self.loaded_models[model_key]
102
+
103
+ # Find model in registry
104
+ model_info = None
105
+ for model in self.model_registry["models"]:
106
+ if model["model_type"] == model_name:
107
+ if version == "latest" or model["version"] == version:
108
+ model_info = model
109
+ break
110
+
111
+ if not model_info:
112
+ raise ValueError(f"Model {model_name} version {version} not found")
113
+
114
+ # Load model from disk
115
+ model_path = model_info["model_path"]
116
+ try:
117
+ model = joblib.load(model_path)
118
+ self.loaded_models[model_key] = model
119
+ self.model_metadata[model_key] = model_info
120
+ self.logger.info(f"Loaded model: {model_key}")
121
+ return model
122
+ except Exception as e:
123
+ self.logger.error(f"Failed to load model {model_key}: {str(e)}")
124
+ raise
125
+
126
+ def unload_model(self, model_name: str, version: str = "latest"):
127
+ """Unload model from memory."""
128
+ model_key = f"{model_name}_{version}"
129
+ if model_key in self.loaded_models:
130
+ del self.loaded_models[model_key]
131
+ del self.model_metadata[model_key]
132
+ self.logger.info(f"Unloaded model: {model_key}")
133
+
134
+ async def predict(self, request: PredictionRequest) -> PredictionResponse:
135
+ """Make prediction."""
136
+ start_time = time.time()
137
+ model_key = f"{request.model_name}_{request.model_version}"
138
+
139
+ try:
140
+ # Load model if not in memory
141
+ model = self.load_model(request.model_name, request.model_version)
142
+
143
+ # Preprocess input
144
+ processed_input = self._preprocess_input(request.input_data, request.preprocessing)
145
+
146
+ # Make prediction
147
+ prediction = model.predict([processed_input])[0] if hasattr(model, 'predict') else model(processed_input)
148
+
149
+ # Postprocess prediction
150
+ final_prediction = self._postprocess_prediction(prediction, request.postprocessing)
151
+
152
+ prediction_time = time.time() - start_time
153
+
154
+ # Record metrics
155
+ prediction_counter.labels(model_name=request.model_name, status='success').inc()
156
+ prediction_duration.labels(model_name=request.model_name).observe(prediction_time)
157
+
158
+ return PredictionResponse(
159
+ prediction=final_prediction,
160
+ model_name=request.model_name,
161
+ model_version=request.model_version,
162
+ prediction_time=prediction_time,
163
+ timestamp=datetime.now().isoformat(),
164
+ metadata=self.model_metadata.get(model_key)
165
+ )
166
+
167
+ except Exception as e:
168
+ prediction_counter.labels(model_name=request.model_name, status='error').inc()
169
+ self.logger.error(f"Prediction failed: {str(e)}")
170
+ raise HTTPException(status_code=500, detail=str(e))
171
+
172
+ def _preprocess_input(self, input_data: Dict[str, Any], preprocessing: Optional[Dict[str, Any]]) -> Any:
173
+ """Preprocess input data."""
174
+ # Implement preprocessing logic based on model requirements
175
+ # This is a placeholder - customize based on your model
176
+ return input_data
177
+
178
+ def _postprocess_prediction(self, prediction: Any, postprocessing: Optional[Dict[str, Any]]) -> Any:
179
+ """Postprocess prediction."""
180
+ # Implement postprocessing logic
181
+ return prediction
182
+
183
+ def get_health(self) -> HealthResponse:
184
+ """Get server health status."""
185
+ return HealthResponse(
186
+ status="healthy",
187
+ models_loaded=list(self.loaded_models.keys()),
188
+ uptime_seconds=time.time() - self.start_time,
189
+ version="1.0.0"
190
+ )
191
+
192
+ # Create model server instance
193
+ model_server = ModelServer()
194
+
195
+ # API endpoints
196
+ @app.post("/predict", response_model=PredictionResponse)
197
+ async def predict(request: PredictionRequest):
198
+ """Make prediction."""
199
+ return await model_server.predict(request)
200
+
201
+ @app.get("/health", response_model=HealthResponse)
202
+ async def health():
203
+ """Health check endpoint."""
204
+ return model_server.get_health()
205
+
206
+ @app.get("/models")
207
+ async def list_models():
208
+ """List available models."""
209
+ return {"models": model_server.model_registry["models"]}
210
+
211
+ @app.post("/models/{model_name}/load")
212
+ async def load_model_endpoint(model_name: str, version: str = "latest"):
213
+ """Load model endpoint."""
214
+ try:
215
+ model_server.load_model(model_name, version)
216
+ return {"status": "success", "message": f"Model {model_name} version {version} loaded"}
217
+ except Exception as e:
218
+ raise HTTPException(status_code=500, detail=str(e))
219
+
220
+ @app.delete("/models/{model_name}/unload")
221
+ async def unload_model_endpoint(model_name: str, version: str = "latest"):
222
+ """Unload model endpoint."""
223
+ model_server.unload_model(model_name, version)
224
+ return {"status": "success", "message": f"Model {model_name} version {version} unloaded"}
225
+
226
+ @app.get("/metrics")
227
+ async def metrics():
228
+ """Prometheus metrics endpoint."""
229
+ return generate_latest()
230
+ ```
231
+
232
+ ### 2. Batch Prediction Service
233
+ Handle batch prediction requests efficiently.
234
+
235
+ ```python
236
+ from concurrent.futures import ThreadPoolExecutor
237
+ import asyncio
238
+ from typing import List
239
+
240
+ class BatchPredictionService:
241
+ """Service for batch predictions."""
242
+
243
+ def __init__(self, model_server: ModelServer, max_workers: int = 4):
244
+ self.model_server = model_server
245
+ self.executor = ThreadPoolExecutor(max_workers=max_workers)
246
+ self.logger = logging.getLogger("BatchPredictionService")
247
+
248
+ async def predict_batch(self, requests: List[PredictionRequest]) -> List[PredictionResponse]:
249
+ """Process multiple prediction requests in parallel."""
250
+ loop = asyncio.get_event_loop()
251
+
252
+ # Create tasks for parallel processing
253
+ tasks = [
254
+ loop.run_in_executor(
255
+ self.executor,
256
+ self._predict_sync,
257
+ request
258
+ )
259
+ for request in requests
260
+ ]
261
+
262
+ # Wait for all tasks to complete
263
+ results = await asyncio.gather(*tasks, return_exceptions=True)
264
+
265
+ # Handle exceptions
266
+ responses = []
267
+ for i, result in enumerate(results):
268
+ if isinstance(result, Exception):
269
+ self.logger.error(f"Batch prediction failed for request {i}: {str(result)}")
270
+ # Create error response
271
+ responses.append(PredictionResponse(
272
+ prediction=None,
273
+ model_name=requests[i].model_name,
274
+ model_version=requests[i].model_version,
275
+ prediction_time=0,
276
+ timestamp=datetime.now().isoformat(),
277
+ metadata={"error": str(result)}
278
+ ))
279
+ else:
280
+ responses.append(result)
281
+
282
+ return responses
283
+
284
+ def _predict_sync(self, request: PredictionRequest) -> PredictionResponse:
285
+ """Synchronous prediction for thread pool."""
286
+ return asyncio.run(self.model_server.predict(request))
287
+
288
+ async def predict_streaming(self, request_generator):
289
+ """Stream predictions as they complete."""
290
+ loop = asyncio.get_event_loop()
291
+
292
+ async for request in request_generator:
293
+ prediction = await self.model_server.predict(request)
294
+ yield prediction
295
+ ```
296
+
297
+ ### 3. Model Caching and Optimization
298
+ Implement model caching and prediction optimization.
299
+
300
+ ```python
301
+ from functools import lru_cache
302
+ import hashlib
303
+ import json
304
+
305
+ class CachedModelServer(ModelServer):
306
+ """Model server with caching capabilities."""
307
+
308
+ def __init__(self, *args, cache_size: int = 1000, cache_ttl: int = 3600, **kwargs):
309
+ super().__init__(*args, **kwargs)
310
+ self.cache_size = cache_size
311
+ self.cache_ttl = cache_ttl
312
+ self.cache = {}
313
+ self.cache_timestamps = {}
314
+ self.logger = logging.getLogger("CachedModelServer")
315
+
316
+ def _generate_cache_key(self, model_name: str, model_version: str, input_data: Dict[str, Any]) -> str:
317
+ """Generate cache key."""
318
+ cache_input = f"{model_name}_{model_version}_{json.dumps(input_data, sort_keys=True)}"
319
+ return hashlib.sha256(cache_input.encode()).hexdigest()
320
+
321
+ def _get_from_cache(self, cache_key: str) -> Optional[Any]:
322
+ """Get prediction from cache."""
323
+ if cache_key in self.cache:
324
+ cache_time = self.cache_timestamps[cache_key]
325
+ if time.time() - cache_time < self.cache_ttl:
326
+ self.logger.debug(f"Cache hit for key: {cache_key}")
327
+ return self.cache[cache_key]
328
+ else:
329
+ # Cache expired
330
+ del self.cache[cache_key]
331
+ del self.cache_timestamps[cache_key]
332
+
333
+ return None
334
+
335
+ def _set_cache(self, cache_key: str, prediction: Any):
336
+ """Set prediction in cache."""
337
+ # Implement simple LRU cache
338
+ if len(self.cache) >= self.cache_size:
339
+ # Remove oldest entry
340
+ oldest_key = min(self.cache_timestamps.keys(), key=lambda k: self.cache_timestamps[k])
341
+ del self.cache[oldest_key]
342
+ del self.cache_timestamps[oldest_key]
343
+
344
+ self.cache[cache_key] = prediction
345
+ self.cache_timestamps[cache_key] = time.time()
346
+
347
+ async def predict(self, request: PredictionRequest) -> PredictionResponse:
348
+ """Predict with caching."""
349
+ cache_key = self._generate_cache_key(request.model_name, request.model_version, request.input_data)
350
+
351
+ # Check cache
352
+ cached_prediction = self._get_from_cache(cache_key)
353
+ if cached_prediction is not None:
354
+ return cached_prediction
355
+
356
+ # Make prediction
357
+ prediction = await super().predict(request)
358
+
359
+ # Cache result
360
+ self._set_cache(cache_key, prediction)
361
+
362
+ return prediction
363
+
364
+ def clear_cache(self):
365
+ """Clear prediction cache."""
366
+ self.cache.clear()
367
+ self.cache_timestamps.clear()
368
+ self.logger.info("Cache cleared")
369
+ ```
370
+
371
+ ### 4. Model Version Management
372
+ Manage multiple model versions and A/B testing.
373
+
374
+ ```python
375
+ class ModelVersionManager:
376
+ """Manage model versions and A/B testing."""
377
+
378
+ def __init__(self, model_server: ModelServer):
379
+ self.model_server = model_server
380
+ self.traffic_rules = {}
381
+ self.logger = logging.getLogger("ModelVersionManager")
382
+
383
+ def set_traffic_split(self, model_name: str, version_rules: Dict[str, float]):
384
+ """Set traffic split for model versions."""
385
+ total_percentage = sum(version_rules.values())
386
+ if abs(total_percentage - 1.0) > 0.01:
387
+ raise ValueError(f"Traffic split must sum to 1.0, got {total_percentage}")
388
+
389
+ self.traffic_rules[model_name] = version_rules
390
+ self.logger.info(f"Set traffic split for {model_name}: {version_rules}")
391
+
392
+ def get_model_for_request(self, model_name: str, request_id: str) -> str:
393
+ """Determine which model version to use for request."""
394
+ if model_name not in self.traffic_rules:
395
+ return "latest" # Default to latest
396
+
397
+ version_rules = self.traffic_rules[model_name]
398
+
399
+ # Use request_id hash for consistent routing
400
+ hash_value = int(hashlib.md5(request_id.encode()).hexdigest(), 16)
401
+ random_value = (hash_value % 100) / 100.0
402
+
403
+ cumulative = 0.0
404
+ for version, percentage in version_rules.items():
405
+ cumulative += percentage
406
+ if random_value <= cumulative:
407
+ return version
408
+
409
+ return list(version_rules.keys())[-1] # Fallback to last version
410
+
411
+ async def predict_with_routing(self, request: PredictionRequest, request_id: str) -> PredictionResponse:
412
+ """Predict with intelligent version routing."""
413
+ # Determine version
414
+ version = self.get_model_for_request(request.model_name, request_id)
415
+ request.model_version = version
416
+
417
+ # Make prediction
418
+ prediction = await self.model_server.predict(request)
419
+ prediction.metadata = prediction.metadata or {}
420
+ prediction.metadata["routed_version"] = version
421
+ prediction.metadata["request_id"] = request_id
422
+
423
+ return prediction
424
+
425
+ class ABTestFramework:
426
+ """A/B testing framework for models."""
427
+
428
+ def __init__(self, version_manager: ModelVersionManager):
429
+ self.version_manager = version_manager
430
+ self.metrics = defaultdict(lambda: {"predictions": 0, "errors": 0, "latencies": []})
431
+
432
+ async def predict_with_tracking(self, request: PredictionRequest, request_id: str) -> PredictionResponse:
433
+ """Predict with A/B test tracking."""
434
+ prediction = await self.version_manager.predict_with_routing(request, request_id)
435
+
436
+ # Track metrics
437
+ version = prediction.metadata.get("routed_version", "unknown")
438
+ self.metrics[version]["predictions"] += 1
439
+ self.metrics[version]["latencies"].append(prediction.prediction_time)
440
+
441
+ return prediction
442
+
443
+ def get_ab_test_results(self) -> Dict[str, Any]:
444
+ """Get A/B test results."""
445
+ results = {}
446
+ for version, data in self.metrics.items():
447
+ latencies = data["latencies"]
448
+ results[version] = {
449
+ "predictions": data["predictions"],
450
+ "errors": data["errors"],
451
+ "avg_latency": sum(latencies) / len(latencies) if latencies else 0,
452
+ "p95_latency": sorted(latencies)[int(len(latencies) * 0.95)] if len(latencies) > 20 else 0,
453
+ "error_rate": data["errors"] / data["predictions"] if data["predictions"] > 0 else 0
454
+ }
455
+
456
+ return results
457
+ ```
458
+
459
+ ### 5. Monitoring and Observability
460
+ Implement comprehensive monitoring for model serving.
461
+
462
+ ```python
463
+ from prometheus_client import Counter, Histogram, Gauge, Info
464
+ import logging
465
+ from logging.handlers import RotatingFileHandler
466
+
467
+ class ModelServingMonitor:
468
+ """Monitor model serving metrics."""
469
+
470
+ def __init__(self):
471
+ # Prometheus metrics
472
+ self.request_counter = Counter('model_requests_total', 'Total model requests', ['model_name', 'version', 'status'])
473
+ self.request_duration = Histogram('model_request_duration_seconds', 'Model request duration', ['model_name', 'version'])
474
+ self.model_load_counter = Counter('model_loads_total', 'Total model loads', ['model_name', 'version', 'status'])
475
+ self.active_models = Gauge('active_models', 'Number of loaded models')
476
+ self.memory_usage = Gauge('memory_usage_bytes', 'Memory usage')
477
+ self.cpu_usage = Gauge('cpu_usage_percent', 'CPU usage percent')
478
+
479
+ # Setup logging
480
+ self._setup_logging()
481
+
482
+ def _setup_logging(self):
483
+ """Setup detailed logging."""
484
+ logger = logging.getLogger("ModelServing")
485
+ logger.setLevel(logging.INFO)
486
+
487
+ # Rotating file handler
488
+ handler = RotatingFileHandler('model_serving.log', maxBytes=10*1024*1024, backupCount=5)
489
+ formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
490
+ handler.setFormatter(formatter)
491
+ logger.addHandler(handler)
492
+ ```
493
+
494
+ ## Constraints
495
+ - **Performance**: Model loading and prediction should be optimized for low latency
496
+ - **Scalability**: Design for horizontal scaling and load balancing
497
+ - **Monitoring**: Implement comprehensive monitoring and alerting
498
+ - **Error Handling**: Robust error handling and graceful degradation
499
+ - **Security**: Implement authentication, authorization, and input validation
500
+ - **Resource Management**: Monitor and manage memory, CPU, and GPU usage
501
+
502
+ ## Expected Output
503
+ Production-ready model serving infrastructure with proper API design, monitoring, caching, and scalability for reliable ML model deployment.
TRAE-Skills/ai_engineering/AI_Monitoring_Observability.md ADDED
@@ -0,0 +1,536 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Skill: AI Monitoring and Observability
2
+
3
+ ## Purpose
4
+ To implement comprehensive monitoring, logging, and observability for AI systems in production to ensure reliability, performance, and safety.
5
+
6
+ ## When to Use
7
+ - When deploying AI models to production
8
+ - When monitoring model performance and drift
9
+ - When troubleshooting AI system issues
10
+ - When ensuring SLA compliance and user satisfaction
11
+
12
+ ## Procedure
13
+
14
+ ### 1. Model Performance Monitoring
15
+ Track key performance metrics in real-time.
16
+
17
+ ```python
18
+ import time
19
+ import logging
20
+ from datetime import datetime
21
+ from collections import defaultdict
22
+ import json
23
+
24
+ class ModelPerformanceMonitor:
25
+ def __init__(self, model_name):
26
+ self.model_name = model_name
27
+ self.metrics = defaultdict(list)
28
+ self.logger = self._setup_logger()
29
+
30
+ def _setup_logger(self):
31
+ """Setup logging configuration."""
32
+ logger = logging.getLogger(f"{self.model_name}_monitor")
33
+ logger.setLevel(logging.INFO)
34
+
35
+ handler = logging.StreamHandler()
36
+ formatter = logging.Formatter(
37
+ '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
38
+ )
39
+ handler.setFormatter(formatter)
40
+ logger.addHandler(handler)
41
+
42
+ return logger
43
+
44
+ def log_prediction(self, input_data, prediction, latency_ms, metadata=None):
45
+ """Log individual prediction with metadata."""
46
+ timestamp = datetime.now().isoformat()
47
+
48
+ log_entry = {
49
+ 'timestamp': timestamp,
50
+ 'model': self.model_name,
51
+ 'input_hash': hash(str(input_data)),
52
+ 'prediction': str(prediction),
53
+ 'latency_ms': latency_ms,
54
+ 'metadata': metadata or {}
55
+ }
56
+
57
+ self.metrics['predictions'].append(log_entry)
58
+ self.logger.info(f"Prediction logged: {latency_ms}ms")
59
+
60
+ return log_entry
61
+
62
+ def log_feedback(self, prediction_id, feedback):
63
+ """Log user feedback on predictions."""
64
+ feedback_entry = {
65
+ 'prediction_id': prediction_id,
66
+ 'feedback': feedback,
67
+ 'timestamp': datetime.now().isoformat()
68
+ }
69
+
70
+ self.metrics['feedback'].append(feedback_entry)
71
+ self.logger.info(f"Feedback received: {feedback}")
72
+
73
+ return feedback_entry
74
+
75
+ def calculate_metrics(self, time_window_minutes=5):
76
+ """Calculate performance metrics over time window."""
77
+ cutoff_time = datetime.now().timestamp() - (time_window_minutes * 60)
78
+
79
+ recent_predictions = [
80
+ p for p in self.metrics['predictions']
81
+ if datetime.fromisoformat(p['timestamp']).timestamp() > cutoff_time
82
+ ]
83
+
84
+ if not recent_predictions:
85
+ return {'error': 'No recent predictions'}
86
+
87
+ latencies = [p['latency_ms'] for p in recent_predictions]
88
+
89
+ metrics = {
90
+ 'total_predictions': len(recent_predictions),
91
+ 'avg_latency_ms': sum(latencies) / len(latencies),
92
+ 'p50_latency': sorted(latencies)[len(latencies) // 2],
93
+ 'p95_latency': sorted(latencies)[int(len(latencies) * 0.95)],
94
+ 'p99_latency': sorted(latencies)[int(len(latencies) * 0.99)],
95
+ 'max_latency': max(latencies),
96
+ 'min_latency': min(latencies)
97
+ }
98
+
99
+ # Calculate accuracy if feedback available
100
+ if self.metrics['feedback']:
101
+ recent_feedback = [
102
+ f for f in self.metrics['feedback']
103
+ if datetime.fromisoformat(f['timestamp']).timestamp() > cutoff_time
104
+ ]
105
+
106
+ if recent_feedback:
107
+ correct = sum(1 for f in recent_feedback if f['feedback'] == 'correct')
108
+ metrics['accuracy'] = correct / len(recent_feedback)
109
+
110
+ return metrics
111
+
112
+ def check_sla_compliance(self, sla_max_latency_ms=500):
113
+ """Check if SLA requirements are met."""
114
+ metrics = self.calculate_metrics()
115
+
116
+ if 'error' in metrics:
117
+ return {'status': 'error', 'message': metrics['error']}
118
+
119
+ compliance = {
120
+ 'sla_max_latency_ms': sla_max_latency_ms,
121
+ 'p95_latency': metrics['p95_latency'],
122
+ 'sla_met': metrics['p95_latency'] <= sla_max_latency_ms,
123
+ 'avg_latency': metrics['avg_latency_ms']
124
+ }
125
+
126
+ if not compliance['sla_met']:
127
+ self.logger.warning(f"SLA violation: P95 latency {metrics['p95_latency']:.2f}ms exceeds {sla_max_latency_ms}ms")
128
+
129
+ return compliance
130
+
131
+ # Usage
132
+ # monitor = ModelPerformanceMonitor("sentiment_model")
133
+ #
134
+ # start_time = time.time()
135
+ # prediction = model.predict("This is great!")
136
+ # latency = (time.time() - start_time) * 1000
137
+ #
138
+ # monitor.log_prediction("This is great!", prediction, latency)
139
+ #
140
+ # metrics = monitor.calculate_metrics()
141
+ # sla_status = monitor.check_sla_compliance(sla_max_latency_ms=500)
142
+ ```
143
+
144
+ ### 2. Data Drift Detection
145
+ Monitor and detect data distribution changes.
146
+
147
+ ```python
148
+ import numpy as np
149
+ from scipy import stats
150
+ from typing import Dict, List
151
+
152
+ class DataDriftDetector:
153
+ def __init__(self, reference_data, significance_level=0.05):
154
+ """
155
+ Initialize with reference (training) data.
156
+
157
+ Args:
158
+ reference_data: Dictionary of feature names to arrays
159
+ significance_level: Threshold for detecting drift
160
+ """
161
+ self.reference_data = reference_data
162
+ self.significance_level = significance_level
163
+ self.drift_history = []
164
+
165
+ def calculate_kl_divergence(self, p, q):
166
+ """Calculate Kullback-Leibler divergence."""
167
+ # Add small epsilon to avoid division by zero
168
+ epsilon = 1e-10
169
+ p = p + epsilon
170
+ q = q + epsilon
171
+
172
+ return np.sum(p * np.log(p / q))
173
+
174
+ def detect_drift(self, new_data):
175
+ """Detect drift in new data compared to reference."""
176
+ drift_report = {
177
+ 'timestamp': datetime.now().isoformat(),
178
+ 'features': {},
179
+ 'overall_drift_detected': False
180
+ }
181
+
182
+ for feature in self.reference_data.keys():
183
+ if feature not in new_data:
184
+ continue
185
+
186
+ ref_values = self.reference_data[feature]
187
+ new_values = new_data[feature]
188
+
189
+ # Kolmogorov-Smirnov test
190
+ ks_statistic, ks_pvalue = stats.ks_2samp(ref_values, new_values)
191
+
192
+ # Calculate distribution statistics
193
+ ref_mean, ref_std = np.mean(ref_values), np.std(ref_values)
194
+ new_mean, new_std = np.mean(new_values), np.std(new_values)
195
+
196
+ # Feature drift detected if p-value < significance level
197
+ feature_drift = ks_pvalue < self.significance_level
198
+
199
+ feature_report = {
200
+ 'drift_detected': feature_drift,
201
+ 'ks_statistic': ks_statistic,
202
+ 'ks_pvalue': ks_pvalue,
203
+ 'reference_mean': ref_mean,
204
+ 'new_mean': new_mean,
205
+ 'reference_std': ref_std,
206
+ 'new_std': new_std,
207
+ 'mean_shift': abs(new_mean - ref_mean)
208
+ }
209
+
210
+ drift_report['features'][feature] = feature_report
211
+
212
+ if feature_drift:
213
+ drift_report['overall_drift_detected'] = True
214
+
215
+ self.drift_history.append(drift_report)
216
+ return drift_report
217
+
218
+ def get_drift_summary(self, window_size=10):
219
+ """Get summary of recent drift detections."""
220
+ recent_drift = self.drift_history[-window_size:]
221
+
222
+ if not recent_drift:
223
+ return {'status': 'No drift history available'}
224
+
225
+ summary = {
226
+ 'total_checks': len(recent_drift),
227
+ 'drift_detected_count': sum(1 for r in recent_drift if r['overall_drift_detected']),
228
+ 'drift_rate': sum(1 for r in recent_drift if r['overall_drift_detected']) / len(recent_drift),
229
+ 'most_drifted_features': self._get_most_drifted_features(recent_drift)
230
+ }
231
+
232
+ return summary
233
+
234
+ def _get_most_drifted_features(self, drift_reports):
235
+ """Identify features with most frequent drift."""
236
+ feature_drift_counts = defaultdict(int)
237
+
238
+ for report in drift_reports:
239
+ for feature, feature_report in report['features'].items():
240
+ if feature_report['drift_detected']:
241
+ feature_drift_counts[feature] += 1
242
+
243
+ return sorted(feature_drift_counts.items(), key=lambda x: x[1], reverse=True)
244
+
245
+ # Usage
246
+ # reference_data = {
247
+ # 'age': np.random.normal(35, 10, 1000),
248
+ # 'income': np.random.normal(50000, 15000, 1000)
249
+ # }
250
+ #
251
+ # detector = DataDriftDetector(reference_data)
252
+ #
253
+ # # Simulate new data with drift
254
+ # new_data = {
255
+ # 'age': np.random.normal(45, 10, 100), # Drifted age
256
+ # 'income': np.random.normal(52000, 15000, 100) # Similar income
257
+ # }
258
+ #
259
+ # drift_report = detector.detect_drift(new_data)
260
+ # print(drift_report)
261
+ ```
262
+
263
+ ### 3. Error Analysis and Tracking
264
+ Track and analyze model errors.
265
+
266
+ ```python
267
+ class ErrorAnalyzer:
268
+ def __init__(self):
269
+ self.errors = []
270
+ self.error_categories = defaultdict(int)
271
+
272
+ def log_error(self, input_data, prediction, ground_truth, error_type, metadata=None):
273
+ """Log model error with details."""
274
+ error_entry = {
275
+ 'timestamp': datetime.now().isoformat(),
276
+ 'input_data': str(input_data),
277
+ 'prediction': prediction,
278
+ 'ground_truth': ground_truth,
279
+ 'error_type': error_type,
280
+ 'metadata': metadata or {}
281
+ }
282
+
283
+ self.errors.append(error_entry)
284
+ self.error_categories[error_type] += 1
285
+
286
+ return error_entry
287
+
288
+ def analyze_error_patterns(self):
289
+ """Analyze patterns in errors."""
290
+ if not self.errors:
291
+ return {'status': 'No errors to analyze'}
292
+
293
+ analysis = {
294
+ 'total_errors': len(self.errors),
295
+ 'error_types': dict(self.error_categories),
296
+ 'error_rate_by_type': {},
297
+ 'recent_errors': self.errors[-10:] # Last 10 errors
298
+ }
299
+
300
+ # Calculate error rates
301
+ total_errors = len(self.errors)
302
+ for error_type, count in self.error_categories.items():
303
+ analysis['error_rate_by_type'][error_type] = count / total_errors
304
+
305
+ return analysis
306
+
307
+ def identify_error_clusters(self, feature_extractor=None):
308
+ """Identify clusters of similar errors."""
309
+ if not self.errors:
310
+ return {'status': 'No errors to cluster'}
311
+
312
+ # Extract error features
313
+ error_features = []
314
+ for error in self.errors:
315
+ if feature_extractor:
316
+ features = feature_extractor(error['input_data'])
317
+ else:
318
+ features = hash(error['input_data'])
319
+
320
+ error_features.append({
321
+ 'error': error,
322
+ 'features': features
323
+ })
324
+
325
+ # Simple clustering by error type
326
+ clusters = defaultdict(list)
327
+ for item in error_features:
328
+ error_type = item['error']['error_type']
329
+ clusters[error_type].append(item['error'])
330
+
331
+ return {
332
+ 'num_clusters': len(clusters),
333
+ 'cluster_sizes': {k: len(v) for k, v in clusters.items()},
334
+ 'clusters': dict(clusters)
335
+ }
336
+
337
+ def generate_error_report(self):
338
+ """Generate comprehensive error report."""
339
+ patterns = self.analyze_error_patterns()
340
+ clusters = self.identify_error_clusters()
341
+
342
+ report = {
343
+ 'summary': {
344
+ 'total_errors': patterns['total_errors'],
345
+ 'error_types': patterns['error_types']
346
+ },
347
+ 'patterns': patterns,
348
+ 'clusters': clusters
349
+ }
350
+
351
+ return report
352
+
353
+ # Usage
354
+ # error_analyzer = ErrorAnalyzer()
355
+ #
356
+ # # Log some errors
357
+ # error_analyzer.log_error(
358
+ # input_data="Great product!",
359
+ # prediction="negative",
360
+ # ground_truth="positive",
361
+ # error_type="sentiment_misclassification"
362
+ # )
363
+ #
364
+ # report = error_analyzer.generate_error_report()
365
+ ```
366
+
367
+ ### 4. System Health Monitoring
368
+ Monitor overall AI system health.
369
+
370
+ ```python
371
+ import psutil
372
+ import GPUtil
373
+
374
+ class AISystemHealthMonitor:
375
+ def __init__(self):
376
+ self.health_metrics = []
377
+
378
+ def collect_system_metrics(self):
379
+ """Collect system resource usage."""
380
+ metrics = {
381
+ 'timestamp': datetime.now().isoformat(),
382
+ 'cpu_percent': psutil.cpu_percent(interval=1),
383
+ 'memory_percent': psutil.virtual_memory().percent,
384
+ 'disk_usage': psutil.disk_usage('/').percent,
385
+ 'network_sent': psutil.net_io_counters().bytes_sent,
386
+ 'network_recv': psutil.net_io_counters().bytes_recv
387
+ }
388
+
389
+ # GPU metrics if available
390
+ try:
391
+ gpus = GPUtil.getGPUs()
392
+ if gpus:
393
+ metrics['gpu_usage'] = gpus[0].load * 100
394
+ metrics['gpu_memory'] = gpus[0].memoryUtil * 100
395
+ except:
396
+ pass
397
+
398
+ self.health_metrics.append(metrics)
399
+ return metrics
400
+
401
+ def check_health_status(self, thresholds=None):
402
+ """Check if system is healthy based on thresholds."""
403
+ if thresholds is None:
404
+ thresholds = {
405
+ 'cpu_percent': 80,
406
+ 'memory_percent': 85,
407
+ 'disk_usage': 90,
408
+ 'gpu_usage': 90
409
+ }
410
+
411
+ latest_metrics = self.collect_system_metrics()
412
+ health_status = {
413
+ 'status': 'healthy',
414
+ 'alerts': [],
415
+ 'metrics': latest_metrics
416
+ }
417
+
418
+ # Check each metric against threshold
419
+ for metric, threshold in thresholds.items():
420
+ if metric in latest_metrics:
421
+ value = latest_metrics[metric]
422
+ if value > threshold:
423
+ health_status['status'] = 'warning'
424
+ health_status['alerts'].append({
425
+ 'metric': metric,
426
+ 'value': value,
427
+ 'threshold': threshold,
428
+ 'message': f'{metric} ({value:.1f}%) exceeds threshold ({threshold}%)'
429
+ })
430
+
431
+ return health_status
432
+
433
+ def generate_health_report(self):
434
+ """Generate system health report."""
435
+ health_status = self.check_health_status()
436
+
437
+ report = f"""
438
+ System Health Report - {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
439
+ {'=' * 60}
440
+
441
+ Status: {health_status['status'].upper()}
442
+
443
+ System Metrics:
444
+ - CPU Usage: {health_status['metrics']['cpu_percent']:.1f}%
445
+ - Memory Usage: {health_status['metrics']['memory_percent']:.1f}%
446
+ - Disk Usage: {health_status['metrics']['disk_usage']:.1f}%
447
+ """
448
+
449
+ if 'gpu_usage' in health_status['metrics']:
450
+ report += f"- GPU Usage: {health_status['metrics']['gpu_usage']:.1f}%\n"
451
+
452
+ if health_status['alerts']:
453
+ report += "\nAlerts:\n"
454
+ for alert in health_status['alerts']:
455
+ report += f" ⚠️ {alert['message']}\n"
456
+ else:
457
+ report += "\n✅ All systems operating within normal parameters.\n"
458
+
459
+ return report
460
+
461
+ # Usage
462
+ # health_monitor = AISystemHealthMonitor()
463
+ # health_report = health_monitor.generate_health_report()
464
+ # print(health_report)
465
+ ```
466
+
467
+ ### 5. Integration with Monitoring Platforms
468
+ Export metrics to monitoring platforms.
469
+
470
+ ```python
471
+ class MonitoringPlatformIntegration:
472
+ def __init__(self, platform='prometheus'):
473
+ self.platform = platform
474
+ self.metrics_buffer = []
475
+
476
+ def export_to_prometheus(self, metrics):
477
+ """Format metrics for Prometheus."""
478
+ prometheus_metrics = []
479
+
480
+ for metric_name, value in metrics.items():
481
+ # Convert metric name to Prometheus format
482
+ prom_name = metric_name.lower().replace(' ', '_')
483
+ prometheus_metrics.append(f"{prom_name} {value}")
484
+
485
+ return '\n'.join(prometheus_metrics)
486
+
487
+ def export_to_datadog(self, metrics):
488
+ """Format metrics for Datadog."""
489
+ datadog_metrics = []
490
+
491
+ for metric_name, value in metrics.items():
492
+ metric_data = {
493
+ 'metric': f'ai.{metric_name.lower().replace(" ", ".")}',
494
+ 'points': [[int(time.time()), value]],
495
+ 'type': 'gauge'
496
+ }
497
+ datadog_metrics.append(metric_data)
498
+
499
+ return datadog_metrics
500
+
501
+ def send_metrics(self, metrics, api_endpoint):
502
+ """Send metrics to monitoring platform."""
503
+ if self.platform == 'prometheus':
504
+ formatted_metrics = self.export_to_prometheus(metrics)
505
+ # In real implementation, push to Prometheus Pushgateway
506
+ print(f"Sending to Prometheus:\n{formatted_metrics}")
507
+
508
+ elif self.platform == 'datadog':
509
+ formatted_metrics = self.export_to_datadog(metrics)
510
+ # In real implementation, use Datadog API
511
+ print(f"Sending to Datadog: {formatted_metrics}")
512
+
513
+ return {'status': 'sent', 'count': len(metrics)}
514
+
515
+ # Usage
516
+ # integration = MonitoringPlatformIntegration('prometheus')
517
+ #
518
+ # metrics = {
519
+ # 'model_latency_ms': 145.2,
520
+ # 'prediction_count': 1000,
521
+ # 'error_rate': 0.02
522
+ # }
523
+ #
524
+ # integration.send_metrics(metrics, 'http://pushgateway:9091')
525
+ ```
526
+
527
+ ## Constraints
528
+ - **Performance Overhead**: Monitoring should not significantly impact system performance
529
+ - **Storage Costs**: Extensive logging can generate large amounts of data
530
+ - **Privacy**: Ensure sensitive data is not logged or is properly anonymized
531
+ - **Real-time Requirements**: Balance between real-time monitoring and batch processing
532
+ - **Alert Fatigue**: Configure thresholds to avoid excessive false alarms
533
+ - **Data Retention**: Implement proper data retention policies for logs and metrics
534
+
535
+ ## Expected Output
536
+ Comprehensive monitoring and observability for AI systems with real-time performance tracking, drift detection, error analysis, and system health monitoring for reliable production deployment.
TRAE-Skills/ai_engineering/AI_Pipeline_Automation.md ADDED
@@ -0,0 +1,562 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Skill: AI Pipeline Automation
2
+
3
+ ## Purpose
4
+ To create automated end-to-end machine learning pipelines that handle data ingestion, preprocessing, training, evaluation, and deployment.
5
+
6
+ ## When to Use
7
+ - When building production ML systems
8
+ - When implementing continuous training and deployment
9
+ - When scaling ML workflows
10
+ - When ensuring reproducibility in ML experiments
11
+
12
+ ## Procedure
13
+
14
+ ### 1. Pipeline Framework Setup
15
+ Create a modular pipeline framework.
16
+
17
+ ```python
18
+ from abc import ABC, abstractmethod
19
+ from typing import Any, Dict, List
20
+ import logging
21
+ from datetime import datetime
22
+
23
+ class PipelineStep(ABC):
24
+ """Abstract base class for pipeline steps."""
25
+
26
+ def __init__(self, name: str):
27
+ self.name = name
28
+ self.logger = logging.getLogger(f"Pipeline.{name}")
29
+
30
+ @abstractmethod
31
+ def execute(self, context: Dict[str, Any]) -> Dict[str, Any]:
32
+ """Execute the pipeline step."""
33
+ pass
34
+
35
+ def __call__(self, context: Dict[str, Any]) -> Dict[str, Any]:
36
+ """Execute with logging."""
37
+ self.logger.info(f"Starting step: {self.name}")
38
+ start_time = datetime.now()
39
+
40
+ try:
41
+ result = self.execute(context)
42
+ duration = (datetime.now() - start_time).total_seconds()
43
+ self.logger.info(f"Completed step: {self.name} in {duration:.2f}s")
44
+ return result
45
+ except Exception as e:
46
+ self.logger.error(f"Failed step: {self.name} - {str(e)}")
47
+ raise
48
+
49
+ class Pipeline:
50
+ """Machine learning pipeline orchestrator."""
51
+
52
+ def __init__(self, name: str, steps: List[PipelineStep]):
53
+ self.name = name
54
+ self.steps = steps
55
+ self.logger = logging.getLogger(f"Pipeline.{name}")
56
+ self.context = {}
57
+
58
+ def add_step(self, step: PipelineStep):
59
+ """Add a step to the pipeline."""
60
+ self.steps.append(step)
61
+
62
+ def run(self, initial_context: Dict[str, Any] = None) -> Dict[str, Any]:
63
+ """Run the entire pipeline."""
64
+ self.context = initial_context or {}
65
+
66
+ self.logger.info(f"Starting pipeline: {self.name}")
67
+ pipeline_start = datetime.now()
68
+
69
+ try:
70
+ for step in self.steps:
71
+ self.context = step(self.context)
72
+
73
+ duration = (datetime.now() - pipeline_start).total_seconds()
74
+ self.logger.info(f"Pipeline {self.name} completed in {duration:.2f}s")
75
+
76
+ return self.context
77
+
78
+ except Exception as e:
79
+ self.logger.error(f"Pipeline {self.name} failed: {str(e)}")
80
+ raise
81
+ ```
82
+
83
+ ### 2. Data Ingestion Step
84
+ Automated data collection and loading.
85
+
86
+ ```python
87
+ import pandas as pd
88
+ from sqlalchemy import create_engine
89
+ import requests
90
+ from io import StringIO
91
+
92
+ class DataIngestionStep(PipelineStep):
93
+ """Ingest data from various sources."""
94
+
95
+ def __init__(self, sources: Dict[str, Any]):
96
+ super().__init__("data_ingestion")
97
+ self.sources = sources
98
+
99
+ def execute(self, context: Dict[str, Any]) -> Dict[str, Any]:
100
+ """Ingest data from configured sources."""
101
+ data = {}
102
+
103
+ for source_name, source_config in self.sources.items():
104
+ source_type = source_config.get('type')
105
+
106
+ if source_type == 'csv':
107
+ data[source_name] = pd.read_csv(source_config['path'])
108
+
109
+ elif source_type == 'database':
110
+ engine = create_engine(source_config['connection_string'])
111
+ query = source_config['query']
112
+ data[source_name] = pd.read_sql(query, engine)
113
+
114
+ elif source_type == 'api':
115
+ response = requests.get(source_config['url'])
116
+ response.raise_for_status()
117
+ json_data = response.json()
118
+ data[source_name] = pd.DataFrame(json_data)
119
+
120
+ elif source_type == 'json':
121
+ data[source_name] = pd.read_json(source_config['path'])
122
+
123
+ self.logger.info(f"Ingested {len(data[source_name])} rows from {source_name}")
124
+
125
+ context['raw_data'] = data
126
+ return context
127
+ ```
128
+
129
+ ### 3. Data Preprocessing Step
130
+ Automated data cleaning and feature engineering.
131
+
132
+ ```python
133
+ from sklearn.preprocessing import StandardScaler, LabelEncoder
134
+ from sklearn.model_selection import train_test_split
135
+ import numpy as np
136
+
137
+ class DataPreprocessingStep(PipelineStep):
138
+ """Preprocess and prepare data for training."""
139
+
140
+ def __init__(self, preprocessing_config: Dict[str, Any]):
141
+ super().__init__("data_preprocessing")
142
+ self.config = preprocessing_config
143
+
144
+ def execute(self, context: Dict[str, Any]) -> Dict[str, Any]:
145
+ """Preprocess data according to configuration."""
146
+ raw_data = context['raw_data']
147
+ processed_data = {}
148
+
149
+ for data_name, df in raw_data.items():
150
+ # Handle missing values
151
+ if self.config.get('drop_missing', False):
152
+ df = df.dropna()
153
+ elif self.config.get('fill_missing'):
154
+ df = df.fillna(self.config['fill_missing'])
155
+
156
+ # Encode categorical variables
157
+ if self.config.get('encode_categorical', False):
158
+ categorical_cols = df.select_dtypes(include=['object']).columns
159
+ for col in categorical_cols:
160
+ le = LabelEncoder()
161
+ df[col] = le.fit_transform(df[col].astype(str))
162
+
163
+ # Feature scaling
164
+ if self.config.get('scale_features', False):
165
+ numeric_cols = df.select_dtypes(include=[np.number]).columns
166
+ scaler = StandardScaler()
167
+ df[numeric_cols] = scaler.fit_transform(df[numeric_cols])
168
+
169
+ # Store scaler for later use
170
+ context[f'{data_name}_scaler'] = scaler
171
+
172
+ processed_data[data_name] = df
173
+ self.logger.info(f"Preprocessed {data_name}: {df.shape}")
174
+
175
+ context['processed_data'] = processed_data
176
+ return context
177
+
178
+ class DataSplitStep(PipelineStep):
179
+ """Split data into train, validation, and test sets."""
180
+
181
+ def __init__(self, target_column: str, test_size: float = 0.2, val_size: float = 0.1):
182
+ super().__init__("data_split")
183
+ self.target_column = target_column
184
+ self.test_size = test_size
185
+ self.val_size = val_size
186
+
187
+ def execute(self, context: Dict[str, Any]) -> Dict[str, Any]:
188
+ """Split data for training."""
189
+ processed_data = context['processed_data']
190
+
191
+ for data_name, df in processed_data.items():
192
+ if self.target_column not in df.columns:
193
+ self.logger.warning(f"Target column {self.target_column} not in {data_name}")
194
+ continue
195
+
196
+ X = df.drop(columns=[self.target_column])
197
+ y = df[self.target_column]
198
+
199
+ # First split: separate test set
200
+ X_train, X_test, y_train, y_test = train_test_split(
201
+ X, y, test_size=self.test_size, random_state=42
202
+ )
203
+
204
+ # Second split: separate validation set from training
205
+ val_ratio = self.val_size / (1 - self.test_size)
206
+ X_train, X_val, y_train, y_val = train_test_split(
207
+ X_train, y_train, test_size=val_ratio, random_state=42
208
+ )
209
+
210
+ context[f'{data_name}_train'] = (X_train, y_train)
211
+ context[f'{data_name}_val'] = (X_val, y_val)
212
+ context[f'{data_name}_test'] = (X_test, y_test)
213
+
214
+ self.logger.info(f"Split {data_name}: train={len(X_train)}, val={len(X_val)}, test={len(X_test)}")
215
+
216
+ return context
217
+ ```
218
+
219
+ ### 4. Model Training Step
220
+ Automated model training with hyperparameter tuning.
221
+
222
+ ```python
223
+ from sklearn.ensemble import RandomForestClassifier
224
+ from sklearn.linear_model import LogisticRegression
225
+ from sklearn.model_selection import GridSearchCV
226
+ import joblib
227
+
228
+ class ModelTrainingStep(PipelineStep):
229
+ """Train machine learning models."""
230
+
231
+ def __init__(self, model_type: str, hyperparameters: Dict[str, Any] = None):
232
+ super().__init__("model_training")
233
+ self.model_type = model_type
234
+ self.hyperparameters = hyperparameters or {}
235
+
236
+ def _get_model(self):
237
+ """Get model instance based on type."""
238
+ models = {
239
+ 'random_forest': RandomForestClassifier,
240
+ 'logistic_regression': LogisticRegression
241
+ }
242
+
243
+ if self.model_type not in models:
244
+ raise ValueError(f"Unknown model type: {self.model_type}")
245
+
246
+ return models[self.model_type](**self.hyperparameters)
247
+
248
+ def execute(self, context: Dict[str, Any]) -> Dict[str, Any]:
249
+ """Train the model."""
250
+ # Find training data
251
+ train_key = None
252
+ for key in context.keys():
253
+ if key.endswith('_train'):
254
+ train_key = key
255
+ break
256
+
257
+ if not train_key:
258
+ raise ValueError("No training data found in context")
259
+
260
+ X_train, y_train = context[train_key]
261
+
262
+ # Get validation data if available
263
+ val_key = train_key.replace('_train', '_val')
264
+ X_val = y_val = None
265
+ if val_key in context:
266
+ X_val, y_val = context[val_key]
267
+
268
+ # Create and train model
269
+ model = self._get_model()
270
+
271
+ self.logger.info(f"Training {self.model_type} model...")
272
+ model.fit(X_train, y_train)
273
+
274
+ # Evaluate on validation set
275
+ if X_val is not None:
276
+ val_score = model.score(X_val, y_val)
277
+ self.logger.info(f"Validation score: {val_score:.4f}")
278
+ context['val_score'] = val_score
279
+
280
+ # Store model
281
+ context['model'] = model
282
+ context['model_type'] = self.model_type
283
+
284
+ return context
285
+
286
+ class HyperparameterTuningStep(PipelineStep):
287
+ """Perform hyperparameter tuning."""
288
+
289
+ def __init__(self, model_type: str, param_grid: Dict[str, List], cv: int = 5):
290
+ super().__init__("hyperparameter_tuning")
291
+ self.model_type = model_type
292
+ self.param_grid = param_grid
293
+ self.cv = cv
294
+
295
+ def execute(self, context: Dict[str, Any]) -> Dict[str, Any]:
296
+ """Perform grid search for hyperparameters."""
297
+ train_key = None
298
+ for key in context.keys():
299
+ if key.endswith('_train'):
300
+ train_key = key
301
+ break
302
+
303
+ X_train, y_train = context[train_key]
304
+
305
+ # Get base model
306
+ if self.model_type == 'random_forest':
307
+ base_model = RandomForestClassifier()
308
+ elif self.model_type == 'logistic_regression':
309
+ base_model = LogisticRegression(max_iter=1000)
310
+ else:
311
+ raise ValueError(f"Unknown model type: {self.model_type}")
312
+
313
+ # Perform grid search
314
+ grid_search = GridSearchCV(
315
+ base_model,
316
+ self.param_grid,
317
+ cv=self.cv,
318
+ scoring='accuracy',
319
+ n_jobs=-1,
320
+ verbose=1
321
+ )
322
+
323
+ self.logger.info("Starting hyperparameter tuning...")
324
+ grid_search.fit(X_train, y_train)
325
+
326
+ # Store results
327
+ context['model'] = grid_search.best_estimator_
328
+ context['best_params'] = grid_search.best_params_
329
+ context['best_score'] = grid_search.best_score_
330
+
331
+ self.logger.info(f"Best parameters: {grid_search.best_params_}")
332
+ self.logger.info(f"Best cross-validation score: {grid_search.best_score_:.4f}")
333
+
334
+ return context
335
+ ```
336
+
337
+ ### 5. Model Evaluation Step
338
+ Comprehensive model evaluation and reporting.
339
+
340
+ ```python
341
+ from sklearn.metrics import classification_report, confusion_matrix, roc_auc_score
342
+ import matplotlib.pyplot as plt
343
+ import seaborn as sns
344
+
345
+ class ModelEvaluationStep(PipelineStep):
346
+ """Evaluate trained models."""
347
+
348
+ def __init__(self, save_plots: bool = True, output_dir: str = './output'):
349
+ super().__init__("model_evaluation")
350
+ self.save_plots = save_plots
351
+ self.output_dir = output_dir
352
+
353
+ def execute(self, context: Dict[str, Any]) -> Dict[str, Any]:
354
+ """Evaluate model on test set."""
355
+ model = context.get('model')
356
+ if not model:
357
+ raise ValueError("No model found in context")
358
+
359
+ # Find test data
360
+ test_key = None
361
+ for key in context.keys():
362
+ if key.endswith('_test'):
363
+ test_key = key
364
+ break
365
+
366
+ if not test_key:
367
+ raise ValueError("No test data found in context")
368
+
369
+ X_test, y_test = context[test_key]
370
+
371
+ # Make predictions
372
+ y_pred = model.predict(X_test)
373
+ test_score = model.score(X_test, y_test)
374
+
375
+ # Calculate metrics
376
+ report = classification_report(y_test, y_pred, output_dict=True)
377
+ conf_matrix = confusion_matrix(y_test, y_pred)
378
+
379
+ # Store results
380
+ context['test_score'] = test_score
381
+ context['classification_report'] = report
382
+ context['confusion_matrix'] = conf_matrix
383
+
384
+ self.logger.info(f"Test score: {test_score:.4f}")
385
+
386
+ # Generate plots
387
+ if self.save_plots:
388
+ self._save_confusion_matrix(conf_matrix, context.get('model_type', 'model'))
389
+ self._save_classification_report(report, context.get('model_type', 'model'))
390
+
391
+ return context
392
+
393
+ def _save_confusion_matrix(self, conf_matrix, model_name):
394
+ """Save confusion matrix plot."""
395
+ plt.figure(figsize=(8, 6))
396
+ sns.heatmap(conf_matrix, annot=True, fmt='d', cmap='Blues')
397
+ plt.title(f'Confusion Matrix - {model_name}')
398
+ plt.ylabel('True Label')
399
+ plt.xlabel('Predicted Label')
400
+ plt.savefig(f'{self.output_dir}/{model_name}_confusion_matrix.png')
401
+ plt.close()
402
+
403
+ def _save_classification_report(self, report, model_name):
404
+ """Save classification report."""
405
+ with open(f'{self.output_dir}/{model_name}_report.txt', 'w') as f:
406
+ f.write(f"Classification Report - {model_name}\n")
407
+ f.write("=" * 50 + "\n\n")
408
+
409
+ for class_name, metrics in report.items():
410
+ if isinstance(metrics, dict):
411
+ f.write(f"Class: {class_name}\n")
412
+ for metric, value in metrics.items():
413
+ f.write(f" {metric}: {value:.4f}\n")
414
+ f.write("\n")
415
+ ```
416
+
417
+ ### 6. Model Deployment Step
418
+ Automated model deployment and versioning.
419
+
420
+ ```python
421
+ import hashlib
422
+ import json
423
+ from datetime import datetime
424
+
425
+ class ModelDeploymentStep(PipelineStep):
426
+ """Deploy trained models."""
427
+
428
+ def __init__(self, deployment_config: Dict[str, Any]):
429
+ super().__init__("model_deployment")
430
+ self.config = deployment_config
431
+
432
+ def execute(self, context: Dict[str, Any]) -> Dict[str, Any]:
433
+ """Deploy model to production."""
434
+ model = context.get('model')
435
+ if not model:
436
+ raise ValueError("No model found in context")
437
+
438
+ # Generate model version
439
+ model_version = self._generate_version(context)
440
+
441
+ # Save model
442
+ model_path = f"{self.config['model_dir']}/model_{model_version}.joblib"
443
+ joblib.dump(model, model_path)
444
+
445
+ # Save metadata
446
+ metadata = {
447
+ 'version': model_version,
448
+ 'model_type': context.get('model_type', 'unknown'),
449
+ 'test_score': context.get('test_score', 0),
450
+ 'best_params': context.get('best_params', {}),
451
+ 'timestamp': datetime.now().isoformat(),
452
+ 'model_path': model_path
453
+ }
454
+
455
+ metadata_path = f"{self.config['model_dir']}/model_{model_version}_metadata.json"
456
+ with open(metadata_path, 'w') as f:
457
+ json.dump(metadata, f, indent=2)
458
+
459
+ # Update model registry
460
+ self._update_model_registry(metadata)
461
+
462
+ context['deployed_model'] = metadata
463
+ self.logger.info(f"Model deployed with version: {model_version}")
464
+
465
+ return context
466
+
467
+ def _generate_version(self, context: Dict[str, Any]) -> str:
468
+ """Generate unique model version."""
469
+ data_string = f"{context.get('model_type')}{context.get('test_score')}{datetime.now().timestamp()}"
470
+ return hashlib.md5(data_string.encode()).hexdigest()[:8]
471
+
472
+ def _update_model_registry(self, metadata: Dict[str, Any]):
473
+ """Update model registry with new deployment."""
474
+ registry_path = f"{self.config['model_dir']}/model_registry.json"
475
+
476
+ # Load existing registry
477
+ try:
478
+ with open(registry_path, 'r') as f:
479
+ registry = json.load(f)
480
+ except FileNotFoundError:
481
+ registry = {'models': [], 'current': None}
482
+
483
+ # Add new model
484
+ registry['models'].append(metadata)
485
+ registry['current'] = metadata['version']
486
+
487
+ # Save updated registry
488
+ with open(registry_path, 'w') as f:
489
+ json.dump(registry, f, indent=2)
490
+ ```
491
+
492
+ ### 7. Complete Pipeline Example
493
+ Assemble and run the complete pipeline.
494
+
495
+ ```python
496
+ def create_ml_pipeline() -> Pipeline:
497
+ """Create a complete ML pipeline."""
498
+
499
+ # Define configuration
500
+ sources = {
501
+ 'training_data': {
502
+ 'type': 'csv',
503
+ 'path': './data/training_data.csv'
504
+ }
505
+ }
506
+
507
+ preprocessing_config = {
508
+ 'drop_missing': True,
509
+ 'encode_categorical': True,
510
+ 'scale_features': True
511
+ }
512
+
513
+ deployment_config = {
514
+ 'model_dir': './models'
515
+ }
516
+
517
+ # Create pipeline steps
518
+ steps = [
519
+ DataIngestionStep(sources),
520
+ DataPreprocessingStep(preprocessing_config),
521
+ DataSplitStep(target_column='target', test_size=0.2, val_size=0.1),
522
+ HyperparameterTuningStep(
523
+ model_type='random_forest',
524
+ param_grid={
525
+ 'n_estimators': [50, 100, 200],
526
+ 'max_depth': [5, 10, 15],
527
+ 'min_samples_split': [2, 5, 10]
528
+ },
529
+ cv=5
530
+ ),
531
+ ModelEvaluationStep(save_plots=True, output_dir='./output'),
532
+ ModelDeploymentStep(deployment_config)
533
+ ]
534
+
535
+ return Pipeline(name="ml_training_pipeline", steps=steps)
536
+
537
+ # Usage
538
+ if __name__ == "__main__":
539
+ # Setup logging
540
+ logging.basicConfig(
541
+ level=logging.INFO,
542
+ format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
543
+ )
544
+
545
+ # Create and run pipeline
546
+ pipeline = create_ml_pipeline()
547
+ result = pipeline.run()
548
+
549
+ print("Pipeline completed successfully!")
550
+ print(f"Test score: {result.get('test_score', 'N/A')}")
551
+ ```
552
+
553
+ ## Constraints
554
+ - **Data Quality**: Garbage in, garbage out - ensure data quality
555
+ - **Pipeline Complexity**: Balance between automation and flexibility
556
+ - **Resource Management**: Monitor computational resources during training
557
+ - **Version Control**: Track all pipeline steps and configurations
558
+ - **Error Handling**: Implement robust error handling and recovery
559
+ - **Scalability**: Design for data and computational scaling
560
+
561
+ ## Expected Output
562
+ Automated, reproducible ML pipelines that handle data ingestion, preprocessing, training, evaluation, and deployment with proper monitoring and version control.
TRAE-Skills/ai_engineering/AI_Safety_Ethics.md ADDED
@@ -0,0 +1,379 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Skill: AI Safety and Ethics
2
+
3
+ ## Purpose
4
+ To implement AI systems that are safe, fair, transparent, and aligned with human values while minimizing potential harms and biases.
5
+
6
+ ## When to Use
7
+ - When deploying AI systems that affect people's lives
8
+ - When working with sensitive data or protected characteristics
9
+ - When implementing automated decision-making systems
10
+ - When ensuring regulatory compliance (GDPR, AI Act, etc.)
11
+
12
+ ## Procedure
13
+
14
+ ### 1. Bias Detection and Mitigation
15
+ Identify and reduce biases in AI systems.
16
+
17
+ ```python
18
+ import pandas as pd
19
+ from sklearn.metrics import confusion_matrix
20
+ from aif360.datasets import BinaryLabelDataset
21
+ from aif360.metrics import BinaryLabelDatasetMetric
22
+ from aif360.algorithms.preprocessing import Reweighing
23
+
24
+ def detect_bias(df, protected_attribute, label, privileged_groups, unprivileged_groups):
25
+ """Detect bias in dataset."""
26
+ # Convert to AIF360 dataset
27
+ dataset = BinaryLabelDataset(
28
+ df=df,
29
+ label_names=[label],
30
+ protected_attribute_names=[protected_attribute],
31
+ favorable_label=1,
32
+ unfavorable_label=0
33
+ )
34
+
35
+ # Calculate fairness metrics
36
+ metric = BinaryLabelDatasetMetric(
37
+ dataset,
38
+ unprivileged_groups=unprivileged_groups,
39
+ privileged_groups=privileged_groups
40
+ )
41
+
42
+ return {
43
+ 'disparate_impact': metric.disparate_impact(),
44
+ 'statistical_parity_difference': metric.statistical_parity_difference()
45
+ }
46
+
47
+ def mitigate_bias(df, protected_attribute, label, privileged_groups, unprivileged_groups):
48
+ """Apply bias mitigation techniques."""
49
+ # Original dataset
50
+ dataset = BinaryLabelDataset(
51
+ df=df,
52
+ label_names=[label],
53
+ protected_attribute_names=[protected_attribute],
54
+ favorable_label=1,
55
+ unfavorable_label=0
56
+ )
57
+
58
+ # Apply reweighing
59
+ reweigher = Reweighing(
60
+ unprivileged_groups=unprivileged_groups,
61
+ privileged_groups=privileged_groups
62
+ )
63
+
64
+ dataset_transformed = reweigher.fit_transform(dataset)
65
+
66
+ return dataset_transformed.convert_to_dataframe()[0]
67
+
68
+ # Example usage
69
+ # df = pd.read_csv('loan_applications.csv')
70
+ # protected_attribute = 'gender'
71
+ # label = 'loan_approved'
72
+ #
73
+ # bias_metrics = detect_bias(df, protected_attribute, label,
74
+ # privileged_groups=[{'gender': 1}],
75
+ # unprivileged_groups=[{'gender': 0}])
76
+ #
77
+ # print(f"Disparate Impact: {bias_metrics['disparate_impact']}")
78
+ #
79
+ # # Mitigate bias
80
+ # fair_df = mitigate_bias(df, protected_attribute, label,
81
+ # privileged_groups=[{'gender': 1}],
82
+ # unprivileged_groups=[{'gender': 0}])
83
+ ```
84
+
85
+ ### 2. Content Moderation and Safety
86
+ Implement safety filters for AI content.
87
+
88
+ ```python
89
+ import openai
90
+
91
+ class SafeContentGenerator:
92
+ def __init__(self):
93
+ self.client = openai.OpenAI()
94
+ self.forbidden_categories = [
95
+ "hate speech",
96
+ "violence",
97
+ "self-harm",
98
+ "sexual content",
99
+ "illegal activities"
100
+ ]
101
+
102
+ def check_safety(self, content):
103
+ """Check if content is safe."""
104
+ moderation_response = self.client.moderations.create(input=content)
105
+ result = moderation_response.results[0]
106
+
107
+ return {
108
+ 'flagged': result.flagged,
109
+ 'categories': result.categories,
110
+ 'category_scores': result.category_scores
111
+ }
112
+
113
+ def generate_safe_content(self, prompt, max_retries=3):
114
+ """Generate content with safety checks."""
115
+ for attempt in range(max_retries):
116
+ response = self.client.chat.completions.create(
117
+ model="gpt-4",
118
+ messages=[{"role": "user", "content": prompt}],
119
+ temperature=0.7
120
+ )
121
+
122
+ content = response.choices[0].message.content
123
+ safety_check = self.check_safety(content)
124
+
125
+ if not safety_check['flagged']:
126
+ return content
127
+
128
+ print(f"Attempt {attempt + 1}: Content flagged as unsafe")
129
+ prompt = f"Generate content that is completely safe and appropriate: {prompt}"
130
+
131
+ raise Exception("Failed to generate safe content after multiple attempts")
132
+
133
+ # Usage
134
+ generator = SafeContentGenerator()
135
+ safe_content = generator.generate_safe_content("Write a story about teamwork")
136
+ ```
137
+
138
+ ### 3. Transparency and Explainability
139
+ Implement explainability for AI decisions.
140
+
141
+ ```python
142
+ import shap
143
+ from sklearn.ensemble import RandomForestClassifier
144
+
145
+ class ExplainableAI:
146
+ def __init__(self, model, feature_names):
147
+ self.model = model
148
+ self.feature_names = feature_names
149
+ self.explainer = None
150
+
151
+ def fit_explainer(self, X_train):
152
+ """Fit SHAP explainer."""
153
+ self.explainer = shap.Explainer(self.model, X_train)
154
+
155
+ def explain_prediction(self, instance):
156
+ """Explain individual prediction."""
157
+ shap_values = self.explainer(instance)
158
+
159
+ # Get feature importance
160
+ feature_importance = list(zip(
161
+ self.feature_names,
162
+ shap_values.values[0]
163
+ ))
164
+
165
+ # Sort by absolute importance
166
+ feature_importance.sort(key=lambda x: abs(x[1]), reverse=True)
167
+
168
+ return feature_importance[:10] # Top 10 features
169
+
170
+ def generate_explanation_text(self, instance, prediction, feature_importance):
171
+ """Generate human-readable explanation."""
172
+ explanation = f"Prediction: {prediction}\n\n"
173
+ explanation += "Key factors influencing this decision:\n"
174
+
175
+ for feature, importance in feature_importance:
176
+ direction = "increases" if importance > 0 else "decreases"
177
+ explanation += f"- {feature}: {direction} likelihood (impact: {abs(importance):.3f})\n"
178
+
179
+ return explanation
180
+
181
+ # Example usage
182
+ # model = RandomForestClassifier()
183
+ # model.fit(X_train, y_train)
184
+ #
185
+ # explainable_ai = ExplainableAI(model, feature_names)
186
+ # explainable_ai.fit_explainer(X_train)
187
+ #
188
+ # instance = X_test[0]
189
+ # prediction = model.predict([instance])[0]
190
+ # feature_importance = explainable_ai.explain_prediction(instance)
191
+ #
192
+ # explanation = explainable_ai.generate_explanation_text(
193
+ # instance, prediction, feature_importance
194
+ # )
195
+ # print(explanation)
196
+ ```
197
+
198
+ ### 4. Privacy-Preserving AI
199
+ Implement privacy protection in AI systems.
200
+
201
+ ```python
202
+ import numpy as np
203
+ from sklearn.preprocessing import StandardScaler
204
+
205
+ class PrivacyPreservingML:
206
+ def __init__(self, epsilon=1.0):
207
+ self.epsilon = epsilon
208
+ self.scaler = StandardScaler()
209
+
210
+ def add_laplace_noise(self, data, sensitivity):
211
+ """Add Laplace noise for differential privacy."""
212
+ scale = sensitivity / self.epsilon
213
+ noise = np.random.laplace(0, scale, data.shape)
214
+ return data + noise
215
+
216
+ def private_aggregation(self, data):
217
+ """Perform differentially private aggregation."""
218
+ sensitivity = 1.0 # Depends on the query
219
+ noisy_mean = self.add_laplace_noise(data, sensitivity)
220
+ return np.mean(noisy_mean)
221
+
222
+ def anonymize_data(self, df, sensitive_columns):
223
+ """Anonymize sensitive data."""
224
+ df_anon = df.copy()
225
+
226
+ for column in sensitive_columns:
227
+ # Generalize or remove sensitive information
228
+ if df[column].dtype == 'object':
229
+ # Categorical: use frequency encoding
230
+ freq = df[column].value_counts(normalize=True)
231
+ df_anon[column] = df[column].map(freq)
232
+ else:
233
+ # Numerical: add noise
234
+ df_anon[column] = self.add_laplace_noise(
235
+ df[column].values,
236
+ sensitivity=df[column].max()
237
+ )
238
+
239
+ return df_anon
240
+
241
+ def federated_learning_step(self, local_models, global_model):
242
+ """Simulate federated learning update."""
243
+ # Aggregate local model updates
244
+ averaged_weights = []
245
+
246
+ for weights_list in zip(*[model.get_weights() for model in local_models]):
247
+ averaged_weights.append(np.mean(weights_list, axis=0))
248
+
249
+ # Update global model
250
+ global_model.set_weights(averaged_weights)
251
+ return global_model
252
+
253
+ # Usage
254
+ # privacy_ml = PrivacyPreservingML(epsilon=0.5)
255
+ #
256
+ # # Anonymize data
257
+ # sensitive_data = df[['age', 'income', 'zip_code']]
258
+ # df_anon = privacy_ml.anonymize_data(df, ['age', 'income'])
259
+ ```
260
+
261
+ ### 5. Ethical Review Framework
262
+ Implement ethical review for AI systems.
263
+
264
+ ```python
265
+ class EthicalReviewer:
266
+ def __init__(self):
267
+ self.checklist = {
268
+ 'fairness': [
269
+ 'Have we tested for bias across demographic groups?',
270
+ 'Are the training datasets representative?',
271
+ 'Have we implemented fairness metrics?'
272
+ ],
273
+ 'transparency': [
274
+ 'Can we explain individual decisions?',
275
+ 'Are users informed about AI involvement?',
276
+ 'Is the system\'s limitations documented?'
277
+ ],
278
+ 'accountability': [
279
+ 'Is there a human in the loop?',
280
+ 'Can decisions be appealed?',
281
+ 'Are logs maintained for audit?'
282
+ ],
283
+ 'safety': [
284
+ 'Have we implemented safety guards?',
285
+ 'Is there content moderation?',
286
+ 'Are there fail-safe mechanisms?'
287
+ ],
288
+ 'privacy': [
289
+ 'Is user data protected?',
290
+ 'Have we obtained proper consent?',
291
+ 'Is data minimization applied?'
292
+ ]
293
+ }
294
+
295
+ def review_system(self, responses):
296
+ """Review AI system against ethical checklist."""
297
+ results = {}
298
+
299
+ for category, questions in self.checklist.items():
300
+ category_score = 0
301
+ category_responses = []
302
+
303
+ for i, question in enumerate(questions):
304
+ response = responses.get(f"{category}_{i}", "not_answered")
305
+
306
+ if response.lower() in ['yes', 'implemented', 'yes_implemented']:
307
+ category_score += 1
308
+ status = "✓"
309
+ elif response.lower() == 'partially':
310
+ category_score += 0.5
311
+ status = "~"
312
+ else:
313
+ status = "✗"
314
+
315
+ category_responses.append({
316
+ 'question': question,
317
+ 'response': response,
318
+ 'status': status
319
+ })
320
+
321
+ results[category] = {
322
+ 'score': category_score / len(questions),
323
+ 'responses': category_responses
324
+ }
325
+
326
+ return results
327
+
328
+ def generate_report(self, review_results):
329
+ """Generate ethical review report."""
330
+ report = "AI System Ethical Review Report\n"
331
+ report += "=" * 50 + "\n\n"
332
+
333
+ for category, data in review_results.items():
334
+ score_percent = data['score'] * 100
335
+ report += f"{category.upper()}: {score_percent:.0f}%\n"
336
+
337
+ for response in data['responses']:
338
+ report += f" {response['status']} {response['question']}\n"
339
+ report += f" Response: {response['response']}\n"
340
+
341
+ report += "\n"
342
+
343
+ overall_score = np.mean([data['score'] for data in review_results.values()])
344
+ report += f"\nOVERALL ETHICAL SCORE: {overall_score * 100:.0f}%\n"
345
+
346
+ if overall_score >= 0.8:
347
+ report += "Status: PASS - System meets ethical standards\n"
348
+ elif overall_score >= 0.6:
349
+ report += "Status: CONDITIONAL - Address identified concerns\n"
350
+ else:
351
+ report += "Status: FAIL - Significant ethical concerns\n"
352
+
353
+ return report
354
+
355
+ # Usage
356
+ # reviewer = EthicalReviewer()
357
+ #
358
+ # responses = {
359
+ # 'fairness_0': 'yes',
360
+ # 'fairness_1': 'partially',
361
+ # 'transparency_0': 'yes',
362
+ # # ... more responses
363
+ # }
364
+ #
365
+ # results = reviewer.review_system(responses)
366
+ # report = reviewer.generate_report(results)
367
+ # print(report)
368
+ ```
369
+
370
+ ## Constraints
371
+ - **Legal Compliance**: Ensure compliance with relevant laws and regulations
372
+ - **Context Dependency**: Ethical considerations vary by application and culture
373
+ - **Trade-offs**: Balance between competing ethical principles may be necessary
374
+ - **Continuous Monitoring**: Ethical behavior requires ongoing monitoring and updates
375
+ - **Stakeholder Involvement**: Include diverse stakeholders in ethical assessments
376
+ - **Transparency Limits**: Some models are inherently difficult to explain
377
+
378
+ ## Expected Output
379
+ AI systems that are safe, fair, transparent, and aligned with ethical principles, with proper documentation and monitoring for responsible deployment.
TRAE-Skills/ai_engineering/AI_Testing_Evaluation.md ADDED
@@ -0,0 +1,400 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Skill: AI Testing and Evaluation
2
+
3
+ ## Purpose
4
+ To systematically evaluate AI model performance, reliability, and safety using comprehensive testing methodologies and metrics.
5
+
6
+ ## When to Use
7
+ - When validating AI models before deployment
8
+ - When comparing different models or approaches
9
+ - When monitoring model performance in production
10
+ - When ensuring AI system reliability and safety
11
+
12
+ ## Procedure
13
+
14
+ ### 1. Model Performance Metrics
15
+ Calculate comprehensive performance metrics.
16
+
17
+ ```python
18
+ import numpy as np
19
+ from sklearn.metrics import (
20
+ accuracy_score, precision_score, recall_score, f1_score,
21
+ confusion_matrix, roc_auc_score, classification_report
22
+ )
23
+
24
+ class ModelEvaluator:
25
+ def __init__(self):
26
+ self.metrics = {}
27
+
28
+ def evaluate_classification(self, y_true, y_pred, y_prob=None):
29
+ """Evaluate classification model performance."""
30
+ self.metrics['accuracy'] = accuracy_score(y_true, y_pred)
31
+ self.metrics['precision'] = precision_score(y_true, y_pred, average='weighted')
32
+ self.metrics['recall'] = recall_score(y_true, y_pred, average='weighted')
33
+ self.metrics['f1_score'] = f1_score(y_true, y_pred, average='weighted')
34
+
35
+ if y_prob is not None:
36
+ self.metrics['roc_auc'] = roc_auc_score(y_true, y_prob, multi_class='ovr')
37
+
38
+ # Confusion matrix
39
+ self.metrics['confusion_matrix'] = confusion_matrix(y_true, y_pred)
40
+
41
+ return self.metrics
42
+
43
+ def evaluate_regression(self, y_true, y_pred):
44
+ """Evaluate regression model performance."""
45
+ from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
46
+
47
+ self.metrics['mse'] = mean_squared_error(y_true, y_pred)
48
+ self.metrics['rmse'] = np.sqrt(self.metrics['mse'])
49
+ self.metrics['mae'] = mean_absolute_error(y_true, y_pred)
50
+ self.metrics['r2_score'] = r2_score(y_true, y_pred)
51
+
52
+ return self.metrics
53
+
54
+ def generate_report(self):
55
+ """Generate evaluation report."""
56
+ report = "Model Evaluation Report\n"
57
+ report += "=" * 40 + "\n"
58
+
59
+ for metric, value in self.metrics.items():
60
+ if metric != 'confusion_matrix':
61
+ if isinstance(value, float):
62
+ report += f"{metric}: {value:.4f}\n"
63
+ else:
64
+ report += f"{metric}: {value}\n"
65
+
66
+ return report
67
+
68
+ # Usage
69
+ # evaluator = ModelEvaluator()
70
+ #
71
+ # y_true = [0, 1, 2, 1, 0]
72
+ # y_pred = [0, 2, 2, 1, 0]
73
+ #
74
+ # metrics = evaluator.evaluate_classification(y_true, y_pred)
75
+ # print(evaluator.generate_report())
76
+ ```
77
+
78
+ ### 2. LLM Quality Evaluation
79
+ Evaluate language model outputs.
80
+
81
+ ```python
82
+ from openai import OpenAI
83
+ import json
84
+
85
+ class LLMEvaluator:
86
+ def __init__(self, model="gpt-4"):
87
+ self.client = OpenAI()
88
+ self.model = model
89
+
90
+ def evaluate_relevance(self, question, answer, reference_answer=None):
91
+ """Evaluate answer relevance."""
92
+ prompt = f"""
93
+ Question: {question}
94
+ Answer: {answer}
95
+
96
+ Rate the relevance of this answer to the question on a scale of 1-10.
97
+ Consider: Does it directly address the question? Is it comprehensive?
98
+
99
+ Provide rating as JSON: {{"relevance_score": <number>, "reasoning": "<explanation>"}}
100
+ """
101
+
102
+ response = self.client.chat.completions.create(
103
+ model=self.model,
104
+ messages=[{"role": "user", "content": prompt}],
105
+ temperature=0
106
+ )
107
+
108
+ try:
109
+ result = json.loads(response.choices[0].message.content)
110
+ return result
111
+ except:
112
+ return {"relevance_score": 0, "reasoning": "Failed to parse evaluation"}
113
+
114
+ def evaluate_accuracy(self, question, answer, ground_truth):
115
+ """Evaluate factual accuracy."""
116
+ prompt = f"""
117
+ Question: {question}
118
+ Generated Answer: {answer}
119
+ Ground Truth: {ground_truth}
120
+
121
+ Compare the generated answer with the ground truth.
122
+ Rate factual accuracy on a scale of 1-10.
123
+
124
+ Provide rating as JSON: {{"accuracy_score": <number>, "errors": [<list of factual errors>]}}
125
+ """
126
+
127
+ response = self.client.chat.completions.create(
128
+ model=self.model,
129
+ messages=[{"role": "user", "content": prompt}],
130
+ temperature=0
131
+ )
132
+
133
+ try:
134
+ result = json.loads(response.choices[0].message.content)
135
+ return result
136
+ except:
137
+ return {"accuracy_score": 0, "errors": ["Failed to parse evaluation"]}
138
+
139
+ def evaluate_toxicity(self, text):
140
+ """Check for toxic content."""
141
+ moderation_response = self.client.moderations.create(input=text)
142
+ result = moderation_response.results[0]
143
+
144
+ return {
145
+ 'flagged': result.flagged,
146
+ 'categories': result.categories,
147
+ 'category_scores': result.category_scores
148
+ }
149
+
150
+ def batch_evaluate(self, test_cases):
151
+ """Evaluate multiple test cases."""
152
+ results = []
153
+
154
+ for case in test_cases:
155
+ result = {
156
+ 'question': case['question'],
157
+ 'answer': case['answer']
158
+ }
159
+
160
+ # Run evaluations
161
+ result['relevance'] = self.evaluate_relevance(
162
+ case['question'],
163
+ case['answer']
164
+ )
165
+
166
+ if 'ground_truth' in case:
167
+ result['accuracy'] = self.evaluate_accuracy(
168
+ case['question'],
169
+ case['answer'],
170
+ case['ground_truth']
171
+ )
172
+
173
+ result['toxicity'] = self.evaluate_toxicity(case['answer'])
174
+
175
+ results.append(result)
176
+
177
+ return results
178
+
179
+ def calculate_aggregate_metrics(self, evaluation_results):
180
+ """Calculate aggregate metrics across all test cases."""
181
+ metrics = {
182
+ 'avg_relevance': np.mean([r['relevance']['relevance_score'] for r in evaluation_results]),
183
+ 'flagged_count': sum([1 for r in evaluation_results if r['toxicity']['flagged']]),
184
+ 'total_cases': len(evaluation_results)
185
+ }
186
+
187
+ if 'accuracy' in evaluation_results[0]:
188
+ metrics['avg_accuracy'] = np.mean([r['accuracy']['accuracy_score'] for r in evaluation_results])
189
+
190
+ return metrics
191
+
192
+ # Usage
193
+ # evaluator = LLMEvaluator()
194
+ #
195
+ # test_cases = [
196
+ # {
197
+ # 'question': 'What is machine learning?',
198
+ # 'answer': 'Machine learning is a subset of AI that enables systems to learn from data.',
199
+ # 'ground_truth': 'Machine learning involves training algorithms to make predictions or decisions based on data.'
200
+ # }
201
+ # ]
202
+ #
203
+ # results = evaluator.batch_evaluate(test_cases)
204
+ # aggregate = evaluator.calculate_aggregate_metrics(results)
205
+ # print(aggregate)
206
+ ```
207
+
208
+ ### 3. Robustness Testing
209
+ Test model robustness against adversarial inputs.
210
+
211
+ ```python
212
+ class RobustnessTester:
213
+ def __init__(self, model):
214
+ self.model = model
215
+
216
+ def test_typos(self, text, num_variations=5):
217
+ """Test model with typographical variations."""
218
+ variations = []
219
+
220
+ # Common typos
221
+ common_typos = {
222
+ 'the': 'teh',
223
+ 'and': 'adn',
224
+ 'is': 'si',
225
+ 'to': 'ot',
226
+ 'of': 'fo'
227
+ }
228
+
229
+ for _ in range(num_variations):
230
+ variation = text
231
+ for correct, typo in common_typos.items():
232
+ variation = variation.replace(correct, typo)
233
+ variations.append(variation)
234
+
235
+ return variations
236
+
237
+ def test_adversarial_examples(self, texts, labels, attack_method='textbugger'):
238
+ """Test against adversarial attacks."""
239
+ # Simplified adversarial example generation
240
+ adversarial_examples = []
241
+
242
+ for text, label in zip(texts, labels):
243
+ # Add slight perturbations
244
+ words = text.split()
245
+ if len(words) > 0:
246
+ # Duplicate a word
247
+ words.append(words[0])
248
+ adversarial = ' '.join(words)
249
+ adversarial_examples.append((adversarial, label))
250
+
251
+ return adversarial_examples
252
+
253
+ def test_out_of_distribution(self, texts):
254
+ """Test with out-of-distribution inputs."""
255
+ ood_cases = [
256
+ # Very short inputs
257
+ "Hi",
258
+ "A",
259
+ "",
260
+
261
+ # Very long inputs
262
+ "word " * 1000,
263
+
264
+ # Special characters
265
+ "!@#$%^&*()",
266
+
267
+ # Mixed languages
268
+ "Hello 你好 Bonjour",
269
+
270
+ # Malformed inputs
271
+ "...test...",
272
+ "123456789"
273
+ ]
274
+
275
+ return ood_cases
276
+
277
+ def evaluate_robustness(self, test_function):
278
+ """Evaluate model robustness."""
279
+ test_cases = {
280
+ 'typos': self.test_typos("What is the meaning of life?"),
281
+ 'ood': self.test_out_of_distribution([]),
282
+ 'adversarial': self.test_adversarial_examples(["Hello world"], [1])
283
+ }
284
+
285
+ results = {}
286
+
287
+ for category, cases in test_cases.items():
288
+ results[category] = []
289
+
290
+ for case in cases:
291
+ try:
292
+ response = test_function(case)
293
+ results[category].append({
294
+ 'input': case,
295
+ 'status': 'success',
296
+ 'response': response
297
+ })
298
+ except Exception as e:
299
+ results[category].append({
300
+ 'input': case,
301
+ 'status': 'failed',
302
+ 'error': str(e)
303
+ })
304
+
305
+ return results
306
+
307
+ # Usage
308
+ # def mock_llm(text):
309
+ # return f"Response to: {text[:50]}"
310
+ #
311
+ # tester = RobustnessTester(model=None)
312
+ # robustness_results = tester.evaluate_robustness(mock_llm)
313
+ ```
314
+
315
+ ### 4. A/B Testing Framework
316
+ Implement A/B testing for model comparison.
317
+
318
+ ```python
319
+ from scipy import stats
320
+
321
+ class ABTestFramework:
322
+ def __init__(self):
323
+ self.results = {'A': [], 'B': []}
324
+
325
+ def add_result(self, group, metric_value):
326
+ """Add a result for a group."""
327
+ if group in ['A', 'B']:
328
+ self.results[group].append(metric_value)
329
+
330
+ def calculate_significance(self, metric='accuracy'):
331
+ """Calculate statistical significance."""
332
+ group_a = self.results['A']
333
+ group_b = self.results['B']
334
+
335
+ # T-test
336
+ t_statistic, p_value = stats.ttest_ind(group_a, group_b)
337
+
338
+ # Effect size (Cohen's d)
339
+ pooled_std = np.sqrt((np.std(group_a)**2 + np.std(group_b)**2) / 2)
340
+ cohens_d = (np.mean(group_a) - np.mean(group_b)) / pooled_std
341
+
342
+ return {
343
+ 'group_a_mean': np.mean(group_a),
344
+ 'group_b_mean': np.mean(group_b),
345
+ 't_statistic': t_statistic,
346
+ 'p_value': p_value,
347
+ 'significant': p_value < 0.05,
348
+ 'cohens_d': cohens_d
349
+ }
350
+
351
+ def generate_report(self):
352
+ """Generate A/B test report."""
353
+ stats = self.calculate_significance()
354
+
355
+ report = f"""
356
+ A/B Test Results Report
357
+ {'=' * 50}
358
+
359
+ Group A: n={len(self.results['A'])}, mean={stats['group_a_mean']:.4f}
360
+ Group B: n={len(self.results['B'])}, mean={stats['group_b_mean']:.4f}
361
+
362
+ Statistical Analysis:
363
+ - t-statistic: {stats['t_statistic']:.4f}
364
+ - p-value: {stats['p_value']:.4f}
365
+ - Significant: {'Yes' if stats['significant'] else 'No'}
366
+ - Effect size (Cohen's d): {stats['cohens_d']:.4f}
367
+
368
+ Conclusion:
369
+ """
370
+ if stats['significant']:
371
+ if stats['group_a_mean'] > stats['group_b_mean']:
372
+ report += "Group A performs significantly better than Group B."
373
+ else:
374
+ report += "Group B performs significantly better than Group A."
375
+ else:
376
+ report += "No significant difference found between groups."
377
+
378
+ return report
379
+
380
+ # Usage
381
+ # ab_test = ABTestFramework()
382
+ #
383
+ # # Add results (in practice, these come from user interactions)
384
+ # for _ in range(100):
385
+ # ab_test.add_result('A', np.random.normal(0.7, 0.1))
386
+ # ab_test.add_result('B', np.random.normal(0.75, 0.1))
387
+ #
388
+ # print(ab_test.generate_report())
389
+ ```
390
+
391
+ ## Constraints
392
+ - **Ground Truth**: High-quality ground truth data is essential for accurate evaluation
393
+ - **Bias in Evaluation**: Evaluation metrics themselves may contain biases
394
+ - **Context Dependency**: Performance may vary significantly across different contexts
395
+ - **Cost**: Comprehensive evaluation can be expensive, especially for LLMs
396
+ - **Subjectivity**: Some metrics (like quality) are inherently subjective
397
+ - **Dynamic Performance**: Model performance may degrade over time
398
+
399
+ ## Expected Output
400
+ Comprehensive evaluation of AI systems with detailed metrics, robustness testing results, and statistical analysis to ensure reliable and safe deployment.
TRAE-Skills/ai_engineering/Chain_of_Thought_Prompting.md ADDED
@@ -0,0 +1,169 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Skill: Chain of Thought Prompting
2
+
3
+ ## Purpose
4
+ To improve LLM reasoning performance by encouraging models to show their work and think through problems step-by-step before arriving at an answer.
5
+
6
+ ## When to Use
7
+ - When solving complex math or logic problems
8
+ - When reasoning through multi-step questions
9
+ - When you need to verify the model's thinking process
10
+ - When working with problems requiring inference
11
+
12
+ ## Procedure
13
+
14
+ ### 1. Basic Chain of Thought
15
+ Structure your prompt to encourage step-by-step reasoning.
16
+
17
+ ```python
18
+ from openai import OpenAI
19
+
20
+ client = OpenAI()
21
+
22
+ prompt = """
23
+ Question: If a store sells apples for $2 each and oranges for $3 each,
24
+ and you buy 5 apples and 3 oranges, how much do you spend?
25
+
26
+ Let's think step by step:
27
+ 1. Calculate the cost of apples: 5 apples × $2 = $10
28
+ 2. Calculate the cost of oranges: 3 oranges × $3 = $9
29
+ 3. Add both amounts: $10 + $9 = $19
30
+
31
+ Answer: $19
32
+
33
+ Question: A train travels 120 miles in 2 hours. If it maintains the same speed,
34
+ how far will it travel in 5 hours?
35
+
36
+ Let's think step by step:
37
+ """
38
+
39
+ response = client.chat.completions.create(
40
+ model="gpt-4",
41
+ messages=[{"role": "user", "content": prompt}]
42
+ )
43
+ print(response.choices[0].message.content)
44
+ ```
45
+
46
+ ### 2. Zero-Shot Chain of Thought
47
+ Simply add "Let's think step by step" to your prompt.
48
+
49
+ ```python
50
+ def zero_shot_cot(question):
51
+ prompt = f"""Question: {question}
52
+
53
+ Let's think step by step:"""
54
+
55
+ response = client.chat.completions.create(
56
+ model="gpt-4",
57
+ messages=[{"role": "user", "content": prompt}]
58
+ )
59
+ return response.choices[0].message.content
60
+
61
+ # Example
62
+ question = "If 3 workers can build a wall in 4 days, how many days will 6 workers need?"
63
+ print(zero_shot_cot(question))
64
+ ```
65
+
66
+ ### 3. Few-Shot Chain of Thought
67
+ Provide examples of the reasoning process.
68
+
69
+ ```python
70
+ few_shot_prompt = """
71
+ Q: Roger has 5 tennis balls. He buys 2 more cans of 3 tennis balls each.
72
+ How many tennis balls does he have now?
73
+ A: Roger started with 5 balls. 2 cans of 3 tennis balls each is 6 tennis balls.
74
+ 5 + 6 = 11. The answer is 11.
75
+
76
+ Q: A restaurant had 23 apples. If they used 20 to make lunch and bought 6 more,
77
+ how many apples do they have?
78
+ A: They had 23 apples and used 20, so 23 - 20 = 3. Then they bought 6 more,
79
+ so 3 + 6 = 9. The answer is 9.
80
+
81
+ Q: If a car travels 60 miles per hour for 3 hours, how far does it travel?
82
+ A:"""
83
+
84
+ response = client.chat.completions.create(
85
+ model="gpt-4",
86
+ messages=[{"role": "user", "content": few_shot_prompt}]
87
+ )
88
+ print(response.choices[0].message.content)
89
+ ```
90
+
91
+ ### 4. Self-Consistency with Chain of Thought
92
+ Generate multiple reasoning paths and take the majority answer.
93
+
94
+ ```python
95
+ import numpy as np
96
+
97
+ def self_consistent_cot(question, num_samples=5):
98
+ responses = []
99
+ for _ in range(num_samples):
100
+ response = client.chat.completions.create(
101
+ model="gpt-4",
102
+ messages=[{"role": "user", "content": f"Question: {question}\nLet's think step by step:"}],
103
+ temperature=0.7 # Add randomness for diverse paths
104
+ )
105
+ responses.append(response.choices[0].message.content)
106
+
107
+ # Parse final answers from responses
108
+ answers = [r.split("Answer:")[-1].strip() if "Answer:" in r else r for r in responses]
109
+
110
+ # Return most common answer
111
+ from collections import Counter
112
+ most_common = Counter(answers).most_common(1)[0][0]
113
+ return most_common
114
+
115
+ # Example
116
+ question = "A bat and ball cost $1.10 in total. The bat costs $1.00 more than the ball. How much does the ball cost?"
117
+ answer = self_consistent_cot(question)
118
+ print(f"Final answer: {answer}")
119
+ ```
120
+
121
+ ### 5. Structured Chain of Thought
122
+ Use specific reasoning templates for different problem types.
123
+
124
+ ```python
125
+ math_template = """
126
+ Solve this math problem systematically:
127
+
128
+ 1. Identify the given information
129
+ 2. Identify what needs to be found
130
+ 3. Determine the appropriate formula or approach
131
+ 4. Execute the calculation
132
+ 5. Verify the answer
133
+
134
+ Question: {question}
135
+
136
+ Answer:"""
137
+
138
+ coding_template = """
139
+ Debug this code step by step:
140
+
141
+ 1. Understand what the code should do
142
+ 2. Trace through the execution line by line
143
+ 3. Identify where the behavior differs from expectations
144
+ 4. Propose and test fixes
145
+
146
+ Code: {code}
147
+
148
+ Issue: {issue}
149
+
150
+ Fix:"""
151
+
152
+ def structured_cot(template, **kwargs):
153
+ prompt = template.format(**kwargs)
154
+ response = client.chat.completions.create(
155
+ model="gpt-4",
156
+ messages=[{"role": "user", "content": prompt}]
157
+ )
158
+ return response.choices[0].message.content
159
+ ```
160
+
161
+ ## Constraints
162
+ - **Token Usage**: Chain of thought increases token consumption significantly
163
+ - **Latency**: More tokens = longer response times
164
+ - **Model Selection**: Works best with larger models (GPT-4, Claude)
165
+ - **Temperature**: Use lower temperature (0-0.3) for more consistent reasoning
166
+ - **Verification**: Always verify the reasoning steps, especially for critical applications
167
+
168
+ ## Expected Output
169
+ Improved reasoning performance on complex problems that require multi-step thinking, with transparent thought processes that can be verified and debugged.
TRAE-Skills/ai_engineering/Computer_Vision_Object_Detection.md ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Skill: Computer Vision - Object Detection
2
+
3
+ ## Purpose
4
+ To locate and identify multiple objects within an image or video stream by drawing bounding boxes and assigning class labels with confidence scores.
5
+
6
+ ## When to Use
7
+ - When counting objects (e.g., people in a crowd, cars on a road)
8
+ - When building autonomous navigation systems or robotics
9
+ - When performing automated quality inspection in manufacturing
10
+ - When extracting specific elements from documents (e.g., tables, signatures)
11
+
12
+ ## Procedure
13
+
14
+ ### 1. Choose the Architecture
15
+ Select an architecture based on the trade-off between speed and accuracy:
16
+ - **YOLO (You Only Look Once)**: Best for real-time inference (YOLOv8, YOLOv10). Very fast and highly accurate.
17
+ - **Faster R-CNN**: Slower but highly accurate, especially for small objects. Good for medical imaging.
18
+ - **DETR (DEtection TRansformer)**: Transformer-based approach that eliminates the need for non-maximum suppression (NMS) and anchor boxes.
19
+
20
+ ### 2. Dataset Preparation
21
+ Ensure the dataset is properly formatted. The most common formats are:
22
+ - **COCO JSON**: A single JSON file containing images, annotations (bounding boxes, polygons), and categories.
23
+ - **YOLO TXT**: One text file per image containing `class_id x_center y_center width height` (normalized between 0 and 1).
24
+
25
+ **Data Augmentation**:
26
+ Apply augmentations to improve robustness using libraries like `albumentations`:
27
+ ```python
28
+ import albumentations as A
29
+
30
+ transform = A.Compose([
31
+ A.HorizontalFlip(p=0.5),
32
+ A.RandomBrightnessContrast(p=0.2),
33
+ A.ShiftScaleRotate(shift_limit=0.0625, scale_limit=0.1, rotate_limit=45, p=0.2),
34
+ ], bbox_params=A.BboxParams(format='yolo', label_fields=['class_labels']))
35
+ ```
36
+
37
+ ### 3. YOLOv8 Implementation Example
38
+ Using the Ultralytics library for training and inference.
39
+
40
+ **Installation**:
41
+ ```bash
42
+ pip install ultralytics
43
+ ```
44
+
45
+ **Training**:
46
+ Create a `data.yaml` file defining the dataset paths and classes:
47
+ ```yaml
48
+ train: ../train/images
49
+ val: ../valid/images
50
+
51
+ nc: 3 # number of classes
52
+ names: ['car', 'pedestrian', 'traffic_light']
53
+ ```
54
+
55
+ ```python
56
+ from ultralytics import YOLO
57
+
58
+ # Load a pre-trained model (recommended for transfer learning)
59
+ model = YOLO('yolov8n.pt') # 'n' for nano, 's' for small, 'm' for medium, etc.
60
+
61
+ # Train the model on your custom dataset
62
+ results = model.train(data='data.yaml', epochs=100, imgsz=640, batch=16, device=0)
63
+ ```
64
+
65
+ **Inference**:
66
+ ```python
67
+ from ultralytics import YOLO
68
+ import cv2
69
+
70
+ # Load the fine-tuned model
71
+ model = YOLO('runs/detect/train/weights/best.pt')
72
+
73
+ # Perform inference on an image
74
+ results = model('test_image.jpg')
75
+
76
+ # View results
77
+ for result in results:
78
+ boxes = result.boxes # Bounding boxes object
79
+ for box in boxes:
80
+ # Extract coordinates, confidence, and class id
81
+ x1, y1, x2, y2 = box.xyxy[0]
82
+ conf = box.conf[0]
83
+ cls_id = int(box.cls[0])
84
+ print(f"Class: {model.names[cls_id]}, Confidence: {conf:.2f}, Box: [{x1}, {y1}, {x2}, {y2}]")
85
+ ```
86
+
87
+ ### 4. Evaluation Metrics
88
+ Understand the standard metrics for object detection:
89
+ - **IoU (Intersection over Union)**: Measures the overlap between the predicted bounding box and the ground truth.
90
+ - **mAP (Mean Average Precision)**: The primary metric. Often calculated at different IoU thresholds (e.g., mAP@0.5, mAP@0.5:0.95).
91
+
92
+ ## Best Practices
93
+ - Ensure a balanced dataset across all classes to prevent the model from ignoring rare objects.
94
+ - Pay attention to image size (`imgsz`). Larger sizes detect smaller objects better but require more memory and slow down inference.
95
+ - Utilize pre-trained weights (Transfer Learning) instead of training from scratch whenever possible.
TRAE-Skills/ai_engineering/Data_Drift_Detection.md ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Skill: Data Drift Detection
2
+
3
+ ## Purpose
4
+ To monitor production machine learning models for performance degradation caused by changes in the statistical properties of the input data (data drift) or the relationship between features and the target variable (concept drift) over time.
5
+
6
+ ## When to Use
7
+ - When deploying models to production environments where data changes frequently (e.g., e-commerce, fraud detection, recommendation systems)
8
+ - When establishing a continuous training pipeline (MLOps)
9
+ - When debugging silent failures in model accuracy without corresponding system errors
10
+
11
+ ## Procedure
12
+
13
+ ### 1. Identify Drift Types
14
+ Distinguish between the types of drift occurring in the data:
15
+ - **Covariate Shift (Data Drift)**: The distribution of input features ($P(X)$) changes, but the relationship with the target remains the same.
16
+ - **Prior Probability Shift**: The distribution of the target variable ($P(Y)$) changes.
17
+ - **Concept Drift**: The relationship between features and the target ($P(Y|X)$) changes (e.g., a new type of fraud emerges).
18
+
19
+ ### 2. Choose Detection Methods
20
+ Select appropriate statistical tests to compare a reference dataset (usually the training data) with the current production data:
21
+ - **Numerical Features**: Kolmogorov-Smirnov (K-S) test, Wasserstein distance, Population Stability Index (PSI).
22
+ - **Categorical Features**: Chi-Square test, Jensen-Shannon distance.
23
+ - **Multivariate**: Domain Classifier (train a model to distinguish between reference and current data).
24
+
25
+ ### 3. Implementation Example (Evidently AI)
26
+ Evidently is an open-source library for monitoring ML models.
27
+
28
+ **Installation**:
29
+ ```bash
30
+ pip install evidently
31
+ ```
32
+
33
+ **Generate a Data Drift Report**:
34
+ ```python
35
+ import pandas as pd
36
+ from evidently.report import Report
37
+ from evidently.metric_preset import DataDriftPreset
38
+
39
+ # Load reference data (e.g., training set) and current data (e.g., last week's production data)
40
+ reference_data = pd.read_csv('train.csv')
41
+ current_data = pd.read_csv('production_week1.csv')
42
+
43
+ # Initialize the report with the DataDriftPreset
44
+ data_drift_report = Report(metrics=[DataDriftPreset()])
45
+
46
+ # Calculate metrics
47
+ data_drift_report.run(reference_data=reference_data, current_data=current_data)
48
+
49
+ # Save report as HTML
50
+ data_drift_report.save_html('data_drift_report.html')
51
+
52
+ # Get JSON output for programmatic integration (e.g., Airflow, Prefect)
53
+ drift_json = data_drift_report.json()
54
+ print(drift_json)
55
+ ```
56
+
57
+ **Custom Tests and Thresholds**:
58
+ You can define specific tests for different features:
59
+ ```python
60
+ from evidently.test_suite import TestSuite
61
+ from evidently.tests import TestNumberOfDriftedColumns, TestShareOfDriftedColumns
62
+ from evidently.tests.base_test import generate_column_tests
63
+ from evidently.tests import TestColumnDrift
64
+
65
+ suite = TestSuite(tests=[
66
+ TestNumberOfDriftedColumns(lt=3), # Fail if more than 2 columns drift
67
+ TestShareOfDriftedColumns(lt=0.3), # Fail if >30% of columns drift
68
+ generate_column_tests(TestColumnDrift, columns=['age', 'income'])
69
+ ])
70
+
71
+ suite.run(reference_data=reference_data, current_data=current_data)
72
+ suite.save_html('test_suite.html')
73
+ ```
74
+
75
+ ### 4. Alerting and Retraining Strategy
76
+ Establish a workflow when drift is detected:
77
+ 1. **Alerting**: Send notifications via Slack, PagerDuty, or email when drift metrics exceed thresholds.
78
+ 2. **Investigation**: Data scientists analyze the report to determine if the drift is benign (e.g., seasonal change) or harmful.
79
+ 3. **Retraining**: Trigger a CI/CD pipeline to retrain the model on the new data, validate the new model against a holdout set, and deploy it if it outperforms the current model.
80
+
81
+ ## Best Practices
82
+ - **Define a Baseline**: Always establish a solid baseline using the training dataset or a validated holdout set.
83
+ - **Choose the Right Window Size**: The timeframe for the "current" data depends on the business context. Daily, weekly, or monthly windows are common.
84
+ - **Monitor the Monitor**: Ensure the drift detection system itself is robust and doesn't generate excessive false positive alerts (alert fatigue).
TRAE-Skills/ai_engineering/Distributed_Training_Horovod.md ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Skill: Distributed Training (Horovod)
2
+
3
+ ## Purpose
4
+ To train large machine learning models faster by distributing the computational workload across multiple GPUs or nodes, using data parallelism or model parallelism techniques. Horovod (by Uber) provides a simple and efficient framework for distributed deep learning.
5
+
6
+ ## When to Use
7
+ - When training large models (e.g., Transformers, high-res CNNs) that exceed a single GPU's memory or take too long to converge
8
+ - When scaling out training to a cluster of machines
9
+ - When utilizing multi-GPU instances in the cloud (AWS p4d, GCP A100)
10
+ - When migrating single-GPU PyTorch or TensorFlow code to multi-GPU without extensive rewrites
11
+
12
+ ## Procedure
13
+
14
+ ### 1. Installation
15
+ Install Horovod with the necessary framework support (PyTorch, TensorFlow, etc.).
16
+ ```bash
17
+ # Requires MPI (Message Passing Interface) installed on the system
18
+ HOROVOD_WITH_PYTORCH=1 pip install horovod[pytorch]
19
+ ```
20
+
21
+ ### 2. PyTorch Integration Example
22
+ Convert a standard PyTorch training script to a distributed one.
23
+
24
+ **Initialize Horovod**:
25
+ ```python
26
+ import torch
27
+ import horovod.torch as hvd
28
+
29
+ # 1. Initialize Horovod
30
+ hvd.init()
31
+
32
+ # 2. Pin GPU to local rank (ensure each process uses a different GPU)
33
+ if torch.cuda.is_available():
34
+ torch.cuda.set_device(hvd.local_rank())
35
+ ```
36
+
37
+ **Data Loading**:
38
+ Partition the dataset among workers using a `DistributedSampler`.
39
+ ```python
40
+ from torch.utils.data.distributed import DistributedSampler
41
+
42
+ dataset = MyDataset()
43
+ # 3. Partition data
44
+ sampler = DistributedSampler(dataset, num_replicas=hvd.size(), rank=hvd.rank())
45
+ train_loader = torch.utils.data.DataLoader(dataset, batch_size=32, sampler=sampler)
46
+ ```
47
+
48
+ **Optimizer and Broadcasting**:
49
+ Scale the learning rate by the number of workers and wrap the optimizer.
50
+ ```python
51
+ model = MyModel().cuda()
52
+ # 4. Scale learning rate
53
+ optimizer = torch.optim.SGD(model.parameters(), lr=0.01 * hvd.size())
54
+
55
+ # 5. Add Horovod Distributed Optimizer
56
+ optimizer = hvd.DistributedOptimizer(
57
+ optimizer, named_parameters=model.named_parameters(),
58
+ op=hvd.Adsum # Default is hvd.Average
59
+ )
60
+
61
+ # 6. Broadcast initial parameters and optimizer state from rank 0 to all other processes
62
+ hvd.broadcast_parameters(model.state_dict(), root_rank=0)
63
+ hvd.broadcast_optimizer_state(optimizer, root_rank=0)
64
+ ```
65
+
66
+ ### 3. Execution
67
+ Run the script using `horovodrun` or `mpirun`.
68
+
69
+ **Local Multi-GPU (e.g., 4 GPUs on one machine)**:
70
+ ```bash
71
+ horovodrun -np 4 -H localhost:4 python train.py
72
+ ```
73
+
74
+ **Multi-Node (e.g., 2 machines, 4 GPUs each)**:
75
+ ```bash
76
+ horovodrun -np 8 -H server1:4,server2:4 python train.py
77
+ ```
78
+
79
+ ## Best Practices
80
+ - **Learning Rate Scaling**: Always scale the learning rate linearly with the number of workers (`lr * hvd.size()`), and consider a warmup period for the first few epochs.
81
+ - **Checkpointing**: Only save checkpoints on `hvd.rank() == 0` to prevent file corruption from concurrent writes.
82
+ - **Batch Size**: The effective batch size becomes `batch_size_per_worker * hvd.size()`. Adjust accordingly to maintain convergence.
TRAE-Skills/ai_engineering/Embedding_Techniques.md ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Skill: Embedding Techniques
2
+
3
+ ## Purpose
4
+ To transform text, images, or other data into dense vector representations that capture semantic meaning for tasks like semantic search, clustering, and recommendation systems.
5
+
6
+ ## When to Use
7
+ - When building semantic search systems
8
+ - When implementing RAG (Retrieval-Augmented Generation)
9
+ - When creating recommendation engines
10
+ - When performing document similarity analysis
11
+ - When clustering content based on meaning
12
+
13
+ ## Procedure
14
+
15
+ ### 1. Choose Your Embedding Model
16
+ Select based on your use case and resource constraints.
17
+
18
+ ```python
19
+ from sentence_transformers import SentenceTransformer
20
+
21
+ # For general purpose semantic search
22
+ model = SentenceTransformer('all-MiniLM-L6-v2')
23
+
24
+ # For multilingual content
25
+ multilingual_model = SentenceTransformer('paraphrase-multilingual-MiniLM-L12-v2')
26
+
27
+ # For code-specific embeddings
28
+ code_model = SentenceTransformer('microsoft/codebert-base')
29
+ ```
30
+
31
+ ### 2. Generate Embeddings
32
+ Transform your documents into vectors.
33
+
34
+ ```python
35
+ documents = [
36
+ "Machine learning is a subset of artificial intelligence",
37
+ "Deep learning uses neural networks with multiple layers",
38
+ "Natural language processing deals with text understanding"
39
+ ]
40
+
41
+ embeddings = model.encode(documents)
42
+
43
+ print(f"Shape: {embeddings.shape}") # (3, 384) for MiniLM
44
+ print(f"Dimension: {len(embeddings[0])}") # 384 dimensions
45
+ ```
46
+
47
+ ### 3. Store in Vector Database
48
+ Persist embeddings for efficient similarity search.
49
+
50
+ ```python
51
+ import faiss
52
+ import numpy as np
53
+
54
+ # Create FAISS index
55
+ dimension = embeddings.shape[1]
56
+ index = faiss.IndexFlatL2(dimension)
57
+
58
+ # Add embeddings
59
+ index.add(embeddings.astype('float32'))
60
+
61
+ # Save index
62
+ faiss.write_index(index, 'document_embeddings.index')
63
+ ```
64
+
65
+ ### 4. Semantic Search
66
+ Find similar documents using vector similarity.
67
+
68
+ ```python
69
+ query = "AI and neural networks"
70
+ query_embedding = model.encode([query])
71
+
72
+ # Search for top-k similar documents
73
+ k = 3
74
+ distances, indices = index.search(query_embedding.astype('float32'), k)
75
+
76
+ results = [(documents[i], distances[0][j]) for j, i in enumerate(indices[0])]
77
+ for doc, score in results:
78
+ print(f"Similarity: {score:.4f} | {doc}")
79
+ ```
80
+
81
+ ### 5. Batch Processing for Large Datasets
82
+ Process large document collections efficiently.
83
+
84
+ ```python
85
+ from tqdm import tqdm
86
+
87
+ def batch_encode(documents, batch_size=32):
88
+ embeddings = []
89
+ for i in tqdm(range(0, len(documents), batch_size)):
90
+ batch = documents[i:i + batch_size]
91
+ batch_embeddings = model.encode(batch)
92
+ embeddings.extend(batch_embeddings)
93
+ return np.array(embeddings)
94
+
95
+ # Usage
96
+ large_corpus = load_large_dataset() # Your data loading function
97
+ embeddings = batch_encode(large_corpus, batch_size=64)
98
+ ```
99
+
100
+ ## Constraints
101
+ - **Dimensionality**: Higher dimensions = better quality but more storage/computation
102
+ - **Batch Size**: Adjust based on available GPU memory
103
+ - **Model Selection**: Consider trade-offs between quality, speed, and model size
104
+ - **Multilingual**: Use specialized models for non-English content
105
+ - **Domain-Specific**: Fine-tune or use domain-specific models for technical content
106
+
107
+ ## Expected Output
108
+ High-quality vector representations that capture semantic meaning, enabling powerful similarity search and retrieval operations.
TRAE-Skills/ai_engineering/Federated_Learning.md ADDED
@@ -0,0 +1,387 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Skill: Federated Learning
2
+
3
+ ## Purpose
4
+ To train machine learning models across decentralized edge devices while keeping data local, preserving privacy and reducing data transfer requirements.
5
+
6
+ ## When to Use
7
+ - When training on sensitive data that cannot leave devices
8
+ - When building healthcare or financial applications with privacy requirements
9
+ - When reducing data transfer costs in distributed systems
10
+ - When compliance with data protection regulations (GDPR, HIPAA)
11
+
12
+ ## Procedure
13
+
14
+ ### 1. Federated Learning Architecture
15
+ Set up the federated learning framework.
16
+
17
+ ```python
18
+ import torch
19
+ import torch.nn as nn
20
+ import torch.optim as optim
21
+ from copy import deepcopy
22
+ import numpy as np
23
+
24
+ class FederatedLearningServer:
25
+ def __init__(self, global_model, learning_rate=0.01):
26
+ self.global_model = global_model
27
+ self.learning_rate = learning_rate
28
+ self.client_weights = []
29
+
30
+ def aggregate_models(self, client_models, client_weights=None):
31
+ """Aggregate client models using FedAvg algorithm."""
32
+ if client_weights is None:
33
+ # Equal weights for all clients
34
+ client_weights = [1.0 / len(client_models)] * len(client_models)
35
+
36
+ # Get global model state dict
37
+ global_state = self.global_model.state_dict()
38
+
39
+ # Initialize aggregated state
40
+ aggregated_state = deepcopy(global_state)
41
+ for key in aggregated_state.keys():
42
+ aggregated_state[key] = torch.zeros_like(aggregated_state[key])
43
+
44
+ # Aggregate weights from all clients
45
+ for client_model, weight in zip(client_models, client_weights):
46
+ client_state = client_model.state_dict()
47
+ for key in aggregated_state.keys():
48
+ aggregated_state[key] += weight * client_state[key]
49
+
50
+ # Update global model
51
+ self.global_model.load_state_dict(aggregated_state)
52
+
53
+ return self.global_model
54
+
55
+ def distribute_model(self):
56
+ """Send global model to clients."""
57
+ return deepcopy(self.global_model)
58
+
59
+ class FederatedLearningClient:
60
+ def __init__(self, local_model, local_data, optimizer_type='adam', learning_rate=0.01):
61
+ self.local_model = local_model
62
+ self.local_data = local_data
63
+ self.optimizer = optim.Adam(self.local_model.parameters(), lr=learning_rate)
64
+ self.criterion = nn.CrossEntropyLoss()
65
+
66
+ def train_local(self, epochs=5, batch_size=32):
67
+ """Train model on local data."""
68
+ self.local_model.train()
69
+
70
+ # Assume local_data is a DataLoader
71
+ for epoch in range(epochs):
72
+ for batch_x, batch_y in self.local_data:
73
+ self.optimizer.zero_grad()
74
+
75
+ outputs = self.local_model(batch_x)
76
+ loss = self.criterion(outputs, batch_y)
77
+
78
+ loss.backward()
79
+ self.optimizer.step()
80
+
81
+ return self.local_model
82
+
83
+ def update_model(self, global_model):
84
+ """Update local model with global model."""
85
+ self.local_model.load_state_dict(global_model.state_dict())
86
+ return self.local_model
87
+ ```
88
+
89
+ ### 2. Differential Privacy Integration
90
+ Add privacy guarantees to federated learning.
91
+
92
+ ```python
93
+ import torch.nn.functional as F
94
+
95
+ class DifferentialPrivacyClient:
96
+ def __init__(self, model, local_data, clip_norm=1.0, noise_multiplier=0.1):
97
+ self.model = model
98
+ self.local_data = local_data
99
+ self.clip_norm = clip_norm
100
+ self.noise_multiplier = noise_multiplier
101
+ self.optimizer = optim.Adam(self.model.parameters(), lr=0.01)
102
+ self.criterion = nn.CrossEntropyLoss()
103
+
104
+ def clip_gradients(self):
105
+ """Clip gradients to bound sensitivity."""
106
+ torch.nn.utils.clip_grad_norm_(self.model.parameters(), self.clip_norm)
107
+
108
+ def add_noise(self, parameters):
109
+ """Add Gaussian noise to gradients."""
110
+ with torch.no_grad():
111
+ for param in parameters:
112
+ noise = torch.randn_like(param) * self.noise_multiplier * self.clip_norm
113
+ param.grad += noise
114
+
115
+ def train_with_dp(self, epochs=5):
116
+ """Train with differential privacy."""
117
+ self.model.train()
118
+
119
+ for epoch in range(epochs):
120
+ for batch_x, batch_y in self.local_data:
121
+ self.optimizer.zero_grad()
122
+
123
+ outputs = self.model(batch_x)
124
+ loss = self.criterion(outputs, batch_y)
125
+
126
+ loss.backward()
127
+
128
+ # Apply differential privacy
129
+ self.clip_gradients()
130
+ self.add_noise(self.model.parameters())
131
+
132
+ self.optimizer.step()
133
+
134
+ return self.model
135
+
136
+ def compute_privacy_spent(self, epochs, noise_multiplier, sample_rate):
137
+ """Compute privacy budget spent."""
138
+ # Simplified privacy accounting
139
+ # In practice, use moments accountant or RDP accountant
140
+ epsilon = epochs * sample_rate / noise_multiplier
141
+ return epsilon
142
+ ```
143
+
144
+ ### 3. Secure Aggregation
145
+ Implement secure aggregation protocols.
146
+
147
+ ```python
148
+ import hashlib
149
+ import random
150
+
151
+ class SecureAggregationServer:
152
+ def __init__(self, global_model):
153
+ self.global_model = global_model
154
+ self.client_seeds = {}
155
+
156
+ def distribute_seeds(self, client_ids):
157
+ """Distribute random seeds to clients."""
158
+ seeds = {}
159
+ for client_id in client_ids:
160
+ seeds[client_id] = random.randint(0, 1000000)
161
+ self.client_seeds[client_id] = seeds[client_id]
162
+ return seeds
163
+
164
+ def secure_aggregate(self, client_updates):
165
+ """Aggregate updates with one-time masking."""
166
+ # In real implementation, use cryptographic protocols
167
+ # This is a simplified version
168
+
169
+ aggregated_update = {}
170
+
171
+ # Remove masks (in real FL, clients mask each other's updates)
172
+ for client_id, update in client_updates.items():
173
+ for key, value in update.items():
174
+ if key not in aggregated_update:
175
+ aggregated_update[key] = value
176
+ else:
177
+ aggregated_update[key] += value
178
+
179
+ # Average the updates
180
+ num_clients = len(client_updates)
181
+ for key in aggregated_update:
182
+ aggregated_update[key] /= num_clients
183
+
184
+ # Update global model
185
+ global_state = self.global_model.state_dict()
186
+ for key, value in aggregated_update.items():
187
+ if key in global_state:
188
+ global_state[key] += value
189
+
190
+ self.global_model.load_state_dict(global_state)
191
+ return self.global_model
192
+
193
+ class SecureAggregationClient:
194
+ def __init__(self, model, data):
195
+ self.model = model
196
+ self.data = data
197
+
198
+ def compute_model_update(self, global_model):
199
+ """Compute model update (difference from global model)."""
200
+ update = {}
201
+ global_state = global_model.state_dict()
202
+ local_state = self.model.state_dict()
203
+
204
+ for key in global_state:
205
+ update[key] = local_state[key] - global_state[key]
206
+
207
+ return update
208
+
209
+ def apply_mask(self, update, seed):
210
+ """Apply random mask to update."""
211
+ random.seed(seed)
212
+ masked_update = {}
213
+
214
+ for key, value in update.items():
215
+ # Generate random mask
216
+ mask = torch.randn_like(value) * 0.01
217
+ masked_update[key] = value + mask
218
+
219
+ return masked_update
220
+ ```
221
+
222
+ ### 4. Federated Learning Simulation
223
+ Simulate federated learning across multiple clients.
224
+
225
+ ```python
226
+ from torch.utils.data import DataLoader, TensorDataset
227
+ import torchvision
228
+ import torchvision.transforms as transforms
229
+
230
+ def create_client_datasets(num_clients=10, samples_per_client=1000):
231
+ """Create local datasets for each client."""
232
+ # Load MNIST dataset
233
+ transform = transforms.Compose([transforms.ToTensor()])
234
+ mnist = torchvision.datasets.MNIST(root='./data', train=True,
235
+ download=True, transform=transform)
236
+
237
+ # Split data among clients (non-IID)
238
+ client_datasets = []
239
+ data_per_client = len(mnist) // num_clients
240
+
241
+ for i in range(num_clients):
242
+ start_idx = i * data_per_client
243
+ end_idx = (i + 1) * data_per_client
244
+
245
+ # Create non-IID distribution by sorting labels
246
+ data_subset = torch.utils.data.Subset(mnist, range(start_idx, end_idx))
247
+ client_datasets.append(DataLoader(data_subset, batch_size=32, shuffle=True))
248
+
249
+ return client_datasets
250
+
251
+ def run_federated_learning(num_rounds=10, num_clients=10, local_epochs=5):
252
+ """Run federated learning simulation."""
253
+ # Create global model
254
+ global_model = nn.Sequential(
255
+ nn.Flatten(),
256
+ nn.Linear(784, 128),
257
+ nn.ReLU(),
258
+ nn.Linear(128, 10)
259
+ )
260
+
261
+ # Create server
262
+ server = FederatedLearningServer(global_model)
263
+
264
+ # Create clients
265
+ client_datasets = create_client_datasets(num_clients)
266
+ clients = []
267
+
268
+ for data in client_datasets:
269
+ client_model = deepcopy(global_model)
270
+ client = FederatedLearningClient(client_model, data)
271
+ clients.append(client)
272
+
273
+ # Training rounds
274
+ for round_num in range(num_rounds):
275
+ print(f"Round {round_num + 1}/{num_rounds}")
276
+
277
+ # Distribute global model
278
+ global_model_state = server.distribute_model()
279
+
280
+ # Select subset of clients (client sampling)
281
+ selected_clients = random.sample(clients, min(5, len(clients)))
282
+
283
+ # Local training
284
+ client_models = []
285
+ for client in selected_clients:
286
+ client.update_model(global_model_state)
287
+ updated_model = client.train_local(epochs=local_epochs)
288
+ client_models.append(updated_model)
289
+
290
+ # Aggregate models
291
+ server.aggregate_models(client_models)
292
+
293
+ # Evaluate global model (simplified)
294
+ print(f" Completed training with {len(client_models)} clients")
295
+
296
+ return global_model
297
+
298
+ # Usage
299
+ # global_model = run_federated_learning(num_rounds=10, num_clients=10, local_epochs=5)
300
+ # print("Federated learning completed!")
301
+ ```
302
+
303
+ ### 5. Monitoring and Evaluation
304
+ Monitor federated learning progress.
305
+
306
+ ```python
307
+ class FederatedLearningMonitor:
308
+ def __init__(self):
309
+ self.metrics = {
310
+ 'round': [],
311
+ 'client_accuracies': [],
312
+ 'global_accuracy': [],
313
+ 'communication_cost': [],
314
+ 'privacy_budget': []
315
+ }
316
+
317
+ def log_round(self, round_num, client_metrics, global_accuracy, comm_cost, privacy_epsilon):
318
+ """Log metrics for a round."""
319
+ self.metrics['round'].append(round_num)
320
+ self.metrics['client_accuracies'].append(client_metrics)
321
+ self.metrics['global_accuracy'].append(global_accuracy)
322
+ self.metrics['communication_cost'].append(comm_cost)
323
+ self.metrics['privacy_budget'].append(privacy_epsilon)
324
+
325
+ def evaluate_global_model(self, model, test_loader):
326
+ """Evaluate global model on test data."""
327
+ model.eval()
328
+ correct = 0
329
+ total = 0
330
+
331
+ with torch.no_grad():
332
+ for batch_x, batch_y in test_loader:
333
+ outputs = model(batch_x)
334
+ _, predicted = torch.max(outputs.data, 1)
335
+ total += batch_y.size(0)
336
+ correct += (predicted == batch_y).sum().item()
337
+
338
+ accuracy = 100 * correct / total
339
+ return accuracy
340
+
341
+ def generate_report(self):
342
+ """Generate training report."""
343
+ import matplotlib.pyplot as plt
344
+
345
+ # Plot global accuracy over rounds
346
+ plt.figure(figsize=(12, 4))
347
+
348
+ plt.subplot(1, 3, 1)
349
+ plt.plot(self.metrics['round'], self.metrics['global_accuracy'])
350
+ plt.xlabel('Round')
351
+ plt.ylabel('Global Accuracy (%)')
352
+ plt.title('Global Model Performance')
353
+
354
+ plt.subplot(1, 3, 2)
355
+ plt.plot(self.metrics['round'], self.metrics['communication_cost'])
356
+ plt.xlabel('Round')
357
+ plt.ylabel('Communication Cost (MB)')
358
+ plt.title('Communication Overhead')
359
+
360
+ plt.subplot(1, 3, 3)
361
+ plt.plot(self.metrics['round'], self.metrics['privacy_budget'])
362
+ plt.xlabel('Round')
363
+ plt.ylabel('Privacy Budget (ε)')
364
+ plt.title('Privacy Budget Consumption')
365
+
366
+ plt.tight_layout()
367
+ plt.savefig('federated_learning_metrics.png')
368
+ plt.close()
369
+
370
+ return "Federated learning metrics saved to federated_learning_metrics.png"
371
+
372
+ # Usage
373
+ # monitor = FederatedLearningMonitor()
374
+ # monitor.log_round(1, [85.2, 87.1, 86.5], 86.0, 5.2, 0.1)
375
+ # monitor.generate_report()
376
+ ```
377
+
378
+ ## Constraints
379
+ - **Communication Overhead**: Frequent model updates can be bandwidth-intensive
380
+ - **Heterogeneity**: Non-IID data across clients can hurt convergence
381
+ - **Privacy-Utility Tradeoff**: Stronger privacy protection may reduce model accuracy
382
+ - **System Complexity**: Federated learning systems are complex to implement and maintain
383
+ - **Client Availability**: Clients may be unavailable or have varying capabilities
384
+ - **Scalability**: Large numbers of clients present coordination challenges
385
+
386
+ ## Expected Output
387
+ A privacy-preserving machine learning system that trains models across decentralized devices while maintaining data locality and providing strong privacy guarantees.
TRAE-Skills/ai_engineering/Fine_Tuning_Custom_Models.md ADDED
@@ -0,0 +1,237 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Skill: Fine-Tuning Custom Models
2
+
3
+ ## Purpose
4
+ To adapt pre-trained LLMs to specific domains, tasks, or styles by training on custom datasets for improved performance on specialized use cases.
5
+
6
+ ## When to Use
7
+ - When you need domain-specific knowledge (legal, medical, technical)
8
+ - When you want a specific writing style or tone
9
+ - When you have a large dataset of example inputs/outputs
10
+ - When you need consistent formatting or structure in outputs
11
+
12
+ ## Procedure
13
+
14
+ ### 1. Prepare Your Dataset
15
+ Create properly formatted training data.
16
+
17
+ ```python
18
+ import json
19
+
20
+ # Training data format for OpenAI fine-tuning
21
+ training_data = [
22
+ {
23
+ "messages": [
24
+ {"role": "system", "content": "You are a legal assistant specializing in contract review."},
25
+ {"role": "user", "content": "Review this clause: 'The company may terminate at any time.'"},
26
+ {"role": "assistant", "content": "This clause is one-sided. Consider adding: 'either party may terminate with 30 days notice.'"}
27
+ ]
28
+ },
29
+ {
30
+ "messages": [
31
+ {"role": "system", "content": "You are a legal assistant specializing in contract review."},
32
+ {"role": "user", "content": "Is this confidentiality clause standard?"},
33
+ {"role": "assistant", "content": "The clause appears standard. It includes mutual confidentiality obligations and defines exceptions appropriately."}
34
+ ]
35
+ }
36
+ ]
37
+
38
+ # Save to JSONL file
39
+ with open('training_data.jsonl', 'w') as f:
40
+ for entry in training_data:
41
+ f.write(json.dumps(entry) + '\n')
42
+ ```
43
+
44
+ ### 2. Validate Your Data
45
+ Ensure data quality before training.
46
+
47
+ ```python
48
+ import json
49
+ from collections import defaultdict
50
+
51
+ def validate_finetuning_data(file_path):
52
+ """Validate fine-tuning dataset."""
53
+ errors = []
54
+ stats = defaultdict(int)
55
+
56
+ with open(file_path, 'r') as f:
57
+ for line_num, line in enumerate(f, 1):
58
+ try:
59
+ entry = json.loads(line)
60
+ stats['total_entries'] += 1
61
+
62
+ # Check required fields
63
+ if 'messages' not in entry:
64
+ errors.append(f"Line {line_num}: Missing 'messages' field")
65
+ continue
66
+
67
+ messages = entry['messages']
68
+ stats['total_messages'] += len(messages)
69
+
70
+ # Validate message structure
71
+ for msg in messages:
72
+ if 'role' not in msg or 'content' not in msg:
73
+ errors.append(f"Line {line_num}: Invalid message structure")
74
+
75
+ if msg['role'] not in ['system', 'user', 'assistant']:
76
+ errors.append(f"Line {line_num}: Invalid role: {msg['role']}")
77
+
78
+ stats[f"role_{msg['role']}"] += 1
79
+
80
+ except json.JSONDecodeError:
81
+ errors.append(f"Line {line_num}: Invalid JSON")
82
+
83
+ return {
84
+ 'errors': errors,
85
+ 'stats': dict(stats)
86
+ }
87
+
88
+ # Usage
89
+ validation_result = validate_finetuning_data('training_data.jsonl')
90
+ print(f"Validation complete: {validation_result['stats']['total_entries']} entries")
91
+ if validation_result['errors']:
92
+ print(f"Errors found: {len(validation_result['errors'])}")
93
+ for error in validation_result['errors'][:10]: # Show first 10 errors
94
+ print(f" - {error}")
95
+ ```
96
+
97
+ ### 3. Upload and Prepare Training
98
+ Upload data to OpenAI and start fine-tuning.
99
+
100
+ ```python
101
+ from openai import OpenAI
102
+
103
+ client = OpenAI()
104
+
105
+ # Upload training file
106
+ with open('training_data.jsonl', 'rb') as f:
107
+ upload_response = client.files.create(
108
+ file=f,
109
+ purpose='fine-tune'
110
+ )
111
+
112
+ training_file_id = upload_response.id
113
+ print(f"File uploaded: {training_file_id}")
114
+
115
+ # Create fine-tuning job
116
+ fine_tune_job = client.fine_tuning.jobs.create(
117
+ training_file=training_file_id,
118
+ model="gpt-3.5-turbo",
119
+ hyperparameters={
120
+ "n_epochs": 3,
121
+ "batch_size": 4,
122
+ "learning_rate_multiplier": 0.1
123
+ }
124
+ )
125
+
126
+ job_id = fine_tune_job.id
127
+ print(f"Fine-tuning job started: {job_id}")
128
+ ```
129
+
130
+ ### 4. Monitor Training Progress
131
+ Track the fine-tuning process.
132
+
133
+ ```python
134
+ def check_finetuning_status(job_id):
135
+ """Check the status of a fine-tuning job."""
136
+ job = client.fine_tuning.jobs.retrieve(job_id)
137
+
138
+ status = {
139
+ 'status': job.status,
140
+ 'created_at': job.created_at,
141
+ 'finished_at': job.finished_at,
142
+ 'model': job.fine_tuned_model,
143
+ 'error': job.error
144
+ }
145
+
146
+ if job.result_files:
147
+ # Retrieve training metrics
148
+ result_file = client.files.retrieve(job.result_files[0])
149
+ print(f"Results file: {result_file.id}")
150
+
151
+ return status
152
+
153
+ # Usage
154
+ import time
155
+
156
+ while True:
157
+ status = check_finetuning_status(job_id)
158
+ print(f"Status: {status['status']}")
159
+
160
+ if status['status'] in ['succeeded', 'failed', 'cancelled']:
161
+ break
162
+
163
+ time.sleep(60) # Check every minute
164
+ ```
165
+
166
+ ### 5. Use the Fine-Tuned Model
167
+ Deploy and use your custom model.
168
+
169
+ ```python
170
+ def use_finetuned_model(model_id, prompt):
171
+ """Use the fine-tuned model for inference."""
172
+ response = client.chat.completions.create(
173
+ model=model_id,
174
+ messages=[{"role": "user", "content": prompt}]
175
+ )
176
+ return response.choices[0].message.content
177
+
178
+ # After training completes
179
+ fine_tuned_model = status['model']
180
+
181
+ # Test the model
182
+ test_prompt = "Review this contract clause: 'Employee shall not compete for 2 years after termination.'"
183
+ result = use_finetuned_model(fine_tuned_model, test_prompt)
184
+ print(result)
185
+ ```
186
+
187
+ ### 6. Evaluate Model Performance
188
+ Assess the quality of your fine-tuned model.
189
+
190
+ ```python
191
+ def evaluate_model(model_id, test_data):
192
+ """Evaluate fine-tuned model on test set."""
193
+ results = []
194
+
195
+ for test_case in test_data:
196
+ # Get model response
197
+ response = use_finetuned_model(model_id, test_case['input'])
198
+
199
+ # Compare with expected output
200
+ results.append({
201
+ 'input': test_case['input'],
202
+ 'expected': test_case['expected'],
203
+ 'actual': response,
204
+ 'match': test_case['expected'].lower() in response.lower()
205
+ })
206
+
207
+ # Calculate metrics
208
+ accuracy = sum(r['match'] for r in results) / len(results)
209
+
210
+ return {
211
+ 'accuracy': accuracy,
212
+ 'results': results
213
+ }
214
+
215
+ # Test dataset
216
+ test_data = [
217
+ {
218
+ 'input': 'Is this termination clause fair?',
219
+ 'expected': 'fair' # or 'unfair'
220
+ }
221
+ # ... more test cases
222
+ ]
223
+
224
+ evaluation = evaluate_model(fine_tuned_model, test_data)
225
+ print(f"Accuracy: {evaluation['accuracy']:.2%}")
226
+ ```
227
+
228
+ ## Constraints
229
+ - **Minimum Data**: Need at least 10-100 examples for meaningful fine-tuning
230
+ - **Data Quality**: Garbage in, garbage out - ensure high-quality training data
231
+ - **Cost**: Fine-tuning can be expensive, especially with large datasets
232
+ - **Overfitting**: Monitor for overfitting to training data
233
+ - **Hallucination**: Fine-tuned models may still hallucinate facts
234
+ - **Maintenance**: Models may need periodic retraining as data evolves
235
+
236
+ ## Expected Output
237
+ A specialized model that performs better on your specific domain tasks compared to base models, with consistent formatting and domain-specific knowledge.
TRAE-Skills/ai_engineering/Fine_tuning_Basics.md ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Skill: Fine-tuning Basics
2
+
3
+ ## Purpose
4
+ To adapt a pre-trained LLM to a specific task, tone, or domain by training it on a specialized dataset, ensuring rigid adherence to format or style.
5
+
6
+ ## When to Use
7
+ - When "Prompt Engineering" fails to produce the desired format consistently.
8
+ - When you need to mimic a very specific brand voice or writing style.
9
+ - To reduce latency and costs by using a smaller model (e.g., GPT-4o-mini) that performs like a larger one on a specific task.
10
+
11
+ ## Procedure
12
+
13
+ ### 1. Data Preparation (JSONL)
14
+ Create a dataset in the specific format required by the provider (OpenAI example).
15
+
16
+ ```json
17
+ // training_data.jsonl
18
+ {"messages": [{"role": "system", "content": "You are a code reviewer."}, {"role": "user", "content": "Review this: const x = 1;"}, {"role": "assistant", "content": "LGTM. Consider using 'let' if reassigning."}]}
19
+ {"messages": [{"role": "system", "content": "You are a code reviewer."}, {"role": "user", "content": "Review this: alert('hi');"}, {"role": "assistant", "content": "Avoid 'alert' in production code."}]}
20
+ ```
21
+
22
+ ### 2. Validation Script (Python)
23
+ Always validate your JSONL before uploading to avoid costly training failures.
24
+
25
+ ```python
26
+ import json
27
+
28
+ def validate_data(file_path):
29
+ with open(file_path, 'r') as f:
30
+ for line in f:
31
+ try:
32
+ data = json.loads(line)
33
+ if "messages" not in data:
34
+ print("Missing 'messages' key")
35
+ except Exception as e:
36
+ print(f"Error parsing line: {e}")
37
+
38
+ validate_data("training_data.jsonl")
39
+ ```
40
+
41
+ ### 3. Starting the Fine-tuning Job (OpenAI CLI)
42
+ Upload the file and start the training process.
43
+
44
+ ```bash
45
+ # Install CLI
46
+ pip install openai
47
+
48
+ # Set Key
49
+ export OPENAI_API_KEY="your-key"
50
+
51
+ # Upload file
52
+ openai files create -f training_data.jsonl -p fine-tune
53
+
54
+ # Start training
55
+ openai fine_tuning.jobs.create -t "file-id-from-upload" -m "gpt-4o-mini-2024-07-18"
56
+ ```
57
+
58
+ ### 4. Monitoring & Evaluation
59
+ Check the status and loss metrics.
60
+
61
+ ```bash
62
+ # List jobs
63
+ openai fine_tuning.jobs.list
64
+
65
+ # Retrieve status
66
+ openai fine_tuning.jobs.retrieve -i "ft-job-id"
67
+ ```
68
+
69
+ ### 5. Using the Fine-tuned Model
70
+ Once completed, use the new model ID in your application.
71
+
72
+ ```typescript
73
+ const completion = await openai.chat.completions.create({
74
+ model: "ft:gpt-4o-mini:your-org:custom-name:id",
75
+ messages: [{ role: "user", content: "Review this: console.log(1);" }],
76
+ });
77
+ ```
78
+
79
+ ## Constraints
80
+ - **Overfitting**: Don't train for too many epochs; the model will lose its general intelligence.
81
+ - **Facts vs Style**: **Never** fine-tune to teach new facts. Use RAG for facts. Use fine-tuning for **how** the model speaks.
82
+ - **Minimum Data**: You need at least 50-100 high-quality examples to see any meaningful improvement.
83
+
84
+ ## Expected Output
85
+ A specialized model ID that delivers high-performance results on a specific, narrow task.
TRAE-Skills/ai_engineering/Function_Calling.md ADDED
@@ -0,0 +1,280 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Skill: Function Calling
2
+
3
+ ## Purpose
4
+ To enable LLMs to interact with external tools, APIs, and databases by defining structured function specifications that models can intelligently invoke.
5
+
6
+ ## When to Use
7
+ - When building AI assistants that need to perform actions
8
+ - When integrating LLMs with existing APIs
9
+ - When requiring structured data extraction
10
+ - When implementing multi-step workflows with external systems
11
+
12
+ ## Procedure
13
+
14
+ ### 1. Define Function Schemas
15
+ Create structured function definitions with clear descriptions.
16
+
17
+ ```python
18
+ from openai import OpenAI
19
+
20
+ client = OpenAI()
21
+
22
+ # Define available functions
23
+ functions = [
24
+ {
25
+ "name": "get_weather",
26
+ "description": "Get the current weather for a specific location",
27
+ "parameters": {
28
+ "type": "object",
29
+ "properties": {
30
+ "location": {
31
+ "type": "string",
32
+ "description": "The city and state, e.g. San Francisco, CA"
33
+ },
34
+ "unit": {
35
+ "type": "string",
36
+ "enum": ["celsius", "fahrenheit"],
37
+ "description": "The temperature unit"
38
+ }
39
+ },
40
+ "required": ["location"]
41
+ }
42
+ },
43
+ {
44
+ "name": "search_database",
45
+ "description": "Search a database for specific records",
46
+ "parameters": {
47
+ "type": "object",
48
+ "properties": {
49
+ "query": {
50
+ "type": "string",
51
+ "description": "The search query"
52
+ },
53
+ "limit": {
54
+ "type": "integer",
55
+ "description": "Maximum number of results to return"
56
+ }
57
+ },
58
+ "required": ["query"]
59
+ }
60
+ }
61
+ ]
62
+ ```
63
+
64
+ ### 2. Implement the Functions
65
+ Create actual implementations of your defined functions.
66
+
67
+ ```python
68
+ import requests
69
+
70
+ def get_weather(location, unit="celsius"):
71
+ """Get weather data for a location."""
72
+ # Example using a weather API
73
+ api_url = f"https://api.weatherapi.com/v1/current.json"
74
+ params = {
75
+ "key": "your-api-key",
76
+ "q": location,
77
+ "aqi": "no"
78
+ }
79
+
80
+ try:
81
+ response = requests.get(api_url, params=params)
82
+ data = response.json()
83
+
84
+ temp = data['current']['temp_c'] if unit == "celsius" else data['current']['temp_f']
85
+ condition = data['current']['condition']['text']
86
+
87
+ return {
88
+ "location": location,
89
+ "temperature": temp,
90
+ "unit": unit,
91
+ "condition": condition
92
+ }
93
+ except Exception as e:
94
+ return {"error": str(e)}
95
+
96
+ def search_database(query, limit=10):
97
+ """Search database for records."""
98
+ # Example database query
99
+ # In production, use your actual database connection
100
+ results = [
101
+ {"id": 1, "title": f"Result for {query}", "content": "..."},
102
+ {"id": 2, "title": f"Another result for {query}", "content": "..."}
103
+ ]
104
+ return results[:limit]
105
+
106
+ # Map function names to implementations
107
+ function_map = {
108
+ "get_weather": get_weather,
109
+ "search_database": search_database
110
+ }
111
+ ```
112
+
113
+ ### 3. Handle Function Calls
114
+ Process LLM responses that request function calls.
115
+
116
+ ```python
117
+ def execute_function_call(function_call):
118
+ """Execute a function call from the LLM."""
119
+ function_name = function_call.name
120
+ function_args = json.loads(function_call.arguments)
121
+
122
+ print(f"Calling function: {function_name}")
123
+ print(f"Arguments: {function_args}")
124
+
125
+ if function_name in function_map:
126
+ function_to_call = function_map[function_name]
127
+ return function_to_call(**function_args)
128
+ else:
129
+ return f"Error: Function {function_name} not found"
130
+ ```
131
+
132
+ ### 4. Complete Conversation Flow
133
+ Implement the full interaction loop.
134
+
135
+ ```python
136
+ def chat_with_functions(user_message, messages_history=None):
137
+ """Handle conversation with function calling."""
138
+ if messages_history is None:
139
+ messages_history = []
140
+
141
+ # Add user message to history
142
+ messages_history.append({"role": "user", "content": user_message})
143
+
144
+ # Make API call with functions
145
+ response = client.chat.completions.create(
146
+ model="gpt-4",
147
+ messages=messages_history,
148
+ functions=functions,
149
+ function_call="auto" # Let model decide whether to call functions
150
+ )
151
+
152
+ response_message = response.choices[0].message
153
+
154
+ # Check if model wants to call a function
155
+ if response_message.function_call:
156
+ print(f"Model wants to call: {response_message.function_call.name}")
157
+
158
+ # Execute function call
159
+ function_response = execute_function_call(response_message.function_call)
160
+
161
+ # Add function response to conversation
162
+ messages_history.append(response_message) # Assistant message with function call
163
+ messages_history.append({
164
+ "role": "function",
165
+ "name": response_message.function_call.name,
166
+ "content": json.dumps(function_response)
167
+ })
168
+
169
+ # Get final response from model
170
+ second_response = client.chat.completions.create(
171
+ model="gpt-4",
172
+ messages=messages_history
173
+ )
174
+
175
+ return second_response.choices[0].message.content
176
+ else:
177
+ return response_message.content
178
+
179
+ # Usage
180
+ messages = []
181
+ while True:
182
+ user_input = input("You: ")
183
+ if user_input.lower() in ['quit', 'exit']:
184
+ break
185
+
186
+ response = chat_with_functions(user_input, messages)
187
+ print(f"Assistant: {response}")
188
+ messages.append({"role": "assistant", "content": response})
189
+ ```
190
+
191
+ ### 5. Advanced: Parallel Function Calls
192
+ Handle multiple function calls in a single request.
193
+
194
+ ```python
195
+ def handle_parallel_function_calls(response_message, messages_history):
196
+ """Handle multiple function calls from the model."""
197
+ # Some models can request multiple function calls at once
198
+ if hasattr(response_message, 'function_calls'):
199
+ function_calls = response_message.function_calls
200
+ else:
201
+ # Single function call (convert to list for uniform handling)
202
+ if response_message.function_call:
203
+ function_calls = [response_message.function_call]
204
+ else:
205
+ return messages_history
206
+
207
+ # Add assistant message with function calls
208
+ messages_history.append(response_message)
209
+
210
+ # Execute all function calls
211
+ for function_call in function_calls:
212
+ function_response = execute_function_call(function_call)
213
+
214
+ # Add each function response
215
+ messages_history.append({
216
+ "role": "function",
217
+ "name": function_call.name,
218
+ "content": json.dumps(function_response)
219
+ })
220
+
221
+ return messages_history
222
+ ```
223
+
224
+ ### 6. Error Handling and Validation
225
+ Add robust error handling for function calls.
226
+
227
+ ```python
228
+ def safe_execute_function_call(function_call):
229
+ """Execute function call with error handling."""
230
+ function_name = function_call.name
231
+
232
+ try:
233
+ function_args = json.loads(function_call.arguments)
234
+ except json.JSONDecodeError as e:
235
+ return {
236
+ "error": f"Invalid JSON in arguments: {str(e)}",
237
+ "arguments": function_call.arguments
238
+ }
239
+
240
+ # Validate function exists
241
+ if function_name not in function_map:
242
+ return {
243
+ "error": f"Unknown function: {function_name}",
244
+ "available_functions": list(function_map.keys())
245
+ }
246
+
247
+ # Validate required parameters
248
+ function_schema = next((f for f in functions if f["name"] == function_name), None)
249
+ if function_schema:
250
+ required_params = function_schema["parameters"].get("required", [])
251
+ missing_params = [p for p in required_params if p not in function_args]
252
+
253
+ if missing_params:
254
+ return {
255
+ "error": f"Missing required parameters: {', '.join(missing_params)}",
256
+ "provided": list(function_args.keys())
257
+ }
258
+
259
+ # Execute function
260
+ try:
261
+ function_to_call = function_map[function_name]
262
+ return function_to_call(**function_args)
263
+ except Exception as e:
264
+ return {
265
+ "error": f"Function execution failed: {str(e)}",
266
+ "function": function_name,
267
+ "arguments": function_args
268
+ }
269
+ ```
270
+
271
+ ## Constraints
272
+ - **Function Descriptions**: Clear, detailed descriptions are crucial for model performance
273
+ - **Parameter Validation**: Always validate function arguments before execution
274
+ - **Error Handling**: Gracefully handle function failures and API errors
275
+ - **Security**: Validate and sanitize all inputs, especially for database operations
276
+ - **Rate Limiting**: Implement rate limits for external API calls
277
+ - **Token Limits**: Function calls consume tokens - consider size of function schemas and responses
278
+
279
+ ## Expected Output
280
+ An intelligent AI assistant capable of understanding user intent and automatically executing appropriate functions to fulfill requests, with proper error handling and response formatting.
TRAE-Skills/ai_engineering/Generative_AI_Image_Synthesis.md ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Skill: Generative AI Image Synthesis
2
+
3
+ ## Purpose
4
+ To create and integrate generative image AI models (Stable Diffusion, DALL-E, Midjourney API) into applications for generating, editing, and manipulating images programmatically.
5
+
6
+ ## When to Use
7
+ - When building applications that require on-demand image generation from text prompts
8
+ - For creating custom image editing tools using AI inpainting/outpainting
9
+ - When implementing AI-powered design tools for creative industries
10
+ - For generating synthetic datasets for computer vision tasks
11
+
12
+ ## Procedure
13
+
14
+ ### 1. Stable Diffusion Integration (Hugging Face)
15
+ Use the Hugging Face Diffusers library for local Stable Diffusion generation.
16
+
17
+ ```python
18
+ from diffusers import StableDiffusionPipeline
19
+ import torch
20
+
21
+ model_id = "runwayml/stable-diffusion-v1-5"
22
+ pipe = StableDiffusionPipeline.from_pretrained(model_id, torch_dtype=torch.float16)
23
+ pipe = pipe.to("cuda")
24
+
25
+ prompt = "A majestic lion standing on a cliff at sunset, photorealistic"
26
+ image = pipe(prompt).images[0]
27
+ image.save("lion_sunset.png")
28
+ ```
29
+
30
+ ### 2. OpenAI DALL-E API Integration
31
+ Use OpenAI's API for cloud-based image generation.
32
+
33
+ ```javascript
34
+ import OpenAI from 'openai';
35
+
36
+ const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
37
+
38
+ async function generateImage(prompt) {
39
+ const response = await openai.images.generate({
40
+ model: 'dall-e-3',
41
+ prompt: prompt,
42
+ n: 1,
43
+ size: '1024x1024',
44
+ quality: 'standard',
45
+ });
46
+ return response.data[0].url;
47
+ }
48
+ ```
49
+
50
+ ### 3. Inpainting for Image Editing
51
+ Modify specific regions of existing images.
52
+
53
+ ```python
54
+ from diffusers import StableDiffusionInpaintPipeline
55
+ from PIL import Image
56
+ import torch
57
+
58
+ pipe = StableDiffusionInpaintPipeline.from_pretrained(
59
+ "runwayml/stable-diffusion-inpainting",
60
+ torch_dtype=torch.float16
61
+ ).to("cuda")
62
+
63
+ image = Image.open("original_image.jpg")
64
+ mask = Image.open("mask_image.png")
65
+
66
+ prompt = "A cute dog sitting on the couch"
67
+ result = pipe(prompt=prompt, image=image, mask_image=mask).images[0]
68
+ result.save("edited_image.jpg")
69
+ ```
70
+
71
+ ### 4. Image-to-Image Translation
72
+ Transform existing images based on text prompts.
73
+
74
+ ```python
75
+ from diffusers import StableDiffusionImg2ImgPipeline
76
+ from PIL import Image
77
+ import torch
78
+
79
+ pipe = StableDiffusionImg2ImgPipeline.from_pretrained(
80
+ "runwayml/stable-diffusion-v1-5",
81
+ torch_dtype=torch.float16
82
+ ).to("cuda")
83
+
84
+ init_image = Image.open("sketch.jpg").convert("RGB")
85
+ prompt = "A realistic watercolor painting of a mountain landscape"
86
+
87
+ result = pipe(prompt=prompt, image=init_image, strength=0.75, guidance_scale=7.5).images[0]
88
+ result.save("watercolor_mountain.jpg")
89
+ ```
90
+
91
+ ## Best Practices
92
+ - **Prompt Engineering**: Be specific about style, lighting, composition, and artists for better results
93
+ - **Memory Management**: Use float16 and model quantization to reduce GPU memory usage
94
+ - **Caching**: Cache frequently used generated images to reduce API costs
95
+ - **Content Moderation**: Implement safety filters to prevent generation of inappropriate content
96
+ - **Rate Limiting**: Respect API rate limits and implement retry logic with exponential backoff
TRAE-Skills/ai_engineering/LLM_Caching_Strategies.md ADDED
@@ -0,0 +1,259 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Skill: LLM Caching Strategies
2
+
3
+ ## Purpose
4
+ To reduce API costs and latency by caching LLM responses and avoiding redundant calls for identical or similar prompts.
5
+
6
+ ## When to Use
7
+ - When users frequently ask similar questions
8
+ - When implementing RAG systems with recurring queries
9
+ - When building applications with repetitive patterns
10
+ - When optimizing for cost reduction
11
+
12
+ ## Procedure
13
+
14
+ ### 1. Simple Exact Match Caching
15
+ Cache responses based on exact prompt matches.
16
+
17
+ ```python
18
+ import hashlib
19
+ import json
20
+ from functools import wraps
21
+ from openai import OpenAI
22
+
23
+ client = OpenAI()
24
+
25
+ # Simple in-memory cache
26
+ response_cache = {}
27
+
28
+ def cache_key(prompt, model, temperature=0):
29
+ """Generate a unique cache key."""
30
+ content = f"{model}:{temperature}:{prompt}"
31
+ return hashlib.sha256(content.encode()).hexdigest()
32
+
33
+ def cached_completion(prompt, model="gpt-4", temperature=0):
34
+ """Get completion with caching."""
35
+ key = cache_key(prompt, model, temperature)
36
+
37
+ if key in response_cache:
38
+ print("Cache hit!")
39
+ return response_cache[key]
40
+
41
+ print("Cache miss - calling API...")
42
+ response = client.chat.completions.create(
43
+ model=model,
44
+ messages=[{"role": "user", "content": prompt}],
45
+ temperature=temperature
46
+ )
47
+
48
+ result = response.choices[0].message.content
49
+ response_cache[key] = result
50
+ return result
51
+ ```
52
+
53
+ ### 2. Semantic Caching with Embeddings
54
+ Cache responses based on semantic similarity.
55
+
56
+ ```python
57
+ import numpy as np
58
+ from sentence_transformers import SentenceTransformer
59
+
60
+ class SemanticCache:
61
+ def __init__(self, similarity_threshold=0.85):
62
+ self.embedder = SentenceTransformer('all-MiniLM-L6-v2')
63
+ self.prompts = []
64
+ self.responses = []
65
+ self.embeddings = []
66
+ self.threshold = similarity_threshold
67
+
68
+ def get(self, prompt):
69
+ """Try to get a cached response based on semantic similarity."""
70
+ if not self.prompts:
71
+ return None
72
+
73
+ # Embed the query prompt
74
+ query_embedding = self.embedder.encode([prompt])[0]
75
+
76
+ # Calculate similarities with cached prompts
77
+ cached_embeddings = np.array(self.embeddings)
78
+ similarities = np.dot(cached_embeddings, query_embedding) / (
79
+ np.linalg.norm(cached_embeddings, axis=1) * np.linalg.norm(query_embedding)
80
+ )
81
+
82
+ # Find the most similar cached prompt
83
+ max_idx = np.argmax(similarities)
84
+ max_similarity = similarities[max_idx]
85
+
86
+ if max_similarity >= self.threshold:
87
+ print(f"Semantic cache hit! Similarity: {max_similarity:.3f}")
88
+ return self.responses[max_idx]
89
+
90
+ print(f"No semantic match found. Max similarity: {max_similarity:.3f}")
91
+ return None
92
+
93
+ def set(self, prompt, response):
94
+ """Store a new prompt-response pair."""
95
+ self.prompts.append(prompt)
96
+ self.responses.append(response)
97
+ self.embeddings.append(self.embedder.encode([prompt])[0])
98
+
99
+ # Usage
100
+ semantic_cache = SemanticCache(similarity_threshold=0.90)
101
+
102
+ def get_response_with_semantic_cache(prompt):
103
+ # Check cache first
104
+ cached = semantic_cache.get(prompt)
105
+ if cached:
106
+ return cached
107
+
108
+ # Call API and cache the result
109
+ response = client.chat.completions.create(
110
+ model="gpt-4",
111
+ messages=[{"role": "user", "content": prompt}]
112
+ )
113
+ result = response.choices[0].message.content
114
+
115
+ semantic_cache.set(prompt, result)
116
+ return result
117
+ ```
118
+
119
+ ### 3. Persistent Caching with Redis
120
+ Store cache entries in Redis for persistence across restarts.
121
+
122
+ ```python
123
+ import redis
124
+ import pickle
125
+ import hashlib
126
+
127
+ redis_client = redis.Redis(host='localhost', port=6379, db=0)
128
+
129
+ def redis_cache_key(prompt, model="gpt-4"):
130
+ """Generate Redis cache key."""
131
+ content = f"llm_cache:{model}:{hashlib.sha256(prompt.encode()).hexdigest()}"
132
+ return content
133
+
134
+ def get_with_redis_cache(prompt, model="gpt-4", expire_hours=24):
135
+ """Get response with Redis caching."""
136
+ key = redis_cache_key(prompt, model)
137
+
138
+ # Try to get from Redis
139
+ cached = redis_client.get(key)
140
+ if cached:
141
+ print("Redis cache hit!")
142
+ return pickle.loads(cached)
143
+
144
+ print("Redis cache miss - calling API...")
145
+ response = client.chat.completions.create(
146
+ model=model,
147
+ messages=[{"role": "user", "content": prompt}]
148
+ )
149
+ result = response.choices[0].message.content
150
+
151
+ # Store in Redis with expiration
152
+ redis_client.setex(key, expire_hours * 3600, pickle.dumps(result))
153
+ return result
154
+ ```
155
+
156
+ ### 4. Hierarchical Caching
157
+ Combine multiple caching strategies for optimal performance.
158
+
159
+ ```python
160
+ class HierarchicalCache:
161
+ def __init__(self):
162
+ self.memory_cache = {} # L1: In-memory cache
163
+ self.semantic_cache = SemanticCache() # L2: Semantic cache
164
+ self.redis_client = redis.Redis() # L3: Persistent cache
165
+
166
+ def get(self, prompt, model="gpt-4"):
167
+ # Check L1: Exact match in memory
168
+ key = cache_key(prompt, model)
169
+ if key in self.memory_cache:
170
+ return self.memory_cache[key]
171
+
172
+ # Check L2: Semantic match
173
+ semantic_result = self.semantic_cache.get(prompt)
174
+ if semantic_result:
175
+ self.memory_cache[key] = semantic_result
176
+ return semantic_result
177
+
178
+ # Check L3: Redis persistent cache
179
+ redis_key = redis_cache_key(prompt, model)
180
+ redis_result = self.redis_client.get(redis_key)
181
+ if redis_result:
182
+ result = pickle.loads(redis_result)
183
+ self.memory_cache[key] = result
184
+ self.semantic_cache.set(prompt, result)
185
+ return result
186
+
187
+ # Cache miss - call API
188
+ response = client.chat.completions.create(
189
+ model=model,
190
+ messages=[{"role": "user", "content": prompt}]
191
+ )
192
+ result = response.choices[0].message.content
193
+
194
+ # Store at all levels
195
+ self.memory_cache[key] = result
196
+ self.semantic_cache.set(prompt, result)
197
+ self.redis_client.setex(redis_key, 86400, pickle.dumps(result))
198
+
199
+ return result
200
+
201
+ # Usage
202
+ hierarchical_cache = HierarchicalCache()
203
+ response = hierarchical_cache.get("Explain quantum computing")
204
+ ```
205
+
206
+ ### 5. Cache Statistics and Monitoring
207
+ Track cache performance to optimize strategies.
208
+
209
+ ```python
210
+ from collections import defaultdict
211
+
212
+ class CacheWithStats:
213
+ def __init__(self):
214
+ self.cache = {}
215
+ self.stats = defaultdict(int)
216
+
217
+ def get(self, key):
218
+ self.stats['total_requests'] += 1
219
+
220
+ if key in self.cache:
221
+ self.stats['cache_hits'] += 1
222
+ self.stats['memory_cache_hits'] += 1
223
+ return self.cache[key]
224
+
225
+ self.stats['cache_misses'] += 1
226
+ return None
227
+
228
+ def set(self, key, value):
229
+ self.cache[key] = value
230
+ self.stats['items_cached'] += 1
231
+
232
+ def get_stats(self):
233
+ total = self.stats['total_requests']
234
+ hits = self.stats['cache_hits']
235
+ hit_rate = (hits / total * 100) if total > 0 else 0
236
+
237
+ return {
238
+ 'total_requests': total,
239
+ 'cache_hits': hits,
240
+ 'cache_misses': self.stats['cache_misses'],
241
+ 'hit_rate': f"{hit_rate:.2f}%",
242
+ 'items_cached': self.stats['items_cached']
243
+ }
244
+
245
+ # Usage
246
+ cache = CacheWithStats()
247
+ # ... perform operations ...
248
+ print(cache.get_stats())
249
+ ```
250
+
251
+ ## Constraints
252
+ - **Memory Usage**: Semantic caching stores embeddings in memory
253
+ - **Staleness**: Cached responses may become outdated
254
+ - **Similarity Threshold**: Tune based on your use case (0.85-0.95)
255
+ - **Cache Size**: Implement cache eviction policies for long-running systems
256
+ - **Cost vs. Freshness**: Balance between caching and getting fresh responses
257
+
258
+ ## Expected Output
259
+ Significant reduction in API costs (50-90% in some cases) and improved latency through intelligent caching of LLM responses.
TRAE-Skills/ai_engineering/LLM_Function_Calling_Advanced.md ADDED
@@ -0,0 +1,234 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Skill: Advanced LLM Function Calling
2
+
3
+ ## Purpose
4
+ To implement advanced function calling patterns with Large Language Models, enabling them to interact with external APIs, databases, and tools in a structured, safe way.
5
+
6
+ ## When to Use
7
+ - When building AI agents that need to take real-world actions
8
+ - For integrating LLMs with existing APIs and services
9
+ - When you need structured, deterministic outputs from LLMs
10
+ - For building copilots and assistant applications
11
+ - When implementing multi-step reasoning and tool use
12
+
13
+ ## Procedure
14
+
15
+ ### 1. Function Definition Schema
16
+ Define functions with clear descriptions and schemas.
17
+
18
+ ```javascript
19
+ import OpenAI from 'openai';
20
+
21
+ const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
22
+
23
+ const functions = [
24
+ {
25
+ name: 'get_weather',
26
+ description: 'Get the current weather in a given location',
27
+ parameters: {
28
+ type: 'object',
29
+ properties: {
30
+ location: {
31
+ type: 'string',
32
+ description: 'The city and state, e.g., San Francisco, CA',
33
+ },
34
+ unit: {
35
+ type: 'string',
36
+ enum: ['celsius', 'fahrenheit'],
37
+ description: 'The temperature unit to use',
38
+ },
39
+ },
40
+ required: ['location'],
41
+ },
42
+ },
43
+ {
44
+ name: 'search_products',
45
+ description: 'Search for products in the catalog',
46
+ parameters: {
47
+ type: 'object',
48
+ properties: {
49
+ query: {
50
+ type: 'string',
51
+ description: 'The search query',
52
+ },
53
+ category: {
54
+ type: 'string',
55
+ enum: ['electronics', 'clothing', 'books'],
56
+ description: 'Product category',
57
+ },
58
+ max_results: {
59
+ type: 'integer',
60
+ description: 'Maximum number of results to return',
61
+ },
62
+ },
63
+ required: ['query'],
64
+ },
65
+ },
66
+ ];
67
+ ```
68
+
69
+ ### 2. Function Calling Loop
70
+ Implement a loop to handle multiple function calls.
71
+
72
+ ```javascript
73
+ async function chatWithFunctions(messages) {
74
+ let response = await openai.chat.completions.create({
75
+ model: 'gpt-4',
76
+ messages,
77
+ functions,
78
+ function_call: 'auto',
79
+ });
80
+
81
+ let message = response.choices[0].message;
82
+
83
+ while (message.function_call) {
84
+ const functionName = message.function_call.name;
85
+ const functionArgs = JSON.parse(message.function_call.arguments);
86
+
87
+ // Execute the function
88
+ let functionResponse;
89
+ switch (functionName) {
90
+ case 'get_weather':
91
+ functionResponse = await getWeather(functionArgs);
92
+ break;
93
+ case 'search_products':
94
+ functionResponse = await searchProducts(functionArgs);
95
+ break;
96
+ default:
97
+ functionResponse = { error: `Unknown function: ${functionName}` };
98
+ }
99
+
100
+ // Add the function response to messages
101
+ messages.push(message);
102
+ messages.push({
103
+ role: 'function',
104
+ name: functionName,
105
+ content: JSON.stringify(functionResponse),
106
+ });
107
+
108
+ // Get next response from LLM
109
+ response = await openai.chat.completions.create({
110
+ model: 'gpt-4',
111
+ messages,
112
+ functions,
113
+ function_call: 'auto',
114
+ });
115
+
116
+ message = response.choices[0].message;
117
+ }
118
+
119
+ return message.content;
120
+ }
121
+
122
+ // Usage
123
+ const messages = [
124
+ { role: 'user', content: 'What is the weather in New York and show me 3 electronics products?' }
125
+ ];
126
+
127
+ const result = await chatWithFunctions(messages);
128
+ console.log(result);
129
+ ```
130
+
131
+ ### 3. Parallel Function Calling
132
+ Execute multiple functions in parallel.
133
+
134
+ ```javascript
135
+ async function chatWithParallelFunctions(messages) {
136
+ let response = await openai.chat.completions.create({
137
+ model: 'gpt-4',
138
+ messages,
139
+ functions,
140
+ function_call: 'auto',
141
+ });
142
+
143
+ let message = response.choices[0].message;
144
+
145
+ while (message.function_call || message.tool_calls) {
146
+ const calls = message.tool_calls || [message.function_call];
147
+
148
+ // Execute all functions in parallel
149
+ const functionResponses = await Promise.all(
150
+ calls.map(async (call) => {
151
+ const funcCall = call.type === 'function' ? call.function : call;
152
+ const name = funcCall.name;
153
+ const args = JSON.parse(funcCall.arguments);
154
+
155
+ let result;
156
+ switch (name) {
157
+ case 'get_weather':
158
+ result = await getWeather(args);
159
+ break;
160
+ case 'search_products':
161
+ result = await searchProducts(args);
162
+ break;
163
+ default:
164
+ result = { error: `Unknown function: ${name}` };
165
+ }
166
+
167
+ return {
168
+ id: call.id,
169
+ role: 'tool',
170
+ name: name,
171
+ content: JSON.stringify(result),
172
+ };
173
+ })
174
+ );
175
+
176
+ messages.push(message);
177
+ messages.push(...functionResponses);
178
+
179
+ response = await openai.chat.completions.create({
180
+ model: 'gpt-4',
181
+ messages,
182
+ functions,
183
+ function_call: 'auto',
184
+ });
185
+
186
+ message = response.choices[0].message;
187
+ }
188
+
189
+ return message.content;
190
+ }
191
+ ```
192
+
193
+ ### 4. Safety & Validation
194
+ Validate function inputs before execution.
195
+
196
+ ```javascript
197
+ import { z } from 'zod';
198
+
199
+ const GetWeatherSchema = z.object({
200
+ location: z.string().min(2),
201
+ unit: z.enum(['celsius', 'fahrenheit']).optional().default('celsius'),
202
+ });
203
+
204
+ async function getWeatherSafe(args) {
205
+ try {
206
+ const validatedArgs = GetWeatherSchema.parse(args);
207
+ return await getWeather(validatedArgs);
208
+ } catch (error) {
209
+ return { error: 'Invalid arguments', details: error.message };
210
+ }
211
+ }
212
+
213
+ // Add authentication and authorization
214
+ async function executeFunction(name, args, userId) {
215
+ // Check if user has permission to use this function
216
+ if (!hasPermission(userId, name)) {
217
+ return { error: 'Permission denied' };
218
+ }
219
+
220
+ // Validate arguments
221
+ // Execute function
222
+ // Log the function call for auditing
223
+ logFunctionCall(userId, name, args);
224
+ }
225
+ ```
226
+
227
+ ## Best Practices
228
+ - **Clear Descriptions**: Write clear, detailed descriptions for functions and parameters
229
+ - **Input Validation**: Always validate function inputs before execution
230
+ - **Error Handling**: Gracefully handle errors and communicate them back to the LLM
231
+ - **Safety**: Implement authentication, authorization, and rate limiting
232
+ - **Idempotency**: Make functions idempotent when possible
233
+ - **Logging**: Log all function calls for debugging and auditing
234
+ - **Context Limit**: Be mindful of context limits and manage conversation history
TRAE-Skills/ai_engineering/LLM_Operations.md ADDED
@@ -0,0 +1,507 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Skill: LLM Operations (LLMOps)
2
+
3
+ ## Purpose
4
+ To operationalize large language models in production environments with proper deployment, scaling, monitoring, and maintenance.
5
+
6
+ ## When to Use
7
+ - When deploying LLMs to production
8
+ - When managing multiple LLM deployments
9
+ - When optimizing LLM performance and costs
10
+ - When implementing LLM version control and rollback
11
+
12
+ ## Procedure
13
+
14
+ ### 1. Model Deployment Strategy
15
+ Implement robust deployment strategies for LLMs.
16
+
17
+ ```python
18
+ from abc import ABC, abstractmethod
19
+ from openai import OpenAI
20
+ import time
21
+ from functools import wraps
22
+ import logging
23
+
24
+ class LLMProvider(ABC):
25
+ """Abstract base class for LLM providers."""
26
+
27
+ @abstractmethod
28
+ def generate(self, prompt, **kwargs):
29
+ pass
30
+
31
+ @abstractmethod
32
+ def health_check(self):
33
+ pass
34
+
35
+ class OpenAIProvider(LLMProvider):
36
+ def __init__(self, api_key, model="gpt-4"):
37
+ self.client = OpenAI(api_key=api_key)
38
+ self.model = model
39
+ self.logger = logging.getLogger(__name__)
40
+
41
+ def generate(self, prompt, temperature=0.7, max_tokens=1000):
42
+ """Generate text using OpenAI API."""
43
+ try:
44
+ start_time = time.time()
45
+
46
+ response = self.client.chat.completions.create(
47
+ model=self.model,
48
+ messages=[{"role": "user", "content": prompt}],
49
+ temperature=temperature,
50
+ max_tokens=max_tokens
51
+ )
52
+
53
+ latency = time.time() - start_time
54
+
55
+ result = {
56
+ 'text': response.choices[0].message.content,
57
+ 'tokens_used': response.usage.total_tokens,
58
+ 'latency': latency,
59
+ 'model': self.model
60
+ }
61
+
62
+ self.logger.info(f"Generated {result['tokens_used']} tokens in {latency:.2f}s")
63
+ return result
64
+
65
+ except Exception as e:
66
+ self.logger.error(f"Generation failed: {str(e)}")
67
+ raise
68
+
69
+ def health_check(self):
70
+ """Check if the API is accessible."""
71
+ try:
72
+ response = self.client.chat.completions.create(
73
+ model=self.model,
74
+ messages=[{"role": "user", "content": "ping"}],
75
+ max_tokens=5
76
+ )
77
+ return {'status': 'healthy', 'model': self.model}
78
+ except Exception as e:
79
+ return {'status': 'unhealthy', 'error': str(e)}
80
+
81
+ class LocalLLMProvider(LLMProvider):
82
+ """Provider for locally hosted LLMs (e.g., using Ollama or vLLM)."""
83
+
84
+ def __init__(self, endpoint, model_name):
85
+ self.endpoint = endpoint
86
+ self.model_name = model_name
87
+ self.logger = logging.getLogger(__name__)
88
+
89
+ def generate(self, prompt, temperature=0.7, max_tokens=1000):
90
+ """Generate text using local LLM."""
91
+ import requests
92
+
93
+ try:
94
+ start_time = time.time()
95
+
96
+ response = requests.post(
97
+ f"{self.endpoint}/generate",
98
+ json={
99
+ "model": self.model_name,
100
+ "prompt": prompt,
101
+ "temperature": temperature,
102
+ "max_tokens": max_tokens
103
+ },
104
+ timeout=30
105
+ )
106
+
107
+ response.raise_for_status()
108
+ data = response.json()
109
+
110
+ latency = time.time() - start_time
111
+
112
+ return {
113
+ 'text': data.get('text', ''),
114
+ 'tokens_used': data.get('tokens_used', 0),
115
+ 'latency': latency,
116
+ 'model': self.model_name
117
+ }
118
+
119
+ except Exception as e:
120
+ self.logger.error(f"Local generation failed: {str(e)}")
121
+ raise
122
+
123
+ def health_check(self):
124
+ """Check if local LLM is running."""
125
+ try:
126
+ import requests
127
+ response = requests.get(f"{self.endpoint}/health", timeout=5)
128
+ response.raise_for_status()
129
+ return {'status': 'healthy', 'model': self.model_name}
130
+ except Exception as e:
131
+ return {'status': 'unhealthy', 'error': str(e)}
132
+
133
+ class LLMOrchestrator:
134
+ """Orchestrate multiple LLM providers with fallback and load balancing."""
135
+
136
+ def __init__(self, providers):
137
+ self.providers = providers
138
+ self.current_provider = 0
139
+ self.logger = logging.getLogger(__name__)
140
+
141
+ def generate(self, prompt, **kwargs):
142
+ """Generate with automatic failover."""
143
+ for attempt in range(len(self.providers)):
144
+ provider = self.providers[self.current_provider]
145
+
146
+ try:
147
+ result = provider.generate(prompt, **kwargs)
148
+ result['provider'] = provider.__class__.__name__
149
+ return result
150
+
151
+ except Exception as e:
152
+ self.logger.warning(f"Provider {provider.__class__.__name__} failed: {str(e)}")
153
+ self.current_provider = (self.current_provider + 1) % len(self.providers)
154
+
155
+ raise Exception("All LLM providers failed")
156
+
157
+ def health_check(self):
158
+ """Health check for all providers."""
159
+ health_status = {}
160
+ for i, provider in enumerate(self.providers):
161
+ health_status[f"provider_{i}"] = provider.health_check()
162
+ return health_status
163
+ ```
164
+
165
+ ### 2. Rate Limiting and Throttling
166
+ Implement rate limiting for API calls.
167
+
168
+ ```python
169
+ import threading
170
+ import time
171
+ from collections import deque
172
+
173
+ class RateLimiter:
174
+ """Token bucket rate limiter."""
175
+
176
+ def __init__(self, rate, burst):
177
+ """
178
+ Args:
179
+ rate: Tokens per second
180
+ burst: Maximum burst size
181
+ """
182
+ self.rate = rate
183
+ self.burst = burst
184
+ self.tokens = burst
185
+ self.last_update = time.time()
186
+ self.lock = threading.Lock()
187
+
188
+ def consume(self, tokens=1):
189
+ """Consume tokens if available."""
190
+ with self.lock:
191
+ now = time.time()
192
+ elapsed = now - self.last_update
193
+
194
+ # Refill tokens based on elapsed time
195
+ self.tokens = min(self.burst, self.tokens + elapsed * self.rate)
196
+ self.last_update = now
197
+
198
+ if self.tokens >= tokens:
199
+ self.tokens -= tokens
200
+ return True
201
+ else:
202
+ return False
203
+
204
+ def wait_for_token(self, tokens=1):
205
+ """Wait until tokens are available."""
206
+ while not self.consume(tokens):
207
+ wait_time = (tokens - self.tokens) / self.rate
208
+ time.sleep(wait_time)
209
+
210
+ class LLMWithRateLimit:
211
+ """LLM wrapper with rate limiting."""
212
+
213
+ def __init__(self, llm_provider, requests_per_second=10):
214
+ self.llm_provider = llm_provider
215
+ self.rate_limiter = RateLimiter(rate=requests_per_second, burst=20)
216
+
217
+ def generate(self, prompt, **kwargs):
218
+ """Generate with rate limiting."""
219
+ self.rate_limiter.wait_for_token()
220
+ return self.llm_provider.generate(prompt, **kwargs)
221
+
222
+ def generate_batch(self, prompts, **kwargs):
223
+ """Generate multiple prompts with rate limiting."""
224
+ results = []
225
+ for prompt in prompts:
226
+ result = self.generate(prompt, **kwargs)
227
+ results.append(result)
228
+ return results
229
+ ```
230
+
231
+ ### 3. Caching and Response Management
232
+ Implement intelligent caching for LLM responses.
233
+
234
+ ```python
235
+ import hashlib
236
+ import json
237
+ from typing import Optional
238
+ import redis
239
+
240
+ class LLMCache:
241
+ """Cache LLM responses."""
242
+
243
+ def __init__(self, redis_client=None, ttl=3600):
244
+ self.redis = redis_client
245
+ self.ttl = ttl
246
+ self.memory_cache = {}
247
+
248
+ def _generate_cache_key(self, prompt, model, **kwargs):
249
+ """Generate cache key from prompt and parameters."""
250
+ params = f"{prompt}:{model}:{json.dumps(kwargs, sort_keys=True)}"
251
+ return hashlib.sha256(params.encode()).hexdigest()
252
+
253
+ def get(self, prompt, model, **kwargs) -> Optional[str]:
254
+ """Get cached response."""
255
+ cache_key = self._generate_cache_key(prompt, model, **kwargs)
256
+
257
+ # Check memory cache first
258
+ if cache_key in self.memory_cache:
259
+ return self.memory_cache[cache_key]
260
+
261
+ # Check Redis
262
+ if self.redis:
263
+ cached = self.redis.get(cache_key)
264
+ if cached:
265
+ self.memory_cache[cache_key] = cached
266
+ return cached
267
+
268
+ return None
269
+
270
+ def set(self, prompt, response, model, **kwargs):
271
+ """Cache response."""
272
+ cache_key = self._generate_cache_key(prompt, model, **kwargs)
273
+
274
+ # Store in memory
275
+ self.memory_cache[cache_key] = response
276
+
277
+ # Store in Redis
278
+ if self.redis:
279
+ self.redis.setex(cache_key, self.ttl, response)
280
+
281
+ class CachedLLM:
282
+ """LLM with caching capability."""
283
+
284
+ def __init__(self, llm_provider, cache=None):
285
+ self.llm_provider = llm_provider
286
+ self.cache = cache or LLMCache()
287
+
288
+ def generate(self, prompt, use_cache=True, **kwargs):
289
+ """Generate with optional caching."""
290
+ model = getattr(self.llm_provider, 'model', 'unknown')
291
+
292
+ if use_cache:
293
+ cached_response = self.cache.get(prompt, model, **kwargs)
294
+ if cached_response:
295
+ return {
296
+ 'text': cached_response,
297
+ 'cached': True,
298
+ 'model': model
299
+ }
300
+
301
+ result = self.llm_provider.generate(prompt, **kwargs)
302
+
303
+ if use_cache:
304
+ self.cache.set(prompt, result['text'], model, **kwargs)
305
+
306
+ result['cached'] = False
307
+ return result
308
+ ```
309
+
310
+ ### 4. Monitoring and Metrics
311
+ Track LLM performance and usage.
312
+
313
+ ```python
314
+ from dataclasses import dataclass
315
+ from typing import List
316
+ import statistics
317
+
318
+ @dataclass
319
+ class LLMCallMetrics:
320
+ """Metrics for individual LLM calls."""
321
+ timestamp: float
322
+ model: str
323
+ tokens_used: int
324
+ latency: float
325
+ success: bool
326
+ error_message: str = ""
327
+
328
+ class LLMMetricsCollector:
329
+ """Collect and analyze LLM metrics."""
330
+
331
+ def __init__(self, max_metrics=10000):
332
+ self.metrics: List[LLMCallMetrics] = []
333
+ self.max_metrics = max_metrics
334
+
335
+ def record_call(self, model, tokens_used, latency, success, error_message=""):
336
+ """Record metrics for an LLM call."""
337
+ metric = LLMCallMetrics(
338
+ timestamp=time.time(),
339
+ model=model,
340
+ tokens_used=tokens_used,
341
+ latency=latency,
342
+ success=success,
343
+ error_message=error_message
344
+ )
345
+
346
+ self.metrics.append(metric)
347
+
348
+ # Keep only recent metrics
349
+ if len(self.metrics) > self.max_metrics:
350
+ self.metrics = self.metrics[-self.max_metrics:]
351
+
352
+ def get_statistics(self, model=None, time_window_seconds=None):
353
+ """Get statistics for LLM calls."""
354
+ filtered_metrics = self.metrics
355
+
356
+ if model:
357
+ filtered_metrics = [m for m in filtered_metrics if m.model == model]
358
+
359
+ if time_window_seconds:
360
+ cutoff = time.time() - time_window_seconds
361
+ filtered_metrics = [m for m in filtered_metrics if m.timestamp > cutoff]
362
+
363
+ if not filtered_metrics:
364
+ return {'error': 'No metrics found'}
365
+
366
+ successful_calls = [m for m in filtered_metrics if m.success]
367
+
368
+ stats = {
369
+ 'total_calls': len(filtered_metrics),
370
+ 'successful_calls': len(successful_calls),
371
+ 'error_rate': (len(filtered_metrics) - len(successful_calls)) / len(filtered_metrics),
372
+ 'avg_tokens': statistics.mean([m.tokens_used for m in successful_calls]) if successful_calls else 0,
373
+ 'avg_latency': statistics.mean([m.latency for m in successful_calls]) if successful_calls else 0,
374
+ 'p50_latency': statistics.median([m.latency for m in successful_calls]) if successful_calls else 0,
375
+ 'p95_latency': statistics.quantiles([m.latency for m in successful_calls], n=20)[18] if len(successful_calls) > 20 else 0,
376
+ 'total_tokens': sum([m.tokens_used for m in successful_calls])
377
+ }
378
+
379
+ return stats
380
+
381
+ class InstrumentedLLM:
382
+ """LLM with automatic metrics collection."""
383
+
384
+ def __init__(self, llm_provider, metrics_collector):
385
+ self.llm_provider = llm_provider
386
+ self.metrics_collector = metrics_collector
387
+
388
+ def generate(self, prompt, **kwargs):
389
+ """Generate with metrics collection."""
390
+ model = getattr(self.llm_provider, 'model', 'unknown')
391
+ start_time = time.time()
392
+
393
+ try:
394
+ result = self.llm_provider.generate(prompt, **kwargs)
395
+ latency = time.time() - start_time
396
+
397
+ self.metrics_collector.record_call(
398
+ model=model,
399
+ tokens_used=result.get('tokens_used', 0),
400
+ latency=latency,
401
+ success=True
402
+ )
403
+
404
+ return result
405
+
406
+ except Exception as e:
407
+ latency = time.time() - start_time
408
+ self.metrics_collector.record_call(
409
+ model=model,
410
+ tokens_used=0,
411
+ latency=latency,
412
+ success=False,
413
+ error_message=str(e)
414
+ )
415
+ raise
416
+ ```
417
+
418
+ ### 5. Deployment Configuration
419
+ Manage deployment configurations.
420
+
421
+ ```python
422
+ from typing import Dict, Any
423
+ import yaml
424
+
425
+ class LLMDeploymentConfig:
426
+ """Configuration for LLM deployment."""
427
+
428
+ def __init__(self, config_dict: Dict[str, Any]):
429
+ self.config = config_dict
430
+
431
+ @classmethod
432
+ def from_file(cls, config_file: str):
433
+ """Load configuration from file."""
434
+ with open(config_file, 'r') as f:
435
+ config_dict = yaml.safe_load(f)
436
+ return cls(config_dict)
437
+
438
+ def get_provider_config(self, provider_name: str):
439
+ """Get configuration for specific provider."""
440
+ return self.config.get('providers', {}).get(provider_name, {})
441
+
442
+ def get_model_config(self, model_name: str):
443
+ """Get configuration for specific model."""
444
+ return self.config.get('models', {}).get(model_name, {})
445
+
446
+ def get_rate_limits(self) -> Dict[str, int]:
447
+ """Get rate limit configuration."""
448
+ return self.config.get('rate_limits', {
449
+ 'requests_per_second': 10,
450
+ 'burst': 20
451
+ })
452
+
453
+ def get_cache_config(self) -> Dict[str, Any]:
454
+ """Get cache configuration."""
455
+ return self.config.get('cache', {
456
+ 'enabled': True,
457
+ 'ttl': 3600,
458
+ 'redis_url': None
459
+ })
460
+
461
+ # Example configuration file
462
+ example_config = {
463
+ 'providers': {
464
+ 'openai': {
465
+ 'api_key': 'your-api-key',
466
+ 'model': 'gpt-4',
467
+ 'temperature': 0.7,
468
+ 'max_tokens': 1000
469
+ },
470
+ 'local': {
471
+ 'endpoint': 'http://localhost:11434',
472
+ 'model': 'llama2',
473
+ 'temperature': 0.7
474
+ }
475
+ },
476
+ 'models': {
477
+ 'gpt-4': {
478
+ 'cost_per_1k_tokens': 0.03,
479
+ 'max_tokens': 8192
480
+ },
481
+ 'gpt-3.5-turbo': {
482
+ 'cost_per_1k_tokens': 0.002,
483
+ 'max_tokens': 4096
484
+ }
485
+ },
486
+ 'rate_limits': {
487
+ 'requests_per_second': 10,
488
+ 'burst': 20
489
+ },
490
+ 'cache': {
491
+ 'enabled': True,
492
+ 'ttl': 3600,
493
+ 'redis_url': 'redis://localhost:6379'
494
+ }
495
+ }
496
+ ```
497
+
498
+ ## Constraints
499
+ - **API Costs**: Monitor and control LLM API costs carefully
500
+ - **Latency**: LLM calls can be slow, implement proper timeouts
501
+ - **Rate Limits**: Respect provider rate limits to avoid being blocked
502
+ - **Error Handling**: Implement robust error handling and retry logic
503
+ - **Monitoring**: Track usage and performance for optimization
504
+ - **Scalability**: Design for horizontal scaling when needed
505
+
506
+ ## Expected Output
507
+ Production-ready LLM deployment with proper rate limiting, caching, monitoring, and multi-provider orchestration for reliable and cost-effective operations.
TRAE-Skills/ai_engineering/LangChain_Basics.md ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Skill: LangChain Basics
2
+
3
+ ## Purpose
4
+ To utilize the LangChain framework to build complex LLM applications by chaining together components (Models, Prompts, Parsers) into composable workflows.
5
+
6
+ ## When to Use
7
+ - When building complex chains (e.g., Retrieval -> Augmentation -> Generation).
8
+ - When you need to swap LLM providers easily (e.g., OpenAI to Anthropic).
9
+ - When integrating structured output parsing.
10
+
11
+ ## Procedure
12
+
13
+ ### 1. Installation
14
+ Install core LangChain packages and the OpenAI integration.
15
+
16
+ ```bash
17
+ npm install @langchain/core @langchain/openai zod
18
+ ```
19
+
20
+ ### 2. Basic Chain Construction (LCEL)
21
+ Use LangChain Expression Language (LCEL) for declarative chain definitions.
22
+
23
+ ```typescript
24
+ import { ChatOpenAI } from "@langchain/openai";
25
+ import { ChatPromptTemplate } from "@langchain/core/prompts";
26
+ import { StringOutputParser } from "@langchain/core/output_parsers";
27
+
28
+ // 1. Initialize Model
29
+ const model = new ChatOpenAI({
30
+ modelName: "gpt-4o",
31
+ temperature: 0,
32
+ apiKey: process.env.OPENAI_API_KEY
33
+ });
34
+
35
+ // 2. Define Prompt
36
+ const prompt = ChatPromptTemplate.fromMessages([
37
+ ["system", "You are a technical documentation expert."],
38
+ ["user", "Explain {topic} in one sentence."]
39
+ ]);
40
+
41
+ // 3. Create Chain
42
+ // Input -> Prompt -> Model -> String Output
43
+ const chain = prompt.pipe(model).pipe(new StringOutputParser());
44
+
45
+ // Usage
46
+ async function runChain() {
47
+ const result = await chain.invoke({ topic: "Dependency Injection" });
48
+ console.log(result);
49
+ }
50
+ ```
51
+
52
+ ### 3. Structured Output Parsing
53
+ Use `StructuredOutputParser` with Zod to guarantee type-safe responses.
54
+
55
+ ```typescript
56
+ import { z } from "zod";
57
+ import { StructuredOutputParser } from "@langchain/core/output_parsers";
58
+
59
+ // Define Schema
60
+ const schema = z.object({
61
+ sentiment: z.enum(["positive", "negative", "neutral"]),
62
+ keywords: z.array(z.string()).describe("List of up to 5 keywords"),
63
+ summary: z.string().describe("Brief summary of the text")
64
+ });
65
+
66
+ const parser = StructuredOutputParser.fromZodSchema(schema);
67
+
68
+ const analysisChain = ChatPromptTemplate.fromTemplate(
69
+ "Analyze the following text.\n{format_instructions}\n\nText: {text}"
70
+ ).pipe(model).pipe(parser);
71
+
72
+ async function analyzeText(text: string) {
73
+ return await analysisChain.invoke({
74
+ text,
75
+ format_instructions: parser.getFormatInstructions()
76
+ });
77
+ }
78
+ ```
79
+
80
+ ### 4. Memory Integration (RunnableWithMessageHistory)
81
+ Manage conversation history for chatbots.
82
+
83
+ ```typescript
84
+ import { RunnableWithMessageHistory } from "@langchain/core/runnables";
85
+ import { InMemoryChatMessageHistory } from "@langchain/core/chat_history";
86
+
87
+ const messageHistory = new InMemoryChatMessageHistory();
88
+
89
+ const chatChain = new RunnableWithMessageHistory({
90
+ runnable: prompt.pipe(model),
91
+ getMessageHistory: async (sessionId) => messageHistory,
92
+ inputMessagesKey: "input",
93
+ historyMessagesKey: "history",
94
+ });
95
+ ```
96
+
97
+ ## Constraints
98
+ - **Abstraction Cost**: LangChain adds a layer of abstraction. For very simple calls, the native SDK might be cleaner.
99
+ - **Debugging**: LCEL chains can be harder to debug than imperative code. Use `LangSmith` for tracing if available.
100
+ - **Version Compatibility**: LangChain evolves fast. Lock versions in `package.json`.
101
+
102
+ ## Expected Output
103
+ A composable pipeline that reliably transforms inputs into structured outputs, leveraging the power of chained LLM operations.
TRAE-Skills/ai_engineering/Local_LLM_Running_Ollama.md ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Skill: Local LLM Running (Ollama)
2
+
3
+ ## Purpose
4
+ To run Large Language Models locally using Ollama, ensuring data privacy, zero API costs, and offline capability while providing a standard REST API for applications.
5
+
6
+ ## When to Use
7
+ - When data privacy is paramount (medical, legal, personal data).
8
+ - For development and testing without incurring API costs.
9
+ - When you need to experiment with open-source models (Llama 3, Mistral, etc.).
10
+
11
+ ## Procedure
12
+
13
+ ### 1. Installation & Model Setup
14
+ Install Ollama and pull the desired model.
15
+
16
+ ```bash
17
+ # Install (macOS/Linux)
18
+ curl -fsSL https://ollama.com/install.sh | sh
19
+
20
+ # Pull a model
21
+ ollama pull llama3:8b
22
+ ```
23
+
24
+ ### 2. Basic Usage (CLI)
25
+ Interact with the model directly in your terminal.
26
+
27
+ ```bash
28
+ ollama run llama3:8b "Why is the sky blue?"
29
+ ```
30
+
31
+ ### 3. Programmatic Integration (Node.js)
32
+ Use the Ollama REST API or official library to integrate into your app.
33
+
34
+ ```bash
35
+ npm install ollama
36
+ ```
37
+
38
+ ```typescript
39
+ import ollama from 'ollama';
40
+
41
+ async function chat() {
42
+ const response = await ollama.chat({
43
+ model: 'llama3:8b',
44
+ messages: [{ role: 'user', content: 'Explain quantum physics to a 5-year old' }],
45
+ stream: true,
46
+ });
47
+
48
+ for await (const part of response) {
49
+ process.stdout.write(part.message.content);
50
+ }
51
+ }
52
+ ```
53
+
54
+ ### 4. Customizing Models (Modelfile)
55
+ Create a specialized version of a model with custom system prompts.
56
+
57
+ 1. Create a file named `Modelfile`:
58
+ ```dockerfile
59
+ FROM llama3:8b
60
+
61
+ # Set parameters
62
+ PARAMETER temperature 0.1
63
+ PARAMETER top_p 0.9
64
+
65
+ # Set system message
66
+ SYSTEM """
67
+ You are a senior TypeScript developer.
68
+ You provide concise, high-performance code snippets.
69
+ Always use ESM syntax.
70
+ """
71
+ ```
72
+
73
+ 2. Create the model:
74
+ ```bash
75
+ ollama create ts-expert -f Modelfile
76
+ ```
77
+
78
+ ### 5. Running as a Service (Docker)
79
+ Run Ollama in a container for consistent deployment.
80
+
81
+ ```bash
82
+ docker run -d -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama
83
+ ```
84
+
85
+ ## Constraints
86
+ - **VRAM Requirements**:
87
+ - 7B/8B models: ~8GB RAM/VRAM.
88
+ - 13B models: ~16GB RAM/VRAM.
89
+ - 70B models: ~48GB+ RAM/VRAM.
90
+ - **Latency**: Local models are significantly slower than GPT-4o unless running on a high-end GPU (RTX 3090/4090 or Apple M2/M3 Max).
91
+ - **Quantization**: Most Ollama models are 4-bit quantized (Q4_K_M) by default, which slightly reduces reasoning capability but saves memory.
92
+
93
+ ## Expected Output
94
+ A locally running LLM service accessible via a REST API on `localhost:11434`.
TRAE-Skills/ai_engineering/ML_Model_Quantization.md ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Skill: ML Model Quantization
2
+
3
+ ## Purpose
4
+ To reduce the memory footprint and improve inference speed of Machine Learning models, particularly deep neural networks, by converting high-precision weights (e.g., FP32) to lower-precision representations (e.g., INT8) with minimal loss of accuracy.
5
+
6
+ ## When to Use
7
+ - When deploying models to edge devices (mobile, IoT) with limited memory or compute
8
+ - When optimizing inference costs on cloud infrastructure
9
+ - When striving for real-time performance in computer vision or NLP tasks
10
+ - When the model size exceeds deployment constraints
11
+
12
+ ## Procedure
13
+
14
+ ### 1. Identify Quantization Strategy
15
+ Choose the appropriate quantization method based on your deployment needs:
16
+ - **Post-Training Quantization (PTQ)**: Applied after training. Easiest to implement. Good for general use cases.
17
+ - **Quantization-Aware Training (QAT)**: Simulates quantization during training. Results in higher accuracy, but requires retraining.
18
+
19
+ ### 2. Post-Training Quantization (PyTorch Example)
20
+
21
+ **Dynamic Quantization** (Best for LSTM/RNN or Transformer models):
22
+ ```python
23
+ import torch
24
+
25
+ # 1. Load your pre-trained model
26
+ model = MyTransformerModel()
27
+ model.load_state_dict(torch.load('model_fp32.pth'))
28
+ model.eval()
29
+
30
+ # 2. Apply dynamic quantization to specific layers (e.g., Linear layers)
31
+ quantized_model = torch.quantization.quantize_dynamic(
32
+ model, {torch.nn.Linear}, dtype=torch.qint8
33
+ )
34
+
35
+ # 3. Save the quantized model
36
+ torch.save(quantized_model.state_dict(), 'model_int8.pth')
37
+ ```
38
+
39
+ **Static Quantization** (Best for CNNs):
40
+ Requires a representative dataset to calibrate the activations.
41
+ ```python
42
+ import torch
43
+
44
+ # 1. Prepare model for static quantization
45
+ model.eval()
46
+ model.qconfig = torch.quantization.get_default_qconfig('fbgemm')
47
+ torch.quantization.prepare(model, inplace=True)
48
+
49
+ # 2. Calibrate with representative data
50
+ for data, _ in representative_dataloader:
51
+ model(data)
52
+
53
+ # 3. Convert to quantized model
54
+ torch.quantization.convert(model, inplace=True)
55
+ ```
56
+
57
+ ### 3. Quantization-Aware Training (QAT)
58
+ If PTQ causes an unacceptable drop in accuracy, use QAT.
59
+
60
+ ```python
61
+ import torch
62
+
63
+ # 1. Prepare model for QAT
64
+ model.train()
65
+ model.qconfig = torch.quantization.get_default_qat_qconfig('fbgemm')
66
+ torch.quantization.prepare_qat(model, inplace=True)
67
+
68
+ # 2. Fine-tune the model
69
+ for epoch in range(num_epochs):
70
+ for data, target in train_dataloader:
71
+ optimizer.zero_grad()
72
+ output = model(data)
73
+ loss = criterion(output, target)
74
+ loss.backward()
75
+ optimizer.step()
76
+
77
+ # 3. Convert to quantized model for inference
78
+ model.eval()
79
+ torch.quantization.convert(model, inplace=True)
80
+ ```
81
+
82
+ ## Best Practices
83
+ - Always benchmark accuracy before and after quantization.
84
+ - For LLMs, consider specialized quantization libraries like `bitsandbytes` (4-bit/8-bit) or formats like GGUF/AWQ.
85
+ - Use the appropriate backend (e.g., `fbgemm` for x86, `qnnpack` for ARM).
TRAE-Skills/ai_engineering/MultiModal_AI.md ADDED
@@ -0,0 +1,333 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Skill: Multi-Modal AI
2
+
3
+ ## Purpose
4
+ To work with AI models that can process and generate multiple types of content including text, images, audio, and video in a unified framework.
5
+
6
+ ## When to Use
7
+ - When building applications that process images and text together
8
+ - When implementing vision-language tasks
9
+ - When generating images from text descriptions
10
+ - When analyzing visual content with natural language queries
11
+
12
+ ## Procedure
13
+
14
+ ### 1. Vision-Language Understanding
15
+ Process images with text queries using GPT-4 Vision.
16
+
17
+ ```python
18
+ from openai import OpenAI
19
+ import base64
20
+
21
+ client = OpenAI()
22
+
23
+ def encode_image(image_path):
24
+ """Encode image to base64."""
25
+ with open(image_path, "rb") as image_file:
26
+ return base64.b64encode(image_file.read()).decode('utf-8')
27
+
28
+ def analyze_image(image_path, question):
29
+ """Analyze image with text query."""
30
+ base64_image = encode_image(image_path)
31
+
32
+ response = client.chat.completions.create(
33
+ model="gpt-4-vision-preview",
34
+ messages=[
35
+ {
36
+ "role": "user",
37
+ "content": [
38
+ {"type": "text", "text": question},
39
+ {
40
+ "type": "image_url",
41
+ "image_url": {
42
+ "url": f"data:image/jpeg;base64,{base64_image}"
43
+ }
44
+ }
45
+ ]
46
+ }
47
+ ],
48
+ max_tokens=500
49
+ )
50
+
51
+ return response.choices[0].message.content
52
+
53
+ # Example
54
+ analysis = analyze_image(
55
+ "product.jpg",
56
+ "What products are shown in this image? What are their key features?"
57
+ )
58
+ print(analysis)
59
+ ```
60
+
61
+ ### 2. Image Generation with DALL-E
62
+ Generate images from text descriptions.
63
+
64
+ ```python
65
+ def generate_image(prompt, size="1024x1024", quality="standard"):
66
+ """Generate image from text prompt."""
67
+ response = client.images.generate(
68
+ model="dall-e-3",
69
+ prompt=prompt,
70
+ size=size,
71
+ quality=quality,
72
+ n=1
73
+ )
74
+
75
+ image_url = response.data[0].url
76
+ revised_prompt = response.data[0].revised_prompt
77
+
78
+ return {
79
+ "url": image_url,
80
+ "revised_prompt": revised_prompt
81
+ }
82
+
83
+ # Example
84
+ result = generate_image(
85
+ "A futuristic smart home with voice-controlled devices and automated lighting",
86
+ size="1024x1024"
87
+ )
88
+ print(f"Image URL: {result['url']}")
89
+ ```
90
+
91
+ ### 3. Image Editing and Variations
92
+ Modify and create variations of existing images.
93
+
94
+ ```python
95
+ from PIL import Image
96
+ import io
97
+
98
+ def edit_image(original_image_path, mask_path, prompt):
99
+ """Edit image with mask and prompt."""
100
+ with open(original_image_path, "rb") as img_file:
101
+ original_image = img_file.read()
102
+
103
+ with open(mask_path, "rb") as mask_file:
104
+ mask_image = mask_file.read()
105
+
106
+ response = client.images.edit(
107
+ model="dall-e-2",
108
+ image=original_image,
109
+ mask=mask_image,
110
+ prompt=prompt,
111
+ n=1,
112
+ size="512x512"
113
+ )
114
+
115
+ return response.data[0].url
116
+
117
+ def create_variations(image_path):
118
+ """Create variations of an image."""
119
+ with open(image_path, "rb") as img_file:
120
+ image_data = img_file.read()
121
+
122
+ response = client.images.create_variation(
123
+ image=image_data,
124
+ n=3,
125
+ size="1024x1024"
126
+ )
127
+
128
+ return [img.url for img in response.data]
129
+
130
+ # Example
131
+ edited_url = edit_image(
132
+ "room.jpg",
133
+ "room_mask.png",
134
+ "Add a modern desk with computer setup"
135
+ )
136
+ print(f"Edited image: {edited_url}")
137
+ ```
138
+
139
+ ### 4. Multi-Modal Document Processing
140
+ Process documents with text and images.
141
+
142
+ ```python
143
+ import pdf2image
144
+ import pytesseract
145
+
146
+ def process_multimodal_document(pdf_path):
147
+ """Extract and analyze content from PDF with images."""
148
+ # Convert PDF to images
149
+ images = pdf2image.convert_from_path(pdf_path)
150
+
151
+ results = []
152
+
153
+ for i, image in enumerate(images):
154
+ # Extract text using OCR
155
+ text = pytesseract.image_to_string(image)
156
+
157
+ # Encode image for GPT-4 Vision analysis
158
+ import io
159
+ import base64
160
+
161
+ img_byte_arr = io.BytesIO()
162
+ image.save(img_byte_arr, format='PNG')
163
+ img_byte_arr = img_byte_arr.getvalue()
164
+ base64_image = base64.b64encode(img_byte_arr).decode('utf-8')
165
+
166
+ # Analyze image content
167
+ vision_response = client.chat.completions.create(
168
+ model="gpt-4-vision-preview",
169
+ messages=[
170
+ {
171
+ "role": "user",
172
+ "content": [
173
+ {"type": "text", "text": "Analyze this document page. What type of content is shown?"},
174
+ {
175
+ "type": "image_url",
176
+ "image_url": {"url": f"data:image/png;base64,{base64_image}"}
177
+ }
178
+ ]
179
+ }
180
+ ]
181
+ )
182
+
183
+ results.append({
184
+ "page": i + 1,
185
+ "ocr_text": text,
186
+ "visual_analysis": vision_response.choices[0].message.content
187
+ })
188
+
189
+ return results
190
+
191
+ # Example
192
+ document_results = process_multimodal_document("contract.pdf")
193
+ for page in document_results:
194
+ print(f"Page {page['page']}: {page['visual_analysis']}")
195
+ ```
196
+
197
+ ### 5. Audio and Text Integration
198
+ Process audio with text analysis.
199
+
200
+ ```python
201
+ import requests
202
+
203
+ def transcribe_and_analyze(audio_path):
204
+ """Transcribe audio and analyze with text."""
205
+ # Transcribe audio using Whisper
206
+ with open(audio_path, "rb") as audio_file:
207
+ transcription_response = client.audio.transcriptions.create(
208
+ model="whisper-1",
209
+ file=audio_file,
210
+ response_format="text"
211
+ )
212
+
213
+ transcript = transcription_response
214
+
215
+ # Analyze transcript with GPT-4
216
+ analysis = client.chat.completions.create(
217
+ model="gpt-4",
218
+ messages=[{
219
+ "role": "user",
220
+ "content": f"Analyze this transcript for key topics, sentiment, and action items:\n\n{transcript}"
221
+ }]
222
+ )
223
+
224
+ return {
225
+ "transcript": transcript,
226
+ "analysis": analysis.choices[0].message.content
227
+ }
228
+
229
+ # Example
230
+ result = transcribe_and_analyze("meeting_recording.mp3")
231
+ print(f"Transcript: {result['transcript']}")
232
+ print(f"Analysis: {result['analysis']}")
233
+ ```
234
+
235
+ ### 6. Multi-Modal RAG System
236
+ Build RAG with image and text retrieval.
237
+
238
+ ```python
239
+ from sentence_transformers import SentenceTransformer
240
+ import faiss
241
+ import numpy as np
242
+
243
+ class MultiModalRAG:
244
+ def __init__(self):
245
+ self.text_model = SentenceTransformer('all-MiniLM-L6-v2')
246
+ self.image_model = SentenceTransformer('clip-ViT-B-32')
247
+ self.text_index = None
248
+ self.image_index = None
249
+ self.text_docs = []
250
+ self.image_docs = []
251
+
252
+ def add_text_documents(self, documents):
253
+ """Add text documents to the index."""
254
+ embeddings = self.text_model.encode(documents)
255
+
256
+ if self.text_index is None:
257
+ dimension = embeddings.shape[1]
258
+ self.text_index = faiss.IndexFlatL2(dimension)
259
+
260
+ self.text_index.add(embeddings.astype('float32'))
261
+ self.text_docs.extend(documents)
262
+
263
+ def add_image_documents(self, image_paths, descriptions):
264
+ """Add images to the index."""
265
+ embeddings = self.image_model.encode(image_paths)
266
+
267
+ if self.image_index is None:
268
+ dimension = embeddings.shape[1]
269
+ self.image_index = faiss.IndexFlatL2(dimension)
270
+
271
+ self.image_index.add(embeddings.astype('float32'))
272
+ self.image_docs.extend(zip(image_paths, descriptions))
273
+
274
+ def search(self, query, k=3):
275
+ """Search across text and images."""
276
+ # Search text
277
+ if self.text_index:
278
+ query_embedding = self.text_model.encode([query])
279
+ text_distances, text_indices = self.text_index.search(
280
+ query_embedding.astype('float32'), k
281
+ )
282
+ text_results = [
283
+ (self.text_docs[i], text_distances[0][j])
284
+ for j, i in enumerate(text_indices[0])
285
+ ]
286
+ else:
287
+ text_results = []
288
+
289
+ # Search images
290
+ if self.image_index:
291
+ query_embedding = self.image_model.encode([query])
292
+ image_distances, image_indices = self.image_index.search(
293
+ query_embedding.astype('float32'), k
294
+ )
295
+ image_results = [
296
+ (self.image_docs[i], image_distances[0][j])
297
+ for j, i in enumerate(image_indices[0])
298
+ ]
299
+ else:
300
+ image_results = []
301
+
302
+ return {
303
+ "text_results": text_results,
304
+ "image_results": image_results
305
+ }
306
+
307
+ # Example usage
308
+ rag = MultiModalRAG()
309
+
310
+ rag.add_text_documents([
311
+ "Python is a high-level programming language",
312
+ "JavaScript is used for web development"
313
+ ])
314
+
315
+ rag.add_image_documents(
316
+ ["python_logo.png", "js_logo.png"],
317
+ ["Python programming language logo", "JavaScript logo"]
318
+ )
319
+
320
+ results = rag.search("programming languages")
321
+ print(results)
322
+ ```
323
+
324
+ ## Constraints
325
+ - **Image Size**: Vision models have limits on image dimensions and file sizes
326
+ - **Cost**: Vision and image generation APIs are more expensive than text-only
327
+ - **Quality**: Generated images may not always match expectations
328
+ - **Processing Time**: Image processing is slower than text-only operations
329
+ - **Accuracy**: OCR accuracy varies based on image quality
330
+ - **Privacy**: Be careful with sensitive visual content
331
+
332
+ ## Expected Output
333
+ Comprehensive multi-modal AI applications that can seamlessly process and generate text, images, and audio content with high accuracy and integration.
TRAE-Skills/ai_engineering/Natural_Language_to_SQL.md ADDED
@@ -0,0 +1,152 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Skill: Natural Language to SQL (NL2SQL)
2
+
3
+ ## Purpose
4
+ To build systems that convert natural language questions into executable SQL queries, enabling non-technical users to interact with databases.
5
+
6
+ ## When to Use
7
+ - When building analytics dashboards for business users
8
+ - For customer support tools that query databases directly
9
+ - When implementing internal tools for non-technical teams
10
+ - For data exploration applications
11
+ - When building chatbots that need database access
12
+
13
+ ## Procedure
14
+
15
+ ### 1. Simple NL2SQL with OpenAI
16
+ Use LLMs to generate SQL from natural language.
17
+
18
+ ```python
19
+ import openai
20
+ import sqlite3
21
+
22
+ client = openai.OpenAI(api_key="your-api-key")
23
+
24
+ def nl_to_sql(question, table_schema):
25
+ prompt = f"""Given the following table schema:
26
+ {table_schema}
27
+
28
+ Generate a SQLite SQL query to answer this question: {question}
29
+
30
+ Only return the SQL query, no explanation.
31
+ """
32
+
33
+ response = client.chat.completions.create(
34
+ model="gpt-4",
35
+ messages=[{"role": "user", "content": prompt}]
36
+ )
37
+
38
+ return response.choices[0].message.content.strip()
39
+
40
+ # Example usage
41
+ table_schema = """
42
+ Table: users
43
+ - id: INTEGER
44
+ - name: TEXT
45
+ - email: TEXT
46
+ - created_at: DATE
47
+ - status: TEXT (active, inactive)
48
+
49
+ Table: orders
50
+ - id: INTEGER
51
+ - user_id: INTEGER
52
+ - total_amount: DECIMAL
53
+ - order_date: DATE
54
+ - status: TEXT (pending, completed, cancelled)
55
+ """
56
+
57
+ question = "Show me all active users who placed orders over $100 in 2024"
58
+ sql_query = nl_to_sql(question, table_schema)
59
+ print(sql_query)
60
+ ```
61
+
62
+ ### 2. Execute Query Safely
63
+ Execute the generated SQL with safety checks.
64
+
65
+ ```python
66
+ def execute_safe_query(db_path, sql):
67
+ # Safety checks
68
+ dangerous_keywords = ['DROP', 'DELETE', 'TRUNCATE', 'ALTER', 'INSERT', 'UPDATE', 'CREATE']
69
+ for keyword in dangerous_keywords:
70
+ if keyword.upper() in sql.upper():
71
+ raise Exception(f"Query contains forbidden operation: {keyword}")
72
+
73
+ conn = sqlite3.connect(db_path)
74
+ cursor = conn.cursor()
75
+ cursor.execute(sql)
76
+ results = cursor.fetchall()
77
+ columns = [description[0] for description in cursor.description]
78
+ conn.close()
79
+
80
+ return {"columns": columns, "results": results}
81
+
82
+ # Usage
83
+ try:
84
+ result = execute_safe_query("mydb.sqlite", sql_query)
85
+ print("Columns:", result["columns"])
86
+ print("Results:", result["results"])
87
+ except Exception as e:
88
+ print("Error:", e)
89
+ ```
90
+
91
+ ### 3. Few-Shot Learning Examples
92
+ Improve accuracy with few-shot examples.
93
+
94
+ ```python
95
+ few_shot_examples = """
96
+ Example 1:
97
+ Question: How many users are there?
98
+ SQL: SELECT COUNT(*) FROM users;
99
+
100
+ Example 2:
101
+ Question: Show users who signed up in 2024
102
+ SQL: SELECT * FROM users WHERE created_at >= '2024-01-01';
103
+
104
+ Example 3:
105
+ Question: What's the total revenue from completed orders?
106
+ SQL: SELECT SUM(total_amount) FROM orders WHERE status = 'completed';
107
+ """
108
+
109
+ def nl_to_sql_with_examples(question, table_schema):
110
+ prompt = f"""Given the following table schema:
111
+ {table_schema}
112
+
113
+ Examples:
114
+ {few_shot_examples}
115
+
116
+ Generate a SQLite SQL query to answer this question: {question}
117
+ Only return the SQL query.
118
+ """
119
+
120
+ response = client.chat.completions.create(
121
+ model="gpt-4",
122
+ messages=[{"role": "user", "content": prompt}]
123
+ )
124
+
125
+ return response.choices[0].message.content.strip()
126
+ ```
127
+
128
+ ### 4. Using LangChain for NL2SQL
129
+ Use LangChain's SQL database chain.
130
+
131
+ ```python
132
+ from langchain_openai import ChatOpenAI
133
+ from langchain_community.utilities import SQLDatabase
134
+ from langchain.chains import create_sql_query_chain
135
+
136
+ db = SQLDatabase.from_uri("sqlite:///mydb.sqlite")
137
+ llm = ChatOpenAI(model="gpt-4", temperature=0)
138
+ chain = create_sql_query_chain(llm, db)
139
+
140
+ question = "Show me the top 5 users by total order amount"
141
+ response = chain.invoke({"question": question})
142
+ print(response)
143
+ ```
144
+
145
+ ## Best Practices
146
+ - **Whitelist Operations**: Only allow SELECT queries in production
147
+ - **Schema Context**: Always provide clear table schema information
148
+ - **Validation**: Validate generated queries before execution
149
+ - **Few-Shot Learning**: Use examples to improve accuracy
150
+ - **Error Handling**: Gracefully handle query generation failures
151
+ - **Sanitize Inputs**: Prevent SQL injection even from generated queries
152
+ - **Log Everything**: Log questions, queries, and results for debugging
TRAE-Skills/ai_engineering/OpenAI_API_Integration.md ADDED
@@ -0,0 +1,142 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Skill: OpenAI API Integration
2
+
3
+ ## Purpose
4
+ To correctly integrate OpenAI's models (GPT-4o, GPT-3.5) into Node.js/TypeScript applications, handling authentication, type-safety, streaming, and robust error management.
5
+
6
+ ## When to Use
7
+ - When building applications that rely on OpenAI's completion or chat API.
8
+ - When you need a production-ready wrapper around the official SDK.
9
+
10
+ ## Procedure
11
+
12
+ ### 1. Installation & Setup
13
+ Install the official library and type definitions.
14
+
15
+ ```bash
16
+ npm install openai zod
17
+ ```
18
+
19
+ ### 2. Robust Client Implementation
20
+ Create a service class that handles initialization and configuration.
21
+
22
+ ```typescript
23
+ // lib/openai-client.ts
24
+ import OpenAI from 'openai';
25
+
26
+ export class OpenAIClient {
27
+ private client: OpenAI;
28
+
29
+ constructor() {
30
+ if (!process.env.OPENAI_API_KEY) {
31
+ throw new Error("Missing OPENAI_API_KEY environment variable");
32
+ }
33
+ this.client = new OpenAI({
34
+ apiKey: process.env.OPENAI_API_KEY,
35
+ maxRetries: 3, // Built-in retry logic
36
+ timeout: 30000, // 30s timeout
37
+ });
38
+ }
39
+
40
+ public getClient() {
41
+ return this.client;
42
+ }
43
+ }
44
+ ```
45
+
46
+ ### 3. Chat Completion with Error Handling
47
+ Implement a method for standard chat completions with try/catch blocks for specific API errors.
48
+
49
+ ```typescript
50
+ // lib/ai-service.ts
51
+ import { OpenAIClient } from './openai-client';
52
+ import OpenAI from 'openai';
53
+
54
+ export class AIService {
55
+ private openai: OpenAI;
56
+
57
+ constructor() {
58
+ this.openai = new OpenAIClient().getClient();
59
+ }
60
+
61
+ async generateResponse(systemPrompt: string, userMessage: string): Promise<string> {
62
+ try {
63
+ const response = await this.openai.chat.completions.create({
64
+ model: "gpt-4o",
65
+ messages: [
66
+ { role: "system", content: systemPrompt },
67
+ { role: "user", content: userMessage },
68
+ ],
69
+ temperature: 0.7,
70
+ });
71
+
72
+ return response.choices[0]?.message?.content || "";
73
+ } catch (error) {
74
+ if (error instanceof OpenAI.APIError) {
75
+ console.error(`OpenAI Error: ${error.status} - ${error.code}`);
76
+ // Handle specific codes: 429 (Rate Limit), 400 (Bad Request), 401 (Auth)
77
+ if (error.status === 429) {
78
+ throw new Error("Rate limit exceeded. Please try again later.");
79
+ }
80
+ }
81
+ throw new Error("Failed to generate AI response");
82
+ }
83
+ }
84
+ }
85
+ ```
86
+
87
+ ### 4. Streaming Response Implementation
88
+ Handle real-time output for better UX.
89
+
90
+ ```typescript
91
+ // lib/stream-service.ts
92
+ import { OpenAIClient } from './openai-client';
93
+
94
+ export async function* streamCompletion(prompt: string) {
95
+ const openai = new OpenAIClient().getClient();
96
+
97
+ const stream = await openai.chat.completions.create({
98
+ model: "gpt-4o",
99
+ messages: [{ role: "user", content: prompt }],
100
+ stream: true,
101
+ });
102
+
103
+ for await (const chunk of stream) {
104
+ const content = chunk.choices[0]?.delta?.content || "";
105
+ if (content) {
106
+ yield content;
107
+ }
108
+ }
109
+ }
110
+
111
+ // Usage:
112
+ // for await (const token of streamCompletion("Hello")) {
113
+ // process.stdout.write(token);
114
+ // }
115
+ ```
116
+
117
+ ### 5. Structured Outputs (JSON)
118
+ Enforce JSON output for programmatic use.
119
+
120
+ ```typescript
121
+ async function extractData(text: string) {
122
+ const openai = new OpenAIClient().getClient();
123
+ const response = await openai.chat.completions.create({
124
+ model: "gpt-4o",
125
+ messages: [
126
+ { role: "system", content: "You are a data extractor. Output valid JSON." },
127
+ { role: "user", content: `Extract names from: ${text}` }
128
+ ],
129
+ response_format: { type: "json_object" },
130
+ });
131
+
132
+ return JSON.parse(response.choices[0].message.content!);
133
+ }
134
+ ```
135
+
136
+ ## Constraints
137
+ - **Costs**: GPT-4 is expensive. Cache responses where possible (e.g., using Redis) for identical inputs.
138
+ - **Security**: Never expose the API key on the client-side (browser). Always proxy requests through your backend.
139
+ - **Timeouts**: LLM requests can be slow. Ensure your HTTP server (e.g., Nginx, Vercel) has appropriate timeout settings (often > 10s).
140
+
141
+ ## Expected Output
142
+ A secure, reusable service module that reliably communicates with OpenAI, handles rate limits, and provides both streaming and blocking interfaces.
TRAE-Skills/ai_engineering/Prompt_Engineering_Basics.md ADDED
@@ -0,0 +1,130 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Skill: Prompt Engineering Basics
2
+
3
+ ## Purpose
4
+ To apply systematic techniques for crafting inputs (prompts) to Large Language Models (LLMs) to ensure accurate, consistent, and high-quality outputs. This skill focuses on structured prompt management and engineering patterns.
5
+
6
+ ## When to Use
7
+ - When interacting with LLMs for any task (generation, summarization, extraction).
8
+ - When model outputs are inconsistent, hallucinatory, or vague.
9
+ - When you need to standardize input/output formats for an application.
10
+
11
+ ## Procedure
12
+
13
+ ### 1. Structured Prompt Management (TypeScript)
14
+ Avoid hardcoding strings. Use a template system.
15
+
16
+ ```typescript
17
+ // prompt-manager.ts
18
+ type PromptVariables = Record<string, string>;
19
+
20
+ interface PromptTemplate {
21
+ system: (vars: PromptVariables) => string;
22
+ user: (vars: PromptVariables) => string;
23
+ }
24
+
25
+ export const summarizationPrompt: PromptTemplate = {
26
+ system: ({ context }) =>
27
+ `You are an expert technical writer. Your task is to summarize the following context into a concise executive summary.
28
+
29
+ Context: ${context}
30
+
31
+ Constraints:
32
+ - Use bullet points.
33
+ - Max 200 words.
34
+ - Maintain a professional tone.`,
35
+
36
+ user: ({ text }) => `Text to summarize:\n${text}`
37
+ };
38
+ ```
39
+
40
+ ### 2. The CO-STAR Framework Implementation
41
+ Implement the CO-STAR framework programmatically to ensure all context is provided.
42
+
43
+ ```typescript
44
+ // co-star-prompt.ts
45
+ interface CoStarParams {
46
+ context: string;
47
+ objective: string;
48
+ style: string;
49
+ tone: string;
50
+ audience: string;
51
+ responseFormat: string;
52
+ }
53
+
54
+ export const buildCoStarSystemMessage = (params: CoStarParams): string => {
55
+ return `
56
+ # CONTEXT
57
+ ${params.context}
58
+
59
+ # OBJECTIVE
60
+ ${params.objective}
61
+
62
+ # STYLE
63
+ ${params.style}
64
+
65
+ # TONE
66
+ ${params.tone}
67
+
68
+ # AUDIENCE
69
+ ${params.audience}
70
+
71
+ # RESPONSE FORMAT
72
+ ${params.responseFormat}
73
+ `;
74
+ };
75
+ ```
76
+
77
+ ### 3. Chain-of-Thought (CoT) & Few-Shot Prompting
78
+ Enhance reasoning by forcing step-by-step logic or providing examples.
79
+
80
+ ```typescript
81
+ // reasoning-prompt.ts
82
+ const fewShotExamples = `
83
+ Input: "The server is down."
84
+ Classification: Critical
85
+ Reasoning: Impact on availability is immediate.
86
+
87
+ Input: "The button color is slightly off."
88
+ Classification: Low
89
+ Reasoning: Purely cosmetic issue.
90
+ `;
91
+
92
+ export const classificationPrompt = (input: string) => `
93
+ Classify the severity of the following issue (Critical, High, Medium, Low).
94
+ First, explain your reasoning step-by-step, then provide the final classification.
95
+
96
+ Examples:
97
+ ${fewShotExamples}
98
+
99
+ Input: "${input}"
100
+ Output:
101
+ `;
102
+ ```
103
+
104
+ ### 4. Handling Output Formats (JSON Mode)
105
+ Always enforce structure when programmatic consumption is needed.
106
+
107
+ ```typescript
108
+ // Ensure your API call sets { response_format: { type: "json_object" } }
109
+ export const jsonExtractionPrompt = (text: string) => `
110
+ Extract the key entities from the text below.
111
+ You must respond with valid JSON only.
112
+
113
+ Schema:
114
+ {
115
+ "names": string[],
116
+ "dates": string[],
117
+ "sentiment": "positive" | "negative" | "neutral"
118
+ }
119
+
120
+ Text: "${text}"
121
+ `;
122
+ ```
123
+
124
+ ## Constraints
125
+ - **Context Window**: Monitor token count. Truncate inputs if they exceed limits (e.g., using `tiktoken`).
126
+ - **Injection Attacks**: Treat user input as untrusted. Delimit user input (e.g., with `"""` or `###`) to prevent prompt injection.
127
+ - **Determinism**: Set `temperature: 0` for classification/extraction tasks; higher for creative tasks.
128
+
129
+ ## Expected Output
130
+ A set of typed, reusable prompt templates that produce consistent, parsed outputs from the LLM.
TRAE-Skills/ai_engineering/RAG_System_Architecture.md ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Skill: RAG System Architecture
2
+
3
+ ## Purpose
4
+ To design and implement a Retrieval-Augmented Generation (RAG) system that grounds LLM responses in specific, external data sources, reducing hallucinations and enabling knowledge on private data.
5
+
6
+ ## When to Use
7
+ - When the LLM needs to answer questions about proprietary documents (PDFs, internal wikis).
8
+ - When the knowledge base is too large to fit in the context window.
9
+ - When data changes frequently and retraining is not feasible.
10
+
11
+ ## Procedure
12
+
13
+ ### 1. Ingestion & Embedding (The ETL Pipeline)
14
+ Process documents into vectors.
15
+
16
+ ```typescript
17
+ import { RecursiveCharacterTextSplitter } from "langchain/text_splitter";
18
+ import { OpenAIEmbeddings } from "@langchain/openai";
19
+ import { MemoryVectorStore } from "langchain/vectorstores/memory";
20
+
21
+ // 1. Text Splitting
22
+ const splitter = new RecursiveCharacterTextSplitter({
23
+ chunkSize: 1000,
24
+ chunkOverlap: 200, // Crucial for context continuity
25
+ });
26
+
27
+ // 2. Embedding Model
28
+ const embeddings = new OpenAIEmbeddings({
29
+ modelName: "text-embedding-3-small", // Efficient & cheap
30
+ });
31
+
32
+ // 3. Vector Store Initialization
33
+ // In production, use Pinecone, Weaviate, or pgvector
34
+ const vectorStore = new MemoryVectorStore(embeddings);
35
+
36
+ export async function ingestDocument(text: string) {
37
+ const docs = await splitter.createDocuments([text]);
38
+ await vectorStore.addDocuments(docs);
39
+ return vectorStore;
40
+ }
41
+ ```
42
+
43
+ ### 2. Retrieval Implementation
44
+ Create a retriever that fetches relevant context.
45
+
46
+ ```typescript
47
+ // Create a retriever from the store
48
+ const retriever = vectorStore.asRetriever({
49
+ k: 3, // Top 3 results
50
+ searchType: "similarity", // or "mmr" for diversity
51
+ });
52
+ ```
53
+
54
+ ### 3. The RAG Chain (Generation)
55
+ Combine retrieval with generation.
56
+
57
+ ```typescript
58
+ import { ChatOpenAI } from "@langchain/openai";
59
+ import { ChatPromptTemplate } from "@langchain/core/prompts";
60
+ import { createStuffDocumentsChain } from "langchain/chains/combine_documents";
61
+ import { createRetrievalChain } from "langchain/chains/retrieval";
62
+
63
+ const model = new ChatOpenAI({ modelName: "gpt-4o" });
64
+
65
+ const prompt = ChatPromptTemplate.fromTemplate(`
66
+ Answer the user's question based ONLY on the following context:
67
+
68
+ <context>
69
+ {context}
70
+ </context>
71
+
72
+ Question: {input}
73
+ `);
74
+
75
+ // 1. Create the document combining chain
76
+ const combineDocsChain = await createStuffDocumentsChain({
77
+ llm: model,
78
+ prompt,
79
+ });
80
+
81
+ // 2. Create the full retrieval chain
82
+ const ragChain = await createRetrievalChain({
83
+ retriever,
84
+ combineDocsChain,
85
+ });
86
+
87
+ // Usage
88
+ export async function askQuestion(question: string) {
89
+ const response = await ragChain.invoke({
90
+ input: question,
91
+ });
92
+ return response.answer;
93
+ }
94
+ ```
95
+
96
+ ### 4. Advanced: Hybrid Search
97
+ For production, combine keyword search (BM25) with semantic search (Vectors) for better accuracy.
98
+
99
+ ```typescript
100
+ // Conceptual example for Supabase/Postgres
101
+ // supabase.rpc('hybrid_search', { query_text: ..., match_threshold: ... })
102
+ ```
103
+
104
+ ## Constraints
105
+ - **Chunk Quality**: If chunks are too small, context is lost. If too large, noise increases.
106
+ - **Latency**: Embedding + Vector Search + Generation = High Latency. Use caching and streaming.
107
+ - **Relevance**: "Garbage In, Garbage Out". Ensure the retrieved context is actually relevant before passing to LLM.
108
+
109
+ ## Expected Output
110
+ A functional RAG pipeline where a user asks a question, the system retrieves relevant docs, and the LLM answers accurately citing the sources.
TRAE-Skills/ai_engineering/Recommender_Systems_Collaborative_Filtering.md ADDED
@@ -0,0 +1,198 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Skill: Recommender Systems with Collaborative Filtering
2
+
3
+ ## Purpose
4
+ To build recommendation systems using collaborative filtering techniques for personalized user experiences.
5
+
6
+ ## When to Use
7
+ - When building product recommendations for e-commerce
8
+ - For movie/music/content recommendations
9
+ - When personalizing user experiences
10
+ - For "Customers who bought this also bought" features
11
+ - When you have user-item interaction data
12
+
13
+ ## Procedure
14
+
15
+ ### 1. User-Based Collaborative Filtering
16
+ Recommend items based on similar users.
17
+
18
+ ```python
19
+ import numpy as np
20
+ import pandas as pd
21
+ from sklearn.metrics.pairwise import cosine_similarity
22
+
23
+ # Sample user-item ratings matrix
24
+ ratings_data = {
25
+ 'User1': [5, 4, 0, 0, 3],
26
+ 'User2': [0, 5, 4, 0, 0],
27
+ 'User3': [4, 0, 5, 3, 0],
28
+ 'User4': [0, 0, 4, 5, 4],
29
+ 'User5': [3, 0, 0, 4, 5]
30
+ }
31
+ items = ['ItemA', 'ItemB', 'ItemC', 'ItemD', 'ItemE']
32
+
33
+ ratings_matrix = pd.DataFrame(ratings_data, index=items).T
34
+
35
+ def user_based_cf(user_id, ratings_matrix, n_recommendations=3):
36
+ # Calculate user similarity
37
+ user_similarity = cosine_similarity(ratings_matrix)
38
+ user_similarity_df = pd.DataFrame(user_similarity, index=ratings_matrix.index, columns=ratings_matrix.index)
39
+
40
+ # Get similar users
41
+ similar_users = user_similarity_df[user_id].sort_values(ascending=False)[1:]
42
+
43
+ # Predict ratings
44
+ user_ratings = ratings_matrix.loc[user_id]
45
+ predicted_ratings = pd.Series(dtype='float64')
46
+
47
+ for item in ratings_matrix.columns:
48
+ if user_ratings[item] == 0:
49
+ weighted_sum = 0
50
+ similarity_sum = 0
51
+ for similar_user in similar_users.index:
52
+ if ratings_matrix.loc[similar_user, item] > 0:
53
+ weighted_sum += similar_users[similar_user] * ratings_matrix.loc[similar_user, item]
54
+ similarity_sum += similar_users[similar_user]
55
+ if similarity_sum > 0:
56
+ predicted_ratings[item] = weighted_sum / similarity_sum
57
+
58
+ return predicted_ratings.sort_values(ascending=False).head(n_recommendations)
59
+
60
+ # Usage
61
+ recommendations = user_based_cf('User1', ratings_matrix)
62
+ print("Recommendations for User1:", recommendations)
63
+ ```
64
+
65
+ ### 2. Item-Based Collaborative Filtering
66
+ Recommend items similar to those the user liked.
67
+
68
+ ```python
69
+ def item_based_cf(user_id, ratings_matrix, n_recommendations=3):
70
+ # Calculate item similarity
71
+ item_similarity = cosine_similarity(ratings_matrix.T)
72
+ item_similarity_df = pd.DataFrame(item_similarity, index=ratings_matrix.columns, columns=ratings_matrix.columns)
73
+
74
+ user_ratings = ratings_matrix.loc[user_id]
75
+ predicted_ratings = pd.Series(dtype='float64')
76
+
77
+ for item in ratings_matrix.columns:
78
+ if user_ratings[item] == 0:
79
+ weighted_sum = 0
80
+ similarity_sum = 0
81
+ for rated_item in user_ratings.index:
82
+ if user_ratings[rated_item] > 0:
83
+ weighted_sum += item_similarity_df[item][rated_item] * user_ratings[rated_item]
84
+ similarity_sum += item_similarity_df[item][rated_item]
85
+ if similarity_sum > 0:
86
+ predicted_ratings[item] = weighted_sum / similarity_sum
87
+
88
+ return predicted_ratings.sort_values(ascending=False).head(n_recommendations)
89
+ ```
90
+
91
+ ### 3. Matrix Factorization with SVD
92
+ Use Singular Value Decomposition for better recommendations.
93
+
94
+ ```python
95
+ from scipy.sparse.linalg import svds
96
+
97
+ def svd_recommender(ratings_matrix, user_id, n_recommendations=3, n_factors=2):
98
+ # Convert to numpy array and center
99
+ ratings = ratings_matrix.values
100
+ user_ratings_mean = np.mean(ratings, axis=1)
101
+ ratings_demeaned = ratings - user_ratings_mean.reshape(-1, 1)
102
+
103
+ # Perform SVD
104
+ U, sigma, Vt = svds(ratings_demeaned, k=n_factors)
105
+ sigma = np.diag(sigma)
106
+
107
+ # Reconstruct ratings
108
+ predicted_ratings = np.dot(np.dot(U, sigma), Vt) + user_ratings_mean.reshape(-1, 1)
109
+ predicted_ratings_df = pd.DataFrame(predicted_ratings, index=ratings_matrix.index, columns=ratings_matrix.columns)
110
+
111
+ # Get recommendations
112
+ user_ratings = ratings_matrix.loc[user_id]
113
+ recommendations = predicted_ratings_df.loc[user_id][user_ratings == 0].sort_values(ascending=False).head(n_recommendations)
114
+
115
+ return recommendations
116
+ ```
117
+
118
+ ### 4. Using Surprise Library
119
+ Use the Surprise library for recommendation systems.
120
+
121
+ ```python
122
+ from surprise import Dataset, Reader, SVD, KNNBasic
123
+ from surprise.model_selection import train_test_split
124
+ from surprise.metrics import accuracy
125
+
126
+ # Load data
127
+ ratings_dict = {
128
+ 'userID': [1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4],
129
+ 'itemID': [1, 2, 3, 1, 2, 4, 2, 3, 4, 1, 3, 4],
130
+ 'rating': [5, 4, 3, 5, 4, 4, 4, 5, 5, 3, 5, 4]
131
+ }
132
+
133
+ reader = Reader(rating_scale=(1, 5))
134
+ data = Dataset.load_from_df(pd.DataFrame(ratings_dict)[['userID', 'itemID', 'rating']], reader)
135
+
136
+ # Split data
137
+ trainset, testset = train_test_split(data, test_size=0.25)
138
+
139
+ # Train SVD model
140
+ algo = SVD()
141
+ algo.fit(trainset)
142
+
143
+ # Test
144
+ predictions = algo.test(testset)
145
+ print("RMSE:", accuracy.rmse(predictions))
146
+
147
+ # Get recommendations for a user
148
+ def get_surprise_recommendations(algo, user_id, item_ids, n_recommendations=3):
149
+ predictions = []
150
+ for item_id in item_ids:
151
+ pred = algo.predict(user_id, item_id)
152
+ predictions.append((item_id, pred.est))
153
+
154
+ predictions.sort(key=lambda x: x[1], reverse=True)
155
+ return predictions[:n_recommendations]
156
+ ```
157
+
158
+ ### 5. Hybrid Recommender
159
+ Combine collaborative filtering with content-based filtering.
160
+
161
+ ```python
162
+ def hybrid_recommender(user_id, ratings_matrix, item_features, n_recommendations=3):
163
+ # Get collaborative filtering recommendations
164
+ cf_recs = user_based_cf(user_id, ratings_matrix, n_recommendations=5)
165
+
166
+ # Get content-based recommendations (using item features)
167
+ item_similarity = cosine_similarity(item_features)
168
+ user_rated_items = ratings_matrix.loc[user_id][ratings_matrix.loc[user_id] > 0].index
169
+
170
+ content_recs = pd.Series(dtype='float64')
171
+ for item in ratings_matrix.columns:
172
+ if item not in user_rated_items:
173
+ sim_sum = 0
174
+ for rated_item in user_rated_items:
175
+ sim_sum += item_similarity[list(ratings_matrix.columns).index(item)][list(ratings_matrix.columns).index(rated_item)]
176
+ content_recs[item] = sim_sum / len(user_rated_items)
177
+
178
+ content_recs = content_recs.sort_values(ascending=False).head(5)
179
+
180
+ # Combine recommendations (simple average)
181
+ combined_recs = pd.Series(dtype='float64')
182
+ for item in set(cf_recs.index).union(set(content_recs.index)):
183
+ cf_score = cf_recs.get(item, 0)
184
+ content_score = content_recs.get(item, 0)
185
+ combined_recs[item] = (cf_score + content_score) / 2
186
+
187
+ return combined_recs.sort_values(ascending=False).head(n_recommendations)
188
+ ```
189
+
190
+ ## Best Practices
191
+ - **Data Preprocessing**: Clean and preprocess your data thoroughly
192
+ - **Cold Start**: Handle new users/items with hybrid approaches
193
+ - **Evaluation**: Use RMSE, MAE, or ranking metrics (NDCG, MAP)
194
+ - **Scalability**: Use matrix factorization or deep learning for large datasets
195
+ - **Diversity**: Ensure recommendations are diverse, not just similar
196
+ - **Freshness**: Update recommendations regularly with new data
197
+ - **A/B Testing**: Always test recommendations with real users
198
+ - **Privacy**: Be mindful of user privacy and data usage
TRAE-Skills/ai_engineering/Reinforcement_Learning_Basics.md ADDED
@@ -0,0 +1,335 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Skill: Reinforcement Learning Basics
2
+
3
+ ## Purpose
4
+ To implement intelligent agents that learn optimal behaviors through interaction with an environment, using rewards and penalties to guide decision-making.
5
+
6
+ ## When to Use
7
+ - When building game-playing AI
8
+ - When optimizing control systems (robotics, autonomous vehicles)
9
+ - When solving sequential decision problems
10
+ - When implementing recommendation systems with user feedback
11
+
12
+ ## Procedure
13
+
14
+ ### 1. Q-Learning Implementation
15
+ Implement basic Q-learning algorithm.
16
+
17
+ ```python
18
+ import numpy as np
19
+ from collections import defaultdict
20
+
21
+ class QLearningAgent:
22
+ def __init__(self, state_size, action_size, learning_rate=0.1, discount_factor=0.95, epsilon=1.0):
23
+ self.state_size = state_size
24
+ self.action_size = action_size
25
+ self.learning_rate = learning_rate
26
+ self.discount_factor = discount_factor
27
+ self.epsilon = epsilon
28
+ self.epsilon_decay = 0.995
29
+ self.epsilon_min = 0.01
30
+ self.q_table = defaultdict(lambda: np.zeros(action_size))
31
+
32
+ def choose_action(self, state):
33
+ """Choose action using epsilon-greedy policy."""
34
+ if np.random.random() <= self.epsilon:
35
+ return np.random.choice(self.action_size)
36
+ else:
37
+ return np.argmax(self.q_table[state])
38
+
39
+ def learn(self, state, action, reward, next_state, done):
40
+ """Update Q-value using Q-learning formula."""
41
+ current_q = self.q_table[state][action]
42
+
43
+ if done:
44
+ max_next_q = 0
45
+ else:
46
+ max_next_q = np.max(self.q_table[next_state])
47
+
48
+ new_q = current_q + self.learning_rate * (reward + self.discount_factor * max_next_q - current_q)
49
+ self.q_table[state][action] = new_q
50
+
51
+ # Decay epsilon
52
+ if self.epsilon > self.epsilon_min:
53
+ self.epsilon *= self.epsilon_decay
54
+
55
+ def save_q_table(self, filename):
56
+ """Save Q-table to file."""
57
+ dict_q_table = dict(self.q_table)
58
+ np.save(filename, dict_q_table)
59
+
60
+ def load_q_table(self, filename):
61
+ """Load Q-table from file."""
62
+ dict_q_table = np.load(filename, allow_pickle=True).item()
63
+ self.q_table = defaultdict(lambda: np.zeros(self.action_size), dict_q_table)
64
+
65
+ # Simple grid world environment
66
+ class GridWorld:
67
+ def __init__(self, size=5):
68
+ self.size = size
69
+ self.start = (0, 0)
70
+ self.goal = (size-1, size-1)
71
+ self.obstacles = [(2, 2), (3, 1), (1, 3)]
72
+ self.current_state = self.start
73
+ self.actions = ['up', 'down', 'left', 'right']
74
+
75
+ def reset(self):
76
+ self.current_state = self.start
77
+ return self.current_state
78
+
79
+ def step(self, action):
80
+ row, col = self.current_state
81
+
82
+ if action == 'up':
83
+ new_row, new_col = row - 1, col
84
+ elif action == 'down':
85
+ new_row, new_col = row + 1, col
86
+ elif action == 'left':
87
+ new_row, new_col = row, col - 1
88
+ elif action == 'right':
89
+ new_row, new_col = row, col + 1
90
+
91
+ # Check boundaries
92
+ if 0 <= new_row < self.size and 0 <= new_col < self.size:
93
+ if (new_row, new_col) not in self.obstacles:
94
+ self.current_state = (new_row, new_col)
95
+
96
+ # Calculate reward
97
+ if self.current_state == self.goal:
98
+ reward = 10
99
+ done = True
100
+ else:
101
+ reward = -1
102
+ done = False
103
+
104
+ return self.current_state, reward, done
105
+
106
+ # Training
107
+ env = GridWorld()
108
+ agent = QLearningAgent(state_size=env.size*env.size, action_size=4)
109
+
110
+ episodes = 1000
111
+ for episode in range(episodes):
112
+ state = env.reset()
113
+ done = False
114
+ total_reward = 0
115
+
116
+ while not done:
117
+ action_idx = agent.choose_action(state)
118
+ action = env.actions[action_idx]
119
+ next_state, reward, done = env.step(action)
120
+
121
+ agent.learn(state, action_idx, reward, next_state, done)
122
+ state = next_state
123
+ total_reward += reward
124
+
125
+ if episode % 100 == 0:
126
+ print(f"Episode {episode}, Total Reward: {total_reward}, Epsilon: {agent.epsilon:.3f}")
127
+ ```
128
+
129
+ ### 2. Deep Q-Network (DQN)
130
+ Implement deep Q-learning with neural networks.
131
+
132
+ ```python
133
+ import torch
134
+ import torch.nn as nn
135
+ import torch.optim as optim
136
+ from collections import deque
137
+ import random
138
+
139
+ class DQN(nn.Module):
140
+ def __init__(self, state_size, action_size):
141
+ super(DQN, self).__init__()
142
+ self.fc1 = nn.Linear(state_size, 64)
143
+ self.fc2 = nn.Linear(64, 64)
144
+ self.fc3 = nn.Linear(64, action_size)
145
+
146
+ def forward(self, x):
147
+ x = torch.relu(self.fc1(x))
148
+ x = torch.relu(self.fc2(x))
149
+ return self.fc3(x)
150
+
151
+ class DQNAgent:
152
+ def __init__(self, state_size, action_size):
153
+ self.state_size = state_size
154
+ self.action_size = action_size
155
+ self.memory = deque(maxlen=10000)
156
+ self.gamma = 0.95
157
+ self.epsilon = 1.0
158
+ self.epsilon_min = 0.01
159
+ self.epsilon_decay = 0.995
160
+ self.learning_rate = 0.001
161
+ self.batch_size = 32
162
+
163
+ self.model = DQN(state_size, action_size)
164
+ self.optimizer = optim.Adam(self.model.parameters(), lr=self.learning_rate)
165
+
166
+ def remember(self, state, action, reward, next_state, done):
167
+ """Store experience in replay memory."""
168
+ self.memory.append((state, action, reward, next_state, done))
169
+
170
+ def act(self, state):
171
+ """Choose action using epsilon-greedy policy."""
172
+ if np.random.random() <= self.epsilon:
173
+ return random.randrange(self.action_size)
174
+
175
+ state = torch.FloatTensor(state).unsqueeze(0)
176
+ q_values = self.model(state)
177
+ return np.argmax(q_values.detach().numpy()[0])
178
+
179
+ def replay(self):
180
+ """Train on a batch of experiences."""
181
+ if len(self.memory) < self.batch_size:
182
+ return
183
+
184
+ minibatch = random.sample(self.memory, self.batch_size)
185
+ states = torch.FloatTensor([t[0] for t in minibatch])
186
+ actions = torch.LongTensor([t[1] for t in minibatch])
187
+ rewards = torch.FloatTensor([t[2] for t in minibatch])
188
+ next_states = torch.FloatTensor([t[3] for t in minibatch])
189
+ dones = torch.FloatTensor([t[4] for t in minibatch])
190
+
191
+ current_q_values = self.model(states).gather(1, actions.unsqueeze(1))
192
+ next_q_values = self.model(next_states).max(1)[0].detach()
193
+ target_q_values = rewards + (1 - dones) * self.gamma * next_q_values
194
+
195
+ loss = nn.MSELoss()(current_q_values.squeeze(), target_q_values)
196
+
197
+ self.optimizer.zero_grad()
198
+ loss.backward()
199
+ self.optimizer.step()
200
+
201
+ if self.epsilon > self.epsilon_min:
202
+ self.epsilon *= self.epsilon_decay
203
+
204
+ def save(self, filename):
205
+ """Save model."""
206
+ torch.save(self.model.state_dict(), filename)
207
+
208
+ def load(self, filename):
209
+ """Load model."""
210
+ self.model.load_state_dict(torch.load(filename))
211
+
212
+ # Usage
213
+ env = GridWorld()
214
+ state_size = env.size * env.size
215
+ action_size = 4
216
+
217
+ agent = DQNAgent(state_size, action_size)
218
+
219
+ episodes = 500
220
+ for episode in range(episodes):
221
+ state = env.reset()
222
+ state_flat = np.array(state).flatten()
223
+ done = False
224
+ total_reward = 0
225
+
226
+ while not done:
227
+ action = agent.act(state_flat)
228
+ next_state, reward, done = env.step(env.actions[action])
229
+ next_state_flat = np.array(next_state).flatten()
230
+
231
+ agent.remember(state_flat, action, reward, next_state_flat, done)
232
+ state = next_state
233
+ state_flat = next_state_flat
234
+ total_reward += reward
235
+
236
+ agent.replay()
237
+
238
+ if episode % 50 == 0:
239
+ print(f"Episode {episode}, Total Reward: {total_reward}, Epsilon: {agent.epsilon:.3f}")
240
+ ```
241
+
242
+ ### 3. Policy Gradient Implementation
243
+ Implement REINFORCE algorithm.
244
+
245
+ ```python
246
+ class PolicyGradientAgent:
247
+ def __init__(self, state_size, action_size, learning_rate=0.01):
248
+ self.state_size = state_size
249
+ self.action_size = action_size
250
+ self.gamma = 0.99
251
+
252
+ # Policy network
253
+ self.policy = nn.Sequential(
254
+ nn.Linear(state_size, 128),
255
+ nn.ReLU(),
256
+ nn.Linear(128, action_size),
257
+ nn.Softmax(dim=-1)
258
+ )
259
+
260
+ self.optimizer = optim.Adam(self.policy.parameters(), lr=learning_rate)
261
+
262
+ def choose_action(self, state):
263
+ """Choose action based on policy."""
264
+ state = torch.FloatTensor(state)
265
+ probs = self.policy(state)
266
+
267
+ # Sample from probability distribution
268
+ action_dist = torch.distributions.Categorical(probs)
269
+ action = action_dist.sample()
270
+
271
+ return action.item(), action_dist.log_prob(action)
272
+
273
+ def update_policy(self, rewards, log_probs):
274
+ """Update policy using REINFORCE."""
275
+ returns = []
276
+ R = 0
277
+
278
+ # Calculate discounted returns
279
+ for r in reversed(rewards):
280
+ R = r + self.gamma * R
281
+ returns.insert(0, R)
282
+
283
+ returns = torch.FloatTensor(returns)
284
+ log_probs = torch.stack(log_probs)
285
+
286
+ # Calculate loss
287
+ policy_loss = []
288
+ for log_prob, R in zip(log_probs, returns):
289
+ policy_loss.append(-log_prob * R)
290
+
291
+ policy_loss = torch.stack(policy_loss).sum()
292
+
293
+ # Update policy
294
+ self.optimizer.zero_grad()
295
+ policy_loss.backward()
296
+ self.optimizer.step()
297
+
298
+ # Training
299
+ env = GridWorld()
300
+ agent = PolicyGradientAgent(state_size=env.size*env.size, action_size=4)
301
+
302
+ episodes = 1000
303
+ for episode in range(episodes):
304
+ state = env.reset()
305
+ state_flat = np.array(state).flatten()
306
+ done = False
307
+ rewards = []
308
+ log_probs = []
309
+
310
+ while not done:
311
+ action, log_prob = agent.choose_action(state_flat)
312
+ next_state, reward, done = env.step(env.actions[action])
313
+
314
+ rewards.append(reward)
315
+ log_probs.append(log_prob)
316
+
317
+ state = next_state
318
+ state_flat = np.array(state).flatten()
319
+
320
+ agent.update_policy(rewards, log_probs)
321
+
322
+ if episode % 100 == 0:
323
+ print(f"Episode {episode}, Total Reward: {sum(rewards)}")
324
+ ```
325
+
326
+ ## Constraints
327
+ - **Training Time**: RL requires many episodes to converge
328
+ - **Hyperparameter Sensitivity**: Performance highly depends on hyperparameter tuning
329
+ - **Sample Efficiency**: Traditional RL is sample inefficient
330
+ - **Exploration vs. Exploitation**: Balancing exploration and exploitation is crucial
331
+ - **Reward Design**: Poor reward design leads to unexpected behaviors
332
+ - **Computational Resources**: Deep RL requires significant computational power
333
+
334
+ ## Expected Output
335
+ Intelligent agents that learn optimal policies through experience, capable of making sequential decisions in complex environments.
TRAE-Skills/ai_engineering/Speech_to_Text_Whisper.md ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Skill: Speech-to-Text Implementation (Whisper)
2
+
3
+ ## Purpose
4
+ To implement robust audio transcription and translation using OpenAI's Whisper model, handling large files, various formats, and specialized vocabulary.
5
+
6
+ ## When to Use
7
+ - When converting user voice commands to text in a web/mobile app.
8
+ - When transcribing long-form content (podcasts, meetings).
9
+ - When you need high-accuracy transcription for non-English languages.
10
+
11
+ ## Procedure
12
+
13
+ ### 1. Handling Large Files (Splitting with FFmpeg)
14
+ Whisper API has a 25MB limit. Use FFmpeg to split or compress.
15
+
16
+ ```bash
17
+ # Split audio into 10-minute segments
18
+ ffmpeg -i input.mp3 -f segment -segment_time 600 -c copy out%03d.mp3
19
+
20
+ # Compress to low-bitrate mono MP3 (saves space while keeping speech clear)
21
+ ffmpeg -i input.wav -ac 1 -ar 16000 -ab 32k output.mp3
22
+ ```
23
+
24
+ ### 2. Basic Transcription (Node.js)
25
+ Integrate the OpenAI SDK for transcription.
26
+
27
+ ```typescript
28
+ import fs from 'fs';
29
+ import OpenAI from 'openai';
30
+
31
+ const openai = new OpenAI();
32
+
33
+ async function transcribe(filePath: string) {
34
+ const response = await openai.audio.transcriptions.create({
35
+ file: fs.createReadStream(filePath),
36
+ model: "whisper-1",
37
+ language: "en", // Optional but improves accuracy
38
+ response_format: "verbose_json", // Gives timestamps
39
+ prompt: "The transcript is about a software architecture meeting.", // Helps with context/acronyms
40
+ });
41
+
42
+ return response;
43
+ }
44
+ ```
45
+
46
+ ### 3. Handling Timestamps & Subtitles
47
+ Use the `srt` or `vtt` format for video captions.
48
+
49
+ ```typescript
50
+ const srtTranscription = await openai.audio.transcriptions.create({
51
+ file: fs.createReadStream("video_audio.mp3"),
52
+ model: "whisper-1",
53
+ response_format: "srt",
54
+ });
55
+
56
+ fs.writeFileSync("subtitles.srt", srtTranscription);
57
+ ```
58
+
59
+ ### 4. Specialized Vocabulary (Prompts)
60
+ Pass technical terms or proper nouns in the `prompt` parameter to ensure correct spelling.
61
+
62
+ ```typescript
63
+ // Prompt example to ensure technical terms are spelled correctly
64
+ const prompt = "The speakers discuss Kubernetes, Istio, and gRPC.";
65
+ ```
66
+
67
+ ### 5. Local Execution (Python/Faster-Whisper)
68
+ For privacy or high volume, use `faster-whisper` locally.
69
+
70
+ ```python
71
+ from faster_whisper import WhisperModel
72
+
73
+ model_size = "large-v3"
74
+ model = WhisperModel(model_size, device="cuda", compute_type="float16")
75
+
76
+ segments, info = model.transcribe("audio.mp3", beam_size=5)
77
+
78
+ for segment in segments:
79
+ print("[%.2fs -> %.2fs] %s" % (segment.start, segment.end, segment.text))
80
+ ```
81
+
82
+ ## Constraints
83
+ - **File Size**: 25MB limit on API. Must split/compress manually.
84
+ - **Latency**: Not real-time (usually 5-15s for a 1-minute clip).
85
+ - **Privacy**: API usage sends data to OpenAI. Use local Whisper for sensitive data.
86
+
87
+ ## Expected Output
88
+ Highly accurate, time-stamped text representing the spoken audio, optionally translated into English.
TRAE-Skills/ai_engineering/Stream_Responses.md ADDED
@@ -0,0 +1,321 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Skill: Stream Responses
2
+
3
+ ## Purpose
4
+ To deliver LLM responses in real-time chunks, improving user experience by providing immediate feedback and reducing perceived latency.
5
+
6
+ ## When to Use
7
+ - When building chat interfaces
8
+ - When processing long responses
9
+ - When users need immediate feedback
10
+ - When implementing real-time AI interactions
11
+
12
+ ## Procedure
13
+
14
+ ### 1. Basic Streaming Setup
15
+ Implement basic streaming with OpenAI API.
16
+
17
+ ```python
18
+ from openai import OpenAI
19
+ import sys
20
+
21
+ client = OpenAI()
22
+
23
+ def stream_response(prompt, model="gpt-4"):
24
+ """Stream a basic response from the LLM."""
25
+ print("Assistant: ", end="", flush=True)
26
+
27
+ stream = client.chat.completions.create(
28
+ model=model,
29
+ messages=[{"role": "user", "content": prompt}],
30
+ stream=True
31
+ )
32
+
33
+ for chunk in stream:
34
+ if chunk.choices[0].delta.content is not None:
35
+ content = chunk.choices[0].delta.content
36
+ print(content, end="", flush=True)
37
+ yield content
38
+
39
+ print() # New line after completion
40
+
41
+ # Usage
42
+ for chunk in stream_response("Explain quantum computing in simple terms"):
43
+ pass # Process chunks if needed
44
+ ```
45
+
46
+ ### 2. Streaming with Buffering
47
+ Implement buffering for more controlled output.
48
+
49
+ ```python
50
+ def buffered_stream(prompt, buffer_size=10, delay=0.1):
51
+ """Stream with buffering to prevent choppy output."""
52
+ import time
53
+
54
+ buffer = []
55
+ stream = client.chat.completions.create(
56
+ model="gpt-4",
57
+ messages=[{"role": "user", "content": prompt}],
58
+ stream=True
59
+ )
60
+
61
+ for chunk in stream:
62
+ if chunk.choices[0].delta.content is not None:
63
+ content = chunk.choices[0].delta.content
64
+ buffer.append(content)
65
+
66
+ if len(buffer) >= buffer_size:
67
+ print("".join(buffer), end="", flush=True)
68
+ buffer = []
69
+ time.sleep(delay)
70
+
71
+ # Print remaining buffer
72
+ if buffer:
73
+ print("".join(buffer), end="", flush=True)
74
+ print()
75
+
76
+ # Usage
77
+ buffered_stream("Write a short story about a robot learning to paint")
78
+ ```
79
+
80
+ ### 3. Async Streaming
81
+ Implement asynchronous streaming for better performance.
82
+
83
+ ```python
84
+ import asyncio
85
+ from openai import AsyncOpenAI
86
+
87
+ async_client = AsyncOpenAI()
88
+
89
+ async def async_stream(prompt):
90
+ """Stream responses asynchronously."""
91
+ stream = await async_client.chat.completions.create(
92
+ model="gpt-4",
93
+ messages=[{"role": "user", "content": prompt}],
94
+ stream=True
95
+ )
96
+
97
+ full_response = ""
98
+ async for chunk in stream:
99
+ if chunk.choices[0].delta.content is not None:
100
+ content = chunk.choices[0].delta.content
101
+ print(content, end="", flush=True)
102
+ full_response += content
103
+
104
+ print()
105
+ return full_response
106
+
107
+ # Usage
108
+ async def main():
109
+ response = await async_stream("What are the benefits of async programming?")
110
+
111
+ asyncio.run(main())
112
+ ```
113
+
114
+ ### 4. Multi-User Streaming
115
+ Handle streaming for multiple concurrent users.
116
+
117
+ ```python
118
+ class StreamingManager:
119
+ def __init__(self):
120
+ self.active_streams = {}
121
+
122
+ async def stream_to_user(self, user_id, prompt):
123
+ """Stream response to a specific user."""
124
+ self.active_streams[user_id] = True
125
+
126
+ try:
127
+ stream = await async_client.chat.completions.create(
128
+ model="gpt-4",
129
+ messages=[{"role": "user", "content": prompt}],
130
+ stream=True
131
+ )
132
+
133
+ async for chunk in stream:
134
+ if not self.active_streams.get(user_id, False):
135
+ print(f"Stream cancelled for user {user_id}")
136
+ break
137
+
138
+ if chunk.choices[0].delta.content is not None:
139
+ # In real implementation, send to user via WebSocket
140
+ content = chunk.choices[0].delta.content
141
+ print(f"User {user_id}: {content}", end="", flush=True)
142
+
143
+ print()
144
+ finally:
145
+ self.active_streams.pop(user_id, None)
146
+
147
+ def cancel_stream(self, user_id):
148
+ """Cancel stream for a specific user."""
149
+ self.active_streams[user_id] = False
150
+
151
+ # Usage
152
+ manager = StreamingManager()
153
+
154
+ async def handle_multiple_users():
155
+ tasks = [
156
+ manager.stream_to_user(1, "Tell me a joke"),
157
+ manager.stream_to_user(2, "Explain machine learning")
158
+ ]
159
+ await asyncio.gather(*tasks)
160
+
161
+ asyncio.run(handle_multiple_users())
162
+ ```
163
+
164
+ ### 5. Process Streaming Output
165
+ Process chunks during streaming.
166
+
167
+ ```python
168
+ class StreamProcessor:
169
+ def __init__(self):
170
+ self.collected_chunks = []
171
+ self.processed_chunks = []
172
+
173
+ def process_chunk(self, chunk):
174
+ """Process individual chunks during streaming."""
175
+ # Example: filter or transform chunks
176
+ processed = chunk.replace("**", "").replace("__", "")
177
+ self.processed_chunks.append(processed)
178
+ return processed
179
+
180
+ def stream_with_processing(self, prompt):
181
+ """Stream and process chunks in real-time."""
182
+ stream = client.chat.completions.create(
183
+ model="gpt-4",
184
+ messages=[{"role": "user", "content": prompt}],
185
+ stream=True
186
+ )
187
+
188
+ for chunk in stream:
189
+ if chunk.choices[0].delta.content is not None:
190
+ content = chunk.choices[0].delta.content
191
+ self.collected_chunks.append(content)
192
+
193
+ processed = self.process_chunk(content)
194
+ print(processed, end="", flush=True)
195
+
196
+ print()
197
+ return "".join(self.processed_chunks)
198
+
199
+ # Usage
200
+ processor = StreamProcessor()
201
+ result = processor.stream_with_processing("Write markdown formatted text with bold and italics")
202
+ ```
203
+
204
+ ### 6. Web Integration with Streaming
205
+ Integrate streaming with web frameworks.
206
+
207
+ ```python
208
+ from fastapi import FastAPI
209
+ from fastapi.responses import StreamingResponse
210
+ import json
211
+
212
+ app = FastAPI()
213
+
214
+ def generate_stream(prompt):
215
+ """Generator for FastAPI streaming response."""
216
+ stream = client.chat.completions.create(
217
+ model="gpt-4",
218
+ messages=[{"role": "user", "content": prompt}],
219
+ stream=True
220
+ )
221
+
222
+ for chunk in stream:
223
+ if chunk.choices[0].delta.content is not None:
224
+ content = chunk.choices[0].delta.content
225
+ # Format as SSE (Server-Sent Events)
226
+ data = json.dumps({"content": content})
227
+ yield f"data: {data}\n\n"
228
+
229
+ yield "data: [DONE]\n\n"
230
+
231
+ @app.post("/chat")
232
+ async def chat_endpoint(prompt: str):
233
+ """Endpoint for streaming chat responses."""
234
+ return StreamingResponse(
235
+ generate_stream(prompt),
236
+ media_type="text/event-stream"
237
+ )
238
+
239
+ # For client-side JavaScript:
240
+ """
241
+ const response = await fetch('/chat', {
242
+ method: 'POST',
243
+ headers: {'Content-Type': 'application/json'},
244
+ body: JSON.stringify({prompt: 'Hello'})
245
+ });
246
+
247
+ const reader = response.body.getReader();
248
+ const decoder = new TextDecoder();
249
+
250
+ while (true) {
251
+ const {done, value} = await reader.read();
252
+ if (done) break;
253
+
254
+ const chunk = decoder.decode(value);
255
+ // Process chunk and update UI
256
+ }
257
+ """
258
+ ```
259
+
260
+ ### 7. Streaming with Metadata
261
+ Include metadata with streaming responses.
262
+
263
+ ```python
264
+ def stream_with_metadata(prompt):
265
+ """Stream response with additional metadata."""
266
+ stream = client.chat.completions.create(
267
+ model="gpt-4",
268
+ messages=[{"role": "user", "content": prompt}],
269
+ stream=True
270
+ )
271
+
272
+ total_tokens = 0
273
+ start_time = time.time()
274
+
275
+ for i, chunk in enumerate(stream):
276
+ if chunk.choices[0].delta.content is not None:
277
+ content = chunk.choices[0].delta.content
278
+ total_tokens += len(content.split())
279
+
280
+ metadata = {
281
+ "chunk": i,
282
+ "tokens": total_tokens,
283
+ "elapsed": time.time() - start_time
284
+ }
285
+
286
+ yield {
287
+ "content": content,
288
+ "metadata": metadata
289
+ }
290
+
291
+ # Final metadata
292
+ final_metadata = {
293
+ "total_chunks": i + 1,
294
+ "estimated_tokens": total_tokens,
295
+ "total_time": time.time() - start_time
296
+ }
297
+
298
+ yield {
299
+ "content": "",
300
+ "metadata": final_metadata,
301
+ "complete": True
302
+ }
303
+
304
+ # Usage
305
+ for response in stream_with_metadata("Write a 500-word essay on AI"):
306
+ if response.get("complete"):
307
+ print(f"\nCompleted in {response['metadata']['total_time']:.2f}s")
308
+ else:
309
+ print(response["content"], end="", flush=True)
310
+ ```
311
+
312
+ ## Constraints
313
+ - **Token Counting**: Streaming makes exact token counting difficult
314
+ - **Error Handling**: Handle connection failures mid-stream gracefully
315
+ - **Buffer Size**: Balance between real-time feedback and choppy output
316
+ - **Memory Usage**: Be careful with memory for very long responses
317
+ - **Cancellation**: Implement proper cancellation for user interruptions
318
+ - **Format Maintenance**: Streaming may break markdown formatting temporarily
319
+
320
+ ## Expected Output
321
+ Real-time streaming responses that provide immediate user feedback, with proper error handling and integration capabilities for various applications.
TRAE-Skills/ai_engineering/Structured_Output_Parsing.md ADDED
@@ -0,0 +1,301 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Skill: Structured Output Parsing
2
+
3
+ ## Purpose
4
+ To force LLMs to output data in specific, parseable formats like JSON, enabling reliable integration with applications and automated workflows.
5
+
6
+ ## When to Use
7
+ - When building APIs that need structured responses
8
+ - When extracting data from unstructured text
9
+ - When generating code, configuration files, or data formats
10
+ - When requiring consistent output formatting for downstream processing
11
+
12
+ ## Procedure
13
+
14
+ ### 1. Basic JSON Output
15
+ Request JSON format in your prompt.
16
+
17
+ ```python
18
+ from openai import OpenAI
19
+ import json
20
+
21
+ client = OpenAI()
22
+
23
+ def get_json_response(prompt, schema_description):
24
+ """Get structured JSON response from LLM."""
25
+ full_prompt = f"""
26
+ {prompt}
27
+
28
+ Provide your response as a JSON object following this structure:
29
+ {schema_description}
30
+
31
+ Return only the JSON, no additional text.
32
+ """
33
+
34
+ response = client.chat.completions.create(
35
+ model="gpt-4",
36
+ messages=[{"role": "user", "content": full_prompt}],
37
+ temperature=0 # Lower temperature for more consistent structure
38
+ )
39
+
40
+ # Parse JSON response
41
+ try:
42
+ return json.loads(response.choices[0].message.content)
43
+ except json.JSONDecodeError:
44
+ # Fallback: ask model to fix the JSON
45
+ return fix_json_parse(response.choices[0].message.content)
46
+
47
+ # Example usage
48
+ person_info = get_json_response(
49
+ "Extract information from: 'John Doe is a 35-year-old software engineer from New York.'",
50
+ """
51
+ {
52
+ "name": "string",
53
+ "age": "number",
54
+ "occupation": "string",
55
+ "location": "string"
56
+ }
57
+ """
58
+ )
59
+ print(person_info)
60
+ ```
61
+
62
+ ### 2. Pydantic Models for Validation
63
+ Use Pydantic for robust schema validation.
64
+
65
+ ```python
66
+ from pydantic import BaseModel, Field
67
+ from typing import List, Optional
68
+
69
+ class Person(BaseModel):
70
+ name: str = Field(description="Full name of the person")
71
+ age: int = Field(description="Age in years", ge=0, le=150)
72
+ occupation: str = Field(description="Job title or occupation")
73
+ location: Optional[str] = Field(default=None, description="City or location")
74
+
75
+ class ProductReview(BaseModel):
76
+ product_name: str
77
+ rating: int = Field(ge=1, le=5)
78
+ review_text: str
79
+ pros: List[str]
80
+ cons: List[str]
81
+ would_recommend: bool
82
+
83
+ def extract_structured_data(text, model_class):
84
+ """Extract structured data using Pydantic model."""
85
+ schema = model_class.model_json_schema()
86
+
87
+ prompt = f"""
88
+ Extract information from the following text and return it as JSON:
89
+
90
+ Text: {text}
91
+
92
+ Return JSON matching this schema:
93
+ {json.dumps(schema, indent=2)}
94
+
95
+ Return only the JSON, no additional text.
96
+ """
97
+
98
+ response = client.chat.completions.create(
99
+ model="gpt-4",
100
+ messages=[{"role": "user", "content": prompt}],
101
+ temperature=0
102
+ )
103
+
104
+ try:
105
+ data = json.loads(response.choices[0].message.content)
106
+ return model_class(**data)
107
+ except Exception as e:
108
+ print(f"Error parsing response: {e}")
109
+ return None
110
+
111
+ # Example usage
112
+ review_text = """
113
+ I bought the Acme Widget Pro last month. Overall I'd give it 4 stars.
114
+ The build quality is excellent and battery life is amazing.
115
+ However, the price is quite high and the app interface is confusing.
116
+ Despite these issues, I would recommend it to others.
117
+ """
118
+
119
+ review = extract_structured_data(review_text, ProductReview)
120
+ if review:
121
+ print(f"Product: {review.product_name}")
122
+ print(f"Rating: {review.rating}/5")
123
+ print(f"Pros: {', '.join(review.pros)}")
124
+ ```
125
+
126
+ ### 3. Few-Shot JSON Examples
127
+ Provide examples to improve JSON formatting.
128
+
129
+ ```python
130
+ def extract_with_few_shots(text):
131
+ """Extract structured data with few-shot examples."""
132
+ prompt = """
133
+ Example 1:
134
+ Input: "Sarah Connor, 28, works as a data analyst in Boston."
135
+ Output: {"name": "Sarah Connor", "age": 28, "occupation": "data analyst", "location": "Boston"}
136
+
137
+ Example 2:
138
+ Input: "Mike Ross is a 32-year-old lawyer from New York."
139
+ Output: {"name": "Mike Ross", "age": 32, "occupation": "lawyer", "location": "New York"}
140
+
141
+ Example 3:
142
+ Input: "Emily Chen, 25, graphic designer, San Francisco"
143
+ Output: {"name": "Emily Chen", "age": 25, "occupation": "graphic designer", "location": "San Francisco"}
144
+
145
+ Now extract from this input:
146
+ Input: "{text}"
147
+ Output:"""
148
+
149
+ response = client.chat.completions.create(
150
+ model="gpt-4",
151
+ messages=[{"role": "user", "content": prompt}],
152
+ temperature=0
153
+ )
154
+
155
+ return json.loads(response.choices[0].message.content)
156
+
157
+ # Usage
158
+ result = extract_with_few_shots("James Wilson, 42, architect, Chicago")
159
+ print(result)
160
+ ```
161
+
162
+ ### 4. Structured Output with Function Calling
163
+ Use function calling for guaranteed structured output.
164
+
165
+ ```python
166
+ def structured_output_with_functions(text):
167
+ """Use function calling for structured output."""
168
+ function_def = {
169
+ "name": "extract_person_info",
170
+ "description": "Extract person information from text",
171
+ "parameters": {
172
+ "type": "object",
173
+ "properties": {
174
+ "name": {"type": "string"},
175
+ "age": {"type": "integer"},
176
+ "occupation": {"type": "string"},
177
+ "location": {"type": "string"}
178
+ },
179
+ "required": ["name", "age", "occupation"]
180
+ }
181
+ }
182
+
183
+ response = client.chat.completions.create(
184
+ model="gpt-4",
185
+ messages=[{
186
+ "role": "user",
187
+ "content": f"Extract person information from: {text}"
188
+ }],
189
+ functions=[function_def],
190
+ function_call={"name": "extract_person_info"}
191
+ )
192
+
193
+ function_call = response.choices[0].message.function_call
194
+ return json.loads(function_call.arguments)
195
+
196
+ # Example
197
+ person = structured_output_with_functions(
198
+ "Dr. Lisa Anderson, 38, cardiologist at Mayo Clinic, Rochester"
199
+ )
200
+ print(person)
201
+ ```
202
+
203
+ ### 5. Complex Nested Structures
204
+ Handle complex nested JSON structures.
205
+
206
+ ```python
207
+ class Company(BaseModel):
208
+ name: str
209
+ founded_year: int
210
+ headquarters: str
211
+ employees: List[str]
212
+ departments: dict
213
+
214
+ def extract_company_info(text):
215
+ """Extract complex nested company information."""
216
+ prompt = f"""
217
+ Extract company information from the following text and return it as JSON.
218
+ Include all employees mentioned and their departments.
219
+
220
+ Text: {text}
221
+
222
+ Return JSON matching this structure:
223
+ {json.dumps(Company.model_json_schema(), indent=2)}
224
+
225
+ Return only valid JSON.
226
+ """
227
+
228
+ response = client.chat.completions.create(
229
+ model="gpt-4",
230
+ messages=[{"role": "user", "content": prompt}],
231
+ temperature=0
232
+ )
233
+
234
+ try:
235
+ data = json.loads(response.choices[0].message.content)
236
+ return Company(**data)
237
+ except Exception as e:
238
+ print(f"Error: {e}")
239
+ return None
240
+
241
+ # Example
242
+ company_text = """
243
+ TechCorp Inc. was founded in 2010 and is headquartered in Austin, Texas.
244
+ The company has three main departments: Engineering, Sales, and Marketing.
245
+ Key employees include:
246
+ - John Smith (CEO, Engineering department)
247
+ - Sarah Johnson (VP of Sales)
248
+ - Michael Chen (CTO, Engineering)
249
+ - Emily Davis (Marketing Director)
250
+ """
251
+
252
+ company = extract_company_info(company_text)
253
+ if company:
254
+ print(f"Company: {company.name}")
255
+ print(f"Departments: {company.departments.keys()}")
256
+ ```
257
+
258
+ ### 6. Error Recovery and Retry Logic
259
+ Implement robust error handling for JSON parsing.
260
+
261
+ ```python
262
+ def extract_with_retry(text, model_class, max_retries=3):
263
+ """Extract structured data with retry logic."""
264
+ schema = model_class.model_json_schema()
265
+
266
+ for attempt in range(max_retries):
267
+ prompt = f"""
268
+ Extract information as JSON following this schema:
269
+ {json.dumps(schema, indent=2)}
270
+
271
+ Text: {text}
272
+
273
+ {'Only return the JSON object, no other text.' if attempt == 0 else 'Your previous response was not valid JSON. Please ensure you return ONLY a valid JSON object, nothing else.'}
274
+ """
275
+
276
+ response = client.chat.completions.create(
277
+ model="gpt-4",
278
+ messages=[{"role": "user", "content": prompt}],
279
+ temperature=0
280
+ )
281
+
282
+ try:
283
+ data = json.loads(response.choices[0].message.content)
284
+ return model_class(**data)
285
+ except Exception as e:
286
+ if attempt == max_retries - 1:
287
+ print(f"Failed after {max_retries} attempts: {e}")
288
+ return None
289
+ print(f"Attempt {attempt + 1} failed, retrying...")
290
+ ```
291
+
292
+ ## Constraints
293
+ - **Model Consistency**: Not all models follow instructions perfectly - use function calling when possible
294
+ - **Temperature**: Use low temperature (0-0.3) for more consistent formatting
295
+ - **Complexity**: Very complex structures may require multiple extraction steps
296
+ - **Validation**: Always validate parsed data before using it
297
+ - **Error Handling**: Implement robust error handling for malformed responses
298
+ - **Token Limits**: Large schemas consume tokens - keep them as minimal as possible
299
+
300
+ ## Expected Output
301
+ Reliable structured data extraction from unstructured text, with properly validated and typed results that can be directly used in applications.
TRAE-Skills/ai_engineering/Time_Series_Forecasting.md ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Skill: Time Series Forecasting
2
+
3
+ ## Purpose
4
+ To predict future values based on previously observed time-ordered data, considering trends, seasonality, and exogenous variables.
5
+
6
+ ## When to Use
7
+ - When forecasting sales, inventory, stock prices, or resource demand
8
+ - When identifying anomalies in system metrics over time
9
+ - When working with IoT sensor data
10
+
11
+ ## Procedure
12
+
13
+ ### 1. Identify the Time Series Characteristics
14
+ Analyze the data for:
15
+ - **Trend**: Long-term upward or downward movement.
16
+ - **Seasonality**: Repeating patterns at fixed intervals (daily, weekly, yearly).
17
+ - **Stationarity**: Whether statistical properties (mean, variance) change over time.
18
+
19
+ ### 2. Choose the Forecasting Model
20
+ Select an appropriate algorithm based on data complexity:
21
+ - **ARIMA / SARIMA**: Traditional statistical models. Best for univariate data with clear seasonality.
22
+ - **Prophet (by Meta)**: Excellent for business time series with daily observations and strong seasonal effects.
23
+ - **XGBoost / LightGBM**: Effective for tabular time series with many exogenous features.
24
+ - **LSTMs / Transformers (e.g., Temporal Fusion Transformer)**: Best for complex, non-linear relationships and long sequences.
25
+
26
+ ### 3. Prophet Implementation Example
27
+
28
+ **Setup and Fitting**:
29
+ ```python
30
+ from prophet import Prophet
31
+ import pandas as pd
32
+
33
+ # Data must have 'ds' (datestamp) and 'y' (target) columns
34
+ df = pd.read_csv('sales_data.csv')
35
+ df.rename(columns={'date': 'ds', 'sales': 'y'}, inplace=True)
36
+
37
+ # Initialize Prophet model
38
+ m = Prophet(
39
+ yearly_seasonality=True,
40
+ weekly_seasonality=True,
41
+ daily_seasonality=False
42
+ )
43
+
44
+ # Add custom holidays or exogenous variables if necessary
45
+ m.add_country_holidays(country_name='US')
46
+
47
+ # Fit the model
48
+ m.fit(df)
49
+ ```
50
+
51
+ **Forecasting**:
52
+ ```python
53
+ # Create future dates
54
+ future = m.make_future_dataframe(periods=365)
55
+
56
+ # Predict future values
57
+ forecast = m.predict(future)
58
+
59
+ # Plotting results
60
+ fig1 = m.plot(forecast)
61
+ fig2 = m.plot_components(forecast)
62
+ ```
63
+
64
+ ### 4. Evaluation Metrics
65
+ Use appropriate error metrics for time series:
66
+ - **MAE (Mean Absolute Error)**: Easy to interpret, robust to outliers.
67
+ - **RMSE (Root Mean Squared Error)**: Penalizes large errors heavily.
68
+ - **MAPE (Mean Absolute Percentage Error)**: Useful for comparing relative performance across different scales.
69
+
70
+ ```python
71
+ from sklearn.metrics import mean_absolute_error, mean_squared_error
72
+ import numpy as np
73
+
74
+ mae = mean_absolute_error(y_true, y_pred)
75
+ rmse = np.sqrt(mean_squared_error(y_true, y_pred))
76
+ ```
77
+
78
+ ### 5. Cross-Validation
79
+ Do not use standard K-Fold cross-validation. Use Time Series Split to respect temporal order.
80
+
81
+ ```python
82
+ from sklearn.model_selection import TimeSeriesSplit
83
+
84
+ tscv = TimeSeriesSplit(n_splits=5)
85
+ for train_index, test_index in tscv.split(X):
86
+ X_train, X_test = X[train_index], X[test_index]
87
+ y_train, y_test = y[train_index], y[test_index]
88
+ # Train and evaluate model
89
+ ```
90
+
91
+ ## Best Practices
92
+ - Always plot your data before modeling. Visual inspection reveals obvious anomalies or structural breaks.
93
+ - Use baseline models (like naive forecasting or moving average) to establish a performance floor before moving to complex models.
94
+ - Handle missing values carefully; avoid interpolating over large gaps without justification.
TRAE-Skills/ai_engineering/Time_Series_Forecasting_LSTM.md ADDED
@@ -0,0 +1,233 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Skill: Time Series Forecasting with LSTM Networks
2
+
3
+ ## Purpose
4
+ To build accurate time series prediction models using Long Short-Term Memory (LSTM) neural networks.
5
+
6
+ ## When to Use
7
+ - For stock price prediction
8
+ - When forecasting sales or demand
9
+ - For predicting energy consumption
10
+ - When analyzing financial markets
11
+ - For weather forecasting with sequential data
12
+
13
+ ## Procedure
14
+
15
+ ### 1. Data Preparation
16
+ Prepare time series data for LSTM.
17
+
18
+ ```python
19
+ import numpy as np
20
+ import pandas as pd
21
+ import matplotlib.pyplot as plt
22
+ from sklearn.preprocessing import MinMaxScaler
23
+ from sklearn.model_selection import train_test_split
24
+
25
+ # Load sample data
26
+ df = pd.read_csv('time_series_data.csv', parse_dates=['date'], index_col='date')
27
+ data = df[['value']].values
28
+
29
+ # Normalize data
30
+ scaler = MinMaxScaler(feature_range=(0, 1))
31
+ scaled_data = scaler.fit_transform(data)
32
+
33
+ # Create sequences
34
+ def create_sequences(data, time_steps=60):
35
+ X, y = [], []
36
+ for i in range(time_steps, len(data)):
37
+ X.append(data[i-time_steps:i, 0])
38
+ y.append(data[i, 0])
39
+ return np.array(X), np.array(y)
40
+
41
+ time_steps = 60
42
+ X, y = create_sequences(scaled_data, time_steps)
43
+
44
+ # Reshape for LSTM (samples, time steps, features)
45
+ X = np.reshape(X, (X.shape[0], X.shape[1], 1))
46
+
47
+ # Split into train and test
48
+ X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, shuffle=False)
49
+ ```
50
+
51
+ ### 2. Build LSTM Model
52
+ Create an LSTM model with Keras.
53
+
54
+ ```python
55
+ from tensorflow.keras.models import Sequential
56
+ from tensorflow.keras.layers import LSTM, Dense, Dropout
57
+ from tensorflow.keras.optimizers import Adam
58
+ from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint
59
+
60
+ model = Sequential([
61
+ LSTM(50, return_sequences=True, input_shape=(X_train.shape[1], 1)),
62
+ Dropout(0.2),
63
+ LSTM(50, return_sequences=False),
64
+ Dropout(0.2),
65
+ Dense(25),
66
+ Dense(1)
67
+ ])
68
+
69
+ model.compile(optimizer=Adam(learning_rate=0.001), loss='mean_squared_error')
70
+
71
+ model.summary()
72
+ ```
73
+
74
+ ### 3. Train the Model
75
+ Train the LSTM model.
76
+
77
+ ```python
78
+ callbacks = [
79
+ EarlyStopping(monitor='val_loss', patience=10, restore_best_weights=True),
80
+ ModelCheckpoint('best_model.h5', monitor='val_loss', save_best_only=True)
81
+ ]
82
+
83
+ history = model.fit(
84
+ X_train, y_train,
85
+ batch_size=32,
86
+ epochs=100,
87
+ validation_data=(X_test, y_test),
88
+ callbacks=callbacks
89
+ )
90
+
91
+ # Plot training history
92
+ plt.figure(figsize=(12, 6))
93
+ plt.plot(history.history['loss'], label='Training Loss')
94
+ plt.plot(history.history['val_loss'], label='Validation Loss')
95
+ plt.title('Model Loss')
96
+ plt.xlabel('Epoch')
97
+ plt.ylabel('Loss')
98
+ plt.legend()
99
+ plt.show()
100
+ ```
101
+
102
+ ### 4. Make Predictions
103
+ Generate predictions with the trained model.
104
+
105
+ ```python
106
+ # Predict on test data
107
+ predictions = model.predict(X_test)
108
+ predictions = scaler.inverse_transform(predictions)
109
+ y_test_actual = scaler.inverse_transform(y_test.reshape(-1, 1))
110
+
111
+ # Plot results
112
+ train = df[:-len(y_test)]
113
+ valid = df[-len(y_test):]
114
+ valid['Predictions'] = predictions
115
+
116
+ plt.figure(figsize=(16, 8))
117
+ plt.title('Time Series Prediction')
118
+ plt.xlabel('Date', fontsize=18)
119
+ plt.ylabel('Value', fontsize=18)
120
+ plt.plot(train['value'])
121
+ plt.plot(valid[['value', 'Predictions']])
122
+ plt.legend(['Training Data', 'Actual Value', 'Predicted Value'], loc='lower right')
123
+ plt.show()
124
+ ```
125
+
126
+ ### 5. Evaluate the Model
127
+ Calculate evaluation metrics.
128
+
129
+ ```python
130
+ from sklearn.metrics import mean_squared_error, mean_absolute_error, mean_absolute_percentage_error
131
+
132
+ rmse = np.sqrt(mean_squared_error(y_test_actual, predictions))
133
+ mae = mean_absolute_error(y_test_actual, predictions)
134
+ mape = mean_absolute_percentage_error(y_test_actual, predictions)
135
+
136
+ print(f'RMSE: {rmse:.2f}')
137
+ print(f'MAE: {mae:.2f}')
138
+ print(f'MAPE: {mape:.2%}')
139
+ ```
140
+
141
+ ### 6. Multi-Step Forecasting
142
+ Predict multiple future time steps.
143
+
144
+ ```python
145
+ def multi_step_forecast(model, last_sequence, steps, scaler, time_steps):
146
+ forecast = []
147
+ current_sequence = last_sequence.copy()
148
+
149
+ for _ in range(steps):
150
+ # Predict next step
151
+ prediction = model.predict(current_sequence.reshape(1, time_steps, 1), verbose=0)
152
+
153
+ # Store prediction
154
+ forecast.append(prediction[0, 0])
155
+
156
+ # Update sequence
157
+ current_sequence = np.roll(current_sequence, -1)
158
+ current_sequence[-1] = prediction[0, 0]
159
+
160
+ # Inverse transform
161
+ forecast = scaler.inverse_transform(np.array(forecast).reshape(-1, 1))
162
+ return forecast.flatten()
163
+
164
+ # Get the last sequence from training data
165
+ last_sequence = X_test[-1]
166
+
167
+ # Forecast next 30 days
168
+ forecast_steps = 30
169
+ forecast = multi_step_forecast(model, last_sequence, forecast_steps, scaler, time_steps)
170
+
171
+ # Create future dates
172
+ last_date = df.index[-1]
173
+ future_dates = pd.date_range(start=last_date + pd.Timedelta(days=1), periods=forecast_steps)
174
+
175
+ # Plot forecast
176
+ plt.figure(figsize=(16, 8))
177
+ plt.plot(df['value'], label='Historical Data')
178
+ plt.plot(future_dates, forecast, label='Forecast', linestyle='--')
179
+ plt.title('Multi-Step Time Series Forecast')
180
+ plt.xlabel('Date')
181
+ plt.ylabel('Value')
182
+ plt.legend()
183
+ plt.show()
184
+ ```
185
+
186
+ ### 7. Multivariate LSTM
187
+ Use multiple features for prediction.
188
+
189
+ ```python
190
+ # Load data with multiple features
191
+ df = pd.read_csv('multivariate_data.csv', parse_dates=['date'], index_col='date')
192
+ features = ['value', 'feature1', 'feature2', 'feature3']
193
+ data = df[features].values
194
+
195
+ # Normalize all features
196
+ scaler = MinMaxScaler(feature_range=(0, 1))
197
+ scaled_data = scaler.fit_transform(data)
198
+
199
+ # Create sequences with multiple features
200
+ def create_multivariate_sequences(data, time_steps=60):
201
+ X, y = [], []
202
+ for i in range(time_steps, len(data)):
203
+ X.append(data[i-time_steps:i, :]) # All features
204
+ y.append(data[i, 0]) # Target is first feature
205
+ return np.array(X), np.array(y)
206
+
207
+ time_steps = 60
208
+ X, y = create_multivariate_sequences(scaled_data, time_steps)
209
+
210
+ # Build multivariate LSTM model
211
+ model = Sequential([
212
+ LSTM(100, return_sequences=True, input_shape=(X.shape[1], X.shape[2])),
213
+ Dropout(0.3),
214
+ LSTM(100, return_sequences=False),
215
+ Dropout(0.3),
216
+ Dense(50),
217
+ Dense(1)
218
+ ])
219
+
220
+ model.compile(optimizer=Adam(learning_rate=0.001), loss='mean_squared_error')
221
+ ```
222
+
223
+ ## Best Practices
224
+ - **Normalize/Standardize**: Always normalize time series data
225
+ - **Sequence Length**: Choose appropriate time step window
226
+ - **Validation**: Use walk-forward validation for time series
227
+ - **Regularization**: Use dropout to prevent overfitting
228
+ - **Early Stopping**: Stop training when validation loss stops improving
229
+ - **Feature Engineering**: Create meaningful features (lags, rolling stats)
230
+ - **Ensemble**: Combine with ARIMA, Prophet for better results
231
+ - **Hyperparameter Tuning**: Optimize layers, units, learning rate
232
+ - **Monitor**: Track performance on both train and validation sets
233
+ - **Update**: Retrain model periodically with new data
TRAE-Skills/ai_engineering/Token_Optimization.md ADDED
@@ -0,0 +1,245 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Skill: Token Optimization
2
+
3
+ ## Purpose
4
+ To minimize token usage while maintaining output quality, reducing API costs and improving response times.
5
+
6
+ ## When to Use
7
+ - When working with large documents or contexts
8
+ - When building cost-sensitive applications
9
+ - When processing multiple documents
10
+ - When optimizing for faster responses
11
+
12
+ ## Procedure
13
+
14
+ ### 1. Prune Redundant Content
15
+ Remove unnecessary information from prompts.
16
+
17
+ ```python
18
+ def prune_redundant_content(text):
19
+ """Remove redundant phrases and content."""
20
+ # Common redundant phrases to remove
21
+ redundant_phrases = [
22
+ "please note that",
23
+ "it is important to mention",
24
+ "as previously stated",
25
+ "in conclusion",
26
+ "additionally",
27
+ "furthermore",
28
+ "moreover"
29
+ ]
30
+
31
+ pruned = text
32
+ for phrase in redundant_phrases:
33
+ pruned = pruned.replace(phrase, "")
34
+
35
+ # Remove multiple spaces
36
+ pruned = " ".join(pruned.split())
37
+
38
+ return pruned
39
+
40
+ # Example
41
+ original = """Please note that it is important to mention that the document
42
+ contains multiple sections. Furthermore, additionally, it has various topics."""
43
+
44
+ optimized = prune_redundant_content(original)
45
+ print(f"Original: {len(original)} tokens")
46
+ print(f"Optimized: {len(optimized)} tokens")
47
+ ```
48
+
49
+ ### 2. Use Efficient Prompt Structures
50
+ Structure prompts to maximize information density.
51
+
52
+ ```python
53
+ # INEFFICIENT - verbose prompt
54
+ inefficient_prompt = """
55
+ I would like you to please help me by analyzing the following text.
56
+ Please provide me with a summary of the main points.
57
+ The text is as follows: {text}
58
+ """
59
+
60
+ # EFFICIENT - concise prompt
61
+ efficient_prompt = """Summarize the main points: {text}"""
62
+
63
+ # Even more efficient with examples
64
+ few_shot_efficient = """Text: {text1}
65
+ Summary: {summary1}
66
+
67
+ Text: {text2}
68
+ Summary: {summary2}
69
+
70
+ Text: {text}
71
+ Summary:"""
72
+ ```
73
+
74
+ ### 3. Chunk and Summarize Large Documents
75
+ Process large documents in chunks with progressive summarization.
76
+
77
+ ```python
78
+ def chunk_text(text, max_chunk_size=2000):
79
+ """Split text into chunks of roughly equal token count."""
80
+ words = text.split()
81
+ chunks = []
82
+ current_chunk = []
83
+ current_length = 0
84
+
85
+ for word in words:
86
+ current_chunk.append(word)
87
+ current_length += 1
88
+
89
+ if current_length >= max_chunk_size:
90
+ chunks.append(" ".join(current_chunk))
91
+ current_chunk = []
92
+ current_length = 0
93
+
94
+ if current_chunk:
95
+ chunks.append(" ".join(current_chunk))
96
+
97
+ return chunks
98
+
99
+ def progressive_summarize(text):
100
+ """Summarize large document progressively."""
101
+ # Split into chunks
102
+ chunks = chunk_text(text, max_chunk_size=2000)
103
+
104
+ # Summarize each chunk
105
+ chunk_summaries = []
106
+ for chunk in chunks:
107
+ summary = client.chat.completions.create(
108
+ model="gpt-4",
109
+ messages=[{
110
+ "role": "user",
111
+ "content": f"Summarize in 1-2 sentences: {chunk}"
112
+ }]
113
+ )
114
+ chunk_summaries.append(summary.choices[0].message.content)
115
+
116
+ # Combine chunk summaries
117
+ combined = " ".join(chunk_summaries)
118
+
119
+ # Final summary
120
+ final_summary = client.chat.completions.create(
121
+ model="gpt-4",
122
+ messages=[{
123
+ "role": "user",
124
+ "content": f"Create a cohesive summary: {combined}"
125
+ }]
126
+ )
127
+
128
+ return final_summary.choices[0].message.content
129
+ ```
130
+
131
+ ### 4. Use System Messages Effectively
132
+ Move static context to system messages.
133
+
134
+ ```python
135
+ # INEFFICIENT - repeating instructions in every message
136
+ messages_inefficient = [
137
+ {
138
+ "role": "user",
139
+ "content": "You are a helpful assistant that provides concise answers.
140
+ Please answer this question: What is machine learning?"
141
+ }
142
+ ]
143
+
144
+ # EFFICIENT - use system message
145
+ messages_efficient = [
146
+ {
147
+ "role": "system",
148
+ "content": "You are a helpful assistant. Provide concise answers in 2-3 sentences."
149
+ },
150
+ {
151
+ "role": "user",
152
+ "content": "What is machine learning?"
153
+ }
154
+ ]
155
+ ```
156
+
157
+ ### 5. Use Smaller Models When Appropriate
158
+ Choose the right model for the task.
159
+
160
+ ```python
161
+ def choose_model(task_complexity, token_count):
162
+ """Choose the most cost-effective model."""
163
+ if token_count < 500 and task_complexity == "simple":
164
+ return "gpt-3.5-turbo"
165
+ elif token_count < 2000 and task_complexity in ["simple", "medium"]:
166
+ return "gpt-3.5-turbo"
167
+ else:
168
+ return "gpt-4"
169
+
170
+ # Example usage
171
+ text = "Your text here..."
172
+ token_count = len(text.split()) * 1.3 # Rough estimate
173
+ model = choose_model("medium", token_count)
174
+
175
+ response = client.chat.completions.create(
176
+ model=model,
177
+ messages=[{"role": "user", "content": text}]
178
+ )
179
+ ```
180
+
181
+ ### 6. Implement Token Counting and Budgeting
182
+ Track and limit token usage.
183
+
184
+ ```python
185
+ import tiktoken
186
+
187
+ def count_tokens(text, model="gpt-4"):
188
+ """Count tokens in text."""
189
+ encoding = tiktoken.encoding_for_model(model)
190
+ return len(encoding.encode(text))
191
+
192
+ class TokenBudget:
193
+ def __init__(self, max_tokens=100000):
194
+ self.max_tokens = max_tokens
195
+ self.used_tokens = 0
196
+ self.encoding = tiktoken.encoding_for_model("gpt-4")
197
+
198
+ def can_process(self, text):
199
+ """Check if we can process this text within budget."""
200
+ tokens = count_tokens(text)
201
+ return (self.used_tokens + tokens) <= self.max_tokens
202
+
203
+ def process(self, text, function):
204
+ """Process text if within budget."""
205
+ if not self.can_process(text):
206
+ raise Exception("Token budget exceeded!")
207
+
208
+ tokens = count_tokens(text)
209
+ self.used_tokens += tokens
210
+
211
+ return function(text)
212
+
213
+ def get_usage(self):
214
+ """Get current token usage."""
215
+ return {
216
+ "used": self.used_tokens,
217
+ "remaining": self.max_tokens - self.used_tokens,
218
+ "percentage": (self.used_tokens / self.max_tokens) * 100
219
+ }
220
+
221
+ # Usage
222
+ budget = TokenBudget(max_tokens=50000)
223
+
224
+ def make_llm_call(text):
225
+ return client.chat.completions.create(
226
+ model="gpt-4",
227
+ messages=[{"role": "user", "content": text}]
228
+ )
229
+
230
+ try:
231
+ result = budget.process("Your text here", make_llm_call)
232
+ print(budget.get_usage())
233
+ except Exception as e:
234
+ print(f"Error: {e}")
235
+ ```
236
+
237
+ ## Constraints
238
+ - **Quality vs. Cost**: Aggressive optimization may impact output quality
239
+ - **Context Loss**: Removing too much content may lose important information
240
+ - **Model Limitations**: Different models have different capabilities
241
+ - **Token Estimation**: Token counts are estimates, not exact
242
+ - **Budget Planning**: Always include buffer for unexpected token usage
243
+
244
+ ## Expected Output
245
+ Reduced API costs (30-70% savings) while maintaining acceptable output quality through intelligent token optimization strategies.
TRAE-Skills/ai_engineering/Vector_Database_Setup.md ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Skill: Vector Database Setup
2
+
3
+ ## Purpose
4
+ To provision and configure a vector database (Vector DB) for storing high-dimensional embeddings, enabling semantic search and RAG applications.
5
+
6
+ ## When to Use
7
+ - Implementing RAG (Retrieval-Augmented Generation).
8
+ - Building recommendation systems based on similarity.
9
+ - Implementing semantic search (search by meaning, not just keywords).
10
+
11
+ ## Procedure
12
+
13
+ ### 1. Choice of Database (Selection)
14
+ - **Pinecone**: Best for managed, serverless, and fast scaling.
15
+ - **pgvector**: Best for existing PostgreSQL users who want to keep data in one place.
16
+ - **Chroma**: Best for local development and simple prototyping.
17
+
18
+ ### 2. Implementation: Pinecone (Managed)
19
+ Install the client and initialize the index.
20
+
21
+ ```bash
22
+ npm install @pinecone-database/pinecone
23
+ ```
24
+
25
+ ```typescript
26
+ import { Pinecone } from '@pinecone-database/pinecone';
27
+
28
+ const pc = new Pinecone({ apiKey: process.env.PINECONE_API_KEY! });
29
+
30
+ async function setupIndex() {
31
+ await pc.createIndex({
32
+ name: 'my-index',
33
+ dimension: 1536, // Must match embedding model (e.g., text-embedding-3-small)
34
+ metric: 'cosine',
35
+ spec: {
36
+ serverless: {
37
+ cloud: 'aws',
38
+ region: 'us-east-1'
39
+ }
40
+ }
41
+ });
42
+ }
43
+ ```
44
+
45
+ ### 3. Implementation: pgvector (PostgreSQL)
46
+ Enable the extension and create a table with a vector column.
47
+
48
+ ```sql
49
+ -- 1. Enable extension
50
+ CREATE EXTENSION IF NOT EXISTS vector;
51
+
52
+ -- 2. Create table
53
+ CREATE TABLE documents (
54
+ id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
55
+ content text,
56
+ metadata jsonb,
57
+ embedding vector(1536) -- Match your model's dimensions
58
+ );
59
+
60
+ -- 3. Create index for fast search (HNSW is recommended)
61
+ CREATE INDEX ON documents USING hnsw (embedding vector_cosine_ops);
62
+ ```
63
+
64
+ ### 4. Data Insertion (Upsert)
65
+ Always batch your insertions for efficiency.
66
+
67
+ ```typescript
68
+ // Pinecone example
69
+ const index = pc.index('my-index');
70
+
71
+ await index.upsert([
72
+ {
73
+ id: 'doc1',
74
+ values: [0.1, 0.2, ...], // The embedding vector
75
+ metadata: { text: 'The actual content...', category: 'legal' }
76
+ }
77
+ ]);
78
+ ```
79
+
80
+ ### 5. Querying (Semantic Search)
81
+ Perform a similarity search using a query vector.
82
+
83
+ ```typescript
84
+ const queryResponse = await index.query({
85
+ vector: [0.1, 0.2, ...], // Vector of the user query
86
+ topK: 5,
87
+ includeMetadata: true,
88
+ });
89
+ ```
90
+
91
+ ## Constraints
92
+ - **Dimension Matching**: The dimension of the index MUST exactly match the output dimension of your embedding model.
93
+ - **Metric Selection**: Use `cosine` for text; `euclidean` or `dotproduct` for other specific use cases.
94
+ - **Batch Limits**: Most vector DBs have limits on payload size per upsert (e.g., 2MB or 100 vectors).
95
+
96
+ ## Expected Output
97
+ A fully configured vector index ready for high-speed similarity searches and data retrieval.
TRAE-Skills/ai_engineering/Vector_Databases_Pinecone_Weaviate.md ADDED
@@ -0,0 +1,220 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Skill: Advanced Vector Databases (Pinecone & Weaviate)
2
+
3
+ ## Purpose
4
+ To build production-ready RAG, semantic search, and similarity systems with modern vector databases.
5
+
6
+ ## When to Use
7
+ - For building semantic search over large document collections
8
+ - When implementing RAG (Retrieval-Augmented Generation)
9
+ - For recommendation systems using embeddings
10
+ - When building question-answering systems
11
+ - For similarity search (images, text, audio)
12
+
13
+ ## Procedure
14
+
15
+ ### 1. Pinecone Setup & Indexing
16
+ Get started with Pinecone.
17
+
18
+ ```python
19
+ import os
20
+ from pinecone import Pinecone, ServerlessSpec
21
+ from langchain_openai import OpenAIEmbeddings
22
+ from langchain_core.documents import Document
23
+ from langchain_pinecone import PineconeVectorStore
24
+
25
+ # Initialize Pinecone
26
+ pc = Pinecone(api_key=os.getenv("PINECONE_API_KEY"))
27
+
28
+ # Create index
29
+ index_name = "rag-index"
30
+ if index_name not in pc.list_indexes().names():
31
+ pc.create_index(
32
+ name=index_name,
33
+ dimension=1536, # text-embedding-3-small
34
+ metric="cosine",
35
+ spec=ServerlessSpec(cloud="aws", region="us-east-1")
36
+ )
37
+
38
+ # Connect to index
39
+ index = pc.Index(index_name)
40
+
41
+ # Create embeddings
42
+ embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
43
+
44
+ # Sample documents
45
+ documents = [
46
+ Document(page_content="LangGraph is a library for building stateful agents.", metadata={"source": "doc1", "category": "ai"}),
47
+ Document(page_content="Vector databases store embeddings for similarity search.", metadata={"source": "doc2", "category": "database"}),
48
+ Document(page_content="RAG combines retrieval with LLM generation.", metadata={"source": "doc3", "category": "ai"}),
49
+ Document(page_content="Pinecone is a serverless vector database.", metadata={"source": "doc4", "category": "database"})
50
+ ]
51
+
52
+ # Add to vector store
53
+ vector_store = PineconeVectorStore.from_documents(
54
+ documents=documents,
55
+ embedding=embeddings,
56
+ index_name=index_name,
57
+ namespace="production"
58
+ )
59
+ ```
60
+
61
+ ### 2. Advanced Retrieval with Pinecone
62
+ Implement hybrid search and filtering.
63
+
64
+ ```python
65
+ # Semantic search
66
+ results = vector_store.similarity_search(
67
+ "What is LangGraph?",
68
+ k=3,
69
+ filter={"category": "ai"} # Metadata filtering
70
+ )
71
+
72
+ # Similarity search with score
73
+ results_with_scores = vector_store.similarity_search_with_score(
74
+ "Tell me about vector databases",
75
+ k=3
76
+ )
77
+
78
+ # Hybrid search (dense + sparse)
79
+ # Use Pinecone's hybrid search with BM25
80
+ from langchain_community.retrievers import PineconeHybridSearchRetriever
81
+ from pinecone_text.sparse import BM25Encoder
82
+
83
+ bm25_encoder = BM25Encoder()
84
+ bm25_encoder.fit([d.page_content for d in documents])
85
+
86
+ hybrid_retriever = PineconeHybridSearchRetriever(
87
+ embeddings=embeddings,
88
+ sparse_encoder=bm25_encoder,
89
+ index=index,
90
+ namespace="production",
91
+ top_k=3
92
+ )
93
+
94
+ hybrid_results = hybrid_retriever.invoke("What is RAG?")
95
+ ```
96
+
97
+ ### 3. Weaviate Setup
98
+ Use Weaviate for self-hosted or managed vector search.
99
+
100
+ ```python
101
+ import weaviate
102
+ import weaviate.classes as wvc
103
+ from weaviate.classes.config import Property, DataType, Configure
104
+
105
+ # Connect to Weaviate
106
+ client = weaviate.connect_to_wcs(
107
+ cluster_url=os.getenv("WEAVIATE_CLUSTER_URL"),
108
+ auth_credentials=weaviate.auth.AuthApiKey(os.getenv("WEAVIATE_API_KEY")),
109
+ headers={
110
+ "X-OpenAI-Api-Key": os.getenv("OPENAI_API_KEY")
111
+ }
112
+ )
113
+
114
+ # Create collection
115
+ if not client.collections.exists("Document"):
116
+ collection = client.collections.create(
117
+ name="Document",
118
+ vectorizer_config=Configure.Vectorizer.text2vec_openai(model="text-embedding-3-small"),
119
+ generative_config=Configure.Generative.openai(model="gpt-4o"),
120
+ properties=[
121
+ Property(name="content", data_type=DataType.TEXT),
122
+ Property(name="source", data_type=DataType.TEXT),
123
+ Property(name="category", data_type=DataType.TEXT),
124
+ Property(name="created_at", data_type=DataType.DATE)
125
+ ]
126
+ )
127
+ else:
128
+ collection = client.collections.get("Document")
129
+
130
+ # Add objects
131
+ with collection.batch.dynamic() as batch:
132
+ for doc in documents:
133
+ batch.add_object(
134
+ properties={
135
+ "content": doc.page_content,
136
+ "source": doc.metadata["source"],
137
+ "category": doc.metadata["category"],
138
+ "created_at": "2024-01-01T00:00:00Z"
139
+ }
140
+ )
141
+ ```
142
+
143
+ ### 4. Weaviate Generative Search (RAG)
144
+ Built-in generative search with Weaviate.
145
+
146
+ ```python
147
+ # Basic search
148
+ response = collection.query.near_text(
149
+ query="What is LangGraph?",
150
+ limit=3,
151
+ filters=wvc.query.Filter.by_property("category").equal("ai"),
152
+ return_properties=["content", "source"]
153
+ )
154
+
155
+ # Generative search (RAG)
156
+ generative_response = collection.generate.near_text(
157
+ query="Explain LangGraph in simple terms",
158
+ limit=3,
159
+ single_prompt="Summarize this content: {content}"
160
+ )
161
+
162
+ for obj in generative_response.objects:
163
+ print(f"Source: {obj.properties['source']}")
164
+ print(f"Generated: {obj.generated}")
165
+ print("---")
166
+
167
+ # Grouped task
168
+ grouped_response = collection.generate.near_text(
169
+ query="Tell me about vector databases",
170
+ limit=5,
171
+ grouped_task="Write a comprehensive summary of all these documents"
172
+ )
173
+
174
+ print("Grouped Summary:", grouped_response.generated)
175
+ ```
176
+
177
+ ### 5. Production Best Practices
178
+ Optimize vector DB for production.
179
+
180
+ ```python
181
+ # Pinecone optimization
182
+ # 1. Use namespaces for isolation
183
+ vector_store = PineconeVectorStore(
184
+ index=index,
185
+ embedding=embeddings,
186
+ namespace="tenant-123"
187
+ )
188
+
189
+ # 2. Batch operations
190
+ from langchain.text_splitter import RecursiveCharacterTextSplitter
191
+
192
+ text_splitter = RecursiveCharacterTextSplitter(
193
+ chunk_size=1000,
194
+ chunk_overlap=200
195
+ )
196
+
197
+ split_docs = text_splitter.split_documents(documents)
198
+
199
+ # Add in batches
200
+ for i in range(0, len(split_docs), 100):
201
+ batch = split_docs[i:i+100]
202
+ vector_store.add_documents(batch)
203
+
204
+ # 3. Weaviate: Use tenant isolation
205
+ multi_tenancy_config = Configure.multi_tenancy(enabled=True)
206
+
207
+ # 4. Monitor usage
208
+ stats = index.describe_index_stats()
209
+ print(f"Total vectors: {stats['total_vector_count']}")
210
+ ```
211
+
212
+ ## Best Practices
213
+ - **Embedding Model**: Choose appropriate embedding model (dimensions, cost)
214
+ - **Chunking**: Use good text splitting strategy (chunk size, overlap)
215
+ - **Metadata**: Add rich metadata for filtering
216
+ - **Indexing**: Use batch operations for large datasets
217
+ - **Hybrid Search**: Combine vector + keyword search for better results
218
+ - **Namespaces/Tenants**: Isolate data for multi-tenant apps
219
+ - **Monitoring**: Monitor query latency and cost
220
+ - **Caching**: Cache frequent queries to reduce cost
TRAE-Skills/architecture/API_Gateway_Pattern.md ADDED
@@ -0,0 +1,488 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Skill: API Gateway Pattern
2
+
3
+ ## Purpose
4
+ To provide a single entry point for microservices by implementing a centralized API gateway that handles routing, authentication, rate limiting, and cross-cutting concerns.
5
+
6
+ ## When to Use
7
+ - When building microservices architectures
8
+ - When you need a single entry point for multiple services
9
+ - When implementing cross-cutting concerns like auth, logging, rate limiting
10
+ - When aggregating responses from multiple services
11
+
12
+ ## Procedure
13
+
14
+ ### 1. Basic API Gateway Setup
15
+ Implement a basic API gateway with routing.
16
+
17
+ ```python
18
+ from fastapi import FastAPI, HTTPException, Request
19
+ from fastapi.responses import JSONResponse
20
+ from httpx import AsyncClient
21
+ import logging
22
+ from typing import Dict, Any
23
+ import asyncio
24
+
25
+ class APIGateway:
26
+ """API Gateway for microservices."""
27
+
28
+ def __init__(self):
29
+ self.app = FastAPI(title="API Gateway")
30
+ self.services: Dict[str, str] = {}
31
+ self.client = AsyncClient()
32
+ self.logger = logging.getLogger("APIGateway")
33
+
34
+ # Setup middleware
35
+ self._setup_middleware()
36
+
37
+ # Setup routes
38
+ self._setup_routes()
39
+
40
+ def _setup_middleware(self):
41
+ """Setup gateway middleware."""
42
+ @self.app.middleware("http")
43
+ async def log_requests(request: Request, call_next):
44
+ start_time = asyncio.get_event_loop().time()
45
+
46
+ # Log request
47
+ self.logger.info(f"Incoming request: {request.method} {request.url.path}")
48
+
49
+ # Process request
50
+ response = await call_next(request)
51
+
52
+ # Log response
53
+ process_time = asyncio.get_event_loop().time() - start_time
54
+ self.logger.info(f"Request completed in {process_time:.3f}s")
55
+
56
+ response.headers["X-Process-Time"] = str(process_time)
57
+ return response
58
+
59
+ def _setup_routes(self):
60
+ """Setup gateway routes."""
61
+
62
+ @self.app.get("/health")
63
+ async def health_check():
64
+ return {"status": "healthy", "gateway": "API Gateway v1.0"}
65
+
66
+ @self.app.api_route("/{service}/{path:path}", methods=["GET", "POST", "PUT", "DELETE"])
67
+ async def proxy_request(service: str, path: str, request: Request):
68
+ """Proxy request to appropriate service."""
69
+ if service not in self.services:
70
+ raise HTTPException(status_code=404, detail=f"Service '{service}' not found")
71
+
72
+ service_url = self.services[service]
73
+ target_url = f"{service_url}/{path}"
74
+
75
+ # Forward request
76
+ body = await request.body()
77
+ headers = dict(request.headers)
78
+
79
+ try:
80
+ response = await self.client.request(
81
+ method=request.method,
82
+ url=target_url,
83
+ headers=headers,
84
+ content=body,
85
+ timeout=30.0
86
+ )
87
+
88
+ return JSONResponse(
89
+ content=response.json(),
90
+ status_code=response.status_code,
91
+ headers=dict(response.headers)
92
+ )
93
+
94
+ except Exception as e:
95
+ self.logger.error(f"Error proxying request: {str(e)}")
96
+ raise HTTPException(status_code=503, detail="Service unavailable")
97
+
98
+ def register_service(self, name: str, url: str):
99
+ """Register a microservice."""
100
+ self.services[name] = url
101
+ self.logger.info(f"Registered service: {name} -> {url}")
102
+
103
+ def get_app(self):
104
+ """Get FastAPI application."""
105
+ return self.app
106
+
107
+ # Usage
108
+ gateway = APIGateway()
109
+
110
+ # Register services
111
+ gateway.register_service("users", "http://localhost:8001")
112
+ gateway.register_service("products", "http://localhost:8002")
113
+ gateway.register_service("orders", "http://localhost:8003")
114
+
115
+ app = gateway.get_app()
116
+ ```
117
+
118
+ ### 2. Authentication and Authorization
119
+ Implement authentication middleware.
120
+
121
+ ```python
122
+ from fastapi import Security, HTTPException, status
123
+ from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
124
+ import jwt
125
+ from datetime import datetime, timedelta
126
+
127
+ security = HTTPBearer()
128
+
129
+ class AuthMiddleware:
130
+ """Authentication middleware for API Gateway."""
131
+
132
+ def __init__(self, secret_key: str, algorithm: str = "HS256"):
133
+ self.secret_key = secret_key
134
+ self.algorithm = algorithm
135
+
136
+ def create_token(self, user_id: str, permissions: list, expires_delta: timedelta = None):
137
+ """Create JWT token."""
138
+ if expires_delta:
139
+ expire = datetime.utcnow() + expires_delta
140
+ else:
141
+ expire = datetime.utcnow() + timedelta(hours=1)
142
+
143
+ payload = {
144
+ "user_id": user_id,
145
+ "permissions": permissions,
146
+ "exp": expire
147
+ }
148
+
149
+ return jwt.encode(payload, self.secret_key, algorithm=self.algorithm)
150
+
151
+ def verify_token(self, token: str) -> Dict[str, Any]:
152
+ """Verify JWT token."""
153
+ try:
154
+ payload = jwt.decode(token, self.secret_key, algorithms=[self.algorithm])
155
+ return payload
156
+ except jwt.ExpiredSignatureError:
157
+ raise HTTPException(
158
+ status_code=status.HTTP_401_UNAUTHORIZED,
159
+ detail="Token expired"
160
+ )
161
+ except jwt.JWTError:
162
+ raise HTTPException(
163
+ status_code=status.HTTP_401_UNAUTHORIZED,
164
+ detail="Invalid token"
165
+ )
166
+
167
+ def check_permission(self, required_permission: str):
168
+ """Check if user has required permission."""
169
+ async def permission_checker(credentials: HTTPAuthorizationCredentials = Security(security)):
170
+ payload = self.verify_token(credentials.credentials)
171
+ permissions = payload.get("permissions", [])
172
+
173
+ if required_permission not in permissions:
174
+ raise HTTPException(
175
+ status_code=status.HTTP_403_FORBIDDEN,
176
+ detail=f"Permission '{required_permission}' required"
177
+ )
178
+
179
+ return payload
180
+
181
+ return permission_checker
182
+
183
+ # Integrate with gateway
184
+ auth_middleware = AuthMiddleware(secret_key="your-secret-key")
185
+
186
+ @gateway.app.get("/protected")
187
+ async def protected_endpoint(user_data: Dict = Depends(auth_middleware.check_permission("read:protected"))):
188
+ return {"message": "Access granted", "user": user_data["user_id"]}
189
+ ```
190
+
191
+ ### 3. Rate Limiting
192
+ Implement rate limiting for API protection.
193
+
194
+ ```python
195
+ from fastapi import Request, HTTPException
196
+ from collections import defaultdict
197
+ import time
198
+ from typing import Dict
199
+
200
+ class RateLimiter:
201
+ """Rate limiter using sliding window algorithm."""
202
+
203
+ def __init__(self, requests_per_minute: int = 60):
204
+ self.requests_per_minute = requests_per_minute
205
+ self.requests: Dict[str, list] = defaultdict(list)
206
+
207
+ def is_allowed(self, key: str) -> bool:
208
+ """Check if request is allowed."""
209
+ now = time.time()
210
+ minute_ago = now - 60
211
+
212
+ # Remove old requests
213
+ self.requests[key] = [
214
+ req_time for req_time in self.requests[key]
215
+ if req_time > minute_ago
216
+ ]
217
+
218
+ # Check if under limit
219
+ if len(self.requests[key]) >= self.requests_per_minute:
220
+ return False
221
+
222
+ # Add current request
223
+ self.requests[key].append(now)
224
+ return True
225
+
226
+ class RateLimitMiddleware:
227
+ """Rate limiting middleware."""
228
+
229
+ def __init__(self, limiter: RateLimiter):
230
+ self.limiter = limiter
231
+
232
+ async def __call__(self, request: Request, call_next):
233
+ """Process request with rate limiting."""
234
+ # Use API key or IP address as key
235
+ api_key = request.headers.get("X-API-Key", request.client.host)
236
+
237
+ if not self.limiter.is_allowed(api_key):
238
+ raise HTTPException(
239
+ status_code=429,
240
+ detail="Too many requests"
241
+ )
242
+
243
+ return await call_next(request)
244
+
245
+ # Integrate with gateway
246
+ rate_limiter = RateLimiter(requests_per_minute=60)
247
+ gateway.app.middleware("http")(RateLimitMiddleware(rate_limiter))
248
+ ```
249
+
250
+ ### 4. Service Aggregation
251
+ Implement response aggregation from multiple services.
252
+
253
+ ```python
254
+ class ServiceAggregator:
255
+ """Aggregate responses from multiple services."""
256
+
257
+ def __init__(self, gateway: APIGateway):
258
+ self.gateway = gateway
259
+
260
+ async def aggregate_user_data(self, user_id: str) -> Dict[str, Any]:
261
+ """Aggregate user data from multiple services."""
262
+ tasks = [
263
+ self.fetch_user_profile(user_id),
264
+ self.fetch_user_orders(user_id),
265
+ self.fetch_user_recommendations(user_id)
266
+ ]
267
+
268
+ results = await asyncio.gather(*tasks, return_exceptions=True)
269
+
270
+ return {
271
+ "user_id": user_id,
272
+ "profile": results[0] if not isinstance(results[0], Exception) else None,
273
+ "orders": results[1] if not isinstance(results[1], Exception) else None,
274
+ "recommendations": results[2] if not isinstance(results[2], Exception) else None
275
+ }
276
+
277
+ async def fetch_user_profile(self, user_id: str) -> Dict[str, Any]:
278
+ """Fetch user profile."""
279
+ service_url = self.gateway.services.get("users")
280
+ if not service_url:
281
+ raise ValueError("Users service not found")
282
+
283
+ response = await self.gateway.client.get(f"{service_url}/users/{user_id}")
284
+ return response.json()
285
+
286
+ async def fetch_user_orders(self, user_id: str) -> Dict[str, Any]:
287
+ """Fetch user orders."""
288
+ service_url = self.gateway.services.get("orders")
289
+ if not service_url:
290
+ raise ValueError("Orders service not found")
291
+
292
+ response = await self.gateway.client.get(f"{service_url}/orders/{user_id}")
293
+ return response.json()
294
+
295
+ async def fetch_user_recommendations(self, user_id: str) -> Dict[str, Any]:
296
+ """Fetch user recommendations."""
297
+ service_url = self.gateway.services.get("products")
298
+ if not service_url:
299
+ raise ValueError("Products service not found")
300
+
301
+ response = await self.gateway.client.get(f"{service_url}/recommendations/{user_id}")
302
+ return response.json()
303
+
304
+ # Add aggregation endpoint
305
+ aggregator = ServiceAggregator(gateway)
306
+
307
+ @gateway.app.get("/aggregate/user/{user_id}")
308
+ async def aggregate_user_endpoint(user_id: str):
309
+ """Aggregate user data."""
310
+ return await aggregator.aggregate_user_data(user_id)
311
+ ```
312
+
313
+ ### 5. Circuit Breaker Pattern
314
+ Implement circuit breaker for fault tolerance.
315
+
316
+ ```python
317
+ from enum import Enum
318
+ import asyncio
319
+
320
+ class CircuitState(Enum):
321
+ CLOSED = "closed" # Normal operation
322
+ OPEN = "open" # Failing, reject requests
323
+ HALF_OPEN = "half_open" # Testing if service recovered
324
+
325
+ class CircuitBreaker:
326
+ """Circuit breaker for service resilience."""
327
+
328
+ def __init__(self, failure_threshold: int = 5, timeout: int = 60):
329
+ self.failure_threshold = failure_threshold
330
+ self.timeout = timeout
331
+ self.failure_count = 0
332
+ self.state = CircuitState.CLOSED
333
+ self.last_failure_time = None
334
+
335
+ def record_success(self):
336
+ """Record successful request."""
337
+ self.failure_count = 0
338
+ if self.state == CircuitState.HALF_OPEN:
339
+ self.state = CircuitState.CLOSED
340
+
341
+ def record_failure(self):
342
+ """Record failed request."""
343
+ self.failure_count += 1
344
+ self.last_failure_time = time.time()
345
+
346
+ if self.failure_count >= self.failure_threshold:
347
+ self.state = CircuitState.OPEN
348
+
349
+ def can_attempt(self) -> bool:
350
+ """Check if request can be attempted."""
351
+ if self.state == CircuitState.CLOSED:
352
+ return True
353
+
354
+ if self.state == CircuitState.OPEN:
355
+ if time.time() - self.last_failure_time > self.timeout:
356
+ self.state = CircuitState.HALF_OPEN
357
+ return True
358
+ return False
359
+
360
+ return True # HALF_OPEN state
361
+
362
+ class CircuitBreakerMiddleware:
363
+ """Circuit breaker middleware."""
364
+
365
+ def __init__(self):
366
+ self.circuit_breakers: Dict[str, CircuitBreaker] = {}
367
+
368
+ def get_breaker(self, service_name: str) -> CircuitBreaker:
369
+ """Get or create circuit breaker for service."""
370
+ if service_name not in self.circuit_breakers:
371
+ self.circuit_breakers[service_name] = CircuitBreaker()
372
+ return self.circuit_breakers[service_name]
373
+
374
+ async def call_with_breaker(self, service_name: str, callable_func, *args, **kwargs):
375
+ """Call service with circuit breaker protection."""
376
+ breaker = self.get_breaker(service_name)
377
+
378
+ if not breaker.can_attempt():
379
+ raise HTTPException(
380
+ status_code=503,
381
+ detail=f"Service '{service_name}' is temporarily unavailable"
382
+ )
383
+
384
+ try:
385
+ result = await callable_func(*args, **kwargs)
386
+ breaker.record_success()
387
+ return result
388
+ except Exception as e:
389
+ breaker.record_failure()
390
+ raise e
391
+
392
+ # Usage
393
+ circuit_breaker = CircuitBreakerMiddleware()
394
+
395
+ @gateway.app.get("/products/{product_id}")
396
+ async def get_product(product_id: str):
397
+ """Get product with circuit breaker protection."""
398
+ async def fetch_product():
399
+ service_url = gateway.services.get("products")
400
+ response = await gateway.client.get(f"{service_url}/products/{product_id}")
401
+ return response.json()
402
+
403
+ return await circuit_breaker.call_with_breaker("products", fetch_product)
404
+ ```
405
+
406
+ ### 6. Configuration and Service Discovery
407
+ Implement service discovery and configuration management.
408
+
409
+ ```python
410
+ import consul
411
+
412
+ class ServiceRegistry:
413
+ """Service registry using Consul."""
414
+
415
+ def __init__(self, consul_host: str = "localhost", consul_port: int = 8500):
416
+ self.consul = consul.Consul(host=consul_host, port=consul_port)
417
+ self.logger = logging.getLogger("ServiceRegistry")
418
+
419
+ def register_service(self, service_name: str, service_id: str, address: str, port: int):
420
+ """Register service with Consul."""
421
+ self.consul.agent.service.register(
422
+ name=service_name,
423
+ service_id=service_id,
424
+ address=address,
425
+ port=port,
426
+ check=consul.Check.http(f"http://{address}:{port}/health", interval="10s")
427
+ )
428
+ self.logger.info(f"Registered service: {service_name} ({service_id})")
429
+
430
+ def deregister_service(self, service_id: str):
431
+ """Deregister service from Consul."""
432
+ self.consul.agent.service.deregister(service_id)
433
+ self.logger.info(f"Deregistered service: {service_id}")
434
+
435
+ def discover_service(self, service_name: str) -> list:
436
+ """Discover service instances."""
437
+ _, services = self.consul.health.service(service_name, passing=True)
438
+
439
+ instances = []
440
+ for service in services:
441
+ instance = {
442
+ "id": service["Service"]["ID"],
443
+ "address": service["Service"]["Address"],
444
+ "port": service["Service"]["Port"]
445
+ }
446
+ instances.append(instance)
447
+
448
+ return instances
449
+
450
+ def get_service_url(self, service_name: str) -> str:
451
+ """Get service URL (load balanced)."""
452
+ instances = self.discover_service(service_name)
453
+ if not instances:
454
+ raise ValueError(f"No healthy instances found for {service_name}")
455
+
456
+ # Simple round-robin selection
457
+ instance = instances[0] # Could implement proper load balancing
458
+ return f"http://{instance['address']}:{instance['port']}"
459
+
460
+ # Integrate service discovery with gateway
461
+ service_registry = ServiceRegistry()
462
+
463
+ # Auto-discover and register services
464
+ async def refresh_services():
465
+ """Refresh service registry."""
466
+ service_names = ["users", "products", "orders"]
467
+
468
+ for service_name in service_names:
469
+ try:
470
+ service_url = service_registry.get_service_url(service_name)
471
+ gateway.register_service(service_name, service_url)
472
+ except ValueError as e:
473
+ gateway.logger.warning(f"Service {service_name} not available: {str(e)}")
474
+
475
+ # Schedule periodic refresh
476
+ # asyncio.create_task(periodic_refresh())
477
+ ```
478
+
479
+ ## Constraints
480
+ - **Single Point of Failure**: API gateway can become a bottleneck - implement high availability
481
+ - **Performance**: Gateway adds latency - optimize routing and caching
482
+ - **Complexity**: Gateway logic can become complex - keep it focused
483
+ - **Scalability**: Design gateway to scale horizontally
484
+ - **Security**: Implement proper authentication and authorization
485
+ - **Monitoring**: Monitor gateway performance and service health
486
+
487
+ ## Expected Output
488
+ A robust API gateway that provides single entry point, authentication, rate limiting, service aggregation, and fault tolerance for microservices architecture.
TRAE-Skills/architecture/Adapter_Pattern_TypeScript.md ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Skill: Adapter Pattern in TypeScript
2
+
3
+ ## Purpose
4
+ To allow incompatible interfaces to work together by wrapping an object in an adapter that translates its interface into one that a client expects.
5
+
6
+ ## When to Use
7
+ - When integrating a third-party library whose interface doesn't match your application's internal requirements.
8
+ - When you want to standardize multiple different implementations of a service (e.g., different payment gateways).
9
+ - When you need to provide a stable interface while the underlying dependency is subject to change.
10
+
11
+ ## Procedure
12
+
13
+ ### 1. Define the Target Interface
14
+ This is the interface your application expects to use.
15
+
16
+ ```typescript
17
+ // logger.interface.ts
18
+ export interface ILogger {
19
+ log(message: string): void;
20
+ error(message: string): void;
21
+ }
22
+ ```
23
+
24
+ ### 2. The Incompatible Service (Adaptee)
25
+ An external library or old code with a different interface.
26
+
27
+ ```typescript
28
+ // legacy-logger.ts
29
+ export class LegacyLogger {
30
+ printMessage(msg: string) {
31
+ console.log(`[LEGACY]: ${msg}`);
32
+ }
33
+
34
+ reportFailure(err: string) {
35
+ console.error(`[LEGACY ERROR]: ${err}`);
36
+ }
37
+ }
38
+ ```
39
+
40
+ ### 3. Implement the Adapter
41
+ The adapter implements the `Target` interface and delegates work to the `Adaptee`.
42
+
43
+ ```typescript
44
+ // logger-adapter.ts
45
+ import { ILogger } from './logger.interface';
46
+ import { LegacyLogger } from './legacy-logger';
47
+
48
+ export class LoggerAdapter implements ILogger {
49
+ private legacyLogger: LegacyLogger;
50
+
51
+ constructor(legacyLogger: LegacyLogger) {
52
+ this.legacyLogger = legacyLogger;
53
+ }
54
+
55
+ log(message: string): void {
56
+ // Translate the call
57
+ this.legacyLogger.printMessage(message);
58
+ }
59
+
60
+ error(message: string): void {
61
+ // Translate the call
62
+ this.legacyLogger.reportFailure(message);
63
+ }
64
+ }
65
+ ```
66
+
67
+ ### 4. Usage in Client Code
68
+ The client only knows about the `ILogger` interface.
69
+
70
+ ```typescript
71
+ function app(logger: ILogger) {
72
+ logger.log("Application started");
73
+ }
74
+
75
+ const legacy = new LegacyLogger();
76
+ const adapter = new LoggerAdapter(legacy);
77
+
78
+ app(adapter);
79
+ ```
80
+
81
+ ## Constraints
82
+ - **Complexity**: Don't use the pattern if you can easily modify the original class to match the interface.
83
+ - **Performance**: While negligible, the extra layer of indirection adds a tiny overhead.
84
+ - **Single Responsibility**: The adapter should only focus on translation, not adding new business logic.
85
+
86
+ ## Expected Output
87
+ A wrapper class that successfully bridges two incompatible interfaces, allowing them to communicate without changing their existing code.
TRAE-Skills/architecture/Authentication_Strategy_Selection.md ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Authentication Strategy Selection
2
+
3
+ ## Strategies
4
+ 1. **Session-Based**: Server stores session ID in cookie/DB. Simple, stateful. Good for monoliths.
5
+ 2. **JWT (Stateless)**: Server signs token, client stores it. Good for microservices/mobile. Harder to revoke.
6
+ 3. **OAuth/OIDC**: Delegated auth (Login with Google). Best for user convenience and security.
7
+ 4. **Passwordless**: Magic links, OTPs. Reduces friction.
8
+
9
+ ## Security Considerations
10
+ - Always use HTTPS.
11
+ - Store passwords using bcrypt/argon2.
12
+ - Use `httpOnly` and `secure` cookies for storage where possible to prevent XSS.