1 Commits

Author SHA1 Message Date
Fatih Kadir Akın 098d444b32 Add Turkish prompt design presentation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-18 09:48:27 +03:00
66 changed files with 1997 additions and 49365 deletions
+21 -40
View File
@@ -2,47 +2,39 @@
Run your own prompts.chat instance using Docker Compose.
[`compose.yml`](/compose.yml) supports both the pre-built container image being fetched from ghcr.io, or being built locally.
## Quick Start
### To build locally
```bash
git clone https://github.com/f/prompts.chat.git
cd prompts.chat
docker compose up -d --build
```
Open http://localhost:4444 in your browser.
### Using a Pre-built Image
Simply remove the `--build` flag from the command:
```bash
git clone https://github.com/f/prompts.chat.git
cd prompts.chat
docker compose up -d
```
Open http://localhost:4444 in your browser.
## Using a Pre-built Image
Edit `compose.yml` and replace the `build` block with the published image:
```yaml
services:
app:
# build:
# context: .
# dockerfile: docker/Dockerfile
image: ghcr.io/f/prompts.chat:latest
```
Then run:
```bash
docker compose up -d
```
## Standalone (Bring Your Own Database)
If you already have a PostgreSQL instance, you can run just the app container:
Need a hosted PostgreSQL database? We recommend [Neon](https://get.neon.com/VqfnMo4) for serverless Postgres with connection pooling and database branching.
<div>
<p>Sponsored by</p>
<a href="https://get.neon.com/VqfnMo4">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/f/prompts.chat/main/public/sponsors/neon-dark.svg">
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/f/prompts.chat/main/public/sponsors/neon.svg">
<img width="250px" alt="Neon Logo fallback" src="https://raw.githubusercontent.com/f/prompts.chat/main/public/sponsors/neon-dark.svg">
</picture>
</a>
</div>
```bash
docker build -f docker/Dockerfile -t prompts.chat .
docker run -d \
@@ -53,17 +45,6 @@ docker run -d \
prompts.chat
```
Or if you simply want to use the pre-built image:
```bash
docker run -d \
--name prompts \
-p 4444:3000 \
-e DATABASE_URL="postgresql://user:pass@your-db-host:5432/prompts?schema=public" \
-e AUTH_SECRET="$(openssl rand -base64 32)" \
ghcr.io/f/prompts.chat:latest
```
## Custom Branding
All branding is configured via `PCHAT_*` environment variables at runtime -- no rebuild needed.
+653 -23144
View File
File diff suppressed because it is too large Load Diff
+1 -22
View File
@@ -58,7 +58,7 @@
## What is this?
A curated collection of **prompts** for AI chat models. Originally created for ChatGPT, these prompts work great with any modern AI assistant.
A curated collection of **prompt examples** for AI chat models. Originally created for ChatGPT, these prompts work great with any modern AI assistant.
| Browse Prompts | Data Formats |
|----------------|--------------|
@@ -116,19 +116,6 @@ npm install && npm run setup
The setup wizard configures branding, theme, authentication (GitHub/Google/Azure AD), and features.
**Recommended database:** prompts.chat uses PostgreSQL. For a hosted database, we recommend [Neon](https://get.neon.com/VqfnMo4).
<div>
<p>Sponsored by</p>
<a href="https://get.neon.com/VqfnMo4">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/f/prompts.chat/main/public/sponsors/neon-dark.svg">
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/f/prompts.chat/main/public/sponsors/neon.svg">
<img width="250px" alt="Neon Logo fallback" src="https://raw.githubusercontent.com/f/prompts.chat/main/public/sponsors/neon-dark.svg">
</picture>
</a>
</div>
📖 **[Full Self-Hosting Guide](SELF-HOSTING.md)** • 🐳 **[Docker Guide](DOCKER.md)**
---
@@ -180,14 +167,6 @@ Use prompts.chat as an MCP server in your AI tools.
## 💖 Sponsors
<p align="center">
<!-- Neon (py-1) -->
<a href="https://get.neon.com/VqfnMo4">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/f/prompts.chat/main/public/sponsors/neon-dark.svg">
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/f/prompts.chat/main/public/sponsors/neon.svg">
<img height="30" alt="Neon" src="https://raw.githubusercontent.com/f/prompts.chat/main/public/sponsors/neon.svg">
</picture>
</a>&nbsp;&nbsp;
<!-- Clemta -->
<a href="https://clemta.com/?utm_source=prompts.chat">
<picture>
-15
View File
@@ -36,21 +36,6 @@ This guide explains how to deploy **prompts.chat** on your own private server fo
- **PostgreSQL** database
- **npm**
## Recommended Database
prompts.chat requires PostgreSQL. For a hosted PostgreSQL database, we recommend [Neon](https://get.neon.com/VqfnMo4): it provides serverless Postgres, connection pooling, and branching that work well for self-hosted prompts.chat deployments.
<div>
<p>Sponsored by</p>
<a href="https://get.neon.com/VqfnMo4">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/f/prompts.chat/main/public/sponsors/neon-dark.svg">
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/f/prompts.chat/main/public/sponsors/neon.svg">
<img width="250px" alt="Neon Logo fallback" src="https://raw.githubusercontent.com/f/prompts.chat/main/public/sponsors/neon-dark.svg">
</picture>
</a>
</div>
## Environment Variables
Create a `.env` file based on `.env.example`:
+5 -5
View File
@@ -18,11 +18,11 @@ services:
app:
image: ghcr.io/f/prompts.chat:latest
# By default, uses the pre-built image above. To build locally instead,
# run: docker compose up -d --build
build:
context: .
dockerfile: docker/Dockerfile
# To build locally instead of using the pre-built image, comment out
# the 'image' line above and uncomment the build block below:
# build:
# context: .
# dockerfile: docker/Dockerfile
restart: unless-stopped
ports:
- "${PORT:-4444}:3000"
+1 -2
View File
@@ -1,6 +1,6 @@
import type { MDXComponents } from "mdx/types";
import type { ComponentPropsWithoutRef } from "react";
import { BeforeAfterEditor, BookPartsNav, BREAKFramework, Callout, ChainErrorDemo, ChainExample, ChainFlowDemo, Checklist, CodeEditor, Collapsible, Compare, ContentPipelineDemo, ContextPlayground, ContextWindowDemo, CostCalculatorDemo, CRISPEFramework, DiffView, EmbeddingsDemo, FallbackDemo, FewShotDemo, FillInTheBlank, IconCheck, IconClipboard, IconLightbulb, IconLock, IconSettings, IconStar, IconTarget, IconUser, IconX, InfoGrid, InteractiveChecklist, IterativeRefinementDemo, JailbreakDemo, JsonYamlDemo, LLMCapabilitiesDemo, LoopEngineeringLab, NavButton, NavFooter, PrinciplesSummary, PromptAnalyzer, PromptBreakdown, PromptBuilder, PromptChallenge, PromptDebugger, Quiz, RTFFramework, SpecificitySpectrum, StructuredOutputDemo, SummarizationDemo, TemperatureDemo, TextToImageDemo, TextToVideoDemo, TokenizerDemo, TokenPredictionDemo, TryIt, ValidationDemo, VersionDiff } from "@/components/book/interactive";
import { BeforeAfterEditor, BookPartsNav, BREAKFramework, Callout, ChainErrorDemo, ChainExample, ChainFlowDemo, Checklist, CodeEditor, Collapsible, Compare, ContentPipelineDemo, ContextPlayground, ContextWindowDemo, CostCalculatorDemo, CRISPEFramework, DiffView, EmbeddingsDemo, FallbackDemo, FewShotDemo, FillInTheBlank, IconCheck, IconClipboard, IconLightbulb, IconLock, IconSettings, IconStar, IconTarget, IconUser, IconX, InfoGrid, InteractiveChecklist, IterativeRefinementDemo, JailbreakDemo, JsonYamlDemo, LLMCapabilitiesDemo, NavButton, NavFooter, PrinciplesSummary, PromptAnalyzer, PromptBreakdown, PromptBuilder, PromptChallenge, PromptDebugger, Quiz, RTFFramework, SpecificitySpectrum, StructuredOutputDemo, SummarizationDemo, TemperatureDemo, TextToImageDemo, TextToVideoDemo, TokenizerDemo, TokenPredictionDemo, TryIt, ValidationDemo, VersionDiff } from "@/components/book/interactive";
import { PromiCharacter, PromiWithMessage, Panel, StoryScene, PromptVsMistake, MagicWords, DragDropPrompt, LevelComplete, Section, PromptParts, ExampleMatcher, PromptDoctor, StepByStep, PromptLab, WordPredictor } from "@/components/kids/elements";
export function useMDXComponents(components: MDXComponents): MDXComponents {
@@ -62,7 +62,6 @@ export function useMDXComponents(components: MDXComponents): MDXComponents {
JailbreakDemo,
JsonYamlDemo,
LLMCapabilitiesDemo,
LoopEngineeringLab,
NavButton,
NavFooter,
PrinciplesSummary,
+2 -4
View File
@@ -1251,7 +1251,7 @@
"interactiveBanner": {
"badge": "النسخة التفاعلية متاحة",
"title": "هل تريد تجربة أكثر تفصيلاً وتفاعلية؟",
"description": "تعمق أكثر مع دليلنا التفاعلي الشامل الذي يضم 26 فصلاً وتمارين عملية وأمثلة من الواقع لإتقان كتابة الأوامر.",
"description": "تعمق أكثر مع دليلنا التفاعلي الشامل الذي يضم 25 فصلاً وتمارين عملية وأمثلة من الواقع لإتقان كتابة الأوامر.",
"cta": "اقرأ الكتاب التفاعلي"
},
"generalTips": {
@@ -1743,7 +1743,7 @@
"part4": "الجزء 4: أفضل الممارسات",
"part5": "الجزء 5: حالات الاستخدام",
"part6": "الجزء 6: الخاتمة",
"chapters": "26 فصلاً تفاعلياً"
"chapters": "25 فصلاً تفاعلياً"
},
"startReading": "ابدأ القراءة",
"skipToChapter1": "انتقل إلى الفصل 1",
@@ -1800,7 +1800,6 @@
"12-handling-edge-cases": "التعامل مع الحالات الحدية",
"13-multimodal-prompting": "الأوامر متعددة الوسائط",
"14-context-engineering": "هندسة السياق",
"14a-loop-engineering": "هندسة الحلقات",
"25-agents-and-skills": "الوكلاء والمهارات",
"15-common-pitfalls": "الأخطاء الشائعة",
"16-ethics-responsible-use": "الأخلاق والاستخدام المسؤول",
@@ -1831,7 +1830,6 @@
"12-handling-edge-cases": "التعامل مع المدخلات غير المتوقعة",
"13-multimodal-prompting": "العمل مع الصور والصوت والفيديو",
"14-context-engineering": "RAG، التضمينات، استدعاءات الوظائف و MCP",
"14a-loop-engineering": "تصميم حلقات تغذية راجعة تتصرف وتتحقق وتتكيف وتعرف متى تتوقف",
"25-agents-and-skills": "بناء وكلاء ذكاء اصطناعي بحزم مهارات قابلة لإعادة الاستخدام",
"15-common-pitfalls": "أخطاء يجب تجنبها",
"16-ethics-responsible-use": "الاعتبارات الأخلاقية في الذكاء الاصطناعي",
+2 -4
View File
@@ -1251,7 +1251,7 @@
"interactiveBanner": {
"badge": "İnteraktiv Versiya Mövcuddur",
"title": "Daha Ətraflı və İnteraktiv Təcrübə İstəyirsiniz?",
"description": "26 fəsil, praktiki təmrinlər və real dünya nümunələri ilə hərtarafəli interaktiv rəhbərimizlə AI prompt yazmağı mənimsaəyin.",
"description": "25 fəsil, praktiki təmrinlər və real dünya nümunələri ilə hərtarafəli interaktiv rəhbərimizlə AI prompt yazmağı mənimsaəyin.",
"cta": "İnteraktiv Kitabı Oxuyun"
},
"generalTips": {
@@ -1743,7 +1743,7 @@
"part4": "Hissə 4: Ən Yaxşı Təcrübələr",
"part5": "Hissə 5: İstifadə Halları",
"part6": "Hissə 6: Nəticə",
"chapters": "26 İnteraktiv Fəsil"
"chapters": "25 İnteraktiv Fəsil"
},
"startReading": "Oxumağa Başla",
"skipToChapter1": "1-ci Fəsilə Keç",
@@ -1800,7 +1800,6 @@
"12-handling-edge-cases": "Kənar Hallarla Məşğul Olmaq",
"13-multimodal-prompting": "Multimodal Prompting",
"14-context-engineering": "Kontekst Mühəndisliyi",
"14a-loop-engineering": "Dövrə Mühəndisliyi",
"25-agents-and-skills": "Agentlər və Bacarıqlar",
"15-common-pitfalls": "Ümumi Səhvlər",
"16-ethics-responsible-use": "Etika və Məsuliyyətli İstifadə",
@@ -1831,7 +1830,6 @@
"12-handling-edge-cases": "Gözlənilməz girişlərlə məşğul olmaq",
"13-multimodal-prompting": "Şəkillər, audio və video ilə işləmək",
"14-context-engineering": "RAG, embeddinglər, funksiya çağırışı və MCP",
"14a-loop-engineering": "Hərəkət edən, yoxlayan, uyğunlaşan və nə vaxt dayanacağını bilən əks əlaqə dövrələri hazırlamaq",
"25-agents-and-skills": "Təkrar istifadə edilə bilən bacarıq paketləri ilə AI agentləri qurmaq",
"15-common-pitfalls": "Qarşısı alınmalı səhvlər",
"16-ethics-responsible-use": "AI-da etik mülahizələr",
+2 -4
View File
@@ -1251,7 +1251,7 @@
"interactiveBanner": {
"badge": "Interaktive Version Verfügbar",
"title": "Möchten Sie ein detaillierteres und interaktives Erlebnis?",
"description": "Tauchen Sie tiefer ein mit unserem umfassenden interaktiven Leitfaden mit 26 Kapiteln, praktischen Übungen und Beispielen aus der Praxis.",
"description": "Tauchen Sie tiefer ein mit unserem umfassenden interaktiven Leitfaden mit 25 Kapiteln, praktischen Übungen und Beispielen aus der Praxis.",
"cta": "Das interaktive Buch lesen"
},
"generalTips": {
@@ -1743,7 +1743,7 @@
"part4": "Teil 4: Best Practices",
"part5": "Teil 5: Anwendungsfälle",
"part6": "Teil 6: Fazit",
"chapters": "26 Interaktive Kapitel"
"chapters": "25 Interaktive Kapitel"
},
"startReading": "Jetzt Lesen",
"skipToChapter1": "Zu Kapitel 1 springen",
@@ -1800,7 +1800,6 @@
"12-handling-edge-cases": "Umgang mit Grenzfällen",
"13-multimodal-prompting": "Multimodales Prompting",
"14-context-engineering": "Kontext-Engineering",
"14a-loop-engineering": "Loop-Engineering",
"25-agents-and-skills": "Agenten & Skills",
"15-common-pitfalls": "Häufige Fallstricke",
"16-ethics-responsible-use": "Ethik & Verantwortungsvolle Nutzung",
@@ -1831,7 +1830,6 @@
"12-handling-edge-cases": "Mit unerwarteten Eingaben umgehen",
"13-multimodal-prompting": "Mit Bildern, Audio und Video arbeiten",
"14-context-engineering": "RAG, Embeddings, Function Calling und MCP",
"14a-loop-engineering": "Feedbackschleifen entwerfen, die handeln, prüfen, sich anpassen und rechtzeitig stoppen",
"25-agents-and-skills": "KI-Agenten mit wiederverwendbaren Skill-Paketen erstellen",
"15-common-pitfalls": "Fehler, die Sie vermeiden sollten",
"16-ethics-responsible-use": "Ethische Überlegungen in der KI",
+2 -4
View File
@@ -1251,7 +1251,7 @@
"interactiveBanner": {
"badge": "Διαδραστική Έκδοση Διαθέσιμη",
"title": "Θέλετε μια πιο λεπτομερή και διαδραστική εμπειρία;",
"description": "Εμβαθύνετε με τον πλήρη διαδραστικό οδηγό μας με 26 κεφάλαια, πρακτικές ασκήσεις και παραδείγματα από τον πραγματικό κόσμο για να κατακτήσετε τα AI prompts.",
"description": "Εμβαθύνετε με τον πλήρη διαδραστικό οδηγό μας με 25 κεφάλαια, πρακτικές ασκήσεις και παραδείγματα από τον πραγματικό κόσμο για να κατακτήσετε τα AI prompts.",
"cta": "Διαβάστε το Διαδραστικό Βιβλίο"
},
"generalTips": {
@@ -1743,7 +1743,7 @@
"part4": "Μέρος 4: Βέλτιστες Πρακτικές",
"part5": "Μέρος 5: Περιπτώσεις Χρήσης",
"part6": "Μέρος 6: Συμπέρασμα",
"chapters": "26 Διαδραστικά Κεφάλαια"
"chapters": "25 Διαδραστικά Κεφάλαια"
},
"startReading": "Ξεκινήστε την Ανάγνωση",
"skipToChapter1": "Μετάβαση στο Κεφάλαιο 1",
@@ -1800,7 +1800,6 @@
"12-handling-edge-cases": "Διαχείριση Ακραίων Περιπτώσεων",
"13-multimodal-prompting": "Πολυτροπικό Prompting",
"14-context-engineering": "Μηχανική Πλαισίου",
"14a-loop-engineering": "Μηχανική Βρόχων",
"25-agents-and-skills": "Πράκτορες και Δεξιότητες",
"15-common-pitfalls": "Συνήθη Λάθη",
"16-ethics-responsible-use": "Ηθική και Υπεύθυνη Χρήση",
@@ -1831,7 +1830,6 @@
"12-handling-edge-cases": "Διαχείριση απροσδόκητης εισόδου",
"13-multimodal-prompting": "Εργασία με εικόνες, ήχο και βίντεο",
"14-context-engineering": "RAG, embeddings, κλήσεις συναρτήσεων και MCP",
"14a-loop-engineering": "Σχεδιασμός βρόχων ανατροφοδότησης που δρουν, επαληθεύουν, προσαρμόζονται και γνωρίζουν πότε να σταματήσουν",
"25-agents-and-skills": "Δημιουργία AI πρακτόρων με επαναχρησιμοποιήσιμα πακέτα δεξιοτήτων",
"15-common-pitfalls": "Λάθη προς αποφυγή",
"16-ethics-responsible-use": "Ηθικές εκτιμήσεις στην AI",
+2 -4
View File
@@ -1251,7 +1251,7 @@
"interactiveBanner": {
"badge": "Interactive Version Available",
"title": "Want a More Detailed & Interactive Experience?",
"description": "Dive deeper with our comprehensive interactive guide featuring 26 chapters, hands-on exercises, and real-world examples to master AI prompting.",
"description": "Dive deeper with our comprehensive interactive guide featuring 25 chapters, hands-on exercises, and real-world examples to master AI prompting.",
"cta": "Read the Interactive Book"
},
"generalTips": {
@@ -1743,7 +1743,7 @@
"part4": "Part 4: Best Practices",
"part5": "Part 5: Use Cases",
"part6": "Part 6: Conclusion",
"chapters": "26 Interactive Chapters"
"chapters": "25 Interactive Chapters"
},
"startReading": "Start Reading",
"skipToChapter1": "Skip to Chapter 1",
@@ -1800,7 +1800,6 @@
"12-handling-edge-cases": "Handling Edge Cases",
"13-multimodal-prompting": "Multimodal Prompting",
"14-context-engineering": "Context Engineering",
"14a-loop-engineering": "Loop Engineering",
"25-agents-and-skills": "Agents & Skills",
"15-common-pitfalls": "Common Pitfalls",
"16-ethics-responsible-use": "Ethics & Responsible Use",
@@ -1831,7 +1830,6 @@
"12-handling-edge-cases": "Dealing with unexpected inputs",
"13-multimodal-prompting": "Working with images, audio, and video",
"14-context-engineering": "RAG, embeddings, function calling, and MCP",
"14a-loop-engineering": "Designing feedback cycles that act, verify, adapt, and know when to stop",
"25-agents-and-skills": "Building AI agents with reusable skill packages",
"15-common-pitfalls": "Mistakes to avoid",
"16-ethics-responsible-use": "Ethical considerations in AI",
+2 -4
View File
@@ -1251,7 +1251,7 @@
"interactiveBanner": {
"badge": "Versión Interactiva Disponible",
"title": "¿Quieres una Experiencia Más Detallada e Interactiva?",
"description": "Profundiza con nuestra guía interactiva completa con 26 capítulos, ejercicios prácticos y ejemplos del mundo real para dominar los prompts de IA.",
"description": "Profundiza con nuestra guía interactiva completa con 25 capítulos, ejercicios prácticos y ejemplos del mundo real para dominar los prompts de IA.",
"cta": "Leer el Libro Interactivo"
},
"generalTips": {
@@ -1743,7 +1743,7 @@
"part4": "Parte 4: Mejores Prácticas",
"part5": "Parte 5: Casos de Uso",
"part6": "Parte 6: Conclusión",
"chapters": "26 Capítulos Interactivos"
"chapters": "25 Capítulos Interactivos"
},
"startReading": "Comenzar a Leer",
"skipToChapter1": "Ir al Capítulo 1",
@@ -1800,7 +1800,6 @@
"12-handling-edge-cases": "Manejo de Casos Límite",
"13-multimodal-prompting": "Prompting Multimodal",
"14-context-engineering": "Ingeniería de Contexto",
"14a-loop-engineering": "Ingeniería de Bucles",
"25-agents-and-skills": "Agentes y Habilidades",
"15-common-pitfalls": "Errores Comunes",
"16-ethics-responsible-use": "Ética y Uso Responsable",
@@ -1831,7 +1830,6 @@
"12-handling-edge-cases": "Manejar entradas inesperadas",
"13-multimodal-prompting": "Trabajar con imágenes, audio y video",
"14-context-engineering": "RAG, embeddings, llamadas a funciones y MCP",
"14a-loop-engineering": "Diseñar ciclos de retroalimentación que actúan, verifican, se adaptan y saben cuándo detenerse",
"25-agents-and-skills": "Construir agentes de IA con paquetes de habilidades reutilizables",
"15-common-pitfalls": "Errores a evitar",
"16-ethics-responsible-use": "Consideraciones éticas en IA",
+2 -4
View File
@@ -1251,7 +1251,7 @@
"interactiveBanner": {
"badge": "نسخه تعاملی موجود است",
"title": "می‌خواهید تجربه‌ای دقیق‌تر و تعاملی‌تر داشته باشید؟",
"description": "با راهنمای تعاملی جامع ما شامل ۲۶ فصل، تمرین‌های عملی و مثال‌های واقعی، در نوشتن پرامپت‌های هوش مصنوعی مهارت پیدا کنید.",
"description": "با راهنمای تعاملی جامع ما شامل ۲۵ فصل، تمرین‌های عملی و مثال‌های واقعی، در نوشتن پرامپت‌های هوش مصنوعی مهارت پیدا کنید.",
"cta": "کتاب تعاملی را بخوانید"
},
"generalTips": {
@@ -1743,7 +1743,7 @@
"part4": "بخش ۴: بهترین شیوه‌ها",
"part5": "بخش ۵: موارد استفاده",
"part6": "بخش ۶: نتیجه‌گیری",
"chapters": "۲۶ فصل تعاملی"
"chapters": "۲۵ فصل تعاملی"
},
"startReading": "شروع مطالعه",
"skipToChapter1": "رفتن به فصل ۱",
@@ -1800,7 +1800,6 @@
"12-handling-edge-cases": "مدیریت موارد حاشیه‌ای",
"13-multimodal-prompting": "پرامپت‌نویسی چندوجهی",
"14-context-engineering": "مهندسی زمینه",
"14a-loop-engineering": "مهندسی حلقه",
"25-agents-and-skills": "عامل‌ها و مهارت‌ها",
"15-common-pitfalls": "اشتباهات رایج",
"16-ethics-responsible-use": "اخلاق و استفاده مسئولانه",
@@ -1831,7 +1830,6 @@
"12-handling-edge-cases": "مدیریت ورودی غیرمنتظره",
"13-multimodal-prompting": "کار با تصاویر، صوت و ویدیو",
"14-context-engineering": "RAG، امبدینگ‌ها، فراخوانی توابع و MCP",
"14a-loop-engineering": "طراحی چرخه‌های بازخوردی که اقدام می‌کنند، راستی‌آزمایی می‌کنند، تطبیق می‌یابند و می‌دانند کِی متوقف شوند",
"25-agents-and-skills": "ساخت عامل‌های هوش مصنوعی با بسته‌های مهارت قابل استفاده مجدد",
"15-common-pitfalls": "اشتباهاتی که باید از آنها اجتناب کرد",
"16-ethics-responsible-use": "ملاحظات اخلاقی در هوش مصنوعی",
+2 -4
View File
@@ -1251,7 +1251,7 @@
"interactiveBanner": {
"badge": "Version Interactive Disponible",
"title": "Vous voulez une expérience plus détaillée et interactive ?",
"description": "Approfondissez avec notre guide interactif complet comprenant 26 chapitres, des exercices pratiques et des exemples concrets pour maîtriser les prompts IA.",
"description": "Approfondissez avec notre guide interactif complet comprenant 25 chapitres, des exercices pratiques et des exemples concrets pour maîtriser les prompts IA.",
"cta": "Lire le Livre Interactif"
},
"generalTips": {
@@ -1743,7 +1743,7 @@
"part4": "Partie 4 : Bonnes Pratiques",
"part5": "Partie 5 : Cas d'Utilisation",
"part6": "Partie 6 : Conclusion",
"chapters": "26 Chapitres Interactifs"
"chapters": "25 Chapitres Interactifs"
},
"startReading": "Commencer la Lecture",
"skipToChapter1": "Aller au Chapitre 1",
@@ -1800,7 +1800,6 @@
"12-handling-edge-cases": "Gestion des Cas Limites",
"13-multimodal-prompting": "Prompting Multimodal",
"14-context-engineering": "Ingénierie du Contexte",
"14a-loop-engineering": "Ingénierie de Boucle",
"25-agents-and-skills": "Agents et Compétences",
"15-common-pitfalls": "Pièges Courants",
"16-ethics-responsible-use": "Éthique et Utilisation Responsable",
@@ -1831,7 +1830,6 @@
"12-handling-edge-cases": "Gérer les entrées inattendues",
"13-multimodal-prompting": "Travailler avec images, audio et vidéo",
"14-context-engineering": "RAG, embeddings, appels de fonction et MCP",
"14a-loop-engineering": "Concevoir des boucles de rétroaction qui agissent, vérifient, s'adaptent et savent quand s'arrêter",
"25-agents-and-skills": "Construire des agents IA avec des packages de compétences réutilisables",
"15-common-pitfalls": "Erreurs à éviter",
"16-ethics-responsible-use": "Considérations éthiques dans l'IA",
+2 -4
View File
@@ -1251,7 +1251,7 @@
"interactiveBanner": {
"badge": "גרסה אינטראקטיבית זמינה",
"title": "רוצים חוויה מפורטת ואינטראקטיבית יותר?",
"description": "העמיקו עם המדריך האינטראקטיבי המקיף שלנו הכולל 26 פרקים, תרגילים מעשיים ודוגמאות מהעולם האמיתי לשליטה בפרומפטים ל-AI.",
"description": "העמיקו עם המדריך האינטראקטיבי המקיף שלנו הכולל 25 פרקים, תרגילים מעשיים ודוגמאות מהעולם האמיתי לשליטה בפרומפטים ל-AI.",
"cta": "קראו את הספר האינטראקטיבי"
},
"generalTips": {
@@ -1743,7 +1743,7 @@
"part4": "חלק 4: שיטות עבודה מומלצות",
"part5": "חלק 5: מקרי שימוש",
"part6": "חלק 6: סיכום",
"chapters": "26 פרקים אינטראקטיביים"
"chapters": "25 פרקים אינטראקטיביים"
},
"startReading": "התחל לקרוא",
"skipToChapter1": "דלג לפרק 1",
@@ -1800,7 +1800,6 @@
"12-handling-edge-cases": "טיפול במקרי קצה",
"13-multimodal-prompting": "Prompting רב-מודאלי",
"14-context-engineering": "הנדסת הקשר",
"14a-loop-engineering": "הנדסת לולאות",
"25-agents-and-skills": "סוכנים ומיומנויות",
"15-common-pitfalls": "מלכודות נפוצות",
"16-ethics-responsible-use": "אתיקה ושימוש אחראי",
@@ -1831,7 +1830,6 @@
"12-handling-edge-cases": "התמודדות עם קלט בלתי צפוי",
"13-multimodal-prompting": "עבודה עם תמונות, אודיו ווידאו",
"14-context-engineering": "RAG, embeddings, קריאות פונקציות ו-MCP",
"14a-loop-engineering": "תכנון לולאות משוב שפועלות, מאמתות, מסתגלות ויודעות מתי לעצור",
"25-agents-and-skills": "בניית סוכני AI עם חבילות מיומנות לשימוש חוזר",
"15-common-pitfalls": "טעויות שיש להימנע מהן",
"16-ethics-responsible-use": "שיקולים אתיים ב-AI",
+2 -4
View File
@@ -1251,7 +1251,7 @@
"interactiveBanner": {
"badge": "Versione Interattiva Disponibile",
"title": "Vuoi un'Esperienza Più Dettagliata e Interattiva?",
"description": "Approfondisci con la nostra guida interattiva completa con 26 capitoli, esercizi pratici ed esempi reali per padroneggiare i prompt IA.",
"description": "Approfondisci con la nostra guida interattiva completa con 25 capitoli, esercizi pratici ed esempi reali per padroneggiare i prompt IA.",
"cta": "Leggi il Libro Interattivo"
},
"generalTips": {
@@ -1743,7 +1743,7 @@
"part4": "Parte 4: Best Practice",
"part5": "Parte 5: Casi d'Uso",
"part6": "Parte 6: Conclusione",
"chapters": "26 Capitoli Interattivi"
"chapters": "25 Capitoli Interattivi"
},
"startReading": "Inizia a Leggere",
"skipToChapter1": "Vai al Capitolo 1",
@@ -1800,7 +1800,6 @@
"12-handling-edge-cases": "Gestione dei Casi Limite",
"13-multimodal-prompting": "Prompting Multimodale",
"14-context-engineering": "Ingegneria del Contesto",
"14a-loop-engineering": "Ingegneria dei Loop",
"25-agents-and-skills": "Agenti e Skill",
"15-common-pitfalls": "Errori Comuni",
"16-ethics-responsible-use": "Etica e Uso Responsabile",
@@ -1831,7 +1830,6 @@
"12-handling-edge-cases": "Gestire input inaspettati",
"13-multimodal-prompting": "Lavorare con immagini, audio e video",
"14-context-engineering": "RAG, embeddings, function calling e MCP",
"14a-loop-engineering": "Progettare cicli di feedback che agiscono, verificano, si adattano e sanno quando fermarsi",
"25-agents-and-skills": "Costruire agenti AI con pacchetti di skill riutilizzabili",
"15-common-pitfalls": "Errori da evitare",
"16-ethics-responsible-use": "Considerazioni etiche nell'AI",
+2 -4
View File
@@ -1251,7 +1251,7 @@
"interactiveBanner": {
"badge": "インタラクティブ版が利用可能",
"title": "より詳細でインタラクティブな体験をお求めですか?",
"description": "26章、実践的な演習、実例を含む包括的なインタラクティブガイドで、AIプロンプトをマスターしましょう。",
"description": "25章、実践的な演習、実例を含む包括的なインタラクティブガイドで、AIプロンプトをマスターしましょう。",
"cta": "インタラクティブブックを読む"
},
"generalTips": {
@@ -1743,7 +1743,7 @@
"part4": "パート4:ベストプラクティス",
"part5": "パート5:ユースケース",
"part6": "パート6:結論",
"chapters": "26のインタラクティブチャプター"
"chapters": "25のインタラクティブチャプター"
},
"startReading": "読み始める",
"skipToChapter1": "第1章へ",
@@ -1800,7 +1800,6 @@
"12-handling-edge-cases": "エッジケースの処理",
"13-multimodal-prompting": "マルチモーダルプロンプティング",
"14-context-engineering": "コンテキストエンジニアリング",
"14a-loop-engineering": "ループエンジニアリング",
"25-agents-and-skills": "エージェントとスキル",
"15-common-pitfalls": "よくある落とし穴",
"16-ethics-responsible-use": "倫理と責任ある使用",
@@ -1831,7 +1830,6 @@
"12-handling-edge-cases": "予期しない入力を処理する",
"13-multimodal-prompting": "画像、音声、動画を扱う",
"14-context-engineering": "RAG、エンベディング、関数呼び出し、MCP",
"14a-loop-engineering": "行動し、検証し、適応し、停止すべき時を判断するフィードバックループの設計",
"25-agents-and-skills": "再利用可能なスキルパッケージでAIエージェントを構築する",
"15-common-pitfalls": "避けるべき間違い",
"16-ethics-responsible-use": "AIにおける倫理的考慮",
+2 -4
View File
@@ -1251,7 +1251,7 @@
"interactiveBanner": {
"badge": "인터랙티브 버전 제공",
"title": "더 상세하고 인터랙티브한 경험을 원하시나요?",
"description": "26개 챕터, 실습 연습, 실제 예제가 포함된 종합 인터랙티브 가이드로 AI 프롬프트를 마스터하세요.",
"description": "25개 챕터, 실습 연습, 실제 예제가 포함된 종합 인터랙티브 가이드로 AI 프롬프트를 마스터하세요.",
"cta": "인터랙티브 북 읽기"
},
"generalTips": {
@@ -1743,7 +1743,7 @@
"part4": "파트 4: 모범 사례",
"part5": "파트 5: 사용 사례",
"part6": "파트 6: 결론",
"chapters": "26개 인터랙티브 챕터"
"chapters": "25개 인터랙티브 챕터"
},
"startReading": "읽기 시작",
"skipToChapter1": "1장으로 이동",
@@ -1800,7 +1800,6 @@
"12-handling-edge-cases": "엣지 케이스 처리",
"13-multimodal-prompting": "멀티모달 프롬프팅",
"14-context-engineering": "컨텍스트 엔지니어링",
"14a-loop-engineering": "루프 엔지니어링",
"25-agents-and-skills": "에이전트와 스킬",
"15-common-pitfalls": "흔한 실수",
"16-ethics-responsible-use": "윤리와 책임있는 사용",
@@ -1831,7 +1830,6 @@
"12-handling-edge-cases": "예상치 못한 입력 처리하기",
"13-multimodal-prompting": "이미지, 오디오, 비디오 작업",
"14-context-engineering": "RAG, 임베딩, 함수 호출 및 MCP",
"14a-loop-engineering": "행동하고 검증하고 적응하며 언제 멈출지 아는 피드백 루프 설계",
"25-agents-and-skills": "재사용 가능한 스킬 패키지로 AI 에이전트 구축",
"15-common-pitfalls": "피해야 할 실수",
"16-ethics-responsible-use": "AI의 윤리적 고려사항",
+2 -4
View File
@@ -1251,7 +1251,7 @@
"interactiveBanner": {
"badge": "Interactieve versie beschikbaar",
"title": "Wil je een meer gedetailleerde & interactieve ervaring?",
"description": "Duik dieper met onze uitgebreide interactieve gids met 26 hoofdstukken, praktische oefeningen en echte voorbeelden om AI-prompting te beheersen.",
"description": "Duik dieper met onze uitgebreide interactieve gids met 25 hoofdstukken, praktische oefeningen en echte voorbeelden om AI-prompting te beheersen.",
"cta": "Lees het interactieve boek"
},
"generalTips": {
@@ -1743,7 +1743,7 @@
"part4": "Deel 4: Best Practices",
"part5": "Deel 5: Use Cases",
"part6": "Deel 6: Conclusie",
"chapters": "26 Interactieve Hoofdstukken"
"chapters": "25 Interactieve Hoofdstukken"
},
"startReading": "Begin met Lezen",
"skipToChapter1": "Ga naar Hoofdstuk 1",
@@ -1800,7 +1800,6 @@
"12-handling-edge-cases": "Omgaan met Edge Cases",
"13-multimodal-prompting": "Multimodale Prompting",
"14-context-engineering": "Context Engineering",
"14a-loop-engineering": "Loop Engineering",
"25-agents-and-skills": "Agents en Skills",
"15-common-pitfalls": "Veelvoorkomende Valkuilen",
"16-ethics-responsible-use": "Ethiek en Verantwoord Gebruik",
@@ -1831,7 +1830,6 @@
"12-handling-edge-cases": "Omgaan met onverwachte input",
"13-multimodal-prompting": "Werken met afbeeldingen, audio en video",
"14-context-engineering": "RAG, embeddings, function calling en MCP",
"14a-loop-engineering": "Feedbackloops ontwerpen die handelen, verifiëren, bijsturen en weten wanneer ze moeten stoppen",
"25-agents-and-skills": "AI-agents bouwen met herbruikbare skill-pakketten",
"15-common-pitfalls": "Fouten om te vermijden",
"16-ethics-responsible-use": "Ethische overwegingen in AI",
+2 -4
View File
@@ -1251,7 +1251,7 @@
"interactiveBanner": {
"badge": "Versão Interativa Disponível",
"title": "Quer uma Experiência Mais Detalhada e Interativa?",
"description": "Aprofunde-se com nosso guia interativo completo com 26 capítulos, exercícios práticos e exemplos do mundo real para dominar prompts de IA.",
"description": "Aprofunde-se com nosso guia interativo completo com 25 capítulos, exercícios práticos e exemplos do mundo real para dominar prompts de IA.",
"cta": "Ler o Livro Interativo"
},
"generalTips": {
@@ -1743,7 +1743,7 @@
"part4": "Parte 4: Melhores Práticas",
"part5": "Parte 5: Casos de Uso",
"part6": "Parte 6: Conclusão",
"chapters": "26 Capítulos Interativos"
"chapters": "25 Capítulos Interativos"
},
"startReading": "Começar a Ler",
"skipToChapter1": "Ir para o Capítulo 1",
@@ -1800,7 +1800,6 @@
"12-handling-edge-cases": "Tratamento de Casos Limites",
"13-multimodal-prompting": "Prompting Multimodal",
"14-context-engineering": "Engenharia de Contexto",
"14a-loop-engineering": "Engenharia de Loop",
"25-agents-and-skills": "Agentes e Habilidades",
"15-common-pitfalls": "Erros Comuns",
"16-ethics-responsible-use": "Ética e Uso Responsável",
@@ -1831,7 +1830,6 @@
"12-handling-edge-cases": "Lidar com entradas inesperadas",
"13-multimodal-prompting": "Trabalhar com imagens, áudio e vídeo",
"14-context-engineering": "RAG, embeddings, chamadas de função e MCP",
"14a-loop-engineering": "Projetar loops de feedback que agem, verificam, se adaptam e sabem quando parar",
"25-agents-and-skills": "Construir agentes de IA com pacotes de habilidades reutilizáveis",
"15-common-pitfalls": "Erros a evitar",
"16-ethics-responsible-use": "Considerações éticas em IA",
+2 -4
View File
@@ -1251,7 +1251,7 @@
"interactiveBanner": {
"badge": "Доступна интерактивная версия",
"title": "Хотите более детальный и интерактивный опыт?",
"description": "Погрузитесь глубже с нашим комплексным интерактивным руководством из 26 глав, практических упражнений и реальных примеров для мастерства в AI-промптах.",
"description": "Погрузитесь глубже с нашим комплексным интерактивным руководством из 25 глав, практических упражнений и реальных примеров для мастерства в AI-промптах.",
"cta": "Читать интерактивную книгу"
},
"generalTips": {
@@ -1743,7 +1743,7 @@
"part4": "Часть 4: Лучшие практики",
"part5": "Часть 5: Примеры использования",
"part6": "Часть 6: Заключение",
"chapters": "26 интерактивных глав"
"chapters": "25 интерактивных глав"
},
"startReading": "Начать чтение",
"skipToChapter1": "Перейти к Главе 1",
@@ -1800,7 +1800,6 @@
"12-handling-edge-cases": "Обработка крайних случаев",
"13-multimodal-prompting": "Мультимодальный промптинг",
"14-context-engineering": "Контекстная инженерия",
"14a-loop-engineering": "Инженерия циклов",
"25-agents-and-skills": "Агенты и навыки",
"15-common-pitfalls": "Распространённые ошибки",
"16-ethics-responsible-use": "Этика и ответственное использование",
@@ -1831,7 +1830,6 @@
"12-handling-edge-cases": "Обработка неожиданного ввода",
"13-multimodal-prompting": "Работа с изображениями, аудио и видео",
"14-context-engineering": "RAG, эмбеддинги, вызовы функций и MCP",
"14a-loop-engineering": "Проектирование циклов обратной связи, которые действуют, проверяют, адаптируются и вовремя останавливаются",
"25-agents-and-skills": "Создание AI-агентов с переиспользуемыми пакетами навыков",
"15-common-pitfalls": "Ошибки, которых следует избегать",
"16-ethics-responsible-use": "Этические соображения в AI",
+2 -4
View File
@@ -1251,7 +1251,7 @@
"interactiveBanner": {
"badge": "İnteraktif Versiyon Mevcut",
"title": "Daha Detaylı ve İnteraktif Bir Deneyim mi İstiyorsunuz?",
"description": "26 bölüm, uygulamalı alıştırmalar ve gerçek dünya örnekleri içeren kapsamlı interaktif rehberimizle AI prompt yazımında ustalaşın.",
"description": "25 bölüm, uygulamalı alıştırmalar ve gerçek dünya örnekleri içeren kapsamlı interaktif rehberimizle AI prompt yazımında ustalaşın.",
"cta": "İnteraktif Kitabı Oku"
},
"generalTips": {
@@ -1743,7 +1743,7 @@
"part4": "Bölüm 4: En İyi Uygulamalar",
"part5": "Bölüm 5: Kullanım Senaryoları",
"part6": "Bölüm 6: Sonuç",
"chapters": "26 İnteraktif Bölüm"
"chapters": "25 İnteraktif Bölüm"
},
"startReading": "Okumaya Başla",
"skipToChapter1": "1. Bölüme Atla",
@@ -1800,7 +1800,6 @@
"12-handling-edge-cases": "Uç Durumları Ele Alma",
"13-multimodal-prompting": "Çok Modlu Prompting",
"14-context-engineering": "Bağlam Mühendisliği",
"14a-loop-engineering": "Döngü Mühendisliği",
"25-agents-and-skills": "Ajanlar ve Yetenekler",
"15-common-pitfalls": "Yaygın Tuzaklar",
"16-ethics-responsible-use": "Etik ve Sorumlu Kullanım",
@@ -1831,7 +1830,6 @@
"12-handling-edge-cases": "Beklenmedik girdilerle başa çıkma",
"13-multimodal-prompting": "Görüntü, ses ve video ile çalışma",
"14-context-engineering": "RAG, embedding'ler, fonksiyon çağırma ve MCP",
"14a-loop-engineering": "Harekete geçen, doğrulayan, uyum sağlayan ve ne zaman duracağını bilen geri bildirim döngüleri tasarlama",
"25-agents-and-skills": "Yeniden kullanılabilir yetenek paketleriyle AI ajanları oluşturma",
"15-common-pitfalls": "Kaçınılması gereken hatalar",
"16-ethics-responsible-use": "AI'da etik değerlendirmeler",
+2 -4
View File
@@ -1251,7 +1251,7 @@
"interactiveBanner": {
"badge": "互动版本已上线",
"title": "想要更详细的互动体验?",
"description": "通过我们包含26章内容、实践练习和真实案例的综合互动指南,深入掌握AI提示词技巧。",
"description": "通过我们包含25章内容、实践练习和真实案例的综合互动指南,深入掌握AI提示词技巧。",
"cta": "阅读互动电子书"
},
"generalTips": {
@@ -1743,7 +1743,7 @@
"part4": "第4部分:最佳实践",
"part5": "第5部分:用例",
"part6": "第6部分:结论",
"chapters": "26个互动章节"
"chapters": "25个互动章节"
},
"startReading": "开始阅读",
"skipToChapter1": "跳至第1章",
@@ -1800,7 +1800,6 @@
"12-handling-edge-cases": "处理边界情况",
"13-multimodal-prompting": "多模态提示词",
"14-context-engineering": "上下文工程",
"14a-loop-engineering": "循环工程",
"25-agents-and-skills": "代理和技能",
"15-common-pitfalls": "常见陷阱",
"16-ethics-responsible-use": "伦理和负责任使用",
@@ -1831,7 +1830,6 @@
"12-handling-edge-cases": "处理意外输入",
"13-multimodal-prompting": "处理图像、音频和视频",
"14-context-engineering": "RAG、嵌入、函数调用和MCP",
"14a-loop-engineering": "设计能够行动、验证、调整并知道何时停止的反馈循环",
"25-agents-and-skills": "使用可重用技能包构建AI代理",
"15-common-pitfalls": "要避免的错误",
"16-ethics-responsible-use": "AI中的伦理考虑",
@@ -1,21 +0,0 @@
import { describe, expect, it } from 'vitest';
import { buildUrl, codePlatforms } from '../cli/platforms';
describe('platform URL builder', () => {
it('builds VS Code Copilot Chat deep links with encoded prompts', () => {
const vscode = codePlatforms.find((platform) => platform.id === 'vscode');
const insiders = codePlatforms.find((platform) => platform.id === 'vscode-insiders');
expect(vscode).toBeDefined();
expect(insiders).toBeDefined();
expect(vscode?.baseUrl).toBe('vscode://GitHub.Copilot-Chat/chat');
expect(insiders?.baseUrl).toBe('vscode-insiders://GitHub.Copilot-Chat/chat');
expect(buildUrl('vscode', vscode!.baseUrl, 'Review this code & explain it')).toBe(
'vscode://GitHub.Copilot-Chat/chat?prompt=Review%20this%20code%20%26%20explain%20it',
);
expect(buildUrl('vscode-insiders', insiders!.baseUrl, '/fix failing tests')).toBe(
'vscode-insiders://GitHub.Copilot-Chat/chat?prompt=%2Ffix%20failing%20tests',
);
});
});
+2 -5
View File
@@ -25,8 +25,8 @@ export const videoPlatforms: Platform[] = [
export const codePlatforms: Platform[] = [
{ id: "windsurf", name: "Windsurf", baseUrl: "windsurf://", isDeeplink: true, supportsQuerystring: false, sponsor: true },
{ id: "vscode", name: "VS Code", baseUrl: "vscode://GitHub.Copilot-Chat/chat", isDeeplink: true },
{ id: "vscode-insiders", name: "VS Code Insiders", baseUrl: "vscode-insiders://GitHub.Copilot-Chat/chat", isDeeplink: true },
{ id: "vscode", name: "VS Code", baseUrl: "vscode://", isDeeplink: true, supportsQuerystring: false },
{ id: "vscode-insiders", name: "VS Code Insiders", baseUrl: "vscode-insiders://", isDeeplink: true, supportsQuerystring: false },
{ id: "cursor", name: "Cursor", baseUrl: "cursor://anysphere.cursor-deeplink/prompt", isDeeplink: true },
{ id: "goose", name: "Goose", baseUrl: "goose://recipe", isDeeplink: true },
{ id: "github-copilot", name: "GitHub Copilot Chat", baseUrl: "https://github.com/copilot" },
@@ -71,9 +71,6 @@ export function buildUrl(
switch (platformId) {
case "cursor":
return `${baseUrl}?text=${encoded}`;
case "vscode":
case "vscode-insiders":
return `${baseUrl}?prompt=${encoded}`;
case "goose": {
const config = JSON.stringify({
version: "1.0.0",
+4 -7
View File
@@ -175,15 +175,15 @@ export const codePlatforms: Platform[] = [
{
id: "vscode",
name: "VS Code",
baseUrl: "vscode://GitHub.Copilot-Chat/chat",
supportsQuerystring: true,
baseUrl: "vscode://",
supportsQuerystring: false,
isDeeplink: true,
},
{
id: "vscode-insiders",
name: "VS Code Insiders",
baseUrl: "vscode-insiders://GitHub.Copilot-Chat/chat",
supportsQuerystring: true,
baseUrl: "vscode-insiders://",
supportsQuerystring: false,
isDeeplink: true,
},
{
@@ -243,9 +243,6 @@ export function buildUrl(
// IDE deeplinks
case "cursor":
return `${baseUrl}?text=${encoded}`;
case "vscode":
case "vscode-insiders":
return `${baseUrl}?prompt=${encoded}`;
case "goose":
case "goose-chat": {
const config = JSON.stringify({
-1
View File
@@ -77,7 +77,6 @@ export default defineConfig({
enabled: !useCloneBranding,
items: [
// Add sponsors here
{ name: "Neon", className: 'py-1', logo: '/sponsors/neon.svg', darkLogo: '/sponsors/neon-dark.svg', url: "https://get.neon.com/VqfnMo4" },
{ name: "Clemta", logo: '/sponsors/clemta.webp', url: "https://clemta.com/?utm_source=prompts.chat" },
{ name: "Wiro.ai", className: 'py-1', darkLogo: '/sponsors/wiro.png', logo: '/sponsors/wiro.png', url: "https://wiro.ai/?utm_source=prompts.chat" },
{ name: "Cognition", logo: "/sponsors/cognition.svg", url: "https://wind.surf/prompts-chat" },
+605 -18296
View File
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -5,7 +5,7 @@
</g>
</g>
<style>
path { fill: #000000; }
@media (prefers-color-scheme: dark) { path { fill: #ffffff; } }
@media (prefers-color-scheme: light) { :root { filter: none; } }
@media (prefers-color-scheme: dark) { :root { filter: invert(100%); } }
</style>
</svg>
</svg>

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

-5
View File
@@ -1,5 +0,0 @@
<svg width="157" height="45" viewBox="0 0 157 45" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M43.9842 0.0123174V44L26.9844 29.2514V44H0.416626V0L43.9842 0.0123174ZM5.75712 38.6595H21.6439V17.5326L38.644 32.5729V5.35124L5.75712 5.34181V38.6595Z" fill="#34D59A"/>
<path d="M79.0701 35.7042L62.1564 20.7349V35.4106H56.8364V9.06775L73.7502 24.037V9.36126H79.0701V35.7042ZM84.9267 35.4106V9.36126H100.85V14.6078H90.2466V19.7443H98.6485V24.8808H90.2466V30.1641H100.85V35.4106H84.9267ZM117.32 35.7042C109.945 35.7042 104.001 29.7605 104.001 22.386C104.001 15.0114 109.945 9.06775 117.32 9.06775C124.694 9.06775 130.638 15.0114 130.638 22.386C130.638 29.7605 124.694 35.7042 117.32 35.7042ZM117.32 30.5677C121.869 30.5677 125.281 26.8987 125.281 22.386C125.281 17.8732 121.869 14.2042 117.32 14.2042C112.77 14.2042 109.358 17.8732 109.358 22.386C109.358 26.8987 112.77 30.5677 117.32 30.5677ZM156.493 35.7042L139.579 20.7349V35.4106H134.259V9.06775L151.173 24.037V9.36126H156.493V35.7042Z" fill="black"/>
<path d="M79.0701 35.7042L62.1564 20.7349V35.4106H56.8364V9.06775L73.7502 24.037V9.36126H79.0701V35.7042ZM84.9267 35.4106V9.36126H100.85V14.6078H90.2466V19.7443H98.6485V24.8808H90.2466V30.1641H100.85V35.4106H84.9267ZM117.32 35.7042C109.945 35.7042 104.001 29.7605 104.001 22.386C104.001 15.0114 109.945 9.06775 117.32 9.06775C124.694 9.06775 130.638 15.0114 130.638 22.386C130.638 29.7605 124.694 35.7042 117.32 35.7042ZM117.32 30.5677C121.869 30.5677 125.281 26.8987 125.281 22.386C125.281 17.8732 121.869 14.2042 117.32 14.2042C112.77 14.2042 109.358 17.8732 109.358 22.386C109.358 26.8987 112.77 30.5677 117.32 30.5677ZM156.493 35.7042L139.579 20.7349V35.4106H134.259V9.06775L151.173 24.037V9.36126H156.493V35.7042Z" fill="white"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB

-4
View File
@@ -1,4 +0,0 @@
<svg width="157" height="45" viewBox="0 0 157 45" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M43.9842 0.0123174V44L26.9844 29.2514V44H0.416626V0L43.9842 0.0123174ZM5.75712 38.6595H21.6439V17.5326L38.644 32.5729V5.35124L5.75712 5.34181V38.6595Z" fill="#37C38F"/>
<path d="M79.0702 35.7042L62.1565 20.7349V35.4106H56.8365V9.06775L73.7503 24.037V9.36126H79.0702V35.7042ZM84.9267 35.4106V9.36126H100.85V14.6078H90.2467V19.7443H98.6485V24.8808H90.2467V30.1641H100.85V35.4106H84.9267ZM117.32 35.7042C109.945 35.7042 104.001 29.7605 104.001 22.386C104.001 15.0114 109.945 9.06775 117.32 9.06775C124.694 9.06775 130.638 15.0114 130.638 22.386C130.638 29.7605 124.694 35.7042 117.32 35.7042ZM117.32 30.5677C121.869 30.5677 125.281 26.8987 125.281 22.386C125.281 17.8732 121.869 14.2042 117.32 14.2042C112.77 14.2042 109.358 17.8732 109.358 22.386C109.358 26.8987 112.77 30.5677 117.32 30.5677ZM156.493 35.7042L139.579 20.7349V35.4106H134.259V9.06775L151.173 24.037V9.36126H156.493V35.7042Z" fill="black"/>
</svg>

Before

Width:  |  Height:  |  Size: 1018 B

-30
View File
@@ -87,36 +87,6 @@ describe("GET /api/prompts", () => {
expect(data.perPage).toBe(24);
});
it("should fall back to defaults when pagination parameters are malformed", async () => {
vi.mocked(db.prompt.findMany).mockResolvedValue([]);
vi.mocked(db.prompt.count).mockResolvedValue(0);
const request = new Request(
"http://localhost:3000/api/prompts?page=not-a-number&perPage=bad-value"
);
const response = await GET(request);
const data = await response.json();
expect(response.status).toBe(200);
expect(data.page).toBe(1);
expect(data.perPage).toBe(24);
});
it("should clamp pagination parameters to configured maximums", async () => {
vi.mocked(db.prompt.findMany).mockResolvedValue([]);
vi.mocked(db.prompt.count).mockResolvedValue(0);
const request = new Request(
"http://localhost:3000/api/prompts?page=20000&perPage=999"
);
const response = await GET(request);
const data = await response.json();
expect(response.status).toBe(200);
expect(data.page).toBe(10000);
expect(data.perPage).toBe(100);
});
it("should filter by type", async () => {
vi.mocked(db.prompt.findMany).mockResolvedValue([]);
vi.mocked(db.prompt.count).mockResolvedValue(0);
@@ -1,110 +0,0 @@
// @vitest-environment node
import { Auth, type AuthConfig } from "@auth/core";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { githubPlugin } from "@/lib/plugins/auth/github";
const ORIGIN = "https://prompts.test";
const GITHUB_ISSUER = "https://github.com/login/oauth";
function responseCookies(response: Response): string {
return response.headers.getSetCookie().map((cookie) => cookie.split(";")[0]).join("; ");
}
describe("GitHub OAuth callback", () => {
const fetchMock = vi.fn<typeof fetch>();
const signIn = vi.fn(() => true);
const logError = vi.fn();
let config: AuthConfig;
beforeEach(() => {
vi.stubEnv("GITHUB_CLIENT_ID", "test-github-client");
vi.stubEnv("GITHUB_CLIENT_SECRET", "test-github-secret");
vi.stubGlobal("fetch", fetchMock);
fetchMock.mockImplementation(async (input) => {
const url = String(input);
if (url === "https://github.com/login/oauth/access_token") {
return Response.json({ access_token: "test-access-token", token_type: "bearer" });
}
if (url === "https://api.github.com/user") {
return Response.json({
id: 123,
login: "testuser",
name: "Test User",
email: "test@example.com",
avatar_url: "https://avatars.githubusercontent.com/u/123",
});
}
throw new Error(`Unexpected fetch: ${url}`);
});
config = {
providers: [githubPlugin.getProvider()],
secret: "github-callback-test-secret",
trustHost: true,
basePath: "/api/auth",
callbacks: { signIn },
logger: { error: logError, warn: vi.fn(), debug: vi.fn() },
};
});
afterEach(() => {
vi.unstubAllEnvs();
vi.unstubAllGlobals();
vi.clearAllMocks();
});
async function startSignIn(): Promise<string> {
const csrfResponse = await Auth(new Request(`${ORIGIN}/api/auth/csrf`), config);
const { csrfToken } = await csrfResponse.json() as { csrfToken: string };
const response = await Auth(new Request(`${ORIGIN}/api/auth/signin/github`, {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
Cookie: responseCookies(csrfResponse),
},
body: new URLSearchParams({ csrfToken, callbackUrl: ORIGIN }),
}), config);
const authorizationUrl = new URL(response.headers.get("location")!);
expect(authorizationUrl.origin).toBe("https://github.com");
expect(authorizationUrl.searchParams.get("code_challenge_method")).toBe("S256");
expect(authorizationUrl.searchParams.get("code_challenge")).toBeTruthy();
return responseCookies(response);
}
it.each([GITHUB_ISSUER, undefined])("accepts GitHub callbacks with issuer %s", async (issuer) => {
const cookies = await startSignIn();
const callbackUrl = new URL(`${ORIGIN}/api/auth/callback/github?code=test-code`);
if (issuer) callbackUrl.searchParams.set("iss", issuer);
const response = await Auth(new Request(callbackUrl, { headers: { Cookie: cookies } }), config);
expect(logError).not.toHaveBeenCalled();
expect(response.headers.get("location")).toBe(ORIGIN);
expect(signIn).toHaveBeenCalledWith(expect.objectContaining({
user: expect.objectContaining({ email: "test@example.com", username: "testuser" }),
account: expect.objectContaining({ provider: "github", providerAccountId: "123" }),
}));
expect(responseCookies(response)).toContain("__Secure-authjs.session-token=");
const tokenRequest = fetchMock.mock.calls.find(([url]) => String(url).endsWith("/access_token"));
expect((tokenRequest?.[1]?.body as URLSearchParams).get("code_verifier")).toBeTruthy();
});
it("rejects a callback from an unexpected issuer before exchanging the code", async () => {
const cookies = await startSignIn();
const callbackUrl = new URL(`${ORIGIN}/api/auth/callback/github?code=test-code`);
callbackUrl.searchParams.set("iss", "https://unexpected.example.com");
const response = await Auth(new Request(callbackUrl, { headers: { Cookie: cookies } }), config);
expect(new URL(response.headers.get("location")!).searchParams.get("error")).toBe("Configuration");
expect(logError).toHaveBeenCalledWith(expect.objectContaining({
cause: expect.objectContaining({
err: expect.objectContaining({ message: 'unexpected "iss" (issuer) response parameter value' }),
}),
}));
expect(fetchMock).not.toHaveBeenCalled();
expect(signIn).not.toHaveBeenCalled();
expect(responseCookies(response)).not.toContain("authjs.session-token");
});
});
@@ -30,11 +30,6 @@ describe("getModelInfo", () => {
expect(getModelInfo("sora 2")).toEqual({ name: "Sora 2", provider: "OpenAI" });
expect(getModelInfo("runway-gen4")).toEqual({ name: "Runway Gen-4", provider: "Runway" });
});
it("returns correct info for MiniMax models", () => {
expect(getModelInfo("minimax-m3")).toEqual({ name: "MiniMax-M3", provider: "MiniMax" });
expect(getModelInfo("minimax-m2-7")).toEqual({ name: "MiniMax-M2.7", provider: "MiniMax" });
});
});
describe("isValidModelSlug", () => {
@@ -66,7 +61,6 @@ describe("getModelsByProvider", () => {
expect(grouped).toHaveProperty("Anthropic");
expect(grouped).toHaveProperty("Google");
expect(grouped).toHaveProperty("xAI");
expect(grouped).toHaveProperty("MiniMax");
});
it("includes all OpenAI models under OpenAI provider", () => {
+2 -24
View File
@@ -306,33 +306,11 @@ export async function POST(request: Request) {
}
// List prompts (for API access)
const MAX_API_PER_PAGE = 100;
const DEFAULT_API_PER_PAGE = 24;
const MAX_API_PAGE = 10000;
const DEFAULT_API_PAGE = 1;
const paginationQuerySchema = z.object({
page: z.coerce
.number()
.int()
.min(1)
.transform((value) => Math.min(value, MAX_API_PAGE))
.catch(DEFAULT_API_PAGE),
perPage: z.coerce
.number()
.int()
.min(1)
.transform((value) => Math.min(value, MAX_API_PER_PAGE))
.catch(DEFAULT_API_PER_PAGE),
});
export async function GET(request: Request) {
try {
const { searchParams } = new URL(request.url);
const { page, perPage } = paginationQuerySchema.parse({
page: searchParams.get("page"),
perPage: searchParams.get("perPage"),
});
const page = parseInt(searchParams.get("page") || "1");
const perPage = parseInt(searchParams.get("perPage") || "24");
const type = searchParams.get("type");
const categoryId = searchParams.get("category");
const tag = searchParams.get("tag");
+1 -1
View File
@@ -107,7 +107,7 @@ const jsonLd = {
name: "Prompt Engineering",
},
isAccessibleForFree: true,
numberOfPages: 26,
numberOfPages: 25,
bookFormat: "https://schema.org/EBook",
license: "https://creativecommons.org/publicdomain/zero/1.0/",
};
-46
View File
@@ -119,52 +119,6 @@ export default async function SelfHostingPage() {
</ul>
</div>
{/* Recommended Database */}
<div className="space-y-4">
<h3 className="text-lg font-semibold flex items-center gap-2">
<Database className="h-5 w-5" />
Recommended Database
</h3>
<div className="rounded-lg border p-4 space-y-4">
<p className="text-muted-foreground">
prompts.chat requires PostgreSQL. For a hosted database, we recommend{" "}
<Link
href="https://get.neon.com/VqfnMo4"
target="_blank"
rel="noopener noreferrer"
className="underline hover:text-foreground"
>
Neon
</Link>
{" "}for serverless Postgres, connection pooling, and database branching.
</p>
<div>
<p className="text-xs uppercase tracking-wide text-muted-foreground mb-3">Sponsored by</p>
<Link
href="https://get.neon.com/VqfnMo4"
target="_blank"
rel="noopener noreferrer"
className="inline-flex"
>
<Image
src="/sponsors/neon.svg"
alt="Neon"
width={250}
height={72}
className="h-10 w-auto dark:hidden"
/>
<Image
src="/sponsors/neon-dark.svg"
alt="Neon"
width={250}
height={72}
className="h-10 w-auto hidden dark:block"
/>
</Link>
</div>
</div>
</div>
{/* Installation */}
<div className="space-y-4">
<h3 className="text-lg font-semibold">Quick Start</h3>
+5 -4
View File
@@ -62,12 +62,12 @@ export const metadata: Metadata = {
publisher: "prompts.chat",
icons: {
icon: [
{ url: "/favicon/favicon.svg", type: "image/svg+xml" },
{ url: "/favicon/favicon-96x96.png", sizes: "96x96", type: "image/png" },
{ url: "/favicon/favicon.ico", sizes: "48x48" },
{ url: "/favicon/favicon-96x96.png", sizes: "96x96", type: "image/png" },
{ url: "/favicon/favicon.svg", type: "image/svg+xml" },
],
apple: "/favicon/apple-touch-icon.png",
shortcut: "/favicon/favicon.svg",
shortcut: "/favicon/favicon.ico",
},
manifest: "/favicon/site.webmanifest",
other: {
@@ -153,6 +153,7 @@ export default async function RootLayout({
const pathname = headersList.get("x-pathname") || headersList.get("x-invoke-path") || "";
const isEmbedRoute = pathname.startsWith("/embed");
const isKidsRoute = pathname.startsWith("/kids");
const isPresentationRoute = pathname.startsWith("/presentation");
const locale = await getLocale();
const messages = await getMessages();
@@ -191,7 +192,7 @@ export default async function RootLayout({
<Analytics gaId={process.env.GOOGLE_ANALYTICS_ID} />
)}
<Providers locale={locale} messages={messages} theme={config.theme} branding={{ ...config.branding, useCloneBranding: config.homepage?.useCloneBranding }}>
{isEmbedRoute || isKidsRoute ? (
{isEmbedRoute || isKidsRoute || isPresentationRoute ? (
children
) : (
<>
+505 -211
View File
@@ -1,233 +1,527 @@
import { SlideDeck, SlideTitle, SlideContent, SlideHighlight } from "@/components/presentation/SlideDeck";
import { MoveRight, Star, GitMerge, FileCode2, Sparkles, MessageSquare, Globe, Users, Code, Zap, Lightbulb } from "lucide-react";
import Link from "next/link";
import { Button } from "@/components/ui/button";
import {
Blocks,
Bot,
BrainCircuit,
CheckCircle2,
CircleDotDashed,
ClipboardCheck,
Clock3,
DatabaseZap,
FileText,
Filter,
GitBranch,
Layers3,
Lightbulb,
MessageSquareText,
Network,
PackageCheck,
Puzzle,
RefreshCw,
Route,
Scissors,
ShieldCheck,
Sparkles,
Target,
TimerReset,
WandSparkles,
} from "lucide-react";
import type { LucideIcon } from "lucide-react";
import Image from "next/image";
import type { ReactNode } from "react";
import { SlideContent, SlideDeck, SlideHighlight, SlideTitle } from "@/components/presentation/SlideDeck";
export const metadata = {
title: "Why prompts.chat? | Presentation",
description: "Discover why prompts are more important than ever in the agentic era.",
title: "Prompt Tasarımı ve Context Yönetimi | Presentation",
description: "30 dakikalık Türkçe konuşma: prompt tasarımı, context yönetimi ve prompts.chat.",
};
const speakerNotes = [
"Açılışta sunumun amacını netleştir: Bu konuşma prompt ezberlemek değil, bağlamı bilinçli yönetmek üzerine. 30 dakika sonunda herkesin kendi işine uygulayabileceği bir kontrol listesi olacak.",
"Konuşmacı slaytı kısa tutulmalı. Kişisel hikaye: Awesome ChatGPT Prompts ile başlayan topluluk deneyimi, prompts.chat ile promptların paylaşılabilir, sürümlenebilir ve geliştirilebilir varlıklara dönüşmesi.",
"Akışı anlat: önce zihinsel model, sonra promptun anatomisi, sonra context yönetimi ve ölçüm. prompts.chat bölümünü ürün demosu gibi değil, bu prensiplerin pratik karşılığı olarak konumlandır.",
"Ana mesaj: Modeli sadece cevap makinesi gibi değil, sınırlı dikkat alanına sahip bir ekip arkadaşı gibi düşünün. Prompt tasarımı görevi tanımlar; context yönetimi modelin neye bakacağını seçer.",
"Prompt tasarımının yalnızca güzel cümle yazmak olmadığını vurgula. Rol, hedef, veri, sınır, örnek ve çıktı sözleşmesi bir araya geldiğinde modelin çalışma alanı oluşur.",
"Bu slaytta kötü prompt / iyi prompt farkını canlı okuyarak göster. İyi örneğin daha uzun olduğu için değil, karar yükünü azalttığı için iyi olduğunu söyle.",
"Context penceresini dosya dolabı değil, toplantı masası metaforu ile anlat. Masaya her şeyi koymak odak kaybettirir; doğru şeyleri doğru sırayla koymak performansı artırır.",
"Bağlam katmanlarını sırayla açıkla. Sistem ve geliştirici talimatlarının politikayı, kullanıcı mesajının amacı, araç sonuçlarının kanıtı, geçmişin ise sürekliliği taşıdığını anlat.",
"Önemli ayrım: Context çokluğu kalite demek değildir. Gürültü, eski kararlar ve çelişkili talimatlar modeli kararsızlaştırır. Context tasarrufu aynı zamanda kalite kontrolüdür.",
"Kısa bir teknik çerçeve ver: seç, sırala, sıkıştır, doğrula. Bu dört fiil context yönetiminin günlük pratiği olabilir.",
"Örnekler model davranışını güçlü biçimde kilitler. Ancak yanlış örnekler de yanlış davranışı kilitler. Örnekleri az ama temsil gücü yüksek seçmek gerektiğini vurgula.",
"Çıktı sözleşmesi özellikle ekiplerde önemlidir. JSON, tablo, diff, adım adım plan gibi formatlar otomasyon ve tekrar üretilebilirlik sağlar.",
"Araç kullanan ajanlarda prompt, sadece cevap formatını değil yetki sınırını da belirler. Ne zaman arama yapmalı, ne zaman sormalı, ne zaman durmalı gibi kararları açık yazın.",
"Context yönetiminin operasyonel tarafı: uzun konuşmalarda özet, dosya tabanlı işlerde ilgili parçalar, arama tabanlı işlerde kaynak ve alıntı. Her şeyi tek mesaja doldurmak yerine akış tasarla.",
"Hata modlarını örneklerle anlat: belirsiz hedef, eski bağlam, çelişki, görünmez varsayım, format eksikliği. Bunlar model hatası gibi görünür ama çoğu zaman tasarım hatasıdır.",
"Ölçüm slaytında küçük bir test setinin değerini anlat. Aynı promptu birkaç gerçek senaryo ile denemek, tek seferlik iyi cevaptan daha güvenilirdir.",
"prompts.chat'i bağlamla ilişkilendir: iyi promptlar tek kişide kalmamalı. Paylaşım, sürümleme ve geri bildirim prompt kalitesini artırır.",
"Ekip pratiğine geç: promptlar kod gibi yaşamalı. Sahiplik, değişiklik geçmişi, review ve örnek çıktılar promptun güvenilirliğini artırır.",
"Kapanış kontrol listesini yavaş oku. Dinleyicilerin kendi promptlarını bu beş soruyla gözden geçirmesini iste.",
"Son slaytta tek cümlelik kapanış: İyi prompt, modele ne yapacağını söyler; iyi context yönetimi, neye dayanarak yapacağını belirler.",
];
type CardProps = {
icon: LucideIcon;
title: string;
children: ReactNode;
accent?: string;
};
function Card({ icon: Icon, title, children, accent = "text-primary" }: CardProps) {
return (
<div className="rounded-3xl border border-border/70 bg-background/70 p-6 shadow-sm backdrop-blur transition-transform duration-300 hover:-translate-y-1">
<div className={`mb-4 flex h-12 w-12 items-center justify-center rounded-2xl bg-primary/10 ${accent}`}>
<Icon className="h-6 w-6" />
</div>
<h3 className="mb-2 text-2xl font-bold text-foreground">{title}</h3>
<p className="text-lg leading-relaxed text-muted-foreground">{children}</p>
</div>
);
}
function Pill({ children }: { children: ReactNode }) {
return (
<span className="inline-flex items-center rounded-full border border-primary/20 bg-primary/10 px-4 py-2 text-base font-semibold text-primary">
{children}
</span>
);
}
function CodePanel({ children, title = "prompt.md" }: { children: ReactNode; title?: string }) {
return (
<div className="overflow-hidden rounded-3xl border border-border bg-zinc-950 text-zinc-100 shadow-2xl">
<div className="flex items-center justify-between border-b border-white/10 bg-white/5 px-5 py-3">
<div className="flex gap-2">
<span className="h-3 w-3 rounded-full bg-red-400" />
<span className="h-3 w-3 rounded-full bg-yellow-400" />
<span className="h-3 w-3 rounded-full bg-green-400" />
</div>
<span className="font-mono text-xs text-zinc-400">{title}</span>
</div>
<pre className="whitespace-pre-wrap p-6 font-mono text-sm leading-relaxed md:text-base">{children}</pre>
</div>
);
}
function FlowStep({ icon: Icon, title, text }: { icon: LucideIcon; title: string; text: string }) {
return (
<div className="relative rounded-3xl border border-border/70 bg-background/75 p-5 shadow-sm">
<div className="mb-4 flex h-12 w-12 items-center justify-center rounded-2xl bg-primary/10 text-primary">
<Icon className="h-6 w-6" />
</div>
<h3 className="text-2xl font-bold">{title}</h3>
<p className="mt-2 text-lg leading-relaxed text-muted-foreground">{text}</p>
</div>
);
}
function ContextLayer({ label, description, tone }: { label: string; description: string; tone: string }) {
return (
<div className="flex items-center gap-4 rounded-2xl border border-border bg-background/75 p-4 shadow-sm">
<div className={`h-14 w-2 rounded-full ${tone}`} />
<div>
<h3 className="text-xl font-bold">{label}</h3>
<p className="text-base text-muted-foreground">{description}</p>
</div>
</div>
);
}
function MiniChecklist({ items }: { items: string[] }) {
return (
<div className="grid gap-3">
{items.map((item) => (
<div key={item} className="flex items-start gap-3 rounded-2xl border border-border/70 bg-background/70 p-4 text-xl font-semibold">
<CheckCircle2 className="mt-1 h-6 w-6 flex-none text-primary" />
<span>{item}</span>
</div>
))}
</div>
);
}
export default function PresentationPage() {
return (
<SlideDeck>
{/* 1. Title Slide */}
<div className="flex flex-col items-center justify-center text-center h-full">
<div className="w-24 h-24 bg-primary/10 rounded-3xl flex items-center justify-center mb-8 rotate-12 transition-transform hover:rotate-0 duration-500">
<Sparkles className="w-12 h-12 text-primary" />
<SlideDeck notes={speakerNotes}>
<div className="flex min-h-[70vh] flex-col items-center justify-center text-center">
<div className="mb-8 flex h-24 w-24 rotate-6 items-center justify-center rounded-[2rem] bg-primary/10 text-primary shadow-xl shadow-primary/10">
<WandSparkles className="h-12 w-12" />
</div>
<SlideTitle className="mb-6">Why prompts.chat?</SlideTitle>
<SlideContent className="max-w-3xl mb-12">Discover why prompts are more important than ever in the agentic era.</SlideContent>
<p className="text-sm text-muted-foreground animate-pulse mt-8">
Use arrow keys <MoveRight className="inline w-4 h-4 mx-1" /> or swipe to navigate
</p>
</div>
{/* 2. The Genesis */}
<div className="flex flex-col justify-center h-full">
<Star className="w-12 h-12 text-yellow-500 mb-6" />
<SlideTitle>The History of prompts.chat</SlideTitle>
<SlideContent>
From a simple repository to a full-fledged platform. We started as Awesome ChatGPT Prompts, and evolved to support the entire AI community with typed prompts, workflows, and skills.
<SlideTitle className="max-w-5xl">Prompt Tasarımı ve Context Yönetimi</SlideTitle>
<SlideContent className="mx-auto max-w-3xl">
30 dakikalık pratik bir çerçeve: daha iyi talimat, daha temiz bağlam, daha güvenilir AI çıktısı.
</SlideContent>
<div className="mt-12 p-6 bg-muted/50 rounded-2xl border border-border max-w-2xl">
<p className="text-lg text-foreground font-mono">
Awesome ChatGPT Prompts → <SlideHighlight>prompts.chat</SlideHighlight>
</p>
<div className="mt-10 flex flex-wrap justify-center gap-3">
<Pill>prompts.chat/presentation</Pill>
<Pill>Ok tuşları, boşluk, F, N</Pill>
</div>
</div>
{/* 3. The Paradigm Shift */}
<div className="flex flex-col justify-center h-full">
<Zap className="w-12 h-12 text-blue-500 mb-6" />
<SlideTitle>The Agentic Era</SlideTitle>
<SlideContent>
Why are prompts still important? Because agents need instructions. As AI becomes more autonomous, the quality of instructions determines the quality of the outcome.
</SlideContent>
</div>
{/* 4. The Core Question */}
<div className="flex flex-col items-center justify-center text-center h-full">
<Lightbulb className="w-16 h-16 text-yellow-400 mb-8" />
<SlideTitle className="text-5xl md:text-6xl">Wait, isn't AI getting smarter?</SlideTitle>
<SlideContent className="max-w-4xl mt-8">
Yes, but <SlideHighlight>smart AI still needs direction.</SlideHighlight>
<br /><br />
A genius without instructions is just a very capable idle machine.
</SlideContent>
</div>
{/* 5. The Agentic Need */}
<div className="flex flex-col justify-center h-full">
<SlideTitle>The Agentic Need</SlideTitle>
<SlideContent>
Agents require precise instructions, constraints, and goal definitions.
<ul className="mt-8 space-y-6 list-disc list-inside ml-4 text-foreground/80 text-2xl md:text-3xl">
<li>What tools can they use?</li>
<li>What are their boundaries?</li>
<li>How should they format the output?</li>
<li>What tone should they adopt?</li>
</ul>
</SlideContent>
</div>
{/* 6. The SLM Revolution */}
<div className="flex flex-col justify-center h-full">
<Globe className="w-12 h-12 text-green-500 mb-6" />
<SlideTitle>Crucial for SLMs</SlideTitle>
<SlideContent>
Small Language Models (SLMs) are the future of edge computing. They require precise, well-crafted prompts to perform tasks accurately without the massive parameter count of frontier models.
</SlideContent>
</div>
{/* 7. SLM Constraints */}
<div className="flex flex-col justify-center h-full">
<SlideTitle>SLM Constraints</SlideTitle>
<SlideContent>
Smaller models lack the vast "common sense" of 1T+ parameter models.
<br /><br />
They require <SlideHighlight>highly optimized, battle-tested prompts</SlideHighlight> to punch above their weight class and run efficiently on local devices.
</SlideContent>
</div>
{/* 8. The New Primitive */}
<div className="flex flex-col justify-center h-full">
<FileCode2 className="w-12 h-12 text-purple-500 mb-6" />
<SlideTitle>Prompts are New Code Snippets</SlideTitle>
<SlideContent>
Just as developers copy/paste code snippets from StackOverflow, AI practitioners now share prompt templates. Prompts are the new primitive of programming.
</SlideContent>
<div className="mt-12 flex items-center gap-4 text-xl md:text-2xl font-mono text-muted-foreground bg-muted p-6 rounded-xl border max-w-fit">
<span>const codeSnippet = "..."</span>
<MoveRight className="w-6 h-6 text-primary mx-2" />
<span className="text-primary">const promptTemplate = "..."</span>
<div className="grid min-h-[70vh] items-center gap-8 lg:grid-cols-[1fr_0.95fr]">
<div className="relative order-2 lg:order-1">
<div className="absolute -left-8 top-10 h-72 w-72 rounded-full bg-primary/20 blur-3xl" />
<div className="relative mx-auto w-full max-w-[34rem]">
<div className="absolute -inset-4 -rotate-3 rounded-[3rem] bg-gradient-to-br from-primary/30 via-primary/10 to-transparent" />
<div className="relative overflow-hidden rounded-[3rem] border border-border bg-background shadow-2xl">
<Image
src="https://github.com/f.png"
alt="Fatih Kadir Akın profil fotoğrafı"
width={900}
height={900}
priority
unoptimized
className="aspect-square w-full object-cover"
/>
<div className="absolute inset-x-0 bottom-0 bg-gradient-to-t from-black/80 via-black/45 to-transparent p-8 text-white">
<p className="text-sm font-bold uppercase tracking-[0.35em] text-white/70">Konuşmacı</p>
<h2 className="mt-2 text-5xl font-black tracking-tight">Fatih Kadir Akın</h2>
<p className="mt-3 max-w-md text-lg font-semibold leading-snug text-white/85">
WordPress Developer Advocate, Automattic - Creator of prompts.chat
</p>
</div>
</div>
</div>
</div>
<div className="order-1 lg:order-2">
<SlideTitle className="mb-5">Merhaba, ben Fatih.</SlideTitle>
<SlideContent className="max-w-2xl">
Geliştiricilerin hayatını kolaylaştıran uygulamalar geliştiriyorum; bunlardan biri de{" "}
<SlideHighlight>prompts.chat</SlideHighlight>.
</SlideContent>
<div className="mt-10 flex flex-wrap items-center gap-5">
<div className="flex items-center gap-3 rounded-2xl border border-border/70 bg-background/75 px-5 py-4 shadow-sm backdrop-blur">
<Image
src="https://cdn.simpleicons.org/wordpress/21759B"
alt="WordPress"
width={40}
height={40}
unoptimized
className="h-10 w-10"
/>
<span className="text-xl font-bold text-foreground">WordPress</span>
</div>
<div className="flex items-center gap-3 rounded-2xl border border-border/70 bg-background/75 px-5 py-4 shadow-sm backdrop-blur">
<Image
src="https://cdn.simpleicons.org/automattic/000000"
alt="Automattic"
width={40}
height={40}
unoptimized
className="h-10 w-10 dark:invert"
/>
<span className="text-xl font-bold text-foreground">Automattic</span>
</div>
</div>
</div>
</div>
{/* 9. Open Source AI */}
<div className="flex flex-col justify-center h-full">
<Users className="w-12 h-12 text-indigo-500 mb-6" />
<SlideTitle>Community Sharing</SlideTitle>
<SlideContent>
Nobody learns in isolation. By sharing prompts, we accelerate the collective understanding of how to communicate with AI. It's the open-source movement for human-AI interaction.
</SlideContent>
</div>
{/* 10. Collective Intelligence */}
<div className="flex flex-col items-center justify-center text-center h-full">
<SlideTitle className="text-5xl md:text-6xl">Collective Intelligence</SlideTitle>
<SlideContent className="max-w-4xl mt-8">
We are building the <SlideHighlight>largest open repository</SlideHighlight> of human-AI interaction patterns.
<br /><br />
Tested, versioned, and peer-reviewed.
</SlideContent>
</div>
{/* 11. Feature - Typed Prompts */}
<div className="flex flex-col justify-center h-full">
<Code className="w-12 h-12 text-red-500 mb-6" />
<SlideTitle>Feature: Typed Prompts</SlideTitle>
<SlideContent>
Natural language is ambiguous. <SlideHighlight>Typed Prompts</SlideHighlight> bring structure.
<br /><br />
Define inputs, outputs, and variables systematically so prompts can be executed predictably via APIs.
</SlideContent>
</div>
{/* 12. Feature - Workflows */}
<div className="flex flex-col justify-center h-full">
<div className="flex gap-2 mb-6">
<div className="w-8 h-8 rounded bg-primary"></div>
<MoveRight className="w-8 h-8 text-muted-foreground" />
<div className="w-8 h-8 rounded bg-primary/70"></div>
<MoveRight className="w-8 h-8 text-muted-foreground" />
<div className="w-8 h-8 rounded bg-primary/40"></div>
<div className="flex min-h-[70vh] flex-col justify-center">
<SlideTitle>Bugünkü rota</SlideTitle>
<div className="grid gap-5 md:grid-cols-2">
<FlowStep icon={BrainCircuit} title="Zihinsel model" text="Modelin neyi, ne sırayla ve hangi amaçla görmesi gerektiğini düşünmek." />
<FlowStep icon={MessageSquareText} title="Prompt anatomisi" text="Rol, hedef, bağlam, kısıtlar, örnekler ve çıktı sözleşmesi." />
<FlowStep icon={Layers3} title="Context yönetimi" text="Sınırlı dikkat alanını seçmek, sıralamak, sıkıştırmak ve temizlemek." />
<FlowStep icon={ClipboardCheck} title="Ölçüm ve paylaşım" text="Promptu tek seferlik cümle değil, iyileştirilebilir artefact yapmak." />
</div>
<SlideTitle>Feature: Workflows</SlideTitle>
<SlideContent>
Some tasks are too complex for a single prompt.
<br /><br />
Chain multiple prompts together to create <SlideHighlight>Workflows</SlideHighlight> — dividing and conquering complex agentic tasks.
</SlideContent>
</div>
{/* 13. Feature - Agent Skills */}
<div className="flex flex-col justify-center h-full">
<SlideTitle>Feature: Agent Skills</SlideTitle>
<SlideContent>
Equip coding assistants (like Claude, Cursor, Windsurf) with specialized, multi-file capabilities.
<br /><br />
Give your AI the context and rules it needs to build within your specific tech stack.
</SlideContent>
</div>
{/* 14. Feature - Change Requests */}
<div className="flex flex-col justify-center h-full">
<GitMerge className="w-12 h-12 text-orange-500 mb-6" />
<SlideTitle>Feature: Change Requests</SlideTitle>
<SlideContent>
Prompts evolve. We've introduced <SlideHighlight>Pull Requests for Prompts.</SlideHighlight>
<br /><br />
Collaborate, suggest improvements, and refine instructions together as a community.
</SlideContent>
</div>
{/* 15. For Developers */}
<div className="flex flex-col justify-center h-full">
<SlideTitle>For Developers</SlideTitle>
<SlideContent>
prompts.chat isn't just for end-users. With features like Agent Skills, Typed Prompts, and API integrations, it's a vital tool for developers building the next generation of AI apps.
</SlideContent>
</div>
{/* 16. For Everyone */}
<div className="flex flex-col justify-center h-full">
<MessageSquare className="w-12 h-12 text-pink-500 mb-6" />
<SlideTitle>For Everyone</SlideTitle>
<SlideContent>
Discover, collect, and learn from <SlideHighlight>Promptmasters</SlideHighlight>.
<br /><br />
A beautifully designed, accessible platform to find exactly what you need to make AI work for you.
</SlideContent>
</div>
{/* 17. Self-Hosted */}
<div className="flex flex-col justify-center h-full">
<Globe className="w-12 h-12 text-teal-500 mb-6" />
<SlideTitle>Fully Self-Hosted</SlideTitle>
<SlideContent>
Your data, your platform.
<br /><br />
prompts.chat is <SlideHighlight>100% open-source</SlideHighlight> and deployable to any server or cloud provider. Own your organization's prompt library securely.
</SlideContent>
</div>
{/* 18. The Vision */}
<div className="flex flex-col items-center justify-center text-center h-full">
<SlideTitle className="text-5xl md:text-6xl">The Vision</SlideTitle>
<SlideContent className="max-w-4xl mt-8">
To create the <SlideHighlight>standard protocol</SlideHighlight> for human-AI interaction.
<br /><br />
Where every great instruction is shared, improved, and accessible to all.
</SlideContent>
</div>
{/* 19. Call to Action */}
<div className="flex flex-col items-center justify-center text-center h-full">
<div className="w-24 h-24 bg-primary/10 rounded-full flex items-center justify-center mb-8">
<Users className="w-12 h-12 text-primary" />
<div className="flex min-h-[70vh] flex-col justify-center">
<SlideTitle>AI ile çalışmak: çok zeki ama bağlama bağımlı bir ekip arkadaşı</SlideTitle>
<div className="grid gap-6 md:grid-cols-3">
<Card icon={Target} title="Amaç net olmalı">
Modelin optimizasyon hedefi belirsizse cevap da belirsizleşir.
</Card>
<Card icon={ShieldCheck} title="Sınırlar görünür olmalı">
Ne yapılmayacağı, ne yapılacağı kadar önemlidir.
</Card>
<Card icon={DatabaseZap} title="Kanıt seçilmeli">
Model en son ve en belirgin bağlama fazla ağırlık verir.
</Card>
</div>
<SlideTitle>Join the Community</SlideTitle>
<SlideContent className="max-w-2xl mb-12">
Start exploring, sharing, and building the future of AI interaction today.
<SlideContent className="mt-10 max-w-4xl">
İyi prompt <SlideHighlight>ne yapılacağını</SlideHighlight>, iyi context yönetimi ise{" "}
<SlideHighlight>neye dayanarak yapılacağını</SlideHighlight> belirler.
</SlideContent>
<div className="flex flex-col sm:flex-row gap-4">
<Link href="/discover">
<Button size="lg" className="text-lg px-8 py-6 rounded-xl">Explore Prompts</Button>
</Link>
<Link href="https://github.com/fka/awesome-chatgpt-prompts" target="_blank">
<Button size="lg" variant="outline" className="text-lg px-8 py-6 rounded-xl">Star on GitHub</Button>
</Link>
</div>
<div className="grid min-h-[70vh] items-center gap-8 lg:grid-cols-2">
<div>
<SlideTitle>Prompt tasarımı cümle süslemek değildir</SlideTitle>
<SlideContent>
Prompt, modelle aranızdaki <SlideHighlight>çalışma sözleşmesidir</SlideHighlight>.
Cevabın amacı, kapsamı, kaynakları, formatı ve kalite barı bu sözleşmede yer alır.
</SlideContent>
</div>
<div className="grid gap-4">
{[
["Rol", "Hangi perspektiften düşünecek?"],
["Görev", "Tam olarak neyi üretecek?"],
["Bağlam", "Hangi bilgiye dayanacak?"],
["Kısıt", "Neyi yapmayacak veya aşmayacak?"],
["Çıktı", "Nasıl teslim edecek?"],
].map(([label, text]) => (
<div key={label} className="flex items-center gap-4 rounded-2xl border border-border bg-background/75 p-4">
<div className="flex h-12 w-12 items-center justify-center rounded-xl bg-primary/10 font-black text-primary">{label[0]}</div>
<div>
<h3 className="text-xl font-bold">{label}</h3>
<p className="text-muted-foreground">{text}</p>
</div>
</div>
))}
</div>
</div>
<div className="grid min-h-[70vh] items-center gap-8 lg:grid-cols-2">
<div>
<SlideTitle>Kötü prompt / iyi prompt</SlideTitle>
<SlideContent>
Uzun olan değil, <SlideHighlight>karar yükünü azaltan</SlideHighlight> prompt daha iyidir.
</SlideContent>
</div>
<div className="space-y-5">
<CodePanel title="belirsiz.prompt">
{`Bana context management hakkında iyi bir yazı yaz.`}
</CodePanel>
<CodePanel title="tasarlanmis.prompt">
{`Rol: Kıdemli AI ürün danışmanı.
Amaç: Teknik olmayan ürün ekibine context management anlat.
Bağlam: 30 dakikalık şirket içi eğitim.
Kısıt: Jargon kullanma, 3 örnek ver, riskleri belirt.
Çıktı: Başlık, 5 maddelik özet, uygulanabilir kontrol listesi.`}
</CodePanel>
</div>
</div>
<div className="flex min-h-[70vh] flex-col justify-center">
<SlideTitle>Context penceresi dosya dolabı değil, toplantı masasıdır</SlideTitle>
<SlideContent className="max-w-5xl">
Masaya her şeyi koyarsanız ekip odaklanamaz. Doğru belgeleri, doğru sırayla, doğru ayrıntı seviyesinde getirirsiniz.
</SlideContent>
<div className="mt-10 grid gap-5 md:grid-cols-4">
<FlowStep icon={Filter} title="Seç" text="İlgili olanı ayır." />
<FlowStep icon={Route} title="Sırala" text="Önceliği görünür yap." />
<FlowStep icon={Scissors} title="Sıkıştır" text="Gürültüyü azalt." />
<FlowStep icon={CheckCircle2} title="Doğrula" text="Kaynak ve sonucu kontrol et." />
</div>
</div>
<div className="grid min-h-[70vh] items-center gap-10 lg:grid-cols-[0.9fr_1.1fr]">
<div>
<SlideTitle>Bağlam katmanları</SlideTitle>
<SlideContent>
Model tek bir metni değil, üst üste binmiş talimat ve kanıt katmanlarını yorumlar.
</SlideContent>
</div>
<div className="grid gap-3">
<ContextLayer label="Sistem" description="Kimlik, güvenlik ve en üst kurallar." tone="bg-red-500" />
<ContextLayer label="Geliştirici" description="Uygulama davranışı, araç kullanımı, format kuralları." tone="bg-orange-500" />
<ContextLayer label="Kullanıcı" description="Anlık amaç, ihtiyaç ve başarı tanımı." tone="bg-primary" />
<ContextLayer label="Araç sonuçları" description="Arama, dosya, API veya veritabanından gelen kanıt." tone="bg-emerald-500" />
<ContextLayer label="Geçmiş" description="Konuşma sürekliliği ve önceki kararlar." tone="bg-sky-500" />
</div>
</div>
<div className="flex min-h-[70vh] flex-col justify-center">
<SlideTitle>Daha fazla context her zaman daha iyi değildir</SlideTitle>
<div className="grid gap-6 md:grid-cols-3">
<Card icon={CircleDotDashed} title="Gürültü" accent="text-orange-500">
Alakasız detaylar, önemli sinyali gömer.
</Card>
<Card icon={RefreshCw} title="Eski kararlar" accent="text-sky-500">
Geçmişte doğru olan bilgi bugün yanlış olabilir.
</Card>
<Card icon={Puzzle} title="Çelişkiler" accent="text-red-500">
Model hangi talimata uyacağını tahmin etmek zorunda kalır.
</Card>
</div>
<SlideContent className="mt-10">
Context yönetimi, token tasarrufu değil; <SlideHighlight>dikkat yönetimidir</SlideHighlight>.
</SlideContent>
</div>
<div className="flex min-h-[70vh] flex-col justify-center">
<SlideTitle>Pratik yöntem: seç, sırala, sıkıştır, doğrula</SlideTitle>
<div className="grid gap-5 lg:grid-cols-4">
<FlowStep icon={Filter} title="Seç" text="Bu görev için gerçekten gerekli bilgi ne?" />
<FlowStep icon={Layers3} title="Sırala" text="En önemli talimat ve kanıt en görünür yerde mi?" />
<FlowStep icon={Scissors} title="Sıkıştır" text="Tekrar, sohbet gürültüsü ve eski kararlar temizlendi mi?" />
<FlowStep icon={ClipboardCheck} title="Doğrula" text="Cevap kaynak, format ve başarı kriteriyle uyuşuyor mu?" />
</div>
</div>
<div className="grid min-h-[70vh] items-center gap-10 lg:grid-cols-2">
<div>
<SlideTitle>Örnekler davranışı kilitler</SlideTitle>
<SlideContent>
Few-shot örnekler modele sadece formatı değil, <SlideHighlight>neyi iyi saydığınızı</SlideHighlight> gösterir.
</SlideContent>
</div>
<div className="rounded-3xl border border-border bg-background/75 p-6 shadow-sm">
<div className="mb-6 flex items-center gap-3">
<Lightbulb className="h-7 w-7 text-yellow-500" />
<h3 className="text-2xl font-bold">Örnek seçerken</h3>
</div>
<MiniChecklist
items={[
"Gerçek kullanım senaryosuna benziyor mu?",
"Başarılı ve başarısız örnek ayrımı var mı?",
"Format, ton ve ayrıntı seviyesi temsil ediliyor mu?",
"Yanlış genelleme yaratacak özel durum var mı?",
]}
/>
</div>
</div>
<div className="grid min-h-[70vh] items-center gap-8 lg:grid-cols-2">
<div>
<SlideTitle>Çıktı sözleşmesi otomasyonun kapısıdır</SlideTitle>
<SlideContent>
İnsan okuyacaksa okunabilirlik, sistem okuyacaksa <SlideHighlight>şema</SlideHighlight> önemlidir.
</SlideContent>
</div>
<CodePanel title="output-contract.json">
{`{
"summary": "en fazla 3 cümle",
"risks": ["kanıta dayalı risk listesi"],
"next_actions": [
{ "owner": "rol", "task": "yapılacak iş", "priority": "P0 | P1 | P2" }
],
"confidence": "low | medium | high"
}`}
</CodePanel>
</div>
<div className="flex min-h-[70vh] flex-col justify-center">
<SlideTitle>Ajanlarda prompt = yetki ve durma kuralları</SlideTitle>
<div className="grid gap-6 md:grid-cols-3">
<Card icon={Bot} title="Ne zaman araç?" accent="text-sky-500">
Bilgi eksikse arama yap; tahminle doldurma.
</Card>
<Card icon={ShieldCheck} title="Ne zaman sormalı?" accent="text-emerald-500">
Kapsam veya risk davranışı etkiliyorsa kullanıcıya dön.
</Card>
<Card icon={TimerReset} title="Ne zaman durmalı?" accent="text-purple-500">
Başarı kriteri tamamlandıysa yeni iş icat etme.
</Card>
</div>
</div>
<div className="grid min-h-[70vh] items-center gap-8 lg:grid-cols-[1fr_1.1fr]">
<div>
<SlideTitle>Uzun işlerde context akışı tasarla</SlideTitle>
<SlideContent>
Tek dev prompt yerine, işi aşamalara böl: keşif, plan, uygulama, doğrulama, özet.
</SlideContent>
</div>
<div className="grid gap-4">
{[
{ icon: Network, title: "Keşif", text: "Dosya, kaynak ve kısıtları topla." },
{ icon: Route, title: "Plan", text: "Kararları ve bağımlılıkları görünür yap." },
{ icon: Blocks, title: "Uygulama", text: "Sadece gerekli bağlamı sonraki adıma taşı." },
{ icon: ClipboardCheck, title: "Doğrulama", text: "Çıktıyı ölçüt ve kaynakla kontrol et." },
].map(({ icon: Icon, title, text }) => (
<div key={title} className="flex items-center gap-4 rounded-2xl border border-border bg-background/75 p-4 shadow-sm">
<div className="flex h-12 w-12 items-center justify-center rounded-xl bg-primary/10 text-primary">
<Icon className="h-6 w-6" />
</div>
<div>
<h3 className="text-xl font-bold">{title}</h3>
<p className="text-muted-foreground">{text}</p>
</div>
</div>
))}
</div>
</div>
<div className="flex min-h-[70vh] flex-col justify-center">
<SlideTitle>En sık görülen hata modları</SlideTitle>
<div className="grid gap-5 md:grid-cols-2">
<FlowStep icon={Target} title="Belirsiz hedef" text="Başarı tanımı yoksa model kendi hedefini seçer." />
<FlowStep icon={Clock3} title="Eski context" text="Önceki kararlar yeni talimatla çakışır." />
<FlowStep icon={Puzzle} title="Görünmez varsayım" text="Sizde açık olan bilgi modelde yoktur." />
<FlowStep icon={FileText} title="Format eksikliği" text="Doğru bilgi yanlış biçimde gelirse kullanılamaz." />
</div>
</div>
<div className="grid min-h-[70vh] items-center gap-10 lg:grid-cols-2">
<div>
<SlideTitle>Promptları ölç: tek iyi cevap yetmez</SlideTitle>
<SlideContent>
Küçük bir test seti, promptun gerçek hayatta dayanıklı olup olmadığını gösterir.
</SlideContent>
</div>
<div className="rounded-3xl border border-border bg-background/75 p-6 shadow-sm">
<MiniChecklist
items={[
"3 normal senaryo",
"2 sınır durum",
"1 kasıtlı belirsiz istek",
"Beklenen format kontrolü",
"İyi cevap nasıl görünür? kısa kontrol listesi",
]}
/>
</div>
</div>
<div className="grid min-h-[70vh] items-center gap-10 lg:grid-cols-[1.05fr_0.95fr]">
<div>
<SlideTitle>prompts.chat: promptları paylaşılabilir hale getirmek</SlideTitle>
<SlideContent>
Promptlar kaybolan sohbet parçaları olmamalı. Keşfedilebilir, fork edilebilir, iyileştirilebilir ve tekrar kullanılabilir olmalı.
</SlideContent>
</div>
<div className="grid gap-4">
<Card icon={Sparkles} title="Keşif">
İyi örneği arayıp bulmak, sıfırdan başlamaktan hızlıdır.
</Card>
<Card icon={GitBranch} title="Değişiklik">
Promptlar review ve geri bildirimle olgunlaşır.
</Card>
<Card icon={PackageCheck} title="Yeniden kullanım">
Aynı kaliteyi farklı ekip ve iş akışlarına taşırsınız.
</Card>
</div>
</div>
<div className="flex min-h-[70vh] flex-col justify-center">
<SlideTitle>Promptlar kod gibi yaşamalı</SlideTitle>
<div className="grid gap-5 md:grid-cols-4">
<FlowStep icon={FileText} title="Sahiplik" text="Kim güncelliyor?" />
<FlowStep icon={GitBranch} title="Sürüm" text="Ne değişti?" />
<FlowStep icon={ClipboardCheck} title="Review" text="Kalite barı ne?" />
<FlowStep icon={DatabaseZap} title="Örnek" text="Hangi veriyle çalıştı?" />
</div>
</div>
<div className="grid min-h-[70vh] items-center gap-10 lg:grid-cols-[0.95fr_1.05fr]">
<div>
<SlideTitle>Kapanış kontrol listesi</SlideTitle>
<SlideContent>
Bir sonraki promptunuzu göndermeden önce bu beş soruyu sorun.
</SlideContent>
</div>
<MiniChecklist
items={[
"Modelin rolü ve hedefi net mi?",
"Gerekli context seçildi ve sıralandı mı?",
"Kısıtlar ve durma kuralları yazıldı mı?",
"Çıktı formatı sözleşmeye bağlandı mı?",
"En az birkaç gerçek senaryoyla denendi mi?",
]}
/>
</div>
<div className="flex min-h-[70vh] flex-col items-center justify-center text-center">
<div className="mb-8 flex h-24 w-24 items-center justify-center rounded-full bg-primary/10 text-primary">
<Sparkles className="h-12 w-12" />
</div>
<SlideTitle>Teşekkürler</SlideTitle>
<SlideContent className="mx-auto max-w-4xl">
İyi prompt modele <SlideHighlight>ne yapacağını</SlideHighlight> söyler.
<br />
İyi context yönetimi <SlideHighlight>neye dayanarak yapacağını</SlideHighlight> belirler.
</SlideContent>
<div className="mt-10 flex flex-wrap justify-center gap-3">
<Pill>prompts.chat</Pill>
<Pill>Q&A</Pill>
</div>
</div>
</SlideDeck>
-1
View File
@@ -12,7 +12,6 @@ export { JailbreakDemo } from "./security";
export { EmbeddingsDemo, LLMCapabilitiesDemo } from "./ai-demos";
export { TextToImageDemo, TextToVideoDemo } from "./media-demos";
export { SummarizationDemo, ContextPlayground } from "./context-demos";
export { LoopEngineeringLab } from "./loop-engineering-lab";
export { BookPartsNav } from "./navigation";
export { TokenPredictionDemo } from "./token-prediction";
export { DiffView, VersionDiff } from "./diff-view";
@@ -1,293 +0,0 @@
"use client";
import { useState } from "react";
import {
ArrowRight,
Check,
CircleDot,
Gauge,
RotateCcw,
} from "lucide-react";
import { cn } from "@/lib/utils";
type LoopStageId = "frame" | "act" | "observe" | "evaluate" | "adapt";
interface LoopStage {
id: LoopStageId;
label: string;
verb: string;
}
interface LoopCycle {
action: string;
observation: string;
evaluation: string;
adaptation: string;
progress: number;
openIssues: number;
}
interface LoopScenario {
id: string;
label: string;
goal: string;
stopRule: string;
evidence: string;
cycles: LoopCycle[];
}
interface LoopEngineeringLabContent {
eyebrow: string;
title: string;
description: string;
chooseScenarioLabel: string;
goalLabel: string;
stopRuleLabel: string;
evidenceLabel: string;
iterationLabel: string;
progressLabel: string;
openIssuesLabel: string;
currentSignalLabel: string;
advanceLabel: string;
nextIterationLabel: string;
resetLabel: string;
completeLabel: string;
completeDescription: string;
stages: LoopStage[];
scenarios: LoopScenario[];
}
interface LoopEngineeringLabProps {
content: LoopEngineeringLabContent;
}
const stageStyles: Record<LoopStageId, string> = {
frame: "border-cyan-600/30 bg-cyan-50 text-cyan-900 dark:border-cyan-400/50 dark:bg-cyan-400/10 dark:text-cyan-200",
act: "border-amber-600/30 bg-amber-50 text-amber-900 dark:border-amber-400/50 dark:bg-amber-400/10 dark:text-amber-200",
observe: "border-sky-600/30 bg-sky-50 text-sky-900 dark:border-sky-400/50 dark:bg-sky-400/10 dark:text-sky-200",
evaluate: "border-fuchsia-600/30 bg-fuchsia-50 text-fuchsia-900 dark:border-fuchsia-400/50 dark:bg-fuchsia-400/10 dark:text-fuchsia-200",
adapt: "border-lime-600/30 bg-lime-50 text-lime-900 dark:border-lime-400/50 dark:bg-lime-400/10 dark:text-lime-200",
};
export function LoopEngineeringLab({ content }: LoopEngineeringLabProps) {
const [scenarioIndex, setScenarioIndex] = useState(0);
const [cycleIndex, setCycleIndex] = useState(0);
const [stageIndex, setStageIndex] = useState(0);
const [isComplete, setIsComplete] = useState(false);
const scenario = content.scenarios[scenarioIndex];
const cycle = scenario.cycles[cycleIndex];
const stage = content.stages[stageIndex];
const previousProgress = cycleIndex > 0 ? scenario.cycles[cycleIndex - 1].progress : 0;
const visibleProgress = stageIndex >= 3 ? cycle.progress : previousProgress;
const visibleOpenIssues = stageIndex >= 3
? cycle.openIssues
: cycleIndex > 0
? scenario.cycles[cycleIndex - 1].openIssues
: scenario.cycles[0].openIssues + 1;
const getSignal = () => {
switch (stage.id) {
case "frame":
return scenario.goal;
case "act":
return cycle.action;
case "observe":
return cycle.observation;
case "evaluate":
return cycle.evaluation;
case "adapt":
return cycle.adaptation;
}
};
const reset = (nextScenarioIndex = scenarioIndex) => {
setScenarioIndex(nextScenarioIndex);
setCycleIndex(0);
setStageIndex(0);
setIsComplete(false);
};
const advance = () => {
if (isComplete) return;
if (stageIndex < content.stages.length - 1) {
setStageIndex((current) => current + 1);
return;
}
if (cycleIndex < scenario.cycles.length - 1) {
setCycleIndex((current) => current + 1);
setStageIndex(0);
return;
}
setIsComplete(true);
};
const buttonLabel = stageIndex === content.stages.length - 1 && cycleIndex < scenario.cycles.length - 1
? content.nextIterationLabel
: content.advanceLabel;
return (
<div
data-testid="loop-engineering-lab"
className="not-prose my-8 overflow-hidden rounded-2xl border border-slate-200 bg-[#fbfcf8] text-slate-900 shadow-2xl shadow-slate-900/10 dark:border-slate-800 dark:bg-[#090d10] dark:text-slate-100 dark:shadow-slate-950/20"
>
<div className="relative overflow-hidden border-b border-slate-200 px-5 py-5 dark:border-slate-800 sm:px-6">
<div
className="pointer-events-none absolute inset-0 bg-[radial-gradient(circle_at_top_right,rgba(8,145,178,0.12),transparent_34%),linear-gradient(rgba(15,23,42,0.04)_1px,transparent_1px),linear-gradient(90deg,rgba(15,23,42,0.04)_1px,transparent_1px)] dark:bg-[radial-gradient(circle_at_top_right,rgba(34,211,238,0.12),transparent_34%),linear-gradient(rgba(255,255,255,0.025)_1px,transparent_1px),linear-gradient(90deg,rgba(255,255,255,0.025)_1px,transparent_1px)]"
style={{ backgroundSize: "auto, 24px 24px, 24px 24px" }}
/>
<div className="relative">
<div className="mb-3 flex items-center gap-2 font-mono text-[10px] font-semibold uppercase tracking-[0.24em] text-cyan-700 dark:text-cyan-300">
<CircleDot className="h-3.5 w-3.5 animate-pulse" aria-hidden="true" />
{content.eyebrow}
</div>
<h3 className="m-0 text-xl font-semibold tracking-tight text-slate-950 dark:text-white sm:text-2xl">
{content.title}
</h3>
<p className="mb-0 mt-2 max-w-2xl text-sm leading-6 text-slate-600 dark:text-slate-400">
{content.description}
</p>
</div>
</div>
<div className="space-y-5 p-4 sm:p-6">
<fieldset>
<legend className="mb-2 font-mono text-[10px] font-semibold uppercase tracking-[0.18em] text-slate-500 dark:text-slate-500">
{content.chooseScenarioLabel}
</legend>
<div className="grid gap-2 sm:grid-cols-3">
{content.scenarios.map((item, index) => (
<button
key={item.id}
type="button"
aria-pressed={scenarioIndex === index}
onClick={() => reset(index)}
className={cn(
"rounded-lg border px-3 py-2.5 text-left text-sm font-medium transition focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-cyan-300",
scenarioIndex === index
? "border-cyan-600/40 bg-cyan-50 text-cyan-950 dark:border-cyan-400/60 dark:bg-cyan-400/10 dark:text-cyan-100"
: "border-slate-200 bg-white/80 text-slate-600 hover:border-slate-400 hover:text-slate-950 dark:border-slate-800 dark:bg-slate-900/60 dark:text-slate-400 dark:hover:border-slate-700 dark:hover:text-slate-200"
)}
>
{item.label}
</button>
))}
</div>
</fieldset>
<div className="grid gap-px overflow-hidden rounded-xl border border-slate-200 bg-slate-200 dark:border-slate-800 dark:bg-slate-800 lg:grid-cols-3">
{[
[content.goalLabel, scenario.goal],
[content.stopRuleLabel, scenario.stopRule],
[content.evidenceLabel, scenario.evidence],
].map(([label, value]) => (
<div key={label} className="bg-white/90 p-4 dark:bg-slate-950/90">
<p className="m-0 font-mono text-[10px] font-semibold uppercase tracking-[0.16em] text-slate-500">{label}</p>
<p className="mb-0 mt-2 text-xs leading-5 text-slate-700 dark:text-slate-300">{value}</p>
</div>
))}
</div>
<div className="grid grid-cols-1 gap-2 sm:grid-cols-5">
{content.stages.map((item, index) => {
const isActive = !isComplete && index === stageIndex;
const isPast = isComplete || index < stageIndex;
return (
<div key={item.id} className="relative">
<div
className={cn(
"h-full min-h-20 rounded-xl border p-3 transition-all duration-300",
isActive
? cn(stageStyles[item.id], "translate-y-[-2px] shadow-lg shadow-slate-900/10 dark:shadow-black/30")
: isPast
? "border-emerald-600/25 bg-emerald-50 text-emerald-800 dark:border-emerald-500/30 dark:bg-emerald-500/8 dark:text-emerald-200"
: "border-slate-200 bg-white/60 text-slate-500 dark:border-slate-800 dark:bg-slate-900/50 dark:text-slate-500"
)}
>
<div className="mb-2 flex items-center justify-between">
<span className="font-mono text-[10px] font-semibold uppercase tracking-[0.16em]">
0{index + 1}
</span>
{isPast && <Check className="h-3.5 w-3.5" aria-hidden="true" />}
</div>
<p className="m-0 text-sm font-semibold">{item.label}</p>
<p className="mb-0 mt-1 text-[11px] leading-4 opacity-70">{item.verb}</p>
</div>
{index < content.stages.length - 1 && (
<ArrowRight className="absolute -right-2 top-1/2 z-10 hidden h-4 w-4 -translate-y-1/2 text-slate-400 dark:text-slate-600 sm:block" aria-hidden="true" />
)}
</div>
);
})}
</div>
<div className="grid gap-3 lg:grid-cols-[1fr_15rem]">
<div className="min-h-44 rounded-xl border border-slate-200 bg-white p-5 dark:border-slate-800 dark:bg-slate-950" aria-live="polite">
<div className="mb-3 flex items-center gap-2">
<span className={cn("h-2 w-2 rounded-full", isComplete ? "bg-emerald-400" : "bg-amber-300 animate-pulse")} />
<p className="m-0 font-mono text-[10px] font-semibold uppercase tracking-[0.18em] text-slate-500">
{isComplete ? content.completeLabel : content.currentSignalLabel}
</p>
</div>
<p data-testid="loop-current-signal" className="m-0 text-base font-medium leading-7 text-slate-900 dark:text-slate-100">
{isComplete ? content.completeDescription : getSignal()}
</p>
</div>
<div className="grid grid-cols-2 gap-px overflow-hidden rounded-xl border border-slate-200 bg-slate-200 dark:border-slate-800 dark:bg-slate-800 lg:grid-cols-1">
<div className="bg-white p-4 dark:bg-slate-950">
<div className="mb-2 flex items-center justify-between">
<span className="font-mono text-[10px] uppercase tracking-[0.14em] text-slate-500">{content.iterationLabel}</span>
<span className="font-mono text-xs text-cyan-700 dark:text-cyan-200">{cycleIndex + 1}/{scenario.cycles.length}</span>
</div>
<div className="h-1.5 overflow-hidden rounded-full bg-slate-200 dark:bg-slate-800">
<div
className="h-full rounded-full bg-cyan-400 transition-all duration-500"
style={{ width: `${((cycleIndex + 1) / scenario.cycles.length) * 100}%` }}
/>
</div>
</div>
<div className="bg-white p-4 dark:bg-slate-950">
<div className="mb-2 flex items-center justify-between text-xs">
<span className="flex items-center gap-1.5 text-slate-500">
<Gauge className="h-3.5 w-3.5" aria-hidden="true" />
{content.progressLabel}
</span>
<span data-testid="loop-progress" className="font-mono text-emerald-700 dark:text-emerald-300">{isComplete ? 100 : visibleProgress}%</span>
</div>
<div className="flex items-center justify-between text-xs">
<span className="text-slate-500">{content.openIssuesLabel}</span>
<span className="font-mono text-amber-700 dark:text-amber-200">{isComplete ? 0 : visibleOpenIssues}</span>
</div>
</div>
</div>
</div>
<div className="flex flex-col gap-2 sm:flex-row sm:justify-end">
<button
type="button"
onClick={() => reset()}
className="inline-flex items-center justify-center gap-2 rounded-lg border border-slate-300 px-4 py-2.5 text-sm font-medium text-slate-700 transition hover:border-slate-500 hover:bg-slate-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-cyan-500 dark:border-slate-700 dark:text-slate-300 dark:hover:border-slate-600 dark:hover:bg-slate-800 dark:focus-visible:ring-cyan-300"
>
<RotateCcw className="h-4 w-4" aria-hidden="true" />
{content.resetLabel}
</button>
<button
type="button"
onClick={advance}
disabled={isComplete}
className="inline-flex items-center justify-center gap-2 rounded-lg bg-cyan-700 px-4 py-2.5 text-sm font-semibold text-white transition hover:bg-cyan-800 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-cyan-500 focus-visible:ring-offset-2 focus-visible:ring-offset-white disabled:cursor-not-allowed disabled:bg-emerald-600 dark:bg-cyan-300 dark:text-slate-950 dark:hover:bg-cyan-200 dark:focus-visible:ring-cyan-100 dark:focus-visible:ring-offset-slate-950 dark:disabled:bg-emerald-300"
>
{isComplete ? <Check className="h-4 w-4" aria-hidden="true" /> : null}
{isComplete ? content.completeLabel : buttonLabel}
{!isComplete ? <ArrowRight className="h-4 w-4" aria-hidden="true" /> : null}
</button>
</div>
</div>
</div>
);
}
-1
View File
@@ -13,7 +13,6 @@ export { JailbreakDemo } from "./elements/security";
export { EmbeddingsDemo, LLMCapabilitiesDemo } from "./elements/ai-demos";
export { TextToImageDemo, TextToVideoDemo } from "./elements/media-demos";
export { SummarizationDemo, ContextPlayground } from "./elements/context-demos";
export { LoopEngineeringLab } from "./elements/loop-engineering-lab";
export { BookPartsNav } from "./elements/navigation";
export { TokenPredictionDemo } from "./elements/token-prediction";
export { DiffView, VersionDiff } from "./elements/diff-view";
+8 -38
View File
@@ -25,52 +25,22 @@ export interface AnnouncementBannerConfig {
// Edit this to change/disable the active announcement.
// Set to `null` to hide the banner entirely.
export const ACTIVE_ANNOUNCEMENT: AnnouncementBannerConfig | null = {
id: "latentshift-istanbul-2026",
id: "ms-build-2026",
href: "https://build.microsoft.com/en-US/sessions/LTG468",
external: true,
message: (
<>
<Link
href="https://latentshift.ai/"
target="_blank"
rel="noopener noreferrer"
className="hover:underline"
>
<span className="font-semibold">prompts.chat</span> is sponsoring to{" "}
<span className="font-semibold">LatentShift AI Conference</span> in 17
October 2026 in Istanbul
</Link>{" "}
·{" "}
<Link
href="https://latentshift.ai/cfp/"
target="_blank"
rel="noopener noreferrer"
className="font-semibold underline-offset-2 hover:underline"
>
CfPs are open until 15 Aug →
</Link>
<span className="font-semibold">Fatih Kadir Akın</span> is speaking about
prompts.chat at <span className="font-semibold">Microsoft Build 2026</span>
{" · June 2–3, San Francisco"}
</>
),
messageShort: (
<>
<Link
href="https://latentshift.ai/"
target="_blank"
rel="noopener noreferrer"
className="hover:underline"
>
<span className="font-semibold">prompts.chat</span> × LatentShift AI ·
Istanbul
</Link>{" "}
·{" "}
<Link
href="https://latentshift.ai/cfp/"
target="_blank"
rel="noopener noreferrer"
className="font-semibold underline-offset-2 hover:underline"
>
CfPs open until 15 Aug →
</Link>
<span className="font-semibold">prompts.chat</span> at Microsoft Build 2026
</>
),
cta: "View session →",
};
export function AnnouncementBanner({
+144 -64
View File
@@ -1,18 +1,25 @@
"use client";
import { useState, useEffect, useCallback, ReactNode } from "react";
import { ChevronLeft, ChevronRight, X } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Children, ReactNode, useCallback, useEffect, useMemo, useRef, useState } from "react";
import { ChevronLeft, ChevronRight, Maximize, Minimize, StickyNote, X } from "lucide-react";
import Link from "next/link";
import { Button } from "@/components/ui/button";
import { cn } from "@/lib/utils";
interface SlideDeckProps {
children: ReactNode[];
children: ReactNode;
notes?: string[];
}
export function SlideDeck({ children }: SlideDeckProps) {
export function SlideDeck({ children, notes }: SlideDeckProps) {
const slides = useMemo(() => Children.toArray(children), [children]);
const [currentSlide, setCurrentSlide] = useState(0);
const totalSlides = children.length;
const [isFullscreen, setIsFullscreen] = useState(false);
const [showNotes, setShowNotes] = useState(false);
const swipeStartX = useRef<number | null>(null);
const containerRef = useRef<HTMLDivElement>(null);
const totalSlides = slides.length;
const currentNote = notes?.[currentSlide];
const nextSlide = useCallback(() => {
setCurrentSlide((prev) => Math.min(prev + 1, totalSlides - 1));
@@ -22,89 +29,156 @@ export function SlideDeck({ children }: SlideDeckProps) {
setCurrentSlide((prev) => Math.max(prev - 1, 0));
}, []);
const toggleFullscreen = useCallback(() => {
if (document.fullscreenElement) {
document.exitFullscreen();
return;
}
containerRef.current?.requestFullscreen();
}, []);
useEffect(() => {
const handleKeyDown = (e: KeyboardEvent) => {
if (e.key === "ArrowRight" || e.key === " ") {
e.preventDefault();
const handleFullscreenChange = () => {
setIsFullscreen(Boolean(document.fullscreenElement));
};
document.addEventListener("fullscreenchange", handleFullscreenChange);
return () => document.removeEventListener("fullscreenchange", handleFullscreenChange);
}, []);
useEffect(() => {
const handleKeyDown = (event: KeyboardEvent) => {
if (event.key === "ArrowRight" || event.key === " " || event.key === "PageDown") {
event.preventDefault();
nextSlide();
} else if (e.key === "ArrowLeft") {
e.preventDefault();
} else if (event.key === "ArrowLeft" || event.key === "PageUp") {
event.preventDefault();
prevSlide();
} else if (event.key === "Home") {
event.preventDefault();
setCurrentSlide(0);
} else if (event.key === "End") {
event.preventDefault();
setCurrentSlide(totalSlides - 1);
} else if (event.key === "f" || event.key === "F") {
event.preventDefault();
toggleFullscreen();
} else if (event.key === "n" || event.key === "N") {
event.preventDefault();
setShowNotes((value) => !value);
}
};
window.addEventListener("keydown", handleKeyDown);
return () => window.removeEventListener("keydown", handleKeyDown);
}, [nextSlide, prevSlide]);
}, [nextSlide, prevSlide, toggleFullscreen, totalSlides]);
return (
<div className="relative h-screen w-screen overflow-hidden bg-background text-foreground flex flex-col">
{/* Top Navigation */}
<div className="absolute top-4 right-4 z-50 flex items-center gap-4">
<div className="text-sm font-medium text-muted-foreground bg-background/50 backdrop-blur-sm px-3 py-1 rounded-full">
<div
ref={containerRef}
className="relative flex h-[100dvh] w-screen flex-col overflow-hidden bg-background text-foreground"
onPointerDown={(event) => {
swipeStartX.current = event.clientX;
}}
onPointerUp={(event) => {
if (swipeStartX.current === null) return;
const deltaX = event.clientX - swipeStartX.current;
swipeStartX.current = null;
if (Math.abs(deltaX) < 64) return;
if (deltaX < 0) nextSlide();
else prevSlide();
}}
>
<div className="pointer-events-none absolute inset-0 bg-[radial-gradient(circle_at_top_left,var(--primary),transparent_34%),radial-gradient(circle_at_bottom_right,var(--primary),transparent_28%)] opacity-10" />
<div className="pointer-events-none absolute inset-0 bg-[linear-gradient(to_right,var(--border)_1px,transparent_1px),linear-gradient(to_bottom,var(--border)_1px,transparent_1px)] bg-[size:72px_72px] opacity-25" />
<div className="absolute right-4 top-4 z-50 flex items-center gap-3">
<div className="rounded-full border border-border/70 bg-background/70 px-3 py-1 text-sm font-medium text-muted-foreground shadow-sm backdrop-blur">
{currentSlide + 1} / {totalSlides}
</div>
{notes && (
<Button
variant="ghost"
size="icon"
onClick={() => setShowNotes((value) => !value)}
className={cn(
"rounded-full border border-border/70 bg-background/70 shadow-sm backdrop-blur hover:bg-background/90",
showNotes && "text-primary"
)}
title="Konuşmacı notları (N)"
>
<StickyNote className="h-5 w-5" />
<span className="sr-only">{showNotes ? "Notları gizle" : "Notları göster"}</span>
</Button>
)}
<Button
variant="ghost"
size="icon"
onClick={toggleFullscreen}
className="rounded-full border border-border/70 bg-background/70 shadow-sm backdrop-blur hover:bg-background/90"
title="Tam ekran (F)"
>
{isFullscreen ? <Minimize className="h-5 w-5" /> : <Maximize className="h-5 w-5" />}
<span className="sr-only">{isFullscreen ? "Tam ekrandan çık" : "Tam ekran yap"}</span>
</Button>
<Link href="/">
<Button variant="ghost" size="icon" className="rounded-full bg-background/50 backdrop-blur-sm hover:bg-background/80">
<X className="w-5 h-5" />
<span className="sr-only">Close</span>
<Button
variant="ghost"
size="icon"
className="rounded-full border border-border/70 bg-background/70 shadow-sm backdrop-blur hover:bg-background/90"
>
<X className="h-5 w-5" />
<span className="sr-only">Kapat</span>
</Button>
</Link>
</div>
{/* Slides Container */}
<div className="flex-1 relative">
{children.map((child, index) => {
// Calculate the relative position (-1 is left, 0 is active, 1 is right)
<div className="relative flex-1">
{slides.map((child, index) => {
const offset = index - currentSlide;
let translateX = "translate-x-full";
if (offset === 0) translateX = "translate-x-0";
else if (offset < 0) translateX = "-translate-x-full";
const translateX = offset === 0 ? "translate-x-0" : offset < 0 ? "-translate-x-full" : "translate-x-full";
return (
<div
<section
key={index}
className={cn(
"absolute inset-0 transition-all duration-500 ease-in-out flex items-center justify-center p-8 md:p-16 lg:p-24",
"absolute inset-0 flex items-center justify-center p-6 transition-all duration-500 ease-out sm:p-10 md:p-14 lg:p-20",
translateX,
offset === 0 ? "opacity-100 scale-100" : "opacity-0 scale-95 pointer-events-none"
offset === 0 ? "opacity-100 scale-100" : "pointer-events-none opacity-0 scale-95"
)}
aria-hidden={offset !== 0}
>
<div className="w-full max-w-5xl mx-auto">
{child}
</div>
</div>
<div className="mx-auto w-full max-w-6xl">{child}</div>
</section>
);
})}
</div>
{/* Bottom Navigation */}
<div className="absolute bottom-8 left-0 right-0 z-50 flex justify-center items-center gap-8">
<div className="absolute inset-x-0 bottom-8 z-50 flex items-center justify-center gap-5 px-4">
<Button
variant="outline"
size="icon"
onClick={prevSlide}
disabled={currentSlide === 0}
className="rounded-full w-12 h-12 bg-background/50 backdrop-blur-sm hover:bg-background/80"
className="h-11 w-11 rounded-full bg-background/70 shadow-sm backdrop-blur hover:bg-background/90"
>
<ChevronLeft className="w-6 h-6" />
<span className="sr-only">Previous</span>
<ChevronLeft className="h-5 w-5" />
<span className="sr-only">Önceki</span>
</Button>
{/* Progress Dots */}
<div className="flex gap-2">
{Array.from({ length: totalSlides }).map((_, i) => (
<div className="flex max-w-[58vw] items-center gap-1.5 overflow-hidden rounded-full border border-border/60 bg-background/60 px-3 py-2 shadow-sm backdrop-blur">
{slides.map((_, index) => (
<button
key={i}
onClick={() => setCurrentSlide(i)}
key={index}
onClick={() => setCurrentSlide(index)}
className={cn(
"w-2.5 h-2.5 rounded-full transition-all duration-300",
i === currentSlide
? "bg-primary w-8"
: "bg-muted-foreground/30 hover:bg-muted-foreground/50"
"h-2.5 rounded-full transition-all duration-300",
index === currentSlide ? "w-8 bg-primary" : "w-2.5 bg-muted-foreground/30 hover:bg-muted-foreground/50"
)}
aria-label={`Go to slide ${i + 1}`}
aria-label={`${index + 1}. slayta git`}
/>
))}
</div>
@@ -114,16 +188,22 @@ export function SlideDeck({ children }: SlideDeckProps) {
size="icon"
onClick={nextSlide}
disabled={currentSlide === totalSlides - 1}
className="rounded-full w-12 h-12 bg-background/50 backdrop-blur-sm hover:bg-background/80"
className="h-11 w-11 rounded-full bg-background/70 shadow-sm backdrop-blur hover:bg-background/90"
>
<ChevronRight className="w-6 h-6" />
<span className="sr-only">Next</span>
<ChevronRight className="h-5 w-5" />
<span className="sr-only">Sonraki</span>
</Button>
</div>
{/* Progress Bar */}
<div className="absolute bottom-0 left-0 right-0 h-1.5 bg-muted">
<div
{showNotes && (
<div className="absolute inset-x-4 bottom-24 z-50 mx-auto max-w-3xl rounded-2xl border border-border bg-background/95 p-4 shadow-2xl backdrop-blur">
<div className="mb-1 text-xs font-bold uppercase tracking-[0.24em] text-primary">Konuşmacı notu</div>
<p className="text-sm leading-relaxed text-foreground">{currentNote || "Bu slayt için not yok."}</p>
</div>
)}
<div className="absolute inset-x-0 bottom-0 h-1.5 bg-muted">
<div
className="h-full bg-primary transition-all duration-500 ease-out"
style={{ width: `${((currentSlide + 1) / totalSlides) * 100}%` }}
/>
@@ -132,10 +212,14 @@ export function SlideDeck({ children }: SlideDeckProps) {
);
}
// Helper components for slide content
export function SlideTitle({ children, className }: { children: ReactNode; className?: string }) {
return (
<h1 className={cn("text-4xl md:text-6xl lg:text-7xl font-bold tracking-tight mb-8 md:mb-12 text-balance leading-tight bg-clip-text text-transparent bg-gradient-to-br from-foreground to-foreground/70", className)}>
<h1
className={cn(
"mb-7 text-balance bg-gradient-to-br from-foreground to-foreground/65 bg-clip-text text-4xl font-bold leading-tight tracking-tight text-transparent md:text-6xl lg:text-7xl",
className
)}
>
{children}
</h1>
);
@@ -143,16 +227,12 @@ export function SlideTitle({ children, className }: { children: ReactNode; class
export function SlideContent({ children, className }: { children: ReactNode; className?: string }) {
return (
<div className={cn("text-xl md:text-3xl lg:text-4xl leading-relaxed text-muted-foreground font-medium", className)}>
<div className={cn("text-balance text-xl font-medium leading-relaxed text-muted-foreground md:text-3xl", className)}>
{children}
</div>
);
}
export function SlideHighlight({ children, className }: { children: ReactNode; className?: string }) {
return (
<span className={cn("text-primary font-semibold", className)}>
{children}
</span>
);
return <span className={cn("font-semibold text-primary", className)}>{children}</span>;
}
+2 -5
View File
@@ -79,8 +79,8 @@ const videoPlatforms: Platform[] = [
const codePlatforms: Platform[] = [
{ id: "commandcode", name: "Command Code", baseUrl: "https://commandcode.ai/?utm_source=prompts.chat", supportsQuerystring: false, sponsor: true },
{ id: "windsurf", name: "Windsurf", baseUrl: "windsurf://", isDeeplink: true, supportsQuerystring: false, sponsor: true },
{ id: "vscode", name: "VS Code", baseUrl: "vscode://GitHub.Copilot-Chat/chat", isDeeplink: true },
{ id: "vscode-insiders", name: "VS Code Insiders", baseUrl: "vscode-insiders://GitHub.Copilot-Chat/chat", isDeeplink: true },
{ id: "vscode", name: "VS Code", baseUrl: "vscode://", isDeeplink: true, supportsQuerystring: false },
{ id: "vscode-insiders", name: "VS Code Insiders", baseUrl: "vscode-insiders://", isDeeplink: true, supportsQuerystring: false },
{ id: "cursor", name: "Cursor", baseUrl: "cursor://anysphere.cursor-deeplink/prompt", isDeeplink: true },
{ id: "goose", name: "Goose", baseUrl: "goose://recipe", isDeeplink: true },
{
@@ -136,9 +136,6 @@ function buildUrl(platformId: string, baseUrl: string, promptText: string, promp
// IDE deeplinks
case "cursor":
return `${baseUrl}?text=${encoded}`;
case "vscode":
case "vscode-insiders":
return `${baseUrl}?prompt=${encoded}`;
case "goose": {
const config = JSON.stringify({
version: "1.0.0",
-405
View File
@@ -1,405 +0,0 @@
Context engineering decides **what the model can see**. Loop engineering decides **what the system does next**.
Instead of a person repeatedly reading an answer and writing the next prompt, a loop turns that follow-up work into a designed system. It gives an AI a goal, lets it act, observes real feedback, evaluates the result, and either adapts or stops.
<Callout type="info" title="The Short Definition">
Loop engineering is the practice of designing the feedback cycle around an AI system: the goal, actions, observations, evaluation, state, guardrails, and stop rules that move work toward a verifiable result.
</Callout>
## From a Good Prompt to a Good Loop
A prompt can produce a strong first attempt. A loop is useful when the number of steps cannot be known in advance, the environment can change, or the first attempt must be checked against evidence.
<Compare
before={{
label: "One-Shot Prompt",
content: "Ask → Generate → Return\n\nThe model produces an answer. A person decides whether it worked and writes the next prompt."
}}
after={{
label: "Engineered Loop",
content: "Frame → Act → Observe → Evaluate → Adapt\n ↑______________________↓\n\nThe system gathers evidence, records state, and continues only while another pass is useful."
}}
/>
This idea builds on earlier agent patterns. The [ReAct paper](https://arxiv.org/abs/2210.03629) showed the value of interleaving actions with observations from an external environment. Anthropic's [evaluator-optimizer pattern](https://www.anthropic.com/engineering/building-effective-agents) adds a distinct feedback step, while OpenAI's [practical guide to agents](https://openai.com/business/guides-and-resources/a-practical-guide-to-building-ai-agents/) describes agent runs as loops governed by exit conditions. The newer term **loop engineering** focuses attention on deliberately designing that whole cycle.
## The Five Moves
<InfoGrid items={[
{ label: "1. Frame", description: "Turn intent into a goal, constraints, success criteria, and a budget.", color: "blue" },
{ label: "2. Act", description: "Choose one bounded action: search, edit, calculate, call a tool, or ask a person.", color: "amber" },
{ label: "3. Observe", description: "Collect what actually happened: test output, API results, citations, or user feedback.", color: "cyan" },
{ label: "4. Evaluate", description: "Compare the evidence with explicit criteria—not with the model's confidence.", color: "purple" },
{ label: "5. Adapt", description: "Update state, change the plan, retry safely, escalate, or stop.", color: "green" },
]} />
The loop is not the arrows. The engineering lives in the **contracts between the arrows**: what counts as an action, which observations are trustworthy, who evaluates them, what state survives, and exactly when execution ends.
<LoopEngineeringLab content={{
eyebrow: "Loop control / interactive simulator",
title: "Step through a working feedback loop",
description: "Choose a task, then advance one signal at a time. Notice how progress comes from environmental evidence and explicit evaluation—not from asking the model whether it feels finished.",
chooseScenarioLabel: "Choose a loop",
goalLabel: "Goal",
stopRuleLabel: "Stop rule",
evidenceLabel: "Trusted evidence",
iterationLabel: "Iteration",
progressLabel: "Verified progress",
openIssuesLabel: "Open issues",
currentSignalLabel: "Current signal",
advanceLabel: "Advance one step",
nextIterationLabel: "Begin next iteration",
resetLabel: "Reset loop",
completeLabel: "Goal verified",
completeDescription: "The success criteria are satisfied, evidence is recorded, and the loop stops instead of spending another cycle.",
stages: [
{ id: "frame", label: "Frame", verb: "Re-read the contract" },
{ id: "act", label: "Act", verb: "Make one bounded move" },
{ id: "observe", label: "Observe", verb: "Read external feedback" },
{ id: "evaluate", label: "Evaluate", verb: "Apply the rubric" },
{ id: "adapt", label: "Adapt", verb: "Update the next move" },
],
scenarios: [
{
id: "code",
label: "Repair a checkout bug",
goal: "Fix the checkout totals without changing valid discount behavior.",
stopRule: "The targeted regression test passes, the full checkout suite passes, and lint is clean—or three attempts are exhausted and the loop escalates.",
evidence: "Reproduction steps, test output, the code diff, and the final regression suite.",
cycles: [
{
action: "Reproduce the reported total and add a failing test for tax plus a percentage discount.",
observation: "The test fails by one cent only when tax is rounded before the discount is applied.",
evaluation: "The bug is reproduced with a deterministic signal, but the root cause is not fixed yet.",
adaptation: "Inspect the rounding boundary and change only the order-total calculation path.",
progress: 34,
openIssues: 2,
},
{
action: "Move rounding to the final monetary boundary and run targeted checkout tests.",
observation: "The regression test passes, but one coupon integration test now fails on a fixed-amount discount.",
evaluation: "The first symptom is fixed, but the change is too broad. The stop rule is not satisfied.",
adaptation: "Narrow the patch and add a case that separates tax rounding from coupon rounding.",
progress: 71,
openIssues: 1,
},
{
action: "Apply the narrow calculation fix, then run the regression test, the full checkout suite, and lint.",
observation: "All checks pass. The diff touches one calculation function and the new regression test.",
evaluation: "Every success criterion has independent evidence, and no budget limit was exceeded.",
adaptation: "Stop, preserve the test output, and hand the small diff to a human reviewer.",
progress: 100,
openIssues: 0,
},
],
},
{
id: "research",
label: "Verify a research claim",
goal: "Assess the claim that remote work always increases team productivity.",
stopRule: "A calibrated conclusion is supported by at least three credible sources, with disagreements and limitations stated.",
evidence: "Direct source links, publication dates, study methods, sample sizes, and quoted metrics.",
cycles: [
{
action: "Search for recent evidence and trace the most repeated productivity statistic to its source.",
observation: "Most articles repeat a vendor survey without linking its questionnaire or raw sample.",
evaluation: "The evidence is popular but not strong enough to support an absolute claim.",
adaptation: "Prioritize peer-reviewed studies and public datasets; search for contrary findings too.",
progress: 28,
openIssues: 3,
},
{
action: "Compare two peer-reviewed studies with a national labor dataset.",
observation: "Results vary by task type, measurement method, and whether work is fully remote or hybrid.",
evaluation: "The evidence contradicts the word 'always'. A conditional conclusion is becoming defensible.",
adaptation: "Check whether the studies distinguish output, hours worked, and perceived productivity.",
progress: 68,
openIssues: 1,
},
{
action: "Build an evidence table and verify every claim against the original source.",
observation: "The sources support mixed effects and identify autonomy, coordination, and task type as key variables.",
evaluation: "The conclusion is supported, uncertainty is visible, and the source threshold is met.",
adaptation: "Stop with a qualified answer and retain the evidence table for review.",
progress: 100,
openIssues: 0,
},
],
},
{
id: "writing",
label: "Polish a launch email",
goal: "Create a concise launch email that explains the benefit and earns qualified demo clicks.",
stopRule: "The email passes the voice rubric, stays under 140 words, contains one clear call to action, and survives a factual review.",
evidence: "Word count, rubric scores, link validation, source product facts, and reviewer notes.",
cycles: [
{
action: "Draft from the product brief and score the result against the audience and voice rubric.",
observation: "The draft is 204 words, opens with features, and contains two competing calls to action.",
evaluation: "Facts are accurate, but the hierarchy and length criteria fail.",
adaptation: "Lead with the customer outcome, remove the secondary action, and cut implementation detail.",
progress: 41,
openIssues: 3,
},
{
action: "Rewrite the opening and compress the body into one problem-benefit-proof sequence.",
observation: "The email is 126 words and has one CTA, but the proof sentence overstates a beta result.",
evaluation: "Structure passes. Factual calibration still fails the rubric.",
adaptation: "Replace the broad claim with the measured beta result and request a final fact check.",
progress: 79,
openIssues: 1,
},
{
action: "Insert the verified metric, validate the link, and run the complete rubric once more.",
observation: "The email is 132 words, the link resolves, facts match the brief, and every rubric item passes.",
evaluation: "The artifact satisfies the defined quality bar with reviewable evidence.",
adaptation: "Stop and send the approved version to the campaign owner.",
progress: 100,
openIssues: 0,
},
],
},
],
}} />
## Write the Loop Contract First
Before choosing a model or framework, write a small contract. If these fields are vague, the loop will turn ambiguity into repeated cost.
```yaml
goal: "What observable state should become true?"
inputs: "What starts the loop?"
state: "What facts and attempts persist between iterations?"
actions: "Which tools may the system use, and with what permissions?"
observations: "What external signals come back from those actions?"
evaluator: "Which rubric or deterministic checks judge the result?"
success: "What evidence proves the goal is complete?"
failure: "Which conditions require recovery or human help?"
budget: "Maximum turns, time, tokens, money, or side effects"
```
<Callout type="warning" title="A Loop Without an Exit Is a Failure Mode">
Always define three exits: **success** when evidence satisfies the goal, **failure** when recovery is no longer useful, and **budget exhausted** when the loop reaches its allowed cost or risk boundary.
</Callout>
## Observations Must Come From the World
The model saying “this looks correct” is not strong evidence. A useful observation is produced by something outside the answer being judged.
<table>
<thead>
<tr>
<th>Task</th>
<th>Weak observation</th>
<th>Strong observation</th>
</tr>
</thead>
<tbody>
<tr>
<td>Code repair</td>
<td>“The fix should work.”</td>
<td>The original failure is reproduced, then the regression test and the full suite pass.</td>
</tr>
<tr>
<td>Research</td>
<td>“Several sources agree.”</td>
<td>Claims link to original sources with dates, methods, and disagreements recorded.</td>
</tr>
<tr>
<td>Data extraction</td>
<td>“The JSON seems valid.”</td>
<td>Schema validation passes and sampled records match the source.</td>
</tr>
<tr>
<td>Content</td>
<td>“The copy feels clear.”</td>
<td>It passes a named rubric, factual review, link checks, and audience testing.</td>
</tr>
<tr>
<td>Operations</td>
<td>“The request succeeded.”</td>
<td>The external system returns the expected state and an audit record exists.</td>
</tr>
</tbody>
</table>
This is why tools matter: tests, browsers, databases, validators, and human review turn an internal guess into an observable result.
## Separate the Maker From the Checker
For low-risk work, one model can draft and self-review. For important work, use a checker with a different job and limited authority.
<InfoGrid columns={2} items={[
{ label: "Maker", description: "Proposes the change, calls action tools, and explains what evidence should be collected.", color: "amber" },
{ label: "Checker", description: "Receives the goal, artifact, and evidence; applies the rubric; cannot silently rewrite the work it grades.", color: "green" },
]} />
The checker does not have to be another AI. Prefer the most deterministic evaluator available:
1. **Exact checks** — types, schemas, constraints, permissions, hashes
2. **Executable checks** — tests, linters, simulations, link validation
3. **Rubric checks** — an independent model or human using named criteria
4. **Outcome checks** — real user behavior or production metrics over time
<Callout type="tip" title="Confidence Is Not Evidence">
A confidence score generated by the same model that made the artifact is still a model output. Treat it as a routing hint, not proof.
</Callout>
## State Is the Spine of the Loop
Context is what the model sees **this turn**. State is the compact record that lets the next turn continue without repeating or forgetting work.
<Checklist title="Useful Loop State" items={[
{ text: "The current goal and acceptance criteria" },
{ text: "Actions already attempted and their observable results" },
{ text: "Artifacts produced, with versions or stable references" },
{ text: "Evaluator verdicts and unresolved issues" },
{ text: "Budget consumed and permissions still available" },
{ text: "The reason for continuing, stopping, or escalating" },
]} />
Store concise decisions and evidence—not a model's private chain of thought. Good state is small, inspectable, and safe to resume.
## Common Loop Shapes
### The Repair Loop
`reproduce → change one thing → run checks → diagnose → repeat or stop`
Best for code, configuration, data cleanup, and any task with executable feedback.
### The Evaluator-Optimizer Loop
`generate → score with a rubric → return targeted feedback → revise`
Best for writing, translation, design critique, and outputs whose quality improves through articulated feedback.
### The Research Loop
`search → inspect sources → identify gaps or conflicts → search again → synthesize`
Best when completeness is not known in advance. The stop rule should measure evidence coverage, not the number of search results.
### The Human-Gated Loop
`prepare → verify automatically → pause before high-risk action → human approves or redirects`
Best for payments, publishing, deletion, access changes, medical or legal decisions, and other consequential actions.
## Failure Modes to Design Out
<table>
<thead>
<tr>
<th>Failure</th>
<th>What happened</th>
<th>Engineering response</th>
</tr>
</thead>
<tbody>
<tr>
<td>Infinite retry</td>
<td>The loop has no measurable success or budget exit.</td>
<td>Add explicit terminal states and a hard iteration cap.</td>
</tr>
<tr>
<td>Self-congratulation</td>
<td>The maker accepts its own plausible answer without evidence.</td>
<td>Use deterministic checks or an independent checker.</td>
</tr>
<tr>
<td>Context snowball</td>
<td>Every iteration appends everything until the model loses the signal.</td>
<td>Persist structured state and rebuild only relevant context.</td>
</tr>
<tr>
<td>Thrashing</td>
<td>The loop alternates between two fixes.</td>
<td>Detect repeated states and require a different strategy or escalation.</td>
</tr>
<tr>
<td>Goal drift</td>
<td>Local improvements replace the original objective.</td>
<td>Re-read the immutable goal and acceptance criteria each cycle.</td>
</tr>
<tr>
<td>Unsafe repetition</td>
<td>A reversible mistake becomes harmful when repeated.</td>
<td>Limit permissions, side effects, rate, spend, and blast radius.</td>
</tr>
</tbody>
</table>
## A Minimal Implementation
```typescript
let state = initialize(goal, acceptanceCriteria, budget);
while (state.budget.remaining > 0) {
const context = assembleRelevantContext(state);
const proposedAction = await maker.chooseAction(context);
const observation = await tools.executeWithinPolicy(proposedAction);
const verdict = await evaluator.check({ goal, observation, state });
state = recordIteration(state, { proposedAction, observation, verdict });
if (verdict.status === "passed") return complete(state);
if (verdict.status === "unsafe" || verdict.status === "blocked") {
return escalateToHuman(state);
}
state = adaptPlan(state, verdict.feedback);
}
return stopWithBudgetReport(state);
```
The code is the easy part. The hard questions are domain questions: Which test proves the bug is gone? Which source is authoritative? Which action is reversible? Who can approve the final step? Those decisions are the actual work of loop engineering.
## Practice: Design a Loop
<TryIt
title="Draft a Loop Contract"
description="Replace the variables with a recurring task from your own work. Ask the AI to challenge weak evidence and ambiguous stop rules."
prompt={`Design a bounded AI work loop for this task:
TASK: \${task:triage new customer support issues each morning}
Define:
1. The observable goal
2. The trigger and required inputs
3. Allowed actions and tool permissions
4. Trusted observations from the external environment
5. The evaluator and its rubric
6. State that persists between iterations
7. Success, failure, and budget-exhausted exits
8. Human approval gates for risky actions
9. A trace format that makes every iteration auditable
Then identify the three most likely failure modes in your design and revise the loop to prevent them.`}
/>
<Quiz
question="An agent edits code, rereads the diff, and says the bug is fixed. What is the most important missing part of the loop?"
options={[
"A longer system prompt",
"An external observation evaluated against a stop rule",
"A second editing pass",
"A larger context window"
]}
correctIndex={1}
explanation="The agent has produced and inspected an artifact, but it has not gathered independent evidence. Reproducing the failure and running relevant tests would create an observable signal that a stop rule can evaluate."
/>
## Further Reading
- [Loop Engineering — Addy Osmani](https://addyosmani.com/blog/loop-engineering/) — the recent framing of replacing manual follow-up prompts with a designed system, plus practical cautions about verification and human responsibility
- [Building Effective Agents — Anthropic](https://www.anthropic.com/engineering/building-effective-agents) — evaluator-optimizer workflows, environmental feedback, stopping conditions, and guidance on when agentic complexity is justified
- [A Practical Guide to Building Agents — OpenAI](https://openai.com/business/guides-and-resources/a-practical-guide-to-building-ai-agents/) — agent runs, exit conditions, tools, guardrails, and human intervention
- [ReAct: Synergizing Reasoning and Acting in Language Models](https://arxiv.org/abs/2210.03629) — foundational research on interleaving actions with observations from an external environment
## Summary
<Callout type="tip" title="Build the Feedback, Not Just the Prompt">
A reliable loop has a measurable goal, bounded actions, trusted observations, an explicit evaluator, compact state, safe exits, and human judgment where consequences demand it. The model is inside the loop; the engineer remains responsible for the loop.
</Callout>
@@ -1,405 +0,0 @@
هندسة السياق تحدد **ما يمكن للنموذج أن يراه**. أما هندسة الحلقات فتحدد **ما يفعله النظام تالياً**.
بدلاً من أن يقرأ شخصٌ الإجابة مراراً ويكتب الموجه التالي، تحوّل الحلقة عملَ المتابعة هذا إلى نظام مصمَّم: تمنح الذكاء الاصطناعي هدفاً، وتتيح له التصرف، وترصد تغذية راجعة حقيقية، وتقيّم النتيجة، ثم إما تتكيف أو تتوقف.
<Callout type="info" title="التعريف المختصر">
هندسة الحلقات هي ممارسة تصميم دورة التغذية الراجعة المحيطة بنظام الذكاء الاصطناعي: الهدف، والإجراءات، والملاحظات، والتقييم، والحالة، وحواجز الحماية، وقواعد التوقف التي تدفع العمل نحو نتيجة يمكن التحقق منها.
</Callout>
## من موجه جيد إلى حلقة جيدة
يمكن لموجه جيد أن ينتج محاولة أولى قوية. أما الحلقة فتصبح مفيدة عندما يتعذر معرفة عدد الخطوات مسبقاً، أو عندما تكون البيئة قابلة للتغير، أو عندما يجب التحقق من المحاولة الأولى في ضوء الأدلة.
<Compare
before={{
label: "موجه لمرة واحدة",
content: "اسأل → ولّد → أعد الإجابة\n\nالنموذج ينتج إجابة، وشخص يقرر ما إذا كانت ناجحة ثم يكتب الموجه التالي."
}}
after={{
label: "حلقة مهندَسة",
content: "أطّر → تصرّف → لاحظ → قيّم → تكيّف\n ↑______________________↓\n\nالنظام يجمع الأدلة، ويسجل الحالة، ولا يستمر إلا ما دامت جولة أخرى مفيدة."
}}
/>
تبني هذه الفكرة على أنماط وكلاء سابقة. فقد أظهرت [ورقة ReAct](https://arxiv.org/abs/2210.03629) قيمة المزاوجة بين الإجراءات والملاحظات القادمة من بيئة خارجية. ويضيف [نمط المقيّم-المحسّن](https://www.anthropic.com/engineering/building-effective-agents) من Anthropic خطوة تغذية راجعة منفصلة، بينما يصف [الدليل العملي لبناء الوكلاء](https://openai.com/business/guides-and-resources/a-practical-guide-to-building-ai-agents/) من OpenAI تشغيلات الوكيل بوصفها حلقات تحكمها شروط خروج. أما المصطلح الأحدث **هندسة الحلقات** فيركّز الانتباه على التصميم المتعمّد لهذه الدورة بأكملها.
## الحركات الخمس
<InfoGrid items={[
{ label: "1. أطّر", description: "حوّل النية إلى هدف وقيود ومعايير نجاح وميزانية.", color: "blue" },
{ label: "2. تصرّف", description: "اختر إجراءً واحداً محدود النطاق: ابحث، أو عدّل، أو احسب، أو استدعِ أداة، أو اسأل شخصاً.", color: "amber" },
{ label: "3. لاحظ", description: "اجمع ما حدث فعلاً: مخرجات الاختبارات، أو نتائج واجهة برمجة التطبيقات، أو الاستشهادات، أو ملاحظات المستخدمين.", color: "cyan" },
{ label: "4. قيّم", description: "قارن الأدلة بمعايير صريحة — لا بثقة النموذج في نفسه.", color: "purple" },
{ label: "5. تكيّف", description: "حدّث الحالة، أو غيّر الخطة، أو أعد المحاولة بأمان، أو صعّد الأمر، أو توقف.", color: "green" },
]} />
الحلقة ليست الأسهم. الهندسة تكمن في **العقود بين الأسهم**: ما الذي يُعد إجراءً، وأي الملاحظات جديرة بالثقة، ومن يقيّمها، وأي حالة تبقى بين الجولات، ومتى ينتهي التنفيذ بالضبط.
<LoopEngineeringLab content={{
eyebrow: "التحكم في الحلقة / محاكٍ تفاعلي",
title: "تتبّع حلقة تغذية راجعة عاملة خطوةً بخطوة",
description: "اختر مهمة، ثم تقدّم إشارةً واحدة في كل مرة. لاحظ كيف يأتي التقدم من أدلة البيئة والتقييم الصريح — لا من سؤال النموذج عما إذا كان يشعر بأنه انتهى.",
chooseScenarioLabel: "اختر حلقة",
goalLabel: "الهدف",
stopRuleLabel: "قاعدة التوقف",
evidenceLabel: "الأدلة الموثوقة",
iterationLabel: "التكرار",
progressLabel: "التقدم المتحقَّق منه",
openIssuesLabel: "المشكلات المفتوحة",
currentSignalLabel: "الإشارة الحالية",
advanceLabel: "تقدّم خطوة واحدة",
nextIterationLabel: "ابدأ التكرار التالي",
resetLabel: "أعد ضبط الحلقة",
completeLabel: "تم التحقق من الهدف",
completeDescription: "استُوفيت معايير النجاح، وسُجلت الأدلة، وتوقفت الحلقة بدلاً من إنفاق دورة أخرى.",
stages: [
{ id: "frame", label: "أطّر", verb: "أعد قراءة العقد" },
{ id: "act", label: "تصرّف", verb: "نفّذ حركة واحدة محدودة" },
{ id: "observe", label: "لاحظ", verb: "اقرأ التغذية الراجعة الخارجية" },
{ id: "evaluate", label: "قيّم", verb: "طبّق معايير التقييم" },
{ id: "adapt", label: "تكيّف", verb: "حدّث الحركة التالية" },
],
scenarios: [
{
id: "code",
label: "إصلاح خلل في إتمام الشراء",
goal: "تصحيح مجاميع إتمام الشراء دون تغيير سلوك الخصومات الصحيح.",
stopRule: "أن ينجح اختبار الانحدار المستهدف، وتنجح حزمة اختبارات إتمام الشراء كاملةً، وتكون نتيجة lint نظيفة — أو تُستنفد ثلاث محاولات فتصعّد الحلقة الأمر إلى إنسان.",
evidence: "خطوات إعادة إنتاج الخلل، ومخرجات الاختبارات، وفرق الكود، وحزمة الانحدار النهائية.",
cycles: [
{
action: "أعد إنتاج المجموع المبلَّغ عنه وأضف اختباراً فاشلاً لحالة الضريبة مع خصم بنسبة مئوية.",
observation: "يفشل الاختبار بفارق سنت واحد فقط عندما تُقرَّب الضريبة قبل تطبيق الخصم.",
evaluation: "أُعيد إنتاج الخلل بإشارة حتمية، لكن مصدره لم يُصلَح بعد.",
adaptation: "افحص موضع التقريب وغيّر مسار حساب مجموع الطلب دون سواه.",
progress: 34,
openIssues: 2,
},
{
action: "انقل التقريب إلى الحد النقدي النهائي وشغّل اختبارات إتمام الشراء المستهدفة.",
observation: "نجح اختبار الانحدار، لكن أحد اختبارات تكامل القسائم يفشل الآن مع خصم بمبلغ ثابت.",
evaluation: "أُصلح العرَض الأول، لكن التغيير أوسع من اللازم. قاعدة التوقف لم تتحقق بعد.",
adaptation: "ضيّق نطاق التعديل وأضف حالة اختبار تفصل تقريب الضريبة عن تقريب القسيمة.",
progress: 71,
openIssues: 1,
},
{
action: "طبّق إصلاح الحساب الضيق، ثم شغّل اختبار الانحدار وحزمة إتمام الشراء كاملة وأداة lint.",
observation: "نجحت جميع الفحوص. الفرق لا يمس سوى دالة حساب واحدة واختبار الانحدار الجديد.",
evaluation: "لكل معيار نجاح دليل مستقل، ولم يُتجاوز أي حد من حدود الميزانية.",
adaptation: "توقف، واحفظ مخرجات الاختبارات، وسلّم الفرق الصغير إلى مراجع بشري.",
progress: 100,
openIssues: 0,
},
],
},
{
id: "research",
label: "التحقق من ادعاء بحثي",
goal: "تقييم الادعاء القائل إن العمل عن بُعد يزيد إنتاجية الفريق دائماً.",
stopRule: "أن يوجد استنتاج مدروس مدعوم بثلاثة مصادر موثوقة على الأقل، مع ذكر أوجه الخلاف والقيود.",
evidence: "روابط مباشرة إلى المصادر، وتواريخ النشر، ومنهجيات الدراسات، وأحجام العينات، والمقاييس المقتبسة.",
cycles: [
{
action: "ابحث عن أدلة حديثة وتتبّع إحصائية الإنتاجية الأكثر تكراراً وصولاً إلى مصدرها.",
observation: "تكرر معظم المقالات استطلاعاً أجرته شركة مورّدة دون رابط إلى استبيانه أو عينته الخام.",
evaluation: "الدليل شائع لكنه ليس قوياً بما يكفي لدعم ادعاء مطلق.",
adaptation: "أعطِ الأولوية للدراسات المحكّمة ومجموعات البيانات العامة، وابحث عن النتائج المخالفة أيضاً.",
progress: 28,
openIssues: 3,
},
{
action: "قارن دراستين محكّمتين بمجموعة بيانات وطنية عن سوق العمل.",
observation: "تختلف النتائج بحسب نوع المهمة وطريقة القياس وما إذا كان العمل عن بُعد كلياً أم هجيناً.",
evaluation: "الأدلة تناقض كلمة «دائماً»، وبدأ استنتاج مشروط يصبح قابلاً للدفاع عنه.",
adaptation: "تحقق مما إذا كانت الدراسات تميّز بين الناتج وساعات العمل والإنتاجية المتصوَّرة.",
progress: 68,
openIssues: 1,
},
{
action: "أنشئ جدول أدلة وتحقق من كل ادعاء بمقارنته بالمصدر الأصلي.",
observation: "تدعم المصادر وجود آثار متباينة، وتحدد الاستقلالية والتنسيق ونوع المهمة بوصفها متغيرات أساسية.",
evaluation: "الاستنتاج مدعوم، وعدم اليقين ظاهر، وتم بلوغ عتبة المصادر المطلوبة.",
adaptation: "توقف بإجابة مشروطة واحتفظ بجدول الأدلة للمراجعة.",
progress: 100,
openIssues: 0,
},
],
},
{
id: "writing",
label: "صقل بريد إطلاق منتج",
goal: "إنشاء بريد إطلاق موجز يشرح الفائدة ويكسب نقرات مؤهلة على طلب العرض التوضيحي.",
stopRule: "أن يجتاز البريد معايير الأسلوب، ويبقى دون 140 كلمة، ويتضمن دعوة واحدة واضحة لاتخاذ إجراء، ويصمد أمام مراجعة الحقائق.",
evidence: "عدد الكلمات، ودرجات معايير التقييم، والتحقق من صلاحية الروابط، وحقائق المنتج المصدرية، وملاحظات المراجع.",
cycles: [
{
action: "اكتب مسودة انطلاقاً من موجز المنتج وقيّم النتيجة وفق معايير الجمهور والأسلوب.",
observation: "المسودة من 204 كلمات، تبدأ بالميزات، وتحتوي على دعوتين متنافستين لاتخاذ إجراء.",
evaluation: "الحقائق دقيقة، لكن معياري ترتيب الأولويات والطول لم يتحققا.",
adaptation: "ابدأ بالنتيجة التي يجنيها العميل، واحذف الإجراء الثانوي، وقلّص تفاصيل التنفيذ.",
progress: 41,
openIssues: 3,
},
{
action: "أعد كتابة الافتتاحية واضغط المتن في تسلسل واحد: مشكلة ففائدة فدليل.",
observation: "البريد من 126 كلمة وفيه دعوة واحدة لاتخاذ إجراء، لكن جملة الدليل تبالغ في نتيجة النسخة التجريبية.",
evaluation: "البنية تجتاز المعايير، لكن دقة الحقائق ما تزال دون المطلوب.",
adaptation: "استبدل الادعاء الفضفاض بنتيجة النسخة التجريبية المقيسة واطلب تدقيقاً نهائياً للحقائق.",
progress: 79,
openIssues: 1,
},
{
action: "أدرج المقياس المتحقَّق منه، وتأكد من صلاحية الرابط، وطبّق معايير التقييم كاملةً مرة أخيرة.",
observation: "البريد من 132 كلمة، والرابط يعمل، والحقائق تطابق الموجز، وكل بند من بنود المعايير يجتاز الفحص.",
evaluation: "الناتج يستوفي عتبة الجودة المحددة بأدلة قابلة للمراجعة.",
adaptation: "توقف وأرسل النسخة المعتمدة إلى مسؤول الحملة.",
progress: 100,
openIssues: 0,
},
],
},
],
}} />
## اكتب عقد الحلقة أولاً
قبل اختيار نموذج أو إطار عمل، اكتب عقداً صغيراً. إذا كانت هذه الحقول غامضة، فستحوّل الحلقة الغموض إلى تكلفة متكررة.
```yaml
goal: "ما الحالة القابلة للملاحظة التي يجب أن تتحقق؟"
inputs: "ما الذي يطلق الحلقة؟"
state: "ما الحقائق والمحاولات التي تبقى بين التكرارات؟"
actions: "ما الأدوات التي يجوز للنظام استخدامها، وبأي صلاحيات؟"
observations: "ما الإشارات الخارجية التي تعود من تلك الإجراءات؟"
evaluator: "ما معايير التقييم أو الفحوص الحتمية التي تحكم على النتيجة؟"
success: "ما الدليل الذي يثبت اكتمال الهدف؟"
failure: "ما الظروف التي تستدعي التعافي أو تدخل إنسان؟"
budget: "الحد الأقصى للجولات أو الوقت أو الرموز أو المال أو الآثار الجانبية"
```
<Callout type="warning" title="حلقة بلا مخرج هي نمط فشل">
حدد دائماً ثلاثة مخارج: **النجاح** عندما تستوفي الأدلة الهدف، و**الفشل** عندما لا يعود التعافي مجدياً، و**استنفاد الميزانية** عندما تبلغ الحلقة حدها المسموح من التكلفة أو المخاطرة.
</Callout>
## الملاحظات يجب أن تأتي من العالم
قولُ النموذج «هذا يبدو صحيحاً» ليس دليلاً قوياً. الملاحظة المفيدة ينتجها شيء يقع خارج الإجابة التي يجري الحكم عليها.
<table>
<thead>
<tr>
<th>المهمة</th>
<th>ملاحظة ضعيفة</th>
<th>ملاحظة قوية</th>
</tr>
</thead>
<tbody>
<tr>
<td>إصلاح الكود</td>
<td>«من المفترض أن ينجح الإصلاح.»</td>
<td>يُعاد إنتاج الفشل الأصلي، ثم ينجح اختبار الانحدار والحزمة الكاملة.</td>
</tr>
<tr>
<td>البحث</td>
<td>«عدة مصادر متفقة.»</td>
<td>ترتبط الادعاءات بمصادرها الأصلية مع تسجيل التواريخ والمنهجيات وأوجه الخلاف.</td>
</tr>
<tr>
<td>استخراج البيانات</td>
<td>«يبدو ملف JSON صالحاً.»</td>
<td>ينجح التحقق من المخطط، وتطابق عيّنةٌ مفحوصة من السجلات المصدرَ.</td>
</tr>
<tr>
<td>المحتوى</td>
<td>«النص يبدو واضحاً.»</td>
<td>يجتاز معايير تقييم مسماة، ومراجعة للحقائق، وفحصاً للروابط، واختباراً على الجمهور.</td>
</tr>
<tr>
<td>العمليات</td>
<td>«لقد نجح الطلب.»</td>
<td>يعيد النظام الخارجي الحالة المتوقعة، ويوجد سجل تدقيق للعملية.</td>
</tr>
</tbody>
</table>
لهذا تكتسب الأدوات أهميتها: فالاختبارات والمتصفحات وقواعد البيانات وأدوات التحقق والمراجعة البشرية تحوّل التخمين الداخلي إلى نتيجة قابلة للملاحظة.
## افصل الصانع عن المدقق
في الأعمال منخفضة المخاطر، يمكن لنموذج واحد أن يصيغ العمل ويراجع نفسه. أما في الأعمال المهمة، فاستخدم مدققاً له مهمة مختلفة وصلاحيات محدودة.
<InfoGrid columns={2} items={[
{ label: "الصانع", description: "يقترح التغيير، ويستدعي أدوات التنفيذ، ويوضح الأدلة التي ينبغي جمعها.", color: "amber" },
{ label: "المدقق", description: "يتلقى الهدف والناتج والأدلة؛ ويطبّق معايير التقييم؛ ولا يستطيع أن يعيد كتابة العمل الذي يقيّمه في الخفاء.", color: "green" },
]} />
لا يلزم أن يكون المدقق ذكاءً اصطناعياً آخر. فضّل دائماً أكثر المقيّمين المتاحين حتميةً:
1. **فحوص دقيقة** — الأنواع، والمخططات، والقيود، والصلاحيات، وقيم التجزئة
2. **فحوص قابلة للتنفيذ** — الاختبارات، وأدوات lint، والمحاكاة، والتحقق من الروابط
3. **فحوص بمعايير تقييم** — نموذج مستقل أو إنسان يستخدم معايير مسماة
4. **فحوص النتائج** — سلوك المستخدمين الفعلي أو مقاييس الإنتاج عبر الزمن
<Callout type="tip" title="الثقة ليست دليلاً">
درجة الثقة التي يولّدها النموذج نفسه الذي أنتج العمل تبقى مخرَجاً من مخرجات النموذج. تعامل معها كتلميح للتوجيه، لا كإثبات.
</Callout>
## الحالة هي العمود الفقري للحلقة
السياق هو ما يراه النموذج **في هذه الجولة**. أما الحالة فهي السجل المضغوط الذي يتيح للجولة التالية أن تستأنف دون تكرار العمل أو نسيانه.
<Checklist title="حالة حلقة مفيدة" items={[
{ text: "الهدف الحالي ومعايير القبول" },
{ text: "الإجراءات المجرَّبة سابقاً ونتائجها القابلة للملاحظة" },
{ text: "النواتج المُنتَجة، مع إصداراتها أو مراجع ثابتة إليها" },
{ text: "أحكام المقيّم والمشكلات غير المحلولة" },
{ text: "الميزانية المستهلكة والصلاحيات التي ما تزال متاحة" },
{ text: "سبب الاستمرار أو التوقف أو التصعيد" },
]} />
خزّن قرارات وأدلة موجزة — لا سلسلة التفكير الداخلية للنموذج. الحالة الجيدة صغيرة، وقابلة للفحص، وآمنة عند الاستئناف.
## أشكال الحلقات الشائعة
### حلقة الإصلاح
`أعد إنتاج الخلل → غيّر شيئاً واحداً → شغّل الفحوص → شخّص → كرر أو توقف`
الأنسب للكود والإعدادات وتنظيف البيانات وأي مهمة ذات تغذية راجعة قابلة للتنفيذ.
### حلقة المقيّم-المحسّن
`ولّد → قيّم بمعايير تقييم → أعد تغذية راجعة موجهة → نقّح`
الأنسب للكتابة والترجمة ونقد التصميم والمخرجات التي تتحسن جودتها بالتغذية الراجعة المفصّلة.
### حلقة البحث
`ابحث → افحص المصادر → حدد الثغرات أو التعارضات → ابحث مجدداً → ركّب النتائج`
الأنسب عندما لا يكون الاكتمال معروفاً مسبقاً. ينبغي أن تقيس قاعدة التوقف تغطية الأدلة، لا عدد نتائج البحث.
### الحلقة الخاضعة لبوابة بشرية
`حضّر → تحقق آلياً → توقف قبل الإجراء عالي الخطورة → يوافق الإنسان أو يعيد التوجيه`
الأنسب للمدفوعات والنشر والحذف وتغييرات الصلاحيات والقرارات الطبية أو القانونية وسائر الإجراءات ذات العواقب الجسيمة.
## أنماط فشل يجب تصميم الحلقة لتفاديها
<table>
<thead>
<tr>
<th>الفشل</th>
<th>ما الذي حدث</th>
<th>الاستجابة الهندسية</th>
</tr>
</thead>
<tbody>
<tr>
<td>إعادة المحاولة اللانهائية</td>
<td>لا تملك الحلقة مخرج نجاح قابلاً للقياس ولا مخرج ميزانية.</td>
<td>أضف حالات نهائية صريحة وسقفاً صارماً لعدد التكرارات.</td>
</tr>
<tr>
<td>الإطراء الذاتي</td>
<td>يقبل الصانع إجابته المعقولة الشكل دون دليل.</td>
<td>استخدم فحوصاً حتمية أو مدققاً مستقلاً.</td>
</tr>
<tr>
<td>تضخّم السياق</td>
<td>يُلحق كل تكرار كل شيء بالسياق حتى يفقد النموذج الإشارة.</td>
<td>خزّن حالة منظمة وأعد بناء السياق ذي الصلة فقط.</td>
</tr>
<tr>
<td>التأرجح</td>
<td>تتناوب الحلقة بين إصلاحين بلا جدوى.</td>
<td>اكتشف الحالات المتكررة واشترط استراتيجية مختلفة أو تصعيداً.</td>
</tr>
<tr>
<td>انحراف الهدف</td>
<td>تحل التحسينات الموضعية محل الهدف الأصلي.</td>
<td>أعد قراءة الهدف الثابت ومعايير القبول في كل دورة.</td>
</tr>
<tr>
<td>التكرار غير الآمن</td>
<td>خطأ قابل للتراجع عنه يصبح ضاراً عند تكراره.</td>
<td>قيّد الصلاحيات والآثار الجانبية والمعدل والإنفاق ونطاق الضرر.</td>
</tr>
</tbody>
</table>
## تنفيذ بالحد الأدنى
```typescript
let state = initialize(goal, acceptanceCriteria, budget);
while (state.budget.remaining > 0) {
const context = assembleRelevantContext(state);
const proposedAction = await maker.chooseAction(context);
const observation = await tools.executeWithinPolicy(proposedAction);
const verdict = await evaluator.check({ goal, observation, state });
state = recordIteration(state, { proposedAction, observation, verdict });
if (verdict.status === "passed") return complete(state);
if (verdict.status === "unsafe" || verdict.status === "blocked") {
return escalateToHuman(state);
}
state = adaptPlan(state, verdict.feedback);
}
return stopWithBudgetReport(state);
```
الكود هو الجزء السهل. الأسئلة الصعبة أسئلةُ مجالٍ: أي اختبار يثبت زوال الخلل؟ أي مصدر يُحتج به؟ أي إجراء يمكن التراجع عنه؟ من يملك اعتماد الخطوة الأخيرة؟ هذه القرارات هي العمل الحقيقي لهندسة الحلقات.
## تدريب: صمّم حلقة
<TryIt
title="اكتب مسودة عقد حلقة"
description="استبدل المتغيرات بمهمة متكررة من عملك، واطلب من الذكاء الاصطناعي أن يعترض على الأدلة الضعيفة وقواعد التوقف الغامضة."
prompt={`صمّم حلقة عمل محدودة للذكاء الاصطناعي لهذه المهمة:
المهمة: \${task:فرز طلبات دعم العملاء الجديدة كل صباح}
حدد ما يلي:
1. الهدف القابل للملاحظة
2. المُطلِق والمدخلات المطلوبة
3. الإجراءات المسموح بها وصلاحيات الأدوات
4. الملاحظات الموثوقة القادمة من البيئة الخارجية
5. المقيّم ومعايير تقييمه
6. الحالة التي تبقى بين التكرارات
7. مخارج النجاح والفشل واستنفاد الميزانية
8. بوابات الموافقة البشرية للإجراءات الخطرة
9. صيغة تتبّع تجعل كل تكرار قابلاً للتدقيق
ثم حدد أنماط الفشل الثلاثة الأكثر ترجيحاً في تصميمك ونقّح الحلقة لمنعها.`}
/>
<Quiz
question="يعدّل وكيلٌ الكود، ويعيد قراءة الفرق، ثم يقول إن الخلل قد أُصلح. ما أهم جزء مفقود في الحلقة؟"
options={[
"موجه نظام أطول",
"ملاحظة خارجية تُقيَّم وفق قاعدة توقف",
"جولة تعديل ثانية",
"نافذة سياق أكبر"
]}
correctIndex={1}
explanation="لقد أنتج الوكيل عملاً وفحصه بنفسه، لكنه لم يجمع دليلاً مستقلاً. إن إعادة إنتاج الفشل وتشغيل الاختبارات ذات الصلة يُنشئان إشارة قابلة للملاحظة تستطيع قاعدة التوقف تقييمها."
/>
## قراءات إضافية
- [Loop Engineering — Addy Osmani](https://addyosmani.com/blog/loop-engineering/) — الطرح الحديث لفكرة استبدال موجهات المتابعة اليدوية بنظام مصمَّم، مع تنبيهات عملية حول التحقق والمسؤولية البشرية
- [Building Effective Agents — Anthropic](https://www.anthropic.com/engineering/building-effective-agents) — تدفقات عمل المقيّم-المحسّن، والتغذية الراجعة من البيئة، وشروط التوقف، وإرشادات حول متى يكون تعقيد الوكلاء مبرراً
- [A Practical Guide to Building Agents — OpenAI](https://openai.com/business/guides-and-resources/a-practical-guide-to-building-ai-agents/) — تشغيلات الوكيل، وشروط الخروج، والأدوات، وحواجز الحماية، والتدخل البشري
- [ReAct: Synergizing Reasoning and Acting in Language Models](https://arxiv.org/abs/2210.03629) — بحث تأسيسي حول المزاوجة بين الإجراءات والملاحظات القادمة من بيئة خارجية
## الخلاصة
<Callout type="tip" title="ابنِ التغذية الراجعة، لا الموجه فقط">
الحلقة الموثوقة لها هدف قابل للقياس، وإجراءات محدودة، وملاحظات موثوقة، ومقيّم صريح، وحالة مضغوطة، ومخارج آمنة، وحكم بشري حيث تقتضيه العواقب. النموذج داخل الحلقة؛ أما المهندس فيبقى مسؤولاً عن الحلقة.
</Callout>
@@ -1,405 +0,0 @@
Kontekst mühəndisliyi **modelin nəyi görə biləcəyinə** qərar verir. Dövrə mühəndisliyi **sistemin bundan sonra nə edəcəyinə** qərar verir.
İnsanın cavabı dəfələrlə oxuyub növbəti promptu yazması əvəzinə, dövrə bu təqib işini layihələndirilmiş sistemə çevirir. O, süni intellektə məqsəd verir, ona hərəkət etməyə imkan yaradır, real əks əlaqəni müşahidə edir, nəticəni qiymətləndirir və ya uyğunlaşır, ya da dayanır.
<Callout type="info" title="Qısa Tərif">
Dövrə mühəndisliyi süni intellekt sistemi ətrafındakı əks əlaqə dövrəsinin layihələndirilməsi təcrübəsidir: işi yoxlanıla bilən nəticəyə doğru aparan məqsəd, hərəkətlər, müşahidələr, qiymətləndirmə, vəziyyət, qoruyucu mexanizmlər və dayanma qaydaları.
</Callout>
## Yaxşı Promptdan Yaxşı Dövrəyə
Prompt güclü ilk cəhd yarada bilər. Dövrə isə addımların sayı əvvəlcədən bilinmədikdə, mühit dəyişə bildikdə və ya ilk cəhd sübutlarla yoxlanılmalı olduqda faydalıdır.
<Compare
before={{
label: "Birdəfəlik Prompt",
content: "Soruş → Yarat → Qaytar\n\nModel cavab hazırlayır. Onun işləyib-işləmədiyinə insan qərar verir və növbəti promptu yazır."
}}
after={{
label: "Mühəndisləşdirilmiş Dövrə",
content: "Çərçivələ → Hərəkət et → Müşahidə et → Qiymətləndir → Uyğunlaş\n ↑______________________↓\n\nSistem sübut toplayır, vəziyyəti qeyd edir və yalnız daha bir dövr faydalı olduğu müddətdə davam edir."
}}
/>
Bu fikir əvvəlki agent nümunələri üzərində qurulub. [ReAct məqaləsi](https://arxiv.org/abs/2210.03629) hərəkətlərin xarici mühitdən gələn müşahidələrlə növbələnməsinin dəyərini göstərdi. Anthropic-in [qiymətləndirici-optimallaşdırıcı nümunəsi](https://www.anthropic.com/engineering/building-effective-agents) ayrıca əks əlaqə addımı əlavə edir, OpenAI-nin [agentlərə dair praktiki bələdçisi](https://openai.com/business/guides-and-resources/a-practical-guide-to-building-ai-agents/) isə agent icralarını çıxış şərtləri ilə idarə olunan dövrələr kimi təsvir edir. Daha yeni termin olan **loop engineering** (dövrə mühəndisliyi) diqqəti bütün bu dövrün şüurlu şəkildə layihələndirilməsinə yönəldir.
## Beş Hərəkət
<InfoGrid items={[
{ label: "1. Çərçivələ", description: "Niyyəti məqsədə, məhdudiyyətlərə, uğur meyarlarına və büdcəyə çevirin.", color: "blue" },
{ label: "2. Hərəkət et", description: "Bir məhdud hərəkət seçin: axtarın, redaktə edin, hesablayın, alət çağırın və ya insandan soruşun.", color: "amber" },
{ label: "3. Müşahidə et", description: "Əslində baş verənləri toplayın: test çıxışı, API nəticələri, sitatlar və ya istifadəçi rəyi.", color: "cyan" },
{ label: "4. Qiymətləndir", description: "Sübutları modelin əminliyi ilə deyil, açıq meyarlarla müqayisə edin.", color: "purple" },
{ label: "5. Uyğunlaş", description: "Vəziyyəti yeniləyin, planı dəyişin, təhlükəsiz şəkildə yenidən cəhd edin, eskalasiya edin və ya dayanın.", color: "green" },
]} />
Dövrə oxlardan ibarət deyil. Mühəndislik **oxlar arasındakı müqavilələrdədir**: nəyin hərəkət sayıldığı, hansı müşahidələrin etibarlı olduğu, onları kimin qiymətləndirdiyi, hansı vəziyyətin qorunub saxlandığı və icranın dəqiq nə vaxt bitdiyi.
<LoopEngineeringLab content={{
eyebrow: "Dövrə nəzarəti / interaktiv simulyator",
title: "İşləyən əks əlaqə dövrəsini addım-addım keçin",
description: "Tapşırıq seçin, sonra siqnalları bir-bir irəlilədin. Diqqət yetirin: irəliləyiş modeldən özünü bitmiş hiss edib-etmədiyini soruşmaqdan deyil, mühitdən gələn sübutlardan və açıq qiymətləndirmədən qaynaqlanır.",
chooseScenarioLabel: "Dövrə seçin",
goalLabel: "Məqsəd",
stopRuleLabel: "Dayanma qaydası",
evidenceLabel: "Etibarlı sübut",
iterationLabel: "İterasiya",
progressLabel: "Təsdiqlənmiş irəliləyiş",
openIssuesLabel: "Açıq məsələlər",
currentSignalLabel: "Cari siqnal",
advanceLabel: "Bir addım irəliləyin",
nextIterationLabel: "Növbəti iterasiyaya başlayın",
resetLabel: "Dövrəni sıfırlayın",
completeLabel: "Məqsəd təsdiqləndi",
completeDescription: "Uğur meyarları ödənilib, sübutlar qeydə alınıb və dövrə daha bir iterasiyaya vaxt sərf etmək əvəzinə dayanır.",
stages: [
{ id: "frame", label: "Çərçivələ", verb: "Müqaviləni yenidən oxuyun" },
{ id: "act", label: "Hərəkət et", verb: "Bir məhdud hərəkət edin" },
{ id: "observe", label: "Müşahidə et", verb: "Xarici əks əlaqəni oxuyun" },
{ id: "evaluate", label: "Qiymətləndir", verb: "Rubrikanı tətbiq edin" },
{ id: "adapt", label: "Uyğunlaş", verb: "Növbəti hərəkəti yeniləyin" },
],
scenarios: [
{
id: "code",
label: "Ödəniş xətasını düzəldin",
goal: "Etibarlı endirim davranışını dəyişmədən ödəniş yekunlarını düzəldin.",
stopRule: "Hədəflənmiş reqressiya testi keçir, tam ödəniş test paketi keçir və lint təmizdir — yaxud üç cəhd tükənir və dövrə eskalasiya edir.",
evidence: "Reproduksiya addımları, test çıxışı, kod diff-i və yekun reqressiya paketi.",
cycles: [
{
action: "Bildirilən yekunu reproduksiya edin və vergi üstəgəl faiz endirimi üçün uğursuz olan test əlavə edin.",
observation: "Test yalnız vergi endirimdən əvvəl yuvarlaqlaşdırıldıqda bir sent fərqlə uğursuz olur.",
evaluation: "Xəta deterministik siqnalla reproduksiya olunub, lakin mənbəyi hələ düzəldilməyib.",
adaptation: "Yuvarlaqlaşdırma sərhədini yoxlayın və yalnız sifariş yekununun hesablanması yolunu dəyişin.",
progress: 34,
openIssues: 2,
},
{
action: "Yuvarlaqlaşdırmanı son pul sərhədinə keçirin və hədəflənmiş ödəniş testlərini işə salın.",
observation: "Reqressiya keçir, lakin bir kupon inteqrasiya testi indi sabit məbləğli endirimdə uğursuz olur.",
evaluation: "İlk simptom aradan qaldırılıb, lakin dəyişiklik həddindən artıq genişdir. Dayanma qaydası ödənilmir.",
adaptation: "Yamağı daraldın və vergi yuvarlaqlaşdırmasını kupon yuvarlaqlaşdırmasından ayıran test halı əlavə edin.",
progress: 71,
openIssues: 1,
},
{
action: "Dar hesablama düzəlişini tətbiq edin, sonra reqressiyanı, tam ödəniş test paketini və linti işə salın.",
observation: "Bütün yoxlamalar keçir. Diff bir hesablama funksiyasına və yeni reqressiya testinə toxunur.",
evaluation: "Hər uğur meyarının müstəqil sübutu var və heç bir büdcə limiti aşılmayıb.",
adaptation: "Dayanın, test çıxışını saxlayın və kiçik diff-i insan rəyçiyə təhvil verin.",
progress: 100,
openIssues: 0,
},
],
},
{
id: "research",
label: "Tədqiqat iddiasını yoxlayın",
goal: "Uzaqdan işin komanda məhsuldarlığını həmişə artırdığı iddiasını qiymətləndirin.",
stopRule: "Kalibrlənmiş nəticə ən azı üç mötəbər mənbə ilə dəstəklənir, fikir ayrılıqları və məhdudiyyətlər göstərilir.",
evidence: "Birbaşa mənbə linkləri, nəşr tarixləri, tədqiqat metodları, seçmə ölçüləri və sitat gətirilən göstəricilər.",
cycles: [
{
action: "Ən yeni sübutları axtarın və ən çox təkrarlanan məhsuldarlıq statistikasını mənbəyinə qədər izləyin.",
observation: "Əksər məqalələr anketinə və ya xam seçməsinə link vermədən bir satıcı sorğusunu təkrarlayır.",
evaluation: "Sübut populyardır, lakin mütləq iddianı dəstəkləmək üçün kifayət qədər güclü deyil.",
adaptation: "Ekspert rəyindən keçmiş tədqiqatlara və açıq verilənlər dəstlərinə üstünlük verin; əks tapıntıları da axtarın.",
progress: 28,
openIssues: 3,
},
{
action: "Ekspert rəyindən keçmiş iki tədqiqatı milli əmək verilənlər dəsti ilə müqayisə edin.",
observation: "Nəticələr tapşırıq növünə, ölçmə metoduna və işin tam uzaqdan, yoxsa hibrid olmasına görə dəyişir.",
evaluation: "Sübutlar “həmişə” sözü ilə ziddiyyət təşkil edir. Şərti nəticə getdikcə müdafiə oluna bilən olur.",
adaptation: "Tədqiqatların hasilatı, işlənmiş saatları və qavranılan məhsuldarlığı ayırd edib-etmədiyini yoxlayın.",
progress: 68,
openIssues: 1,
},
{
action: "Sübut cədvəli qurun və hər iddianı orijinal mənbə ilə tutuşdurub yoxlayın.",
observation: "Mənbələr qarışıq effektləri dəstəkləyir və muxtariyyəti, koordinasiyanı və tapşırıq növünü əsas dəyişənlər kimi müəyyən edir.",
evaluation: "Nəticə dəstəklənir, qeyri-müəyyənlik görünür və mənbə həddi ödənilir.",
adaptation: "Şərtləndirilmiş cavabla dayanın və sübut cədvəlini baxış üçün saxlayın.",
progress: 100,
openIssues: 0,
},
],
},
{
id: "writing",
label: "Təqdimat e-poçtunu cilalayın",
goal: "Faydanı izah edən və keyfiyyətli demo klikləri qazanan yığcam təqdimat e-poçtu yaradın.",
stopRule: "E-poçt üslub rubrikasını keçir, 140 sözdən aşağı qalır, bir aydın hərəkətə çağırış ehtiva edir və fakt yoxlamasından uğurla keçir.",
evidence: "Söz sayı, rubrika balları, linkin yoxlanması, məhsul haqqında mənbə faktları və rəyçi qeydləri.",
cycles: [
{
action: "Məhsul brifindən qaralama hazırlayın və nəticəni auditoriya və üslub rubrikası üzrə qiymətləndirin.",
observation: "Qaralama 204 sözdür, xüsusiyyətlərlə açılır və bir-biri ilə rəqabət aparan iki hərəkətə çağırış ehtiva edir.",
evaluation: "Faktlar dəqiqdir, lakin iyerarxiya və uzunluq meyarları keçmir.",
adaptation: "Müştərinin qazandığı nəticə ilə başlayın, ikinci dərəcəli hərəkəti çıxarın və icra detallarını ixtisar edin.",
progress: 41,
openIssues: 3,
},
{
action: "Girişi yenidən yazın və əsas mətni bir problem-fayda-sübut ardıcıllığına sıxın.",
observation: "E-poçt 126 sözdür və bir CTA-sı var, lakin sübut cümləsi beta nəticəsini şişirdir.",
evaluation: "Struktur keçir. Fakt kalibrləməsi hələ də rubrikadan keçmir.",
adaptation: "Geniş iddianı ölçülmüş beta nəticəsi ilə əvəz edin və yekun fakt yoxlaması xahiş edin.",
progress: 79,
openIssues: 1,
},
{
action: "Təsdiqlənmiş göstəricini daxil edin, linki yoxlayın və tam rubrikanı bir daha tətbiq edin.",
observation: "E-poçt 132 sözdür, link açılır, faktlar brifə uyğun gəlir və hər rubrika maddəsi keçir.",
evaluation: "Artefakt müəyyən edilmiş keyfiyyət səviyyəsini baxıla bilən sübutlarla ödəyir.",
adaptation: "Dayanın və təsdiqlənmiş versiyanı kampaniya sahibinə göndərin.",
progress: 100,
openIssues: 0,
},
],
},
],
}} />
## Əvvəlcə Dövrə Müqaviləsini Yazın
Model və ya freymvork seçməzdən əvvəl kiçik bir müqavilə yazın. Bu sahələr qeyri-müəyyən qalarsa, dövrə qeyri-müəyyənliyi təkrarlanan xərcə çevirəcək.
```yaml
goal: "Hansı müşahidə edilə bilən vəziyyət gerçəkləşməlidir?"
inputs: "Dövrəni nə işə salır?"
state: "İterasiyalar arasında hansı faktlar və cəhdlər qorunur?"
actions: "Sistem hansı alətlərdən və hansı icazələrlə istifadə edə bilər?"
observations: "Bu hərəkətlərdən hansı xarici siqnallar qayıdır?"
evaluator: "Nəticəni hansı rubrika və ya deterministik yoxlamalar qiymətləndirir?"
success: "Məqsədin tamamlandığını hansı sübutlar təsdiqləyir?"
failure: "Hansı şərtlər bərpa və ya insan köməyi tələb edir?"
budget: "Maksimum növbə sayı, vaxt, token, pul və ya yan təsirlər"
```
<Callout type="warning" title="Çıxışı Olmayan Dövrə Uğursuzluq Rejimidir">
Həmişə üç çıxış müəyyənləşdirin: sübutlar məqsədi təmin etdikdə **uğur**, bərpa artıq faydalı olmadıqda **uğursuzluq** və dövrə icazə verilən xərc və ya risk sərhədinə çatdıqda **büdcə tükənməsi**.
</Callout>
## Müşahidələr Dünyadan Gəlməlidir
Modelin “bu düzgün görünür” deməsi güclü sübut deyil. Faydalı müşahidə mühakimə olunan cavabdan kənarda duran bir şey tərəfindən yaradılır.
<table>
<thead>
<tr>
<th>Tapşırıq</th>
<th>Zəif müşahidə</th>
<th>Güclü müşahidə</th>
</tr>
</thead>
<tbody>
<tr>
<td>Kod təmiri</td>
<td>“Düzəliş işləməlidir.”</td>
<td>Əvvəlcə orijinal uğursuzluq reproduksiya olunur, sonra reqressiya və tam test paketi keçir.</td>
</tr>
<tr>
<td>Tədqiqat</td>
<td>“Bir neçə mənbə razılaşır.”</td>
<td>İddialar tarixləri, metodları və fikir ayrılıqları qeydə alınmış orijinal mənbələrə link verir.</td>
</tr>
<tr>
<td>Məlumatların çıxarılması</td>
<td>“JSON etibarlı görünür.”</td>
<td>Sxem yoxlaması keçir və seçmə qeydlər mənbəyə uyğun gəlir.</td>
</tr>
<tr>
<td>Məzmun</td>
<td>“Mətn aydın görünür.”</td>
<td>Adı müəyyən rubrikadan, fakt yoxlamasından, link yoxlamalarından və auditoriya testindən keçir.</td>
</tr>
<tr>
<td>Əməliyyatlar</td>
<td>“Sorğu uğurla nəticələndi.”</td>
<td>Xarici sistem gözlənilən vəziyyəti qaytarır və audit qeydi mövcuddur.</td>
</tr>
</tbody>
</table>
Alətlər buna görə vacibdir: testlər, brauzerlər, verilənlər bazaları, validatorlar və insan baxışı daxili təxmini müşahidə edilə bilən nəticəyə çevirir.
## Yaradanı Yoxlayıcıdan Ayırın
Aşağı riskli iş üçün bir model həm qaralama hazırlaya, həm də öz işini yoxlaya bilər. Vacib iş üçün isə vəzifəsi fərqli və səlahiyyəti məhdud olan yoxlayıcıdan istifadə edin.
<InfoGrid columns={2} items={[
{ label: "Yaradan", description: "Dəyişikliyi təklif edir, hərəkət alətlərini çağırır və hansı sübutların toplanmalı olduğunu izah edir.", color: "amber" },
{ label: "Yoxlayıcı", description: "Məqsədi, artefaktı və sübutları alır; rubrikanı tətbiq edir; qiymətləndirdiyi işi səssizcə yenidən yaza bilməz.", color: "green" },
]} />
Yoxlayıcının başqa bir süni intellekt olması şərt deyil. Mövcud olan ən deterministik qiymətləndiriciyə üstünlük verin:
1. **Dəqiq yoxlamalar** — tiplər, sxemlər, məhdudiyyətlər, icazələr, hash-lər
2. **İcra edilə bilən yoxlamalar** — testlər, linterlər, simulyasiyalar, linklərin yoxlanması
3. **Rubrika yoxlamaları** — müstəqil model və ya adı müəyyən meyarlardan istifadə edən insan
4. **Nəticə yoxlamaları** — zamanla real istifadəçi davranışı və ya produksiya göstəriciləri
<Callout type="tip" title="Əminlik Sübut Deyil">
Artefaktı yaradan modelin özü tərəfindən verilən əminlik balı da model çıxışıdır. Onu sübut kimi yox, yönləndirmə işarəsi kimi qəbul edin.
</Callout>
## Vəziyyət Dövrənin Onurğasıdır
Kontekst modelin **bu növbədə** gördüyüdür. Vəziyyət isə növbəti növbənin işi təkrarlamadan və ya unutmadan davam etməsinə imkan verən yığcam qeyddir.
<Checklist title="Faydalı Dövrə Vəziyyəti" items={[
{ text: "Cari məqsəd və qəbul meyarları" },
{ text: "Artıq cəhd edilmiş hərəkətlər və onların müşahidə edilə bilən nəticələri" },
{ text: "Yaradılmış artefaktlar — versiyaları və ya sabit istinadları ilə" },
{ text: "Qiymətləndiricinin hökmləri və həll olunmamış məsələlər" },
{ text: "Sərf olunmuş büdcə və hələ də mövcud olan icazələr" },
{ text: "Davam etmə, dayanma və ya eskalasiya səbəbi" },
]} />
Yığcam qərarları və sübutları saxlayın — modelin daxili düşüncə zəncirini yox. Yaxşı vəziyyət kiçikdir, yoxlanıla biləndir və işi ondan təhlükəsiz davam etdirmək mümkündür.
## Ümumi Dövrə Formaları
### Təmir Dövrəsi
`reproduksiya edin → bir şeyi dəyişin → yoxlamaları işə salın → diaqnoz qoyun → təkrarlayın və ya dayanın`
Kod, konfiqurasiya, məlumat təmizliyi və icra edilə bilən əks əlaqəsi olan istənilən tapşırıq üçün ən yaxşısıdır.
### Qiymətləndirici-Optimallaşdırıcı Dövrə
`yaradın → rubrika ilə bal verin → hədəflənmiş rəy qaytarın → yenidən işləyin`
Yazı, tərcümə, dizayn tənqidi və keyfiyyəti aydın ifadə olunmuş rəylə yaxşılaşan nəticələr üçün ən yaxşısıdır.
### Tədqiqat Dövrəsi
`axtarın → mənbələri yoxlayın → boşluqları və ya ziddiyyətləri müəyyənləşdirin → yenidən axtarın → sintez edin`
Tamlıq əvvəlcədən bilinməyəndə ən yaxşısıdır. Dayanma qaydası axtarış nəticələrinin sayını yox, sübutların əhatə dairəsini ölçməlidir.
### İnsan Təsdiqli Dövrə
`hazırlayın → avtomatik yoxlayın → yüksək riskli hərəkətdən əvvəl dayanın → insan təsdiqləyir və ya istiqaməti dəyişir`
Ödənişlər, dərc etmə, silmə, giriş hüququ dəyişiklikləri, tibbi və ya hüquqi qərarlar və digər ciddi nəticələri olan hərəkətlər üçün ən yaxşısıdır.
## Dizaynla Aradan Qaldırılmalı Uğursuzluq Rejimləri
<table>
<thead>
<tr>
<th>Uğursuzluq</th>
<th>Nə baş verdi</th>
<th>Mühəndislik cavabı</th>
</tr>
</thead>
<tbody>
<tr>
<td>Sonsuz təkrar cəhd</td>
<td>Dövrənin ölçülə bilən uğur və ya büdcə çıxışı yoxdur.</td>
<td>Açıq yekun vəziyyətlər və sərt iterasiya limiti əlavə edin.</td>
</tr>
<tr>
<td>Özünü təbrik etmə</td>
<td>Yaradan öz inandırıcı cavabını sübut olmadan qəbul edir.</td>
<td>Deterministik yoxlamalardan və ya müstəqil yoxlayıcıdan istifadə edin.</td>
</tr>
<tr>
<td>Kontekst qartopu</td>
<td>Hər iterasiya model siqnalı itirənə qədər hər şeyi üstünə əlavə edir.</td>
<td>Strukturlaşdırılmış vəziyyəti qalıcı saxlayın və yalnız müvafiq konteksti yenidən qurun.</td>
</tr>
<tr>
<td>Var-gəl</td>
<td>Dövrə iki düzəliş arasında növbələşir.</td>
<td>Təkrarlanan vəziyyətləri aşkar edin və fərqli strategiya və ya eskalasiya tələb edin.</td>
</tr>
<tr>
<td>Məqsəd sürüşməsi</td>
<td>Yerli təkmilləşdirmələr ilkin məqsədi əvəz edir.</td>
<td>Hər dövrdə dəyişməz məqsədi və qəbul meyarlarını yenidən oxuyun.</td>
</tr>
<tr>
<td>Təhlükəli təkrarlama</td>
<td>Geri qaytarıla bilən səhv təkrarlananda zərərli olur.</td>
<td>İcazələri, yan təsirləri, sürəti, xərci və təsir dairəsini məhdudlaşdırın.</td>
</tr>
</tbody>
</table>
## Minimal Tətbiq
```typescript
let state = initialize(goal, acceptanceCriteria, budget);
while (state.budget.remaining > 0) {
const context = assembleRelevantContext(state);
const proposedAction = await maker.chooseAction(context);
const observation = await tools.executeWithinPolicy(proposedAction);
const verdict = await evaluator.check({ goal, observation, state });
state = recordIteration(state, { proposedAction, observation, verdict });
if (verdict.status === "passed") return complete(state);
if (verdict.status === "unsafe" || verdict.status === "blocked") {
return escalateToHuman(state);
}
state = adaptPlan(state, verdict.feedback);
}
return stopWithBudgetReport(state);
```
Kod işin asan hissəsidir. Çətin suallar sahəyə aid suallardır: Hansı test xətanın aradan qalxdığını sübut edir? Hansı mənbə mötəbərdir? Hansı hərəkət geri qaytarıla biləndir? Yekun addımı kim təsdiqləyə bilər? Dövrə mühəndisliyinin əsl işi məhz bu qərarlardır.
## Təcrübə: Dövrə Dizayn Edin
<TryIt
title="Dövrə Müqaviləsi Hazırlayın"
description="Dəyişənləri öz işinizdən təkrarlanan bir tapşırıqla əvəz edin. Süni intellektdən zəif sübutları və qeyri-müəyyən dayanma qaydalarını sorğulamasını xahiş edin."
prompt={`Bu tapşırıq üçün sərhədləri müəyyən edilmiş süni intellekt iş dövrəsi dizayn et:
TAPŞIRIQ: \${task:hər səhər yeni müştəri dəstəyi müraciətlərini çeşidləmək}
Bunları müəyyən et:
1. Müşahidə edilə bilən məqsəd
2. İşəsalma (trigger) və tələb olunan girişlər
3. İcazə verilən hərəkətlər və alət icazələri
4. Xarici mühitdən gələn etibarlı müşahidələr
5. Qiymətləndirici və onun rubrikası
6. İterasiyalar arasında qorunan vəziyyət
7. Uğur, uğursuzluq və büdcə tükənməsi çıxışları
8. Riskli hərəkətlər üçün insan təsdiqi qapıları
9. Hər iterasiyanı auditə yararlı edən iz formatı
Sonra dizaynında ən ehtimallı üç uğursuzluq rejimini müəyyənləşdir və onların qarşısını almaq üçün dövrəyə yenidən baxış ver.`}
/>
<Quiz
question="Agent kodu redaktə edir, diff-i yenidən oxuyur və xətanın düzəldildiyini deyir. Dövrənin ən vacib çatışmayan hissəsi hansıdır?"
options={[
"Daha uzun sistem promptu",
"Dayanma qaydası ilə qiymətləndirilən xarici müşahidə",
"İkinci redaktə gedişi",
"Daha böyük kontekst pəncərəsi"
]}
correctIndex={1}
explanation="Agent artefakt yaradıb və ona baxıb, lakin müstəqil sübut toplamayıb. Uğursuzluğu reproduksiya etmək və müvafiq testləri işə salmaq dayanma qaydasının qiymətləndirə biləcəyi müşahidə edilə bilən siqnal yaradardı."
/>
## Əlavə Oxu
- [Loop Engineering — Addy Osmani](https://addyosmani.com/blog/loop-engineering/) — əl ilə yazılan təqib promptlarını layihələndirilmiş sistemlə əvəz etməyin yeni çərçivəsi, üstəgəl yoxlama və insan məsuliyyəti barədə praktiki xəbərdarlıqlar
- [Effektiv Agentlərin Qurulması — Anthropic](https://www.anthropic.com/engineering/building-effective-agents) — qiymətləndirici-optimallaşdırıcı iş axınları, mühitdən gələn əks əlaqə, dayanma şərtləri və agent mürəkkəbliyinin nə vaxt özünü doğrultduğuna dair göstərişlər
- [Agentlərin Qurulmasına dair Praktiki Bələdçi — OpenAI](https://openai.com/business/guides-and-resources/a-practical-guide-to-building-ai-agents/) — agent icraları, çıxış şərtləri, alətlər, qoruyucu mexanizmlər və insan müdaxiləsi
- [ReAct: Dil Modellərində Düşünmə və Hərəkətin Sinergiyası](https://arxiv.org/abs/2210.03629) — hərəkətlərin xarici mühitdən gələn müşahidələrlə növbələnməsinə dair fundamental tədqiqat
## Xülasə
<Callout type="tip" title="Təkcə Promptu Deyil, Əks Əlaqəni Qurun">
Etibarlı dövrənin ölçülə bilən məqsədi, məhdud hərəkətləri, etibarlı müşahidələri, açıq qiymətləndiricisi, yığcam vəziyyəti, təhlükəsiz çıxışları və nəticələrin ciddi olduğu yerlərdə insan mühakiməsi olur. Model dövrənin içindədir; dövrəyə görə məsuliyyət isə mühəndisin üzərində qalır.
</Callout>
@@ -1,405 +0,0 @@
Kontext-Engineering entscheidet, **was das Modell sehen kann**. Loop-Engineering entscheidet, **was das System als Nächstes tut**.
Statt dass ein Mensch immer wieder eine Antwort liest und den nächsten Prompt schreibt, macht eine Schleife aus dieser Nacharbeit ein bewusst entworfenes System. Sie gibt einer KI ein Ziel, lässt sie handeln, beobachtet echtes Feedback, bewertet das Ergebnis und passt sich an – oder stoppt.
<Callout type="info" title="Die Kurzdefinition">
Loop-Engineering ist die Praxis, den Feedback-Zyklus rund um ein KI-System bewusst zu gestalten: das Ziel, die Aktionen, die Beobachtungen, die Bewertung, den Zustand, die Leitplanken und die Stoppregeln, die die Arbeit auf ein überprüfbares Ergebnis zubewegen.
</Callout>
## Vom guten Prompt zur guten Schleife
Ein Prompt kann einen starken ersten Versuch liefern. Eine Schleife lohnt sich, wenn die Zahl der Schritte nicht im Voraus feststeht, sich die Umgebung ändern kann oder der erste Versuch anhand von Belegen geprüft werden muss.
<Compare
before={{
label: "One-Shot-Prompt",
content: "Fragen → Generieren → Zurückgeben\n\nDas Modell liefert eine Antwort. Ein Mensch entscheidet, ob sie funktioniert hat, und schreibt den nächsten Prompt."
}}
after={{
label: "Konstruierte Schleife",
content: "Rahmen → Handeln → Beobachten → Bewerten → Anpassen\n ↑______________________↓\n\nDas System sammelt Belege, hält den Zustand fest und macht nur weiter, solange ein weiterer Durchlauf nützlich ist."
}}
/>
Diese Idee baut auf früheren Agent-Mustern auf. Das [ReAct-Paper](https://arxiv.org/abs/2210.03629) zeigte, wie wertvoll es ist, Aktionen mit Beobachtungen aus einer externen Umgebung zu verzahnen. Anthropics [Evaluator-Optimizer-Muster](https://www.anthropic.com/engineering/building-effective-agents) ergänzt einen eigenständigen Feedback-Schritt, während OpenAIs [praktischer Leitfaden für Agents](https://openai.com/business/guides-and-resources/a-practical-guide-to-building-ai-agents/) Agent-Läufe als Schleifen beschreibt, die über Exit-Bedingungen gesteuert werden. Der neuere Begriff **Loop-Engineering** lenkt den Blick darauf, diesen gesamten Zyklus bewusst zu entwerfen.
## Die fünf Züge
<InfoGrid items={[
{ label: "1. Rahmen", description: "Verwandle die Absicht in ein Ziel, Randbedingungen, Erfolgskriterien und ein Budget.", color: "blue" },
{ label: "2. Handeln", description: "Wähle eine einzelne, begrenzte Aktion: suchen, bearbeiten, rechnen, ein Tool aufrufen oder einen Menschen fragen.", color: "amber" },
{ label: "3. Beobachten", description: "Sammle, was tatsächlich passiert ist: Testausgaben, API-Ergebnisse, Quellenangaben oder Nutzerfeedback.", color: "cyan" },
{ label: "4. Bewerten", description: "Vergleiche die Belege mit expliziten Kriterien – nicht mit der Zuversicht des Modells.", color: "purple" },
{ label: "5. Anpassen", description: "Aktualisiere den Zustand, ändere den Plan, versuche es kontrolliert erneut, eskaliere oder stoppe.", color: "green" },
]} />
Die Schleife besteht nicht aus den Pfeilen. Das Engineering steckt in den **Verträgen zwischen den Pfeilen**: was als Aktion zählt, welchen Beobachtungen man trauen kann, wer sie bewertet, welcher Zustand erhalten bleibt und wann genau die Ausführung endet.
<LoopEngineeringLab content={{
eyebrow: "Schleifensteuerung / interaktiver Simulator",
title: "Geh Schritt für Schritt durch eine funktionierende Feedbackschleife",
description: "Wähle eine Aufgabe und schalte dann Signal für Signal weiter. Achte darauf, dass der Fortschritt aus Belegen aus der Umgebung und expliziter Bewertung entsteht – nicht daraus, das Modell zu fragen, ob es sich fertig fühlt.",
chooseScenarioLabel: "Wähle eine Schleife",
goalLabel: "Ziel",
stopRuleLabel: "Stoppregel",
evidenceLabel: "Vertrauenswürdige Belege",
iterationLabel: "Iteration",
progressLabel: "Verifizierter Fortschritt",
openIssuesLabel: "Offene Punkte",
currentSignalLabel: "Aktuelles Signal",
advanceLabel: "Einen Schritt weiter",
nextIterationLabel: "Nächste Iteration starten",
resetLabel: "Schleife zurücksetzen",
completeLabel: "Ziel verifiziert",
completeDescription: "Die Erfolgskriterien sind erfüllt, die Belege sind festgehalten, und die Schleife stoppt, statt einen weiteren Zyklus zu verbrauchen.",
stages: [
{ id: "frame", label: "Rahmen", verb: "Den Vertrag erneut lesen" },
{ id: "act", label: "Handeln", verb: "Einen begrenzten Zug machen" },
{ id: "observe", label: "Beobachten", verb: "Externes Feedback lesen" },
{ id: "evaluate", label: "Bewerten", verb: "Das Bewertungsraster anwenden" },
{ id: "adapt", label: "Anpassen", verb: "Den nächsten Zug aktualisieren" },
],
scenarios: [
{
id: "code",
label: "Einen Checkout-Bug beheben",
goal: "Die Checkout-Summen korrigieren, ohne das korrekte Rabattverhalten zu verändern.",
stopRule: "Der gezielte Regressionstest besteht, die komplette Checkout-Suite besteht und Lint ist sauber – oder drei Versuche sind aufgebraucht und die Schleife eskaliert.",
evidence: "Reproduktionsschritte, Testausgabe, der Code-Diff und die abschließende Regressionssuite.",
cycles: [
{
action: "Die gemeldete Summe reproduzieren und einen fehlschlagenden Test für Steuer plus prozentualen Rabatt hinzufügen.",
observation: "Der Test schlägt genau dann um einen Cent fehl, wenn die Steuer gerundet wird, bevor der Rabatt angewendet wird.",
evaluation: "Der Bug ist mit einem deterministischen Signal reproduziert, seine Ursache ist aber noch nicht behoben.",
adaptation: "Die Rundungsgrenze untersuchen und nur den Berechnungspfad für die Bestellsumme ändern.",
progress: 34,
openIssues: 2,
},
{
action: "Die Rundung an die letzte monetäre Grenze verschieben und gezielte Checkout-Tests laufen lassen.",
observation: "Der Regressionstest besteht, aber ein Coupon-Integrationstest schlägt jetzt bei einem Festbetragsrabatt fehl.",
evaluation: "Das erste Symptom ist behoben, aber die Änderung greift zu weit. Die Stoppregel ist nicht erfüllt.",
adaptation: "Den Patch enger fassen und einen Testfall ergänzen, der die Steuerrundung von der Coupon-Rundung trennt.",
progress: 71,
openIssues: 1,
},
{
action: "Den eng gefassten Berechnungsfix anwenden, dann Regressionstest, komplette Checkout-Suite und Lint laufen lassen.",
observation: "Alle Prüfungen bestehen. Der Diff berührt eine einzige Berechnungsfunktion und den neuen Regressionstest.",
evaluation: "Für jedes Erfolgskriterium gibt es unabhängige Belege, und keine Budgetgrenze wurde überschritten.",
adaptation: "Stoppen, die Testausgabe sichern und den kleinen Diff an einen menschlichen Reviewer übergeben.",
progress: 100,
openIssues: 0,
},
],
},
{
id: "research",
label: "Eine Forschungsbehauptung überprüfen",
goal: "Die Behauptung bewerten, dass Remote-Arbeit die Teamproduktivität immer steigert.",
stopRule: "Eine kalibrierte Schlussfolgerung stützt sich auf mindestens drei glaubwürdige Quellen, wobei Widersprüche und Einschränkungen benannt sind.",
evidence: "Direkte Quellenlinks, Erscheinungsdaten, Studienmethoden, Stichprobengrößen und zitierte Kennzahlen.",
cycles: [
{
action: "Nach aktueller Evidenz suchen und die am häufigsten wiederholte Produktivitätsstatistik bis zu ihrer Quelle zurückverfolgen.",
observation: "Die meisten Artikel wiederholen eine Anbieterumfrage, ohne deren Fragebogen oder Rohstichprobe zu verlinken.",
evaluation: "Die Belege sind populär, aber nicht stark genug, um eine absolute Behauptung zu stützen.",
adaptation: "Peer-reviewte Studien und öffentliche Datensätze priorisieren; auch nach gegenteiligen Befunden suchen.",
progress: 28,
openIssues: 3,
},
{
action: "Zwei peer-reviewte Studien mit einem nationalen Arbeitsmarkt-Datensatz vergleichen.",
observation: "Die Ergebnisse variieren je nach Aufgabentyp, Messmethode und danach, ob vollständig remote oder hybrid gearbeitet wird.",
evaluation: "Die Evidenz widerspricht dem Wort „immer“. Eine bedingte Schlussfolgerung wird vertretbar.",
adaptation: "Prüfen, ob die Studien zwischen Output, geleisteten Stunden und wahrgenommener Produktivität unterscheiden.",
progress: 68,
openIssues: 1,
},
{
action: "Eine Evidenztabelle erstellen und jede Behauptung gegen die Originalquelle verifizieren.",
observation: "Die Quellen belegen gemischte Effekte und benennen Autonomie, Koordination und Aufgabentyp als Schlüsselvariablen.",
evaluation: "Die Schlussfolgerung ist gestützt, die Unsicherheit sichtbar, und die Mindestzahl an Quellen ist erreicht.",
adaptation: "Mit einer differenzierten Antwort stoppen und die Evidenztabelle für die Überprüfung aufbewahren.",
progress: 100,
openIssues: 0,
},
],
},
{
id: "writing",
label: "Eine Launch-E-Mail verfeinern",
goal: "Eine prägnante Launch-E-Mail erstellen, die den Nutzen erklärt und qualifizierte Demo-Klicks einbringt.",
stopRule: "Die E-Mail besteht das Tonalitätsraster, bleibt unter 140 Wörtern, enthält genau einen klaren Call-to-Action und übersteht eine Faktenprüfung.",
evidence: "Wortzahl, Raster-Bewertungen, Link-Validierung, belegte Produktfakten und Anmerkungen der Reviewer.",
cycles: [
{
action: "Aus dem Produktbriefing einen Entwurf schreiben und das Ergebnis am Zielgruppen- und Tonalitätsraster bewerten.",
observation: "Der Entwurf hat 204 Wörter, beginnt mit Features und enthält zwei konkurrierende Calls-to-Action.",
evaluation: "Die Fakten stimmen, aber die Kriterien für Hierarchie und Länge sind nicht erfüllt.",
adaptation: "Mit dem Kundennutzen einsteigen, den zweiten Call-to-Action entfernen und Implementierungsdetails streichen.",
progress: 41,
openIssues: 3,
},
{
action: "Den Einstieg neu schreiben und den Text zu einer Abfolge aus Problem, Nutzen und Beleg verdichten.",
observation: "Die E-Mail hat 126 Wörter und einen CTA, aber der Belegsatz überzeichnet ein Beta-Ergebnis.",
evaluation: "Die Struktur besteht. Die faktische Kalibrierung fällt im Raster weiterhin durch.",
adaptation: "Die pauschale Behauptung durch das gemessene Beta-Ergebnis ersetzen und eine abschließende Faktenprüfung anfordern.",
progress: 79,
openIssues: 1,
},
{
action: "Die verifizierte Kennzahl einsetzen, den Link validieren und das komplette Raster noch einmal durchgehen.",
observation: "Die E-Mail hat 132 Wörter, der Link funktioniert, die Fakten decken sich mit dem Briefing, und jeder Punkt des Rasters ist erfüllt.",
evaluation: "Das Artefakt erfüllt den definierten Qualitätsanspruch mit nachprüfbaren Belegen.",
adaptation: "Stoppen und die freigegebene Version an die für die Kampagne verantwortliche Person senden.",
progress: 100,
openIssues: 0,
},
],
},
],
}} />
## Schreib zuerst den Schleifenvertrag
Bevor du ein Modell oder Framework auswählst, schreib einen kleinen Vertrag. Sind diese Felder vage, verwandelt die Schleife die Mehrdeutigkeit in wiederkehrende Kosten.
```yaml
goal: "Welcher beobachtbare Zustand soll eintreten?"
inputs: "Was startet die Schleife?"
state: "Welche Fakten und Versuche bleiben zwischen den Iterationen erhalten?"
actions: "Welche Tools darf das System nutzen, und mit welchen Berechtigungen?"
observations: "Welche externen Signale kommen aus diesen Aktionen zurück?"
evaluator: "Welches Bewertungsraster oder welche deterministischen Prüfungen beurteilen das Ergebnis?"
success: "Welche Belege zeigen, dass das Ziel erreicht ist?"
failure: "Welche Bedingungen erfordern eine Korrektur oder menschliche Hilfe?"
budget: "Obergrenzen für Durchläufe, Zeit, Tokens, Geld oder Seiteneffekte"
```
<Callout type="warning" title="Eine Schleife ohne Ausgang ist ein Fehlermodus">
Definiere immer drei Ausgänge: **Erfolg**, wenn die Belege das Ziel erfüllen, **Misserfolg**, wenn eine Korrektur nichts mehr bringt, und **Budget erschöpft**, wenn die Schleife ihre erlaubte Kosten- oder Risikogrenze erreicht.
</Callout>
## Beobachtungen müssen aus der Welt kommen
Dass das Modell sagt, „das sieht korrekt aus“, ist kein starker Beleg. Eine nützliche Beobachtung stammt von etwas außerhalb der Antwort, die gerade beurteilt wird.
<table>
<thead>
<tr>
<th>Aufgabe</th>
<th>Schwache Beobachtung</th>
<th>Starke Beobachtung</th>
</tr>
</thead>
<tbody>
<tr>
<td>Code-Reparatur</td>
<td>„Der Fix müsste funktionieren.“</td>
<td>Der ursprüngliche Fehler wird reproduziert, danach bestehen der Regressionstest und die komplette Suite.</td>
</tr>
<tr>
<td>Recherche</td>
<td>„Mehrere Quellen sind sich einig.“</td>
<td>Behauptungen verlinken auf Originalquellen; Datumsangaben, Methoden und Widersprüche sind festgehalten.</td>
</tr>
<tr>
<td>Datenextraktion</td>
<td>„Das JSON sieht gültig aus.“</td>
<td>Die Schema-Validierung besteht, und stichprobenartig geprüfte Datensätze stimmen mit der Quelle überein.</td>
</tr>
<tr>
<td>Content</td>
<td>„Der Text wirkt klar.“</td>
<td>Er besteht ein benanntes Bewertungsraster, eine Faktenprüfung, Link-Checks und Tests mit der Zielgruppe.</td>
</tr>
<tr>
<td>Betrieb</td>
<td>„Die Anfrage war erfolgreich.“</td>
<td>Das externe System meldet den erwarteten Zustand zurück, und es existiert ein Audit-Eintrag.</td>
</tr>
</tbody>
</table>
Deshalb sind Tools so wichtig: Tests, Browser, Datenbanken, Validatoren und menschliche Reviews verwandeln eine interne Vermutung in ein beobachtbares Ergebnis.
## Trenne den Ersteller vom Prüfer
Bei risikoarmen Aufgaben kann ein Modell entwerfen und sich selbst prüfen. Für wichtige Arbeit brauchst du einen Prüfer mit einer anderen Aufgabe und begrenzten Befugnissen.
<InfoGrid columns={2} items={[
{ label: "Ersteller", description: "Schlägt die Änderung vor, ruft Aktions-Tools auf und erklärt, welche Belege gesammelt werden sollten.", color: "amber" },
{ label: "Prüfer", description: "Erhält Ziel, Artefakt und Belege; wendet das Bewertungsraster an; darf die Arbeit, die er benotet, nicht stillschweigend umschreiben.", color: "green" },
]} />
Der Prüfer muss keine zweite KI sein. Bevorzuge den deterministischsten Evaluator, der verfügbar ist:
1. **Exakte Prüfungen** – Typen, Schemata, Constraints, Berechtigungen, Hashes
2. **Ausführbare Prüfungen** – Tests, Linter, Simulationen, Link-Validierung
3. **Raster-Prüfungen** – ein unabhängiges Modell oder ein Mensch mit benannten Kriterien
4. **Ergebnis-Prüfungen** – echtes Nutzerverhalten oder Produktionsmetriken über die Zeit
<Callout type="tip" title="Zuversicht ist kein Beleg">
Ein Konfidenzwert, den dasselbe Modell erzeugt hat, das auch das Artefakt gebaut hat, ist immer noch eine Modellausgabe. Behandle ihn als Routing-Hinweis, nicht als Beweis.
</Callout>
## Der Zustand ist das Rückgrat der Schleife
Kontext ist das, was das Modell **in diesem Durchlauf** sieht. Der Zustand ist die kompakte Aufzeichnung, mit der der nächste Durchlauf weitermachen kann, ohne Arbeit zu wiederholen oder zu vergessen.
<Checklist title="Nützlicher Schleifenzustand" items={[
{ text: "Das aktuelle Ziel und die Abnahmekriterien" },
{ text: "Bereits versuchte Aktionen und ihre beobachtbaren Ergebnisse" },
{ text: "Erzeugte Artefakte, mit Versionen oder stabilen Referenzen" },
{ text: "Urteile des Evaluators und ungelöste Punkte" },
{ text: "Verbrauchtes Budget und noch verfügbare Berechtigungen" },
{ text: "Der Grund, weiterzumachen, zu stoppen oder zu eskalieren" },
]} />
Speichere knappe Entscheidungen und Belege – nicht die private Gedankenkette eines Modells. Guter Zustand ist klein, einsehbar und lässt sich gefahrlos wieder aufnehmen.
## Gängige Schleifenformen
### Die Reparaturschleife
`reproduzieren → eine Sache ändern → Prüfungen laufen lassen → diagnostizieren → wiederholen oder stoppen`
Am besten für Code, Konfiguration, Datenbereinigung und jede Aufgabe mit ausführbarem Feedback.
### Die Evaluator-Optimizer-Schleife
`generieren → mit einem Raster bewerten → gezieltes Feedback zurückgeben → überarbeiten`
Am besten für Schreiben, Übersetzen, Designkritik und Ergebnisse, deren Qualität durch ausformuliertes Feedback steigt.
### Die Rechercheschleife
`suchen → Quellen prüfen → Lücken oder Widersprüche identifizieren → erneut suchen → synthetisieren`
Am besten, wenn die Vollständigkeit vorab unbekannt ist. Die Stoppregel sollte die Abdeckung der Evidenz messen, nicht die Zahl der Suchtreffer.
### Die Schleife mit menschlicher Freigabe
`vorbereiten → automatisch verifizieren → vor riskanten Aktionen pausieren → Mensch gibt frei oder lenkt um`
Am besten für Zahlungen, Veröffentlichungen, Löschungen, Zugriffsänderungen, medizinische oder rechtliche Entscheidungen und andere folgenreiche Aktionen.
## Fehlermodi, die dein Design ausschließen sollte
<table>
<thead>
<tr>
<th>Fehler</th>
<th>Was passiert ist</th>
<th>Engineering-Antwort</th>
</tr>
</thead>
<tbody>
<tr>
<td>Endlose Wiederholung</td>
<td>Die Schleife hat keinen messbaren Erfolgs- oder Budget-Ausgang.</td>
<td>Füge explizite Endzustände und eine harte Obergrenze für Iterationen hinzu.</td>
</tr>
<tr>
<td>Selbstbeweihräucherung</td>
<td>Der Ersteller akzeptiert seine eigene plausible Antwort ohne Belege.</td>
<td>Nutze deterministische Prüfungen oder einen unabhängigen Prüfer.</td>
</tr>
<tr>
<td>Kontext-Schneeball</td>
<td>Jede Iteration hängt alles an, bis das Modell das Signal verliert.</td>
<td>Halte strukturierten Zustand fest und baue nur den relevanten Kontext neu auf.</td>
</tr>
<tr>
<td>Thrashing</td>
<td>Die Schleife pendelt zwischen zwei Fixes hin und her.</td>
<td>Erkenne wiederholte Zustände und verlange eine andere Strategie oder Eskalation.</td>
</tr>
<tr>
<td>Zieldrift</td>
<td>Lokale Verbesserungen verdrängen das ursprüngliche Ziel.</td>
<td>Lies das unveränderliche Ziel und die Abnahmekriterien in jedem Zyklus erneut.</td>
</tr>
<tr>
<td>Unsichere Wiederholung</td>
<td>Ein umkehrbarer Fehler wird schädlich, wenn er sich wiederholt.</td>
<td>Begrenze Berechtigungen, Seiteneffekte, Frequenz, Ausgaben und Schadensradius.</td>
</tr>
</tbody>
</table>
## Eine minimale Implementierung
```typescript
let state = initialize(goal, acceptanceCriteria, budget);
while (state.budget.remaining > 0) {
const context = assembleRelevantContext(state);
const proposedAction = await maker.chooseAction(context);
const observation = await tools.executeWithinPolicy(proposedAction);
const verdict = await evaluator.check({ goal, observation, state });
state = recordIteration(state, { proposedAction, observation, verdict });
if (verdict.status === "passed") return complete(state);
if (verdict.status === "unsafe" || verdict.status === "blocked") {
return escalateToHuman(state);
}
state = adaptPlan(state, verdict.feedback);
}
return stopWithBudgetReport(state);
```
Der Code ist der einfache Teil. Die schwierigen Fragen sind Fachfragen: Welcher Test beweist, dass der Bug weg ist? Welche Quelle ist maßgeblich? Welche Aktion ist umkehrbar? Wer darf den letzten Schritt freigeben? Diese Entscheidungen sind die eigentliche Arbeit des Loop-Engineerings.
## Übung: Entwirf eine Schleife
<TryIt
title="Entwirf einen Schleifenvertrag"
description="Ersetze die Variable durch eine wiederkehrende Aufgabe aus deiner eigenen Arbeit. Bitte die KI, schwache Belege und unklare Stoppregeln infrage zu stellen."
prompt={`Entwirf eine begrenzte KI-Arbeitsschleife für diese Aufgabe:
AUFGABE: \${task:jeden Morgen neue Kundensupport-Tickets sichten und priorisieren}
Definiere:
1. Das beobachtbare Ziel
2. Den Auslöser und die benötigten Eingaben
3. Erlaubte Aktionen und Tool-Berechtigungen
4. Vertrauenswürdige Beobachtungen aus der externen Umgebung
5. Den Evaluator und sein Bewertungsraster
6. Den Zustand, der zwischen Iterationen erhalten bleibt
7. Ausgänge für Erfolg, Misserfolg und erschöpftes Budget
8. Menschliche Freigabepunkte für riskante Aktionen
9. Ein Trace-Format, das jede Iteration nachvollziehbar macht
Identifiziere anschließend die drei wahrscheinlichsten Fehlermodi in deinem Entwurf und überarbeite die Schleife, um sie zu verhindern.`}
/>
<Quiz
question="Ein Agent bearbeitet Code, liest den Diff noch einmal und erklärt, der Bug sei behoben. Was ist der wichtigste fehlende Teil der Schleife?"
options={[
"Ein längerer System-Prompt",
"Eine externe Beobachtung, die gegen eine Stoppregel bewertet wird",
"Ein zweiter Bearbeitungsdurchgang",
"Ein größeres Kontextfenster"
]}
correctIndex={1}
explanation="Der Agent hat ein Artefakt erzeugt und angesehen, aber keine unabhängigen Belege gesammelt. Den Fehler zu reproduzieren und die relevanten Tests laufen zu lassen würde ein beobachtbares Signal erzeugen, das eine Stoppregel bewerten kann."
/>
## Weiterführende Literatur
- [Loop Engineering – Addy Osmani](https://addyosmani.com/blog/loop-engineering/) – die aktuelle Rahmung, manuelle Folge-Prompts durch ein bewusst entworfenes System zu ersetzen, plus praktische Hinweise zu Verifikation und menschlicher Verantwortung
- [Building Effective Agents – Anthropic](https://www.anthropic.com/engineering/building-effective-agents) – Evaluator-Optimizer-Workflows, Feedback aus der Umgebung, Stoppbedingungen und Hinweise, wann agentische Komplexität gerechtfertigt ist
- [A Practical Guide to Building Agents – OpenAI](https://openai.com/business/guides-and-resources/a-practical-guide-to-building-ai-agents/) – Agent-Läufe, Exit-Bedingungen, Tools, Leitplanken und menschliches Eingreifen
- [ReAct: Synergizing Reasoning and Acting in Language Models](https://arxiv.org/abs/2210.03629) – Grundlagenforschung zur Verzahnung von Aktionen mit Beobachtungen aus einer externen Umgebung
## Zusammenfassung
<Callout type="tip" title="Baue das Feedback, nicht nur den Prompt">
Eine zuverlässige Schleife hat ein messbares Ziel, begrenzte Aktionen, vertrauenswürdige Beobachtungen, einen expliziten Evaluator, einen kompakten Zustand, sichere Ausgänge und menschliches Urteilsvermögen, wo die Konsequenzen es verlangen. Das Modell steckt in der Schleife; verantwortlich für die Schleife bleibt der Engineer.
</Callout>
@@ -1,405 +0,0 @@
Το context engineering αποφασίζει **τι μπορεί να δει το μοντέλο**. Η μηχανική βρόχων αποφασίζει **τι θα κάνει το σύστημα στη συνέχεια**.
Αντί ένας άνθρωπος να διαβάζει ξανά και ξανά μια απάντηση και να γράφει το επόμενο prompt, ένας βρόχος μετατρέπει αυτή τη συνεχή παρακολούθηση σε σχεδιασμένο σύστημα. Δίνει στο AI έναν στόχο, το αφήνει να δράσει, παρατηρεί πραγματική ανατροφοδότηση, αξιολογεί το αποτέλεσμα και είτε προσαρμόζεται είτε σταματά.
<Callout type="info" title="Ο Σύντομος Ορισμός">
Μηχανική βρόχων είναι η πρακτική του σχεδιασμού του κύκλου ανατροφοδότησης γύρω από ένα σύστημα AI: ο στόχος, οι ενέργειες, οι παρατηρήσεις, η αξιολόγηση, η κατάσταση, οι δικλείδες ασφαλείας και οι κανόνες διακοπής που οδηγούν τη δουλειά σε ένα επαληθεύσιμο αποτέλεσμα.
</Callout>
## Από ένα Καλό Prompt σε έναν Καλό Βρόχο
Ένα prompt μπορεί να δώσει μια δυνατή πρώτη προσπάθεια. Ένας βρόχος είναι χρήσιμος όταν ο αριθμός των βημάτων δεν μπορεί να είναι γνωστός εκ των προτέρων, όταν το περιβάλλον μπορεί να αλλάξει ή όταν η πρώτη προσπάθεια πρέπει να ελεγχθεί με βάση αποδείξεις.
<Compare
before={{
label: "Μεμονωμένο Prompt",
content: "Ερώτηση → Παραγωγή → Επιστροφή\n\nΤο μοντέλο παράγει μια απάντηση. Ένας άνθρωπος αποφασίζει αν δούλεψε και γράφει το επόμενο prompt."
}}
after={{
label: "Σχεδιασμένος Βρόχος",
content: "Πλαισίωση → Δράση → Παρατήρηση → Αξιολόγηση → Προσαρμογή\n ↑______________________↓\n\nΤο σύστημα συγκεντρώνει αποδείξεις, καταγράφει την κατάσταση και συνεχίζει μόνο όσο ένα ακόμη πέρασμα είναι χρήσιμο."
}}
/>
Η ιδέα αυτή χτίζει πάνω σε προγενέστερα μοτίβα agents. Η [εργασία ReAct](https://arxiv.org/abs/2210.03629) έδειξε την αξία της εναλλαγής ενεργειών με παρατηρήσεις από ένα εξωτερικό περιβάλλον. Το [μοτίβο evaluator-optimizer](https://www.anthropic.com/engineering/building-effective-agents) της Anthropic προσθέτει ένα διακριτό βήμα ανατροφοδότησης, ενώ ο [πρακτικός οδηγός για agents](https://openai.com/business/guides-and-resources/a-practical-guide-to-building-ai-agents/) της OpenAI περιγράφει τις εκτελέσεις των agents ως βρόχους που διέπονται από συνθήκες εξόδου. Ο νεότερος όρος **μηχανική βρόχων** στρέφει την προσοχή στον συνειδητό σχεδιασμό ολόκληρου αυτού του κύκλου.
## Οι Πέντε Κινήσεις
<InfoGrid items={[
{ label: "1. Πλαισίωση", description: "Μετάτρεψε την πρόθεση σε στόχο, περιορισμούς, κριτήρια επιτυχίας και προϋπολογισμό.", color: "blue" },
{ label: "2. Δράση", description: "Διάλεξε μία οριοθετημένη ενέργεια: αναζήτηση, επεξεργασία, υπολογισμό, κλήση εργαλείου ή ερώτηση σε άνθρωπο.", color: "amber" },
{ label: "3. Παρατήρηση", description: "Συγκέντρωσε ό,τι πραγματικά συνέβη: έξοδο τεστ, αποτελέσματα API, παραπομπές ή σχόλια χρηστών.", color: "cyan" },
{ label: "4. Αξιολόγηση", description: "Σύγκρινε τις αποδείξεις με ρητά κριτήρια—όχι με την αυτοπεποίθηση του μοντέλου.", color: "purple" },
{ label: "5. Προσαρμογή", description: "Ενημέρωσε την κατάσταση, άλλαξε το σχέδιο, ξαναδοκίμασε με ασφάλεια, κλιμάκωσε ή σταμάτα.", color: "green" },
]} />
Ο βρόχος δεν είναι τα βέλη. Η μηχανική βρίσκεται στα **συμβόλαια ανάμεσα στα βέλη**: τι μετράει ως ενέργεια, ποιες παρατηρήσεις είναι αξιόπιστες, ποιος τις αξιολογεί, ποια κατάσταση διατηρείται και πότε ακριβώς τερματίζεται η εκτέλεση.
<LoopEngineeringLab content={{
eyebrow: "Έλεγχος βρόχου / διαδραστικός προσομοιωτής",
title: "Προχώρησε βήμα-βήμα μέσα από έναν λειτουργικό βρόχο ανατροφοδότησης",
description: "Διάλεξε μια εργασία και μετά προχώρα ένα σήμα τη φορά. Πρόσεξε πώς η πρόοδος προκύπτει από αποδείξεις του περιβάλλοντος και ρητή αξιολόγηση—όχι από το να ρωτάς το μοντέλο αν νιώθει ότι τελείωσε.",
chooseScenarioLabel: "Διάλεξε έναν βρόχο",
goalLabel: "Στόχος",
stopRuleLabel: "Κανόνας διακοπής",
evidenceLabel: "Αξιόπιστες αποδείξεις",
iterationLabel: "Επανάληψη",
progressLabel: "Επαληθευμένη πρόοδος",
openIssuesLabel: "Ανοιχτά ζητήματα",
currentSignalLabel: "Τρέχον σήμα",
advanceLabel: "Προχώρησε ένα βήμα",
nextIterationLabel: "Ξεκίνα την επόμενη επανάληψη",
resetLabel: "Επαναφορά βρόχου",
completeLabel: "Ο στόχος επαληθεύτηκε",
completeDescription: "Τα κριτήρια επιτυχίας ικανοποιούνται, οι αποδείξεις έχουν καταγραφεί και ο βρόχος σταματά αντί να ξοδέψει έναν ακόμη κύκλο.",
stages: [
{ id: "frame", label: "Πλαισίωση", verb: "Ξαναδιάβασε το συμβόλαιο" },
{ id: "act", label: "Δράση", verb: "Κάνε μία οριοθετημένη κίνηση" },
{ id: "observe", label: "Παρατήρηση", verb: "Διάβασε την εξωτερική ανατροφοδότηση" },
{ id: "evaluate", label: "Αξιολόγηση", verb: "Εφάρμοσε τη ρουμπρίκα" },
{ id: "adapt", label: "Προσαρμογή", verb: "Ενημέρωσε την επόμενη κίνηση" },
],
scenarios: [
{
id: "code",
label: "Διόρθωσε ένα bug στο checkout",
goal: "Διόρθωσε τα σύνολα του checkout χωρίς να αλλάξεις την έγκυρη συμπεριφορά των εκπτώσεων.",
stopRule: "Το στοχευμένο regression test περνάει, ολόκληρη η σουίτα του checkout περνάει και το lint είναι καθαρό—ή εξαντλούνται τρεις προσπάθειες και ο βρόχος κλιμακώνει σε άνθρωπο.",
evidence: "Βήματα αναπαραγωγής, έξοδος των τεστ, το diff του κώδικα και η τελική σουίτα regression.",
cycles: [
{
action: "Αναπαράγαγε το αναφερόμενο σύνολο και πρόσθεσε ένα τεστ που αποτυγχάνει για φόρο συν ποσοστιαία έκπτωση.",
observation: "Το τεστ αποτυγχάνει κατά ένα σεντ μόνο όταν ο φόρος στρογγυλοποιείται πριν εφαρμοστεί η έκπτωση.",
evaluation: "Το bug αναπαράγεται με ντετερμινιστικό σήμα, αλλά η αιτία του δεν έχει διορθωθεί ακόμη.",
adaptation: "Εξέτασε το όριο της στρογγυλοποίησης και άλλαξε μόνο τη διαδρομή υπολογισμού του συνόλου της παραγγελίας.",
progress: 34,
openIssues: 2,
},
{
action: "Μετακίνησε τη στρογγυλοποίηση στο τελικό νομισματικό όριο και τρέξε στοχευμένα τεστ του checkout.",
observation: "Το regression περνάει, αλλά ένα τεστ ενσωμάτωσης κουπονιών αποτυγχάνει τώρα σε έκπτωση σταθερού ποσού.",
evaluation: "Το πρώτο σύμπτωμα διορθώθηκε, αλλά η αλλαγή είναι υπερβολικά ευρεία. Ο κανόνας διακοπής δεν ικανοποιείται.",
adaptation: "Στένεψε τη διόρθωση και πρόσθεσε μια περίπτωση που διαχωρίζει τη στρογγυλοποίηση φόρου από τη στρογγυλοποίηση κουπονιών.",
progress: 71,
openIssues: 1,
},
{
action: "Εφάρμοσε τη στενή διόρθωση του υπολογισμού και μετά τρέξε το regression, ολόκληρη τη σουίτα του checkout και το lint.",
observation: "Όλοι οι έλεγχοι περνούν. Το diff αγγίζει μία συνάρτηση υπολογισμού και το νέο regression test.",
evaluation: "Κάθε κριτήριο επιτυχίας έχει ανεξάρτητες αποδείξεις και δεν ξεπεράστηκε κανένα όριο του προϋπολογισμού.",
adaptation: "Σταμάτα, κράτησε την έξοδο των τεστ και παράδωσε το μικρό diff σε άνθρωπο για ανασκόπηση.",
progress: 100,
openIssues: 0,
},
],
},
{
id: "research",
label: "Επαλήθευσε έναν ερευνητικό ισχυρισμό",
goal: "Αξιολόγησε τον ισχυρισμό ότι η εξ αποστάσεως εργασία αυξάνει πάντα την παραγωγικότητα της ομάδας.",
stopRule: "Ένα σταθμισμένο συμπέρασμα υποστηρίζεται από τουλάχιστον τρεις αξιόπιστες πηγές, με τις διαφωνίες και τους περιορισμούς να αναφέρονται ρητά.",
evidence: "Άμεσοι σύνδεσμοι προς τις πηγές, ημερομηνίες δημοσίευσης, μέθοδοι των μελετών, μεγέθη δειγμάτων και οι μετρικές που παρατίθενται.",
cycles: [
{
action: "Αναζήτησε πρόσφατα στοιχεία και ανίχνευσε το πιο συχνά επαναλαμβανόμενο στατιστικό παραγωγικότητας μέχρι την πηγή του.",
observation: "Τα περισσότερα άρθρα αναπαράγουν μια έρευνα προμηθευτή χωρίς σύνδεσμο προς το ερωτηματολόγιο ή το πρωτογενές δείγμα της.",
evaluation: "Τα στοιχεία είναι δημοφιλή, αλλά όχι αρκετά ισχυρά για να στηρίξουν έναν απόλυτο ισχυρισμό.",
adaptation: "Δώσε προτεραιότητα σε μελέτες με αξιολόγηση από ομοτίμους και δημόσια σύνολα δεδομένων· αναζήτησε και αντίθετα ευρήματα.",
progress: 28,
openIssues: 3,
},
{
action: "Σύγκρινε δύο μελέτες με αξιολόγηση από ομοτίμους με ένα εθνικό σύνολο δεδομένων για την αγορά εργασίας.",
observation: "Τα αποτελέσματα ποικίλλουν ανάλογα με τον τύπο της εργασίας, τη μέθοδο μέτρησης και το αν η εργασία είναι πλήρως απομακρυσμένη ή υβριδική.",
evaluation: "Τα στοιχεία αντικρούουν τη λέξη «πάντα». Ένα συμπέρασμα υπό όρους αρχίζει να γίνεται υποστηρίξιμο.",
adaptation: "Έλεγξε αν οι μελέτες διακρίνουν το παραγόμενο έργο, τις ώρες εργασίας και την αντιλαμβανόμενη παραγωγικότητα.",
progress: 68,
openIssues: 1,
},
{
action: "Φτιάξε έναν πίνακα αποδείξεων και επαλήθευσε κάθε ισχυρισμό με βάση την αρχική πηγή.",
observation: "Οι πηγές υποστηρίζουν μικτές επιδράσεις και αναδεικνύουν την αυτονομία, τον συντονισμό και τον τύπο της εργασίας ως βασικές μεταβλητές.",
evaluation: "Το συμπέρασμα τεκμηριώνεται, η αβεβαιότητα είναι ορατή και το κατώφλι των πηγών έχει καλυφθεί.",
adaptation: "Σταμάτα με μια απάντηση με επιφυλάξεις και κράτησε τον πίνακα αποδείξεων για ανασκόπηση.",
progress: 100,
openIssues: 0,
},
],
},
{
id: "writing",
label: "Τελειοποίησε ένα email λανσαρίσματος",
goal: "Φτιάξε ένα συνοπτικό email λανσαρίσματος που εξηγεί το όφελος και κερδίζει ποιοτικά κλικ για demo.",
stopRule: "Το email περνάει τη ρουμπρίκα ύφους, μένει κάτω από 140 λέξεις, περιέχει ένα σαφές κάλεσμα σε δράση και αντέχει σε έλεγχο γεγονότων.",
evidence: "Αριθμός λέξεων, βαθμολογίες ρουμπρίκας, επικύρωση συνδέσμων, τα στοιχεία του προϊόντος από την πηγή και σημειώσεις του αναθεωρητή.",
cycles: [
{
action: "Γράψε ένα προσχέδιο από το brief του προϊόντος και βαθμολόγησε το αποτέλεσμα με τη ρουμπρίκα κοινού και ύφους.",
observation: "Το προσχέδιο έχει 204 λέξεις, ανοίγει με χαρακτηριστικά και περιέχει δύο ανταγωνιστικά καλέσματα σε δράση.",
evaluation: "Τα γεγονότα είναι ακριβή, αλλά τα κριτήρια ιεράρχησης και μήκους αποτυγχάνουν.",
adaptation: "Ξεκίνα με το όφελος για τον πελάτη, αφαίρεσε τη δευτερεύουσα ενέργεια και κόψε τις λεπτομέρειες υλοποίησης.",
progress: 41,
openIssues: 3,
},
{
action: "Ξαναγράψε την εισαγωγή και συμπύκνωσε το κείμενο σε μία αλληλουχία πρόβλημα-όφελος-απόδειξη.",
observation: "Το email έχει 126 λέξεις και ένα CTA, αλλά η πρόταση της απόδειξης υπερβάλλει για ένα αποτέλεσμα της beta.",
evaluation: "Η δομή περνάει. Η ακρίβεια των γεγονότων εξακολουθεί να αποτυγχάνει στη ρουμπρίκα.",
adaptation: "Αντικατάστησε τον γενικόλογο ισχυρισμό με το μετρημένο αποτέλεσμα της beta και ζήτησε έναν τελικό έλεγχο γεγονότων.",
progress: 79,
openIssues: 1,
},
{
action: "Βάλε την επαληθευμένη μετρική, επικύρωσε τον σύνδεσμο και τρέξε άλλη μία φορά ολόκληρη τη ρουμπρίκα.",
observation: "Το email έχει 132 λέξεις, ο σύνδεσμος ανοίγει, τα γεγονότα συμφωνούν με το brief και κάθε στοιχείο της ρουμπρίκας περνάει.",
evaluation: "Το παραδοτέο ικανοποιεί τον ορισμένο πήχη ποιότητας με αποδείξεις που μπορούν να ελεγχθούν.",
adaptation: "Σταμάτα και στείλε την εγκεκριμένη έκδοση στον υπεύθυνο της καμπάνιας.",
progress: 100,
openIssues: 0,
},
],
},
],
}} />
## Γράψε Πρώτα το Συμβόλαιο του Βρόχου
Πριν διαλέξεις μοντέλο ή framework, γράψε ένα μικρό συμβόλαιο. Αν αυτά τα πεδία είναι ασαφή, ο βρόχος θα μετατρέψει την ασάφεια σε επαναλαμβανόμενο κόστος.
```yaml
goal: "Ποια παρατηρήσιμη κατάσταση πρέπει να γίνει αληθής;"
inputs: "Τι ξεκινά τον βρόχο;"
state: "Ποια γεγονότα και προσπάθειες διατηρούνται μεταξύ των επαναλήψεων;"
actions: "Ποια εργαλεία επιτρέπεται να χρησιμοποιεί το σύστημα και με ποια δικαιώματα;"
observations: "Ποια εξωτερικά σήματα επιστρέφουν από αυτές τις ενέργειες;"
evaluator: "Ποια ρουμπρίκα ή ποιοι ντετερμινιστικοί έλεγχοι κρίνουν το αποτέλεσμα;"
success: "Ποιες αποδείξεις τεκμηριώνουν ότι ο στόχος ολοκληρώθηκε;"
failure: "Ποιες συνθήκες απαιτούν ανάκαμψη ή ανθρώπινη βοήθεια;"
budget: "Μέγιστοι γύροι, χρόνος, tokens, χρήματα ή παρενέργειες"
```
<Callout type="warning" title="Βρόχος Χωρίς Έξοδο Είναι Μορφή Αποτυχίας">
Όρισε πάντα τρεις εξόδους: **επιτυχία** όταν οι αποδείξεις ικανοποιούν τον στόχο, **αποτυχία** όταν η ανάκαμψη δεν είναι πια χρήσιμη, και **εξάντληση προϋπολογισμού** όταν ο βρόχος φτάσει στο επιτρεπόμενο όριο κόστους ή ρίσκου.
</Callout>
## Οι Παρατηρήσεις Πρέπει να Έρχονται από τον Κόσμο
Το να λέει το μοντέλο «αυτό φαίνεται σωστό» δεν είναι ισχυρή απόδειξη. Μια χρήσιμη παρατήρηση παράγεται από κάτι έξω από την απάντηση που κρίνεται.
<table>
<thead>
<tr>
<th>Εργασία</th>
<th>Αδύναμη παρατήρηση</th>
<th>Ισχυρή παρατήρηση</th>
</tr>
</thead>
<tbody>
<tr>
<td>Διόρθωση κώδικα</td>
<td>«Η διόρθωση θα πρέπει να δουλεύει.»</td>
<td>Η αρχική αποτυχία αναπαράγεται και μετά το regression και ολόκληρη η σουίτα περνούν.</td>
</tr>
<tr>
<td>Έρευνα</td>
<td>«Αρκετές πηγές συμφωνούν.»</td>
<td>Οι ισχυρισμοί παραπέμπουν σε πρωτότυπες πηγές, με καταγεγραμμένες ημερομηνίες, μεθόδους και διαφωνίες.</td>
</tr>
<tr>
<td>Εξαγωγή δεδομένων</td>
<td>«Το JSON μοιάζει έγκυρο.»</td>
<td>Η επικύρωση του schema περνάει και δειγματοληπτικές εγγραφές συμφωνούν με την πηγή.</td>
</tr>
<tr>
<td>Περιεχόμενο</td>
<td>«Το κείμενο μοιάζει σαφές.»</td>
<td>Περνάει μια συγκεκριμένη ρουμπρίκα, έλεγχο γεγονότων, ελέγχους συνδέσμων και δοκιμή στο κοινό.</td>
</tr>
<tr>
<td>Λειτουργίες</td>
<td>«Το αίτημα πέτυχε.»</td>
<td>Το εξωτερικό σύστημα επιστρέφει την αναμενόμενη κατάσταση και υπάρχει εγγραφή ελέγχου (audit).</td>
</tr>
</tbody>
</table>
Γι' αυτό έχουν σημασία τα εργαλεία: τα τεστ, οι browsers, οι βάσεις δεδομένων, οι validators και η ανθρώπινη ανασκόπηση μετατρέπουν μια εσωτερική εικασία σε παρατηρήσιμο αποτέλεσμα.
## Διαχώρισε τον Δημιουργό από τον Ελεγκτή
Για δουλειά χαμηλού ρίσκου, ένα μοντέλο μπορεί να συντάσσει και να αυτοελέγχεται. Για σημαντική δουλειά, χρησιμοποίησε έναν ελεγκτή με διαφορετικό ρόλο και περιορισμένη εξουσία.
<InfoGrid columns={2} items={[
{ label: "Δημιουργός (maker)", description: "Προτείνει την αλλαγή, καλεί τα εργαλεία δράσης και εξηγεί ποιες αποδείξεις πρέπει να συλλεχθούν.", color: "amber" },
{ label: "Ελεγκτής (checker)", description: "Λαμβάνει τον στόχο, το παραδοτέο και τις αποδείξεις· εφαρμόζει τη ρουμπρίκα· δεν μπορεί να ξαναγράψει σιωπηλά τη δουλειά που βαθμολογεί.", color: "green" },
]} />
Ο ελεγκτής δεν χρειάζεται να είναι ένα ακόμη AI. Προτίμησε τον πιο ντετερμινιστικό αξιολογητή που είναι διαθέσιμος:
1. **Ακριβείς έλεγχοι** — τύποι, schemas, περιορισμοί, δικαιώματα, hashes
2. **Εκτελέσιμοι έλεγχοι** — τεστ, linters, προσομοιώσεις, επικύρωση συνδέσμων
3. **Έλεγχοι με ρουμπρίκα** — ένα ανεξάρτητο μοντέλο ή ένας άνθρωπος που χρησιμοποιεί συγκεκριμένα κριτήρια
4. **Έλεγχοι αποτελέσματος** — πραγματική συμπεριφορά χρηστών ή μετρικές παραγωγής σε βάθος χρόνου
<Callout type="tip" title="Η Αυτοπεποίθηση Δεν Είναι Απόδειξη">
Ένα σκορ βεβαιότητας που παράγεται από το ίδιο μοντέλο που έφτιαξε το παραδοτέο παραμένει έξοδος του μοντέλου. Αντιμετώπισέ το ως ένδειξη για δρομολόγηση, όχι ως απόδειξη.
</Callout>
## Η Κατάσταση Είναι η Ραχοκοκαλιά του Βρόχου
Το context είναι αυτό που βλέπει το μοντέλο **σε αυτόν τον γύρο**. Η κατάσταση (state) είναι η συμπαγής καταγραφή που επιτρέπει στον επόμενο γύρο να συνεχίσει χωρίς να επαναλάβει ή να ξεχάσει δουλειά.
<Checklist title="Χρήσιμη Κατάσταση Βρόχου" items={[
{ text: "Ο τρέχων στόχος και τα κριτήρια αποδοχής" },
{ text: "Ενέργειες που έχουν ήδη δοκιμαστεί και τα παρατηρήσιμα αποτελέσματά τους" },
{ text: "Παραδοτέα που παράχθηκαν, με εκδόσεις ή σταθερές αναφορές" },
{ text: "Ετυμηγορίες του αξιολογητή και ανεπίλυτα ζητήματα" },
{ text: "Ο προϋπολογισμός που καταναλώθηκε και τα δικαιώματα που παραμένουν διαθέσιμα" },
{ text: "Ο λόγος για συνέχιση, διακοπή ή κλιμάκωση" },
]} />
Αποθήκευσε συνοπτικές αποφάσεις και αποδείξεις—όχι την εσωτερική αλυσίδα σκέψης ενός μοντέλου. Η καλή κατάσταση είναι μικρή, επιθεωρήσιμη και ασφαλής για συνέχιση.
## Συνηθισμένα Σχήματα Βρόχων
### Ο Βρόχος Επιδιόρθωσης
`αναπαραγωγή → αλλαγή ενός πράγματος → εκτέλεση ελέγχων → διάγνωση → επανάληψη ή διακοπή`
Ιδανικός για κώδικα, ρυθμίσεις, καθαρισμό δεδομένων και κάθε εργασία με εκτελέσιμη ανατροφοδότηση.
### Ο Βρόχος Evaluator-Optimizer
`παραγωγή → βαθμολόγηση με ρουμπρίκα → επιστροφή στοχευμένης ανατροφοδότησης → αναθεώρηση`
Ιδανικός για γράψιμο, μετάφραση, κριτική σχεδιασμού και αποτελέσματα των οποίων η ποιότητα βελτιώνεται μέσα από διατυπωμένη ανατροφοδότηση.
### Ο Βρόχος Έρευνας
`αναζήτηση → εξέταση πηγών → εντοπισμός κενών ή αντιφάσεων → νέα αναζήτηση → σύνθεση`
Ιδανικός όταν η πληρότητα δεν είναι γνωστή εκ των προτέρων. Ο κανόνας διακοπής πρέπει να μετρά την κάλυψη των αποδείξεων, όχι τον αριθμό των αποτελεσμάτων αναζήτησης.
### Ο Βρόχος με Ανθρώπινη Έγκριση
`προετοιμασία → αυτόματη επαλήθευση → παύση πριν από ενέργεια υψηλού ρίσκου → ο άνθρωπος εγκρίνει ή ανακατευθύνει`
Ιδανικός για πληρωμές, δημοσιεύσεις, διαγραφές, αλλαγές πρόσβασης, ιατρικές ή νομικές αποφάσεις και άλλες ενέργειες με σοβαρές συνέπειες.
## Μορφές Αποτυχίας που Πρέπει να Εξαλείψεις με τον Σχεδιασμό
<table>
<thead>
<tr>
<th>Αποτυχία</th>
<th>Τι συνέβη</th>
<th>Μηχανική απάντηση</th>
</tr>
</thead>
<tbody>
<tr>
<td>Ατέρμονη επανάληψη</td>
<td>Ο βρόχος δεν έχει μετρήσιμη έξοδο επιτυχίας ή προϋπολογισμού.</td>
<td>Πρόσθεσε ρητές τερματικές καταστάσεις και ένα αυστηρό όριο επαναλήψεων.</td>
</tr>
<tr>
<td>Αυτοεπιβράβευση</td>
<td>Ο δημιουργός αποδέχεται τη δική του εύλογη απάντηση χωρίς αποδείξεις.</td>
<td>Χρησιμοποίησε ντετερμινιστικούς ελέγχους ή έναν ανεξάρτητο ελεγκτή.</td>
</tr>
<tr>
<td>Χιονοστιβάδα context</td>
<td>Κάθε επανάληψη προσθέτει τα πάντα, μέχρι το μοντέλο να χάσει το σήμα.</td>
<td>Διατήρησε δομημένη κατάσταση και ανασυγκρότησε μόνο το σχετικό context.</td>
</tr>
<tr>
<td>Αμφιταλάντευση (thrashing)</td>
<td>Ο βρόχος εναλλάσσεται άσκοπα ανάμεσα σε δύο διορθώσεις.</td>
<td>Εντόπισε επαναλαμβανόμενες καταστάσεις και απαίτησε διαφορετική στρατηγική ή κλιμάκωση.</td>
</tr>
<tr>
<td>Απόκλιση από τον στόχο</td>
<td>Τοπικές βελτιώσεις αντικαθιστούν τον αρχικό σκοπό.</td>
<td>Ξαναδιάβασε τον αμετάβλητο στόχο και τα κριτήρια αποδοχής σε κάθε κύκλο.</td>
</tr>
<tr>
<td>Μη ασφαλής επανάληψη</td>
<td>Ένα αναστρέψιμο λάθος γίνεται επιζήμιο όταν επαναλαμβάνεται.</td>
<td>Περιόρισε δικαιώματα, παρενέργειες, ρυθμό, δαπάνη και εμβέλεια της ζημιάς.</td>
</tr>
</tbody>
</table>
## Μια Ελάχιστη Υλοποίηση
```typescript
let state = initialize(goal, acceptanceCriteria, budget);
while (state.budget.remaining > 0) {
const context = assembleRelevantContext(state);
const proposedAction = await maker.chooseAction(context);
const observation = await tools.executeWithinPolicy(proposedAction);
const verdict = await evaluator.check({ goal, observation, state });
state = recordIteration(state, { proposedAction, observation, verdict });
if (verdict.status === "passed") return complete(state);
if (verdict.status === "unsafe" || verdict.status === "blocked") {
return escalateToHuman(state);
}
state = adaptPlan(state, verdict.feedback);
}
return stopWithBudgetReport(state);
```
Ο κώδικας είναι το εύκολο κομμάτι. Οι δύσκολες ερωτήσεις είναι ερωτήσεις του εκάστοτε πεδίου: Ποιο τεστ αποδεικνύει ότι το bug εξαφανίστηκε; Ποια πηγή είναι έγκυρη; Ποια ενέργεια είναι αναστρέψιμη; Ποιος μπορεί να εγκρίνει το τελικό βήμα; Αυτές οι αποφάσεις είναι η πραγματική δουλειά της μηχανικής βρόχων.
## Εξάσκηση: Σχεδίασε έναν Βρόχο
<TryIt
title="Σύνταξε ένα Συμβόλαιο Βρόχου"
description="Αντικατάστησε τις μεταβλητές με μια επαναλαμβανόμενη εργασία από τη δική σου δουλειά. Ζήτησε από το AI να αμφισβητήσει τις αδύναμες αποδείξεις και τους ασαφείς κανόνες διακοπής."
prompt={`Σχεδίασε έναν οριοθετημένο βρόχο εργασίας AI για αυτή την εργασία:
ΕΡΓΑΣΙΑ: \${task:διαλογή των νέων αιτημάτων υποστήριξης πελατών κάθε πρωί}
Όρισε:
1. Τον παρατηρήσιμο στόχο
2. Το έναυσμα και τις απαιτούμενες εισόδους
3. Τις επιτρεπόμενες ενέργειες και τα δικαιώματα των εργαλείων
4. Τις αξιόπιστες παρατηρήσεις από το εξωτερικό περιβάλλον
5. Τον αξιολογητή και τη ρουμπρίκα του
6. Την κατάσταση που διατηρείται μεταξύ των επαναλήψεων
7. Τις εξόδους επιτυχίας, αποτυχίας και εξάντλησης προϋπολογισμού
8. Τα σημεία ανθρώπινης έγκρισης για επικίνδυνες ενέργειες
9. Μια μορφή καταγραφής (trace) που κάνει κάθε επανάληψη ελέγξιμη
Στη συνέχεια, εντόπισε τις τρεις πιο πιθανές μορφές αποτυχίας στον σχεδιασμό σου και αναθεώρησε τον βρόχο για να τις αποτρέψεις.`}
/>
<Quiz
question="Ένας agent επεξεργάζεται κώδικα, ξαναδιαβάζει το diff και λέει ότι το bug διορθώθηκε. Ποιο είναι το πιο σημαντικό κομμάτι του βρόχου που λείπει;"
options={[
"Ένα μεγαλύτερο system prompt",
"Μια εξωτερική παρατήρηση που αξιολογείται με βάση έναν κανόνα διακοπής",
"Ένα δεύτερο πέρασμα επεξεργασίας",
"Ένα μεγαλύτερο παράθυρο context"
]}
correctIndex={1}
explanation="Ο agent έχει παραγάγει και επιθεωρήσει ένα παραδοτέο, αλλά δεν έχει συγκεντρώσει ανεξάρτητες αποδείξεις. Η αναπαραγωγή της αποτυχίας και η εκτέλεση των σχετικών τεστ θα δημιουργούσαν ένα παρατηρήσιμο σήμα που μπορεί να αξιολογηθεί από έναν κανόνα διακοπής."
/>
## Περαιτέρω Ανάγνωση
- [Loop Engineering — Addy Osmani](https://addyosmani.com/blog/loop-engineering/) — η πρόσφατη διατύπωση της αντικατάστασης των χειροκίνητων επόμενων prompts με ένα σχεδιασμένο σύστημα, μαζί με πρακτικές επιφυλάξεις για την επαλήθευση και την ανθρώπινη ευθύνη
- [Building Effective Agents — Anthropic](https://www.anthropic.com/engineering/building-effective-agents) — ροές εργασίας evaluator-optimizer, ανατροφοδότηση από το περιβάλλον, συνθήκες διακοπής και καθοδήγηση για το πότε δικαιολογείται η πολυπλοκότητα των agents
- [A Practical Guide to Building Agents — OpenAI](https://openai.com/business/guides-and-resources/a-practical-guide-to-building-ai-agents/) — εκτελέσεις agents, συνθήκες εξόδου, εργαλεία, δικλείδες ασφαλείας και ανθρώπινη παρέμβαση
- [ReAct: Synergizing Reasoning and Acting in Language Models](https://arxiv.org/abs/2210.03629) — θεμελιώδης έρευνα για την εναλλαγή ενεργειών με παρατηρήσεις από ένα εξωτερικό περιβάλλον
## Σύνοψη
<Callout type="tip" title="Χτίσε την Ανατροφοδότηση, Όχι Μόνο το Prompt">
Ένας αξιόπιστος βρόχος έχει μετρήσιμο στόχο, οριοθετημένες ενέργειες, αξιόπιστες παρατηρήσεις, ρητό αξιολογητή, συμπαγή κατάσταση, ασφαλείς εξόδους και ανθρώπινη κρίση εκεί όπου οι συνέπειες το απαιτούν. Το μοντέλο βρίσκεται μέσα στον βρόχο· ο μηχανικός παραμένει υπεύθυνος για τον βρόχο.
</Callout>
@@ -1,405 +0,0 @@
La ingeniería de contexto decide **qué puede ver el modelo**. La ingeniería de bucles decide **qué hace el sistema a continuación**.
En lugar de que una persona lea una respuesta una y otra vez y escriba el siguiente prompt, un bucle convierte ese trabajo de seguimiento en un sistema diseñado. Le da a la IA un objetivo, la deja actuar, observa retroalimentación real, evalúa el resultado y se adapta o se detiene.
<Callout type="info" title="La Definición Corta">
La ingeniería de bucles es la práctica de diseñar el ciclo de retroalimentación alrededor de un sistema de IA: el objetivo, las acciones, las observaciones, la evaluación, el estado, las salvaguardas y las reglas de parada que llevan el trabajo hacia un resultado verificable.
</Callout>
## De un Buen Prompt a un Buen Bucle
Un prompt puede producir un primer intento sólido. Un bucle es útil cuando el número de pasos no se puede conocer de antemano, el entorno puede cambiar, o el primer intento debe contrastarse con evidencia.
<Compare
before={{
label: "Prompt Único",
content: "Preguntar → Generar → Devolver\n\nEl modelo produce una respuesta. Una persona decide si funcionó y escribe el siguiente prompt."
}}
after={{
label: "Bucle Diseñado",
content: "Encuadrar → Actuar → Observar → Evaluar → Adaptar\n ↑______________________↓\n\nEl sistema reúne evidencia, registra el estado y continúa solo mientras otra pasada resulte útil."
}}
/>
Esta idea se apoya en patrones de agentes anteriores. El [artículo de ReAct](https://arxiv.org/abs/2210.03629) demostró el valor de intercalar acciones con observaciones de un entorno externo. El [patrón evaluador-optimizador](https://www.anthropic.com/engineering/building-effective-agents) de Anthropic añade un paso de retroalimentación independiente, mientras que la [guía práctica de agentes](https://openai.com/business/guides-and-resources/a-practical-guide-to-building-ai-agents/) de OpenAI describe las ejecuciones de agentes como bucles gobernados por condiciones de salida. El término más reciente, **ingeniería de bucles**, pone el foco en diseñar deliberadamente todo ese ciclo.
## Los Cinco Movimientos
<InfoGrid items={[
{ label: "1. Encuadrar", description: "Convierte la intención en un objetivo, restricciones, criterios de éxito y un presupuesto.", color: "blue" },
{ label: "2. Actuar", description: "Elige una sola acción acotada: buscar, editar, calcular, llamar a una herramienta o preguntar a una persona.", color: "amber" },
{ label: "3. Observar", description: "Recoge lo que realmente ocurrió: salida de pruebas, resultados de API, citas o retroalimentación de usuarios.", color: "cyan" },
{ label: "4. Evaluar", description: "Compara la evidencia con criterios explícitos, no con la confianza del modelo.", color: "purple" },
{ label: "5. Adaptar", description: "Actualiza el estado, cambia el plan, reintenta de forma segura, escala o detente.", color: "green" },
]} />
El bucle no son las flechas. La ingeniería vive en los **contratos entre las flechas**: qué cuenta como acción, qué observaciones son fiables, quién las evalúa, qué estado sobrevive y exactamente cuándo termina la ejecución.
<LoopEngineeringLab content={{
eyebrow: "Control de bucles / simulador interactivo",
title: "Recorre paso a paso un bucle de retroalimentación en funcionamiento",
description: "Elige una tarea y avanza una señal a la vez. Fíjate en cómo el progreso proviene de evidencia del entorno y de una evaluación explícita, no de preguntarle al modelo si le parece que ha terminado.",
chooseScenarioLabel: "Elige un bucle",
goalLabel: "Objetivo",
stopRuleLabel: "Regla de parada",
evidenceLabel: "Evidencia fiable",
iterationLabel: "Iteración",
progressLabel: "Progreso verificado",
openIssuesLabel: "Problemas abiertos",
currentSignalLabel: "Señal actual",
advanceLabel: "Avanzar un paso",
nextIterationLabel: "Comenzar la siguiente iteración",
resetLabel: "Reiniciar bucle",
completeLabel: "Objetivo verificado",
completeDescription: "Los criterios de éxito se cumplen, la evidencia queda registrada y el bucle se detiene en lugar de gastar otro ciclo.",
stages: [
{ id: "frame", label: "Encuadrar", verb: "Relee el contrato" },
{ id: "act", label: "Actuar", verb: "Haz un movimiento acotado" },
{ id: "observe", label: "Observar", verb: "Lee la retroalimentación externa" },
{ id: "evaluate", label: "Evaluar", verb: "Aplica la rúbrica" },
{ id: "adapt", label: "Adaptar", verb: "Ajusta el siguiente movimiento" },
],
scenarios: [
{
id: "code",
label: "Reparar un bug en el checkout",
goal: "Corregir los totales del checkout sin alterar el comportamiento válido de los descuentos.",
stopRule: "La prueba de regresión específica pasa, la suite completa del checkout pasa y el lint está limpio; o se agotan tres intentos y el bucle escala a un humano.",
evidence: "Pasos de reproducción, salida de las pruebas, el diff del código y la suite de regresión final.",
cycles: [
{
action: "Reproducir el total reportado y añadir una prueba que falle para impuesto más descuento porcentual.",
observation: "La prueba falla por un centavo solo cuando el impuesto se redondea antes de aplicar el descuento.",
evaluation: "El bug se reproduce con una señal determinista, pero su origen aún no está corregido.",
adaptation: "Inspeccionar la frontera de redondeo y cambiar solo la ruta de cálculo del total del pedido.",
progress: 34,
openIssues: 2,
},
{
action: "Mover el redondeo a la frontera monetaria final y ejecutar las pruebas específicas del checkout.",
observation: "La regresión pasa, pero una prueba de integración de cupones ahora falla con un descuento de monto fijo.",
evaluation: "El primer síntoma está corregido, pero el cambio es demasiado amplio. La regla de parada no se cumple.",
adaptation: "Acotar el parche y añadir un caso que separe el redondeo de impuestos del redondeo de cupones.",
progress: 71,
openIssues: 1,
},
{
action: "Aplicar la corrección acotada del cálculo y luego ejecutar la regresión, la suite completa del checkout y el lint.",
observation: "Todas las comprobaciones pasan. El diff toca una sola función de cálculo y la nueva prueba de regresión.",
evaluation: "Cada criterio de éxito tiene evidencia independiente y no se superó ningún límite de presupuesto.",
adaptation: "Detenerse, conservar la salida de las pruebas y entregar el diff pequeño a un revisor humano.",
progress: 100,
openIssues: 0,
},
],
},
{
id: "research",
label: "Verificar una afirmación de investigación",
goal: "Evaluar la afirmación de que el trabajo remoto siempre aumenta la productividad del equipo.",
stopRule: "Una conclusión calibrada está respaldada por al menos tres fuentes creíbles, con los desacuerdos y las limitaciones declarados.",
evidence: "Enlaces directos a las fuentes, fechas de publicación, métodos de los estudios, tamaños de muestra y métricas citadas.",
cycles: [
{
action: "Buscar evidencia reciente y rastrear la estadística de productividad más repetida hasta su fuente.",
observation: "La mayoría de los artículos repiten una encuesta de un proveedor sin enlazar su cuestionario ni su muestra original.",
evaluation: "La evidencia es popular, pero no lo bastante sólida para respaldar una afirmación absoluta.",
adaptation: "Priorizar estudios revisados por pares y conjuntos de datos públicos; buscar también hallazgos contrarios.",
progress: 28,
openIssues: 3,
},
{
action: "Comparar dos estudios revisados por pares con un conjunto de datos laborales nacional.",
observation: "Los resultados varían según el tipo de tarea, el método de medición y si el trabajo es totalmente remoto o híbrido.",
evaluation: "La evidencia contradice la palabra «siempre». Una conclusión condicional empieza a ser defendible.",
adaptation: "Comprobar si los estudios distinguen entre producción, horas trabajadas y productividad percibida.",
progress: 68,
openIssues: 1,
},
{
action: "Construir una tabla de evidencia y verificar cada afirmación contra la fuente original.",
observation: "Las fuentes respaldan efectos mixtos e identifican la autonomía, la coordinación y el tipo de tarea como variables clave.",
evaluation: "La conclusión está respaldada, la incertidumbre es visible y se alcanza el umbral de fuentes.",
adaptation: "Detenerse con una respuesta matizada y conservar la tabla de evidencia para su revisión.",
progress: 100,
openIssues: 0,
},
],
},
{
id: "writing",
label: "Pulir un correo de lanzamiento",
goal: "Crear un correo de lanzamiento conciso que explique el beneficio y consiga clics de demo cualificados.",
stopRule: "El correo pasa la rúbrica de voz, se mantiene por debajo de 140 palabras, contiene una sola llamada a la acción clara y sobrevive a una revisión factual.",
evidence: "Recuento de palabras, puntuaciones de la rúbrica, validación de enlaces, datos verificados del producto y notas del revisor.",
cycles: [
{
action: "Redactar a partir del brief del producto y puntuar el resultado contra la rúbrica de audiencia y voz.",
observation: "El borrador tiene 204 palabras, abre con funcionalidades y contiene dos llamadas a la acción que compiten entre sí.",
evaluation: "Los datos son precisos, pero los criterios de jerarquía y extensión fallan.",
adaptation: "Abrir con el resultado para el cliente, eliminar la acción secundaria y recortar los detalles de implementación.",
progress: 41,
openIssues: 3,
},
{
action: "Reescribir la apertura y comprimir el cuerpo en una única secuencia problema-beneficio-prueba.",
observation: "El correo tiene 126 palabras y una sola CTA, pero la frase de prueba exagera un resultado de la beta.",
evaluation: "La estructura pasa. La calibración factual aún no cumple la rúbrica.",
adaptation: "Sustituir la afirmación genérica por el resultado medido de la beta y pedir una verificación factual final.",
progress: 79,
openIssues: 1,
},
{
action: "Insertar la métrica verificada, validar el enlace y ejecutar la rúbrica completa una vez más.",
observation: "El correo tiene 132 palabras, el enlace funciona, los datos coinciden con el brief y todos los puntos de la rúbrica pasan.",
evaluation: "El artefacto satisface el estándar de calidad definido con evidencia revisable.",
adaptation: "Detenerse y enviar la versión aprobada a la persona responsable de la campaña.",
progress: 100,
openIssues: 0,
},
],
},
],
}} />
## Escribe Primero el Contrato del Bucle
Antes de elegir un modelo o un framework, escribe un pequeño contrato. Si estos campos son vagos, el bucle convertirá la ambigüedad en costo repetido.
```yaml
goal: "¿Qué estado observable debería hacerse realidad?"
inputs: "¿Qué pone en marcha el bucle?"
state: "¿Qué hechos e intentos persisten entre iteraciones?"
actions: "¿Qué herramientas puede usar el sistema, y con qué permisos?"
observations: "¿Qué señales externas devuelven esas acciones?"
evaluator: "¿Qué rúbrica o comprobaciones deterministas juzgan el resultado?"
success: "¿Qué evidencia demuestra que el objetivo está cumplido?"
failure: "¿Qué condiciones exigen recuperación o ayuda humana?"
budget: "Máximo de turnos, tiempo, tokens, dinero o efectos secundarios"
```
<Callout type="warning" title="Un Bucle Sin Salida Es un Modo de Fallo">
Define siempre tres salidas: **éxito** cuando la evidencia satisface el objetivo, **fallo** cuando la recuperación ya no es útil, y **presupuesto agotado** cuando el bucle alcanza su límite permitido de costo o riesgo.
</Callout>
## Las Observaciones Deben Venir del Mundo
Que el modelo diga «esto parece correcto» no es evidencia sólida. Una observación útil la produce algo externo a la respuesta que se está juzgando.
<table>
<thead>
<tr>
<th>Tarea</th>
<th>Observación débil</th>
<th>Observación sólida</th>
</tr>
</thead>
<tbody>
<tr>
<td>Reparación de código</td>
<td>«La corrección debería funcionar.»</td>
<td>Se reproduce el fallo original y luego pasan la regresión y la suite completa.</td>
</tr>
<tr>
<td>Investigación</td>
<td>«Varias fuentes coinciden.»</td>
<td>Las afirmaciones enlazan a fuentes originales con fechas, métodos y desacuerdos registrados.</td>
</tr>
<tr>
<td>Extracción de datos</td>
<td>«El JSON parece válido.»</td>
<td>La validación del esquema pasa y los registros muestreados coinciden con la fuente.</td>
</tr>
<tr>
<td>Contenido</td>
<td>«El texto se siente claro.»</td>
<td>Pasa una rúbrica con nombre, una revisión factual, comprobaciones de enlaces y pruebas con la audiencia.</td>
</tr>
<tr>
<td>Operaciones</td>
<td>«La solicitud tuvo éxito.»</td>
<td>El sistema externo devuelve el estado esperado y existe un registro de auditoría.</td>
</tr>
</tbody>
</table>
Por eso importan las herramientas: las pruebas, los navegadores, las bases de datos, los validadores y la revisión humana convierten una suposición interna en un resultado observable.
## Separa a Quien Crea de Quien Verifica
Para trabajo de bajo riesgo, un mismo modelo puede redactar y autorrevisarse. Para trabajo importante, usa un verificador con una función distinta y autoridad limitada.
<InfoGrid columns={2} items={[
{ label: "Creador", description: "Propone el cambio, llama a las herramientas de acción y explica qué evidencia debe recogerse.", color: "amber" },
{ label: "Verificador", description: "Recibe el objetivo, el artefacto y la evidencia; aplica la rúbrica; no puede reescribir en silencio el trabajo que califica.", color: "green" },
]} />
El verificador no tiene por qué ser otra IA. Prefiere el evaluador más determinista que tengas disponible:
1. **Comprobaciones exactas** — tipos, esquemas, restricciones, permisos, hashes
2. **Comprobaciones ejecutables** — pruebas, linters, simulaciones, validación de enlaces
3. **Comprobaciones con rúbrica** — un modelo independiente o un humano que aplica criterios con nombre
4. **Comprobaciones de resultado** — comportamiento real de usuarios o métricas de producción a lo largo del tiempo
<Callout type="tip" title="La Confianza No Es Evidencia">
Una puntuación de confianza generada por el mismo modelo que creó el artefacto sigue siendo una salida del modelo. Trátala como una pista para enrutar, no como una prueba.
</Callout>
## El Estado Es la Columna Vertebral del Bucle
El contexto es lo que el modelo ve **en este turno**. El estado es el registro compacto que permite que el siguiente turno continúe sin repetir ni olvidar trabajo.
<Checklist title="Estado Útil de un Bucle" items={[
{ text: "El objetivo actual y los criterios de aceptación" },
{ text: "Las acciones ya intentadas y sus resultados observables" },
{ text: "Los artefactos producidos, con versiones o referencias estables" },
{ text: "Los veredictos del evaluador y los problemas sin resolver" },
{ text: "El presupuesto consumido y los permisos aún disponibles" },
{ text: "La razón para continuar, detenerse o escalar" },
]} />
Almacena decisiones y evidencia concisas, no la cadena de pensamiento privada de un modelo. Un buen estado es pequeño, inspeccionable y seguro de retomar.
## Formas Comunes de Bucle
### El Bucle de Reparación
`reproducir → cambiar una sola cosa → ejecutar comprobaciones → diagnosticar → repetir o detenerse`
Ideal para código, configuración, limpieza de datos y cualquier tarea con retroalimentación ejecutable.
### El Bucle Evaluador-Optimizador
`generar → puntuar con una rúbrica → devolver retroalimentación específica → revisar`
Ideal para escritura, traducción, crítica de diseño y resultados cuya calidad mejora con retroalimentación articulada.
### El Bucle de Investigación
`buscar → inspeccionar fuentes → identificar lagunas o conflictos → volver a buscar → sintetizar`
Ideal cuando la completitud no se conoce de antemano. La regla de parada debería medir la cobertura de la evidencia, no la cantidad de resultados de búsqueda.
### El Bucle con Aprobación Humana
`preparar → verificar automáticamente → pausar antes de la acción de alto riesgo → un humano aprueba o redirige`
Ideal para pagos, publicaciones, eliminaciones, cambios de acceso, decisiones médicas o legales y otras acciones con consecuencias.
## Modos de Fallo que Hay que Eliminar desde el Diseño
<table>
<thead>
<tr>
<th>Fallo</th>
<th>Qué ocurrió</th>
<th>Respuesta de ingeniería</th>
</tr>
</thead>
<tbody>
<tr>
<td>Reintento infinito</td>
<td>El bucle no tiene una salida medible de éxito ni de presupuesto.</td>
<td>Añade estados terminales explícitos y un tope estricto de iteraciones.</td>
</tr>
<tr>
<td>Autocomplacencia</td>
<td>El creador acepta su propia respuesta plausible sin evidencia.</td>
<td>Usa comprobaciones deterministas o un verificador independiente.</td>
</tr>
<tr>
<td>Bola de nieve de contexto</td>
<td>Cada iteración lo acumula todo hasta que el modelo pierde la señal.</td>
<td>Persiste estado estructurado y reconstruye solo el contexto relevante.</td>
</tr>
<tr>
<td>Vaivén</td>
<td>El bucle alterna inútilmente entre dos arreglos.</td>
<td>Detecta estados repetidos y exige una estrategia distinta o escalar a un humano.</td>
</tr>
<tr>
<td>Deriva del objetivo</td>
<td>Las mejoras locales sustituyen al objetivo original.</td>
<td>Relee el objetivo inmutable y los criterios de aceptación en cada ciclo.</td>
</tr>
<tr>
<td>Repetición insegura</td>
<td>Un error reversible se vuelve dañino cuando se repite.</td>
<td>Limita permisos, efectos secundarios, ritmo, gasto y alcance del daño.</td>
</tr>
</tbody>
</table>
## Una Implementación Mínima
```typescript
let state = initialize(goal, acceptanceCriteria, budget);
while (state.budget.remaining > 0) {
const context = assembleRelevantContext(state);
const proposedAction = await maker.chooseAction(context);
const observation = await tools.executeWithinPolicy(proposedAction);
const verdict = await evaluator.check({ goal, observation, state });
state = recordIteration(state, { proposedAction, observation, verdict });
if (verdict.status === "passed") return complete(state);
if (verdict.status === "unsafe" || verdict.status === "blocked") {
return escalateToHuman(state);
}
state = adaptPlan(state, verdict.feedback);
}
return stopWithBudgetReport(state);
```
El código es la parte fácil. Las preguntas difíciles son preguntas de dominio: ¿Qué prueba demuestra que el bug desapareció? ¿Qué fuente es autorizada? ¿Qué acción es reversible? ¿Quién puede aprobar el paso final? Esas decisiones son el verdadero trabajo de la ingeniería de bucles.
## Práctica: Diseña un Bucle
<TryIt
title="Redacta un Contrato de Bucle"
description="Sustituye las variables por una tarea recurrente de tu propio trabajo. Pídele a la IA que cuestione la evidencia débil y las reglas de parada ambiguas."
prompt={`Diseña un bucle de trabajo de IA acotado para esta tarea:
TAREA: \${task:clasificar cada mañana los nuevos tickets de soporte al cliente}
Define:
1. El objetivo observable
2. El disparador y las entradas requeridas
3. Las acciones permitidas y los permisos de herramientas
4. Las observaciones fiables provenientes del entorno externo
5. El evaluador y su rúbrica
6. El estado que persiste entre iteraciones
7. Las salidas de éxito, fallo y presupuesto agotado
8. Los puntos de aprobación humana para acciones arriesgadas
9. Un formato de traza que haga auditable cada iteración
Luego identifica los tres modos de fallo más probables de tu diseño y revisa el bucle para prevenirlos.`}
/>
<Quiz
question="Un agente edita código, relee el diff y dice que el bug está corregido. ¿Cuál es la pieza faltante más importante del bucle?"
options={[
"Un prompt de sistema más largo",
"Una observación externa evaluada contra una regla de parada",
"Una segunda pasada de edición",
"Una ventana de contexto más grande"
]}
correctIndex={1}
explanation="El agente ha producido e inspeccionado un artefacto, pero no ha reunido evidencia independiente. Reproducir el fallo y ejecutar las pruebas relevantes crearía una señal observable que una regla de parada puede evaluar."
/>
## Lecturas Adicionales
- [Loop Engineering — Addy Osmani](https://addyosmani.com/blog/loop-engineering/) — el planteamiento reciente de sustituir los prompts de seguimiento manuales por un sistema diseñado, con advertencias prácticas sobre verificación y responsabilidad humana
- [Building Effective Agents — Anthropic](https://www.anthropic.com/engineering/building-effective-agents) — flujos de trabajo evaluador-optimizador, retroalimentación del entorno, condiciones de parada y orientación sobre cuándo se justifica la complejidad agéntica
- [A Practical Guide to Building Agents — OpenAI](https://openai.com/business/guides-and-resources/a-practical-guide-to-building-ai-agents/) — ejecuciones de agentes, condiciones de salida, herramientas, salvaguardas e intervención humana
- [ReAct: Synergizing Reasoning and Acting in Language Models](https://arxiv.org/abs/2210.03629) — investigación fundacional sobre intercalar acciones con observaciones de un entorno externo
## Resumen
<Callout type="tip" title="Construye la Retroalimentación, No Solo el Prompt">
Un bucle fiable tiene un objetivo medible, acciones acotadas, observaciones fiables, un evaluador explícito, estado compacto, salidas seguras y juicio humano donde las consecuencias lo exigen. El modelo está dentro del bucle; el ingeniero sigue siendo responsable del bucle.
</Callout>
@@ -1,405 +0,0 @@
مهندسی زمینه تعیین می‌کند **مدل چه چیزی را می‌بیند**. مهندسی حلقه تعیین می‌کند **سیستم در گام بعد چه می‌کند**.
به‌جای اینکه انسانی بارها پاسخ را بخواند و پرامپت بعدی را بنویسد، حلقه همین کارِ پیگیری را به یک سیستم طراحی‌شده تبدیل می‌کند: به هوش مصنوعی هدفی می‌دهد، اجازه می‌دهد اقدام کند، بازخورد واقعی را مشاهده می‌کند، نتیجه را ارزیابی می‌کند و سپس یا مسیر را اصلاح می‌کند یا متوقف می‌شود.
<Callout type="info" title="تعریف کوتاه">
مهندسی حلقه یعنی طراحی آگاهانهٔ چرخهٔ بازخورد پیرامون یک سیستم هوش مصنوعی: هدف، اقدام‌ها، مشاهده‌ها، ارزیابی، وضعیت، حفاظ‌ها و قوانین توقفی که کار را به سمت نتیجه‌ای قابل راستی‌آزمایی پیش می‌برند.
</Callout>
## از پرامپت خوب تا حلقهٔ خوب
یک پرامپت می‌تواند تلاش اول قدرتمندی تولید کند. اما حلقه زمانی به کار می‌آید که تعداد گام‌ها از پیش معلوم نیست، محیط ممکن است تغییر کند، یا تلاش اول باید با شواهد سنجیده شود.
<Compare
before={{
label: "پرامپت تک‌مرحله‌ای",
content: "بپرس → تولید کن → برگردان\n\nمدل پاسخی تولید می‌کند. یک انسان تصمیم می‌گیرد که آیا جواب داده یا نه و پرامپت بعدی را می‌نویسد."
}}
after={{
label: "حلقهٔ مهندسی‌شده",
content: "چارچوب‌بندی → اقدام → مشاهده → ارزیابی → تطبیق\n ↑______________________↓\n\nسیستم شواهد جمع می‌کند، وضعیت را ثبت می‌کند و تنها تا وقتی ادامه می‌دهد که یک دور دیگر مفید باشد."
}}
/>
این ایده بر پایهٔ الگوهای قدیمی‌ترِ عامل‌ها بنا شده است. [مقالهٔ ReAct](https://arxiv.org/abs/2210.03629) ارزش درهم‌بافتن اقدام‌ها با مشاهده‌هایی از یک محیط بیرونی را نشان داد. [الگوی ارزیاب-بهینه‌ساز](https://www.anthropic.com/engineering/building-effective-agents) شرکت Anthropic یک گام بازخورد مجزا به آن می‌افزاید و [راهنمای عملی ساخت عامل‌ها](https://openai.com/business/guides-and-resources/a-practical-guide-to-building-ai-agents/) از OpenAI اجرای عامل را حلقه‌ای توصیف می‌کند که شرط‌های خروج بر آن حاکم‌اند. اصطلاح جدیدترِ **مهندسی حلقه** توجه را به طراحی آگاهانهٔ کل این چرخه معطوف می‌کند.
## پنج حرکت
<InfoGrid items={[
{ label: "1. چارچوب‌بندی", description: "نیت را به هدف، محدودیت‌ها، معیارهای موفقیت و یک بودجه تبدیل کنید.", color: "blue" },
{ label: "2. اقدام", description: "یک اقدام محدود انتخاب کنید: جست‌وجو، ویرایش، محاسبه، فراخوانی یک ابزار یا پرسیدن از یک انسان.", color: "amber" },
{ label: "3. مشاهده", description: "آنچه واقعاً رخ داده را گردآوری کنید: خروجی تست‌ها، نتایج API، استنادها یا بازخورد کاربر.", color: "cyan" },
{ label: "4. ارزیابی", description: "شواهد را با معیارهای صریح مقایسه کنید—نه با میزان اطمینان مدل.", color: "purple" },
{ label: "5. تطبیق", description: "وضعیت را به‌روز کنید، برنامه را تغییر دهید، با احتیاط دوباره تلاش کنید، به انسان ارجاع دهید یا متوقف شوید.", color: "green" },
]} />
حلقه همان فلش‌ها نیست؛ مهندسیِ واقعی در **قراردادهای میان فلش‌ها** نهفته است: چه چیزی اقدام محسوب می‌شود، کدام مشاهده‌ها قابل اعتمادند، چه کسی آن‌ها را ارزیابی می‌کند، چه وضعیتی باقی می‌ماند و اجرا دقیقاً کِی به پایان می‌رسد.
<LoopEngineeringLab content={{
eyebrow: "کنترل حلقه / شبیه‌ساز تعاملی",
title: "یک حلقهٔ بازخورد واقعی را گام‌به‌گام دنبال کنید",
description: "یک کار انتخاب کنید و هر بار یک سیگنال جلو بروید. دقت کنید که پیشرفت از شواهد محیطی و ارزیابی صریح به دست می‌آید—نه از اینکه از مدل بپرسیم آیا حس می‌کند کار تمام شده است.",
chooseScenarioLabel: "یک حلقه انتخاب کنید",
goalLabel: "هدف",
stopRuleLabel: "قانون توقف",
evidenceLabel: "شواهد قابل اعتماد",
iterationLabel: "تکرار",
progressLabel: "پیشرفت راستی‌آزمایی‌شده",
openIssuesLabel: "مسائل باز",
currentSignalLabel: "سیگنال فعلی",
advanceLabel: "یک گام جلو بروید",
nextIterationLabel: "شروع تکرار بعدی",
resetLabel: "بازنشانی حلقه",
completeLabel: "هدف راستی‌آزمایی شد",
completeDescription: "معیارهای موفقیت برآورده شده‌اند، شواهد ثبت شده است و حلقه به‌جای صرف یک چرخهٔ دیگر متوقف می‌شود.",
stages: [
{ id: "frame", label: "چارچوب‌بندی", verb: "قرارداد را دوباره بخوانید" },
{ id: "act", label: "اقدام", verb: "یک حرکت محدود انجام دهید" },
{ id: "observe", label: "مشاهده", verb: "بازخورد بیرونی را بخوانید" },
{ id: "evaluate", label: "ارزیابی", verb: "روبریک را اعمال کنید" },
{ id: "adapt", label: "تطبیق", verb: "حرکت بعدی را به‌روز کنید" },
],
scenarios: [
{
id: "code",
label: "رفع یک باگ در فرایند پرداخت",
goal: "جمع مبالغ فرایند پرداخت را اصلاح کنید، بدون آنکه رفتار درست تخفیف‌ها تغییر کند.",
stopRule: "تست رگرسیون هدفمند پاس شود، کل مجموعه تست‌های فرایند پرداخت پاس شود و lint تمیز باشد—یا سه تلاش به پایان برسد و حلقه کار را به انسان ارجاع دهد.",
evidence: "گام‌های بازتولید خطا، خروجی تست‌ها، دیف کد و مجموعه تست رگرسیون نهایی.",
cycles: [
{
action: "جمع گزارش‌شده را بازتولید کنید و یک تست شکست‌خورده برای حالت مالیات به‌علاوهٔ تخفیف درصدی اضافه کنید.",
observation: "تست فقط زمانی یک سنت اختلاف نشان می‌دهد که مالیات پیش از اعمال تخفیف گرد شود.",
evaluation: "باگ با یک سیگنال قطعی بازتولید شده است، اما ریشهٔ آن هنوز رفع نشده.",
adaptation: "مرز گردکردن را بررسی کنید و فقط مسیر محاسبهٔ جمع کل سفارش را تغییر دهید.",
progress: 34,
openIssues: 2,
},
{
action: "گردکردن را به آخرین مرز پولی منتقل کنید و تست‌های هدفمند فرایند پرداخت را اجرا کنید.",
observation: "تست رگرسیون پاس می‌شود، اما حالا یک تست یکپارچگی کوپن روی تخفیف با مبلغ ثابت شکست می‌خورد.",
evaluation: "علامت اولیه رفع شده، اما تغییر بیش از حد گسترده است. قانون توقف هنوز برآورده نشده.",
adaptation: "وصله را محدودتر کنید و حالتی اضافه کنید که گردکردن مالیات را از گردکردن کوپن جدا می‌کند.",
progress: 71,
openIssues: 1,
},
{
action: "اصلاح محدودِ محاسبه را اعمال کنید، سپس تست رگرسیون، کل مجموعه تست فرایند پرداخت و lint را اجرا کنید.",
observation: "همهٔ بررسی‌ها پاس می‌شوند. دیف فقط یک تابع محاسبه و تست رگرسیون جدید را تغییر می‌دهد.",
evaluation: "هر معیار موفقیت شواهد مستقل خودش را دارد و از هیچ سقف بودجه‌ای عبور نشده است.",
adaptation: "متوقف شوید، خروجی تست‌ها را نگه دارید و دیف کوچک را به یک بازبین انسانی بسپارید.",
progress: 100,
openIssues: 0,
},
],
},
{
id: "research",
label: "راستی‌آزمایی یک ادعای پژوهشی",
goal: "این ادعا را بسنجید که دورکاری همیشه بهره‌وری تیم را افزایش می‌دهد.",
stopRule: "نتیجه‌گیری سنجیده‌ای به دست آمده باشد که دست‌کم سه منبع معتبر از آن پشتیبانی کنند و اختلاف‌نظرها و محدودیت‌ها بیان شده باشند.",
evidence: "پیوند مستقیم منابع، تاریخ انتشار، روش مطالعه، اندازهٔ نمونه و اعداد نقل‌شده.",
cycles: [
{
action: "شواهد تازه را جست‌وجو کنید و پرتکرارترین آمار بهره‌وری را تا منبع اصلی‌اش ردیابی کنید.",
observation: "بیشتر مقاله‌ها یک نظرسنجی شرکتی را تکرار می‌کنند، بدون آنکه به پرسشنامه یا نمونهٔ خام آن پیوند بدهند.",
evaluation: "این شواهد پرتکرارند، اما آن‌قدر قوی نیستند که ادعایی مطلق را پشتیبانی کنند.",
adaptation: "به مطالعات داوری‌شده و مجموعه‌داده‌های عمومی اولویت بدهید؛ در پی یافته‌های مخالف هم بگردید.",
progress: 28,
openIssues: 3,
},
{
action: "دو مطالعهٔ داوری‌شده را با یک مجموعه‌دادهٔ ملی نیروی کار مقایسه کنید.",
observation: "نتایج بسته به نوع کار، روش اندازه‌گیری و اینکه کار تمام‌دورکاری است یا ترکیبی، متفاوت است.",
evaluation: "شواهد با واژهٔ «همیشه» در تضادند. یک نتیجه‌گیری مشروط کم‌کم قابل دفاع می‌شود.",
adaptation: "بررسی کنید که آیا مطالعات میان خروجی، ساعات کار و بهره‌وریِ ادراک‌شده تمایز می‌گذارند یا نه.",
progress: 68,
openIssues: 1,
},
{
action: "یک جدول شواهد بسازید و هر ادعا را با منبع اصلی آن تطبیق دهید.",
observation: "منابع از اثرهای متفاوت حکایت دارند و خودمختاری، هماهنگی و نوع کار را متغیرهای کلیدی می‌دانند.",
evaluation: "نتیجه‌گیری پشتوانه دارد، عدم قطعیت شفاف است و حد نصاب منابع برآورده شده است.",
adaptation: "با پاسخی مشروط متوقف شوید و جدول شواهد را برای بازبینی نگه دارید.",
progress: 100,
openIssues: 0,
},
],
},
{
id: "writing",
label: "صیقل‌دادن یک ایمیل معرفی محصول",
goal: "یک ایمیل معرفی کوتاه بسازید که مزیت محصول را توضیح دهد و کلیک‌های دموی باکیفیت به دست آورد.",
stopRule: "ایمیل روبریک لحن را پاس کند، زیر ۱۴۰ کلمه بماند، یک فراخوان اقدام روشن داشته باشد و از بازبینی واقعیت‌ها سربلند بیرون بیاید.",
evidence: "شمار کلمات، امتیازهای روبریک، اعتبارسنجی پیوند، واقعیت‌های مستند محصول و یادداشت‌های بازبین.",
cycles: [
{
action: "بر اساس بریف محصول پیش‌نویسی بنویسید و نتیجه را با روبریک مخاطب و لحن نمره‌دهی کنید.",
observation: "پیش‌نویس ۲۰۴ کلمه است، با ویژگی‌ها شروع می‌شود و دو فراخوان اقدام رقیب دارد.",
evaluation: "واقعیت‌ها درست‌اند، اما معیارهای اولویت‌بندی و طول رد می‌شوند.",
adaptation: "با دستاورد مشتری شروع کنید، اقدام فرعی را حذف کنید و جزئیات پیاده‌سازی را حذف کنید.",
progress: 41,
openIssues: 3,
},
{
action: "شروع ایمیل را بازنویسی کنید و بدنه را به یک توالی مسئله-مزیت-شاهد فشرده کنید.",
observation: "ایمیل ۱۲۶ کلمه است و یک CTA دارد، اما جملهٔ شاهد، نتیجهٔ نسخهٔ بتا را بزرگ‌تر از واقعیت نشان می‌دهد.",
evaluation: "ساختار پاس می‌شود، اما دقت واقعیت‌ها هنوز در روبریک رد می‌شود.",
adaptation: "ادعای کلی را با نتیجهٔ اندازه‌گیری‌شدهٔ بتا جایگزین کنید و یک راستی‌آزمایی نهایی بخواهید.",
progress: 79,
openIssues: 1,
},
{
action: "عدد راستی‌آزمایی‌شده را جای‌گذاری کنید، پیوند را بیازمایید و یک بار دیگر کل روبریک را اجرا کنید.",
observation: "ایمیل ۱۳۲ کلمه است، پیوند باز می‌شود، واقعیت‌ها با بریف می‌خوانند و همهٔ بندهای روبریک پاس می‌شوند.",
evaluation: "خروجی با شواهد قابل بازبینی به سطح کیفی تعریف‌شده رسیده است.",
adaptation: "متوقف شوید و نسخهٔ تأییدشده را برای مسئول کمپین بفرستید.",
progress: 100,
openIssues: 0,
},
],
},
],
}} />
## اول قرارداد حلقه را بنویسید
پیش از انتخاب مدل یا فریم‌ورک، یک قرارداد کوچک بنویسید. اگر این فیلدها مبهم باشند، حلقه ابهام را به هزینهٔ تکرارشونده تبدیل می‌کند.
```yaml
goal: "چه وضعیت قابل مشاهده‌ای باید محقق شود؟"
inputs: "چه چیزی حلقه را آغاز می‌کند؟"
state: "چه واقعیت‌ها و تلاش‌هایی میان تکرارها باقی می‌مانند؟"
actions: "سیستم مجاز به استفاده از کدام ابزارها و با چه مجوزهایی است؟"
observations: "چه سیگنال‌های بیرونی از آن اقدام‌ها برمی‌گردد؟"
evaluator: "کدام روبریک یا بررسی‌های قطعی نتیجه را داوری می‌کنند؟"
success: "چه شواهدی ثابت می‌کند هدف کامل شده است؟"
failure: "کدام شرایط نیازمند بازیابی یا کمک انسانی است؟"
budget: "حداکثر نوبت‌ها، زمان، توکن، پول یا اثرهای جانبی"
```
<Callout type="warning" title="حلقهٔ بدون راه خروج خودش یک حالت شکست است">
همیشه سه راه خروج تعریف کنید: **موفقیت** وقتی شواهد هدف را برآورده می‌کنند، **شکست** وقتی بازیابی دیگر فایده‌ای ندارد، و **اتمام بودجه** وقتی حلقه به سقف هزینه یا مرز ریسک مجاز خود می‌رسد.
</Callout>
## مشاهده‌ها باید از دنیای واقعی بیایند
اینکه مدل بگوید «این درست به نظر می‌رسد» شاهد محکمی نیست. مشاهدهٔ مفید حاصل چیزی است بیرون از خودِ پاسخی که داوری می‌شود.
<table>
<thead>
<tr>
<th>کار</th>
<th>مشاهدهٔ ضعیف</th>
<th>مشاهدهٔ قوی</th>
</tr>
</thead>
<tbody>
<tr>
<td>تعمیر کد</td>
<td>«اصلاح باید کار کند.»</td>
<td>خطای اولیه بازتولید می‌شود، سپس تست رگرسیون و کل مجموعه تست‌ها پاس می‌شوند.</td>
</tr>
<tr>
<td>پژوهش</td>
<td>«چند منبع هم‌نظرند.»</td>
<td>ادعاها به منابع اصلی پیوند دارند و تاریخ‌ها، روش‌ها و اختلاف‌نظرها ثبت شده‌اند.</td>
</tr>
<tr>
<td>استخراج داده</td>
<td>«JSON معتبر به نظر می‌رسد.»</td>
<td>اعتبارسنجی اسکیما پاس می‌شود و رکوردهای نمونه‌گیری‌شده با منبع مطابقت دارند.</td>
</tr>
<tr>
<td>محتوا</td>
<td>«متن شفاف به نظر می‌رسد.»</td>
<td>یک روبریک مشخص، بازبینی واقعیت‌ها، بررسی پیوندها و آزمون مخاطب را پاس می‌کند.</td>
</tr>
<tr>
<td>عملیات</td>
<td>«درخواست موفق بود.»</td>
<td>سیستم بیرونی وضعیت مورد انتظار را برمی‌گرداند و یک رکورد ممیزی وجود دارد.</td>
</tr>
</tbody>
</table>
به همین دلیل ابزارها مهم‌اند: تست‌ها، مرورگرها، پایگاه‌های داده، اعتبارسنج‌ها و بازبینی انسانی، حدس درونی را به نتیجه‌ای قابل مشاهده تبدیل می‌کنند.
## سازنده را از بررسی‌کننده جدا کنید
برای کارهای کم‌ریسک، یک مدل می‌تواند هم پیش‌نویس بنویسد و هم خودش آن را بازبینی کند. برای کارهای مهم، از بررسی‌کننده‌ای با نقشی متفاوت و اختیاراتی محدود استفاده کنید.
<InfoGrid columns={2} items={[
{ label: "سازنده", description: "تغییر را پیشنهاد می‌دهد، ابزارهای اقدام را فراخوانی می‌کند و توضیح می‌دهد چه شواهدی باید گردآوری شود.", color: "amber" },
{ label: "بررسی‌کننده", description: "هدف، خروجی و شواهد را دریافت می‌کند؛ روبریک را اعمال می‌کند؛ و نمی‌تواند کاری را که نمره می‌دهد بی‌سروصدا بازنویسی کند.", color: "green" },
]} />
بررسی‌کننده لازم نیست حتماً یک هوش مصنوعی دیگر باشد. قطعی‌ترین ارزیابِ در دسترس را ترجیح بدهید:
1. **بررسی‌های دقیق** — تایپ‌ها، اسکیماها، محدودیت‌ها، مجوزها، هش‌ها
2. **بررسی‌های اجرایی** — تست‌ها، لینترها، شبیه‌سازی‌ها، اعتبارسنجی پیوندها
3. **بررسی‌های روبریک‌محور** — یک مدل مستقل یا یک انسان، با معیارهای مشخص و نام‌گذاری‌شده
4. **بررسی‌های نتیجه‌محور** — رفتار واقعی کاربران یا سنجه‌های محیط عملیاتی در گذر زمان
<Callout type="tip" title="اطمینان مدل شاهد نیست">
امتیاز اطمینانی که همان مدلِ سازندهٔ خروجی تولید کرده باشد، خودش باز هم یک خروجی مدل است. آن را نشانه‌ای برای مسیریابی بدانید، نه اثبات.
</Callout>
## وضعیت، ستون فقرات حلقه است
زمینه چیزی است که مدل **در این نوبت** می‌بیند. وضعیت (state) رکورد فشرده‌ای است که به نوبت بعدی اجازه می‌دهد بدون تکرار یا فراموش‌کردن کارهای قبلی ادامه دهد.
<Checklist title="وضعیت مفید برای حلقه" items={[
{ text: "هدف فعلی و معیارهای پذیرش" },
{ text: "اقدام‌های انجام‌شده و نتایج قابل مشاهدهٔ آن‌ها" },
{ text: "خروجی‌های تولیدشده، همراه با نسخه یا ارجاع پایدار" },
{ text: "رأی‌های ارزیاب و مسائل حل‌نشده" },
{ text: "بودجهٔ مصرف‌شده و مجوزهای هنوز در دسترس" },
{ text: "دلیل ادامه‌دادن، توقف یا ارجاع به انسان" },
]} />
تصمیم‌ها و شواهد فشرده را ذخیره کنید—نه زنجیرهٔ فکر خصوصی مدل را. وضعیت خوب کوچک است، قابل بازرسی است و ازسرگیری آن امن است.
## شکل‌های رایج حلقه
### حلقهٔ تعمیر
`بازتولید → تغییر فقط یک چیز → اجرای بررسی‌ها → عیب‌یابی → تکرار یا توقف`
بهترین گزینه برای کد، پیکربندی، پاک‌سازی داده و هر کاری که بازخورد اجرایی دارد.
### حلقهٔ ارزیاب-بهینه‌ساز
`تولید → نمره‌دهی با روبریک → بازخورد هدفمند → بازنویسی`
بهترین گزینه برای نوشتن، ترجمه، نقد طراحی و خروجی‌هایی که کیفیتشان با بازخورد صریح بهتر می‌شود.
### حلقهٔ پژوهش
`جست‌وجو → بررسی منابع → شناسایی شکاف‌ها یا تضادها → جست‌وجوی دوباره → جمع‌بندی`
بهترین گزینه وقتی از پیش معلوم نیست کار کی کامل می‌شود. قانون توقف باید پوشش شواهد را بسنجد، نه تعداد نتایج جست‌وجو را.
### حلقهٔ با تأیید انسانی
`آماده‌سازی → راستی‌آزمایی خودکار → توقف پیش از اقدام پرریسک → تأیید یا تغییر مسیر توسط انسان`
بهترین گزینه برای پرداخت‌ها، انتشار محتوا، حذف، تغییر دسترسی‌ها، تصمیم‌های پزشکی یا حقوقی و دیگر اقدام‌های پیامددار.
## حالت‌های شکستی که باید از طراحی حذف شوند
<table>
<thead>
<tr>
<th>شکست</th>
<th>چه اتفاقی افتاده</th>
<th>پاسخ مهندسی</th>
</tr>
</thead>
<tbody>
<tr>
<td>تلاش مجدد بی‌پایان</td>
<td>حلقه نه راه خروج موفقیتِ سنجش‌پذیری دارد و نه راه خروج بودجه.</td>
<td>حالت‌های پایانی صریح و یک سقف سفت‌وسخت برای تکرار اضافه کنید.</td>
</tr>
<tr>
<td>خودتحسینی</td>
<td>سازنده پاسخ به‌ظاهر قابل قبول خودش را بدون شواهد می‌پذیرد.</td>
<td>از بررسی‌های قطعی یا یک بررسی‌کنندهٔ مستقل استفاده کنید.</td>
</tr>
<tr>
<td>گلوله‌برفی‌شدن زمینه</td>
<td>هر تکرار همه‌چیز را الحاق می‌کند تا جایی که مدل سیگنال را گم می‌کند.</td>
<td>وضعیت ساخت‌یافته را نگه دارید و فقط زمینهٔ مرتبط را بازسازی کنید.</td>
</tr>
<tr>
<td>درجازدن</td>
<td>حلقه مدام میان دو اصلاح رفت‌وبرگشت می‌کند.</td>
<td>وضعیت‌های تکراری را تشخیص دهید و راهبردی متفاوت یا ارجاع به انسان را الزامی کنید.</td>
</tr>
<tr>
<td>انحراف از هدف</td>
<td>بهبودهای موضعی جای هدف اصلی را می‌گیرند.</td>
<td>در هر چرخه، هدف تغییرناپذیر و معیارهای پذیرش را دوباره بخوانید.</td>
</tr>
<tr>
<td>تکرار ناامن</td>
<td>یک اشتباه برگشت‌پذیر با تکرار زیان‌بار می‌شود.</td>
<td>مجوزها، اثرهای جانبی، نرخ، هزینه و دامنهٔ آسیب را محدود کنید.</td>
</tr>
</tbody>
</table>
## یک پیاده‌سازی حداقلی
```typescript
let state = initialize(goal, acceptanceCriteria, budget);
while (state.budget.remaining > 0) {
const context = assembleRelevantContext(state);
const proposedAction = await maker.chooseAction(context);
const observation = await tools.executeWithinPolicy(proposedAction);
const verdict = await evaluator.check({ goal, observation, state });
state = recordIteration(state, { proposedAction, observation, verdict });
if (verdict.status === "passed") return complete(state);
if (verdict.status === "unsafe" || verdict.status === "blocked") {
return escalateToHuman(state);
}
state = adaptPlan(state, verdict.feedback);
}
return stopWithBudgetReport(state);
```
کد بخش آسان ماجراست. پرسش‌های سخت، پرسش‌های حوزه‌ای‌اند: کدام تست ثابت می‌کند باگ از بین رفته است؟ کدام منبع معتبر است؟ کدام اقدام برگشت‌پذیر است؟ چه کسی می‌تواند گام نهایی را تأیید کند؟ همین تصمیم‌ها کار واقعی مهندسی حلقه‌اند.
## تمرین: یک حلقه طراحی کنید
<TryIt
title="پیش‌نویس یک قرارداد حلقه"
description="متغیرها را با یک کار تکرارشونده از کار واقعی خودتان جایگزین کنید. از هوش مصنوعی بخواهید شواهد ضعیف و قوانین توقف مبهم را به چالش بکشد."
prompt={`برای این کار یک حلقهٔ کاری محدود مبتنی بر هوش مصنوعی طراحی کن:
کار: \${task:هر روز صبح درخواست‌های جدید پشتیبانی مشتریان را اولویت‌بندی کن}
این موارد را تعریف کن:
1. هدف قابل مشاهده
2. محرک شروع و ورودی‌های لازم
3. اقدام‌های مجاز و مجوزهای ابزارها
4. مشاهده‌های قابل اعتماد از محیط بیرونی
5. ارزیاب و روبریک آن
6. وضعیتی که میان تکرارها باقی می‌ماند
7. راه‌های خروج موفقیت، شکست و اتمام بودجه
8. نقاط تأیید انسانی برای اقدام‌های پرریسک
9. قالب ردگیری‌ای که هر تکرار را قابل ممیزی کند
سپس محتمل‌ترین سه حالت شکست را در طراحی خودت شناسایی کن و حلقه را برای پیشگیری از آن‌ها بازنگری کن.`}
/>
<Quiz
question="یک عامل کدی را ویرایش می‌کند، دیف را دوباره می‌خواند و می‌گوید باگ رفع شده است. مهم‌ترین بخش گم‌شدهٔ این حلقه چیست؟"
options={[
"یک پرامپت سیستم طولانی‌تر",
"یک مشاهدهٔ بیرونی که با قانون توقف سنجیده شود",
"یک دور ویرایش دیگر",
"یک پنجرهٔ زمینهٔ بزرگ‌تر"
]}
correctIndex={1}
explanation="عامل خروجی‌ای تولید و بازبینی کرده است، اما هیچ شاهد مستقلی گردآوری نکرده. بازتولید خطا و اجرای تست‌های مرتبط، سیگنالی قابل مشاهده می‌سازد که قانون توقف بتواند آن را ارزیابی کند."
/>
## مطالعهٔ بیشتر
- [Loop Engineering — Addy Osmani](https://addyosmani.com/blog/loop-engineering/) — صورت‌بندی تازهٔ جایگزین‌کردن پرامپت‌های پیگیری دستی با یک سیستم طراحی‌شده، همراه با هشدارهای عملی دربارهٔ راستی‌آزمایی و مسئولیت انسانی
- [Building Effective Agents — Anthropic](https://www.anthropic.com/engineering/building-effective-agents) — گردش‌کارهای ارزیاب-بهینه‌ساز، بازخورد محیطی، شرایط توقف و راهنمایی دربارهٔ اینکه پیچیدگی عامل‌محور کِی توجیه دارد
- [A Practical Guide to Building Agents — OpenAI](https://openai.com/business/guides-and-resources/a-practical-guide-to-building-ai-agents/) — اجرای عامل‌ها، شرایط خروج، ابزارها، حفاظ‌ها و مداخلهٔ انسانی
- [ReAct: Synergizing Reasoning and Acting in Language Models](https://arxiv.org/abs/2210.03629) — پژوهش بنیادین دربارهٔ درهم‌بافتن اقدام‌ها با مشاهده‌هایی از یک محیط بیرونی
## خلاصه
<Callout type="tip" title="بازخورد را بسازید، نه فقط پرامپت را">
یک حلقهٔ قابل اعتماد هدفی سنجش‌پذیر، اقدام‌هایی محدود، مشاهده‌هایی قابل اعتماد، ارزیابی صریح، وضعیتی فشرده، راه‌های خروج امن و—هر جا پیامدها ایجاب کنند—قضاوت انسانی دارد. مدل درون حلقه است؛ مسئولیت حلقه همچنان با مهندس است.
</Callout>
@@ -1,405 +0,0 @@
L'ingénierie du contexte détermine **ce que le modèle peut voir**. L'ingénierie de boucle détermine **ce que le système fait ensuite**.
Plutôt qu'une personne qui relit chaque réponse et rédige le prompt suivant, une boucle transforme ce travail de suivi en un système conçu à dessein. Elle donne un objectif à une IA, la laisse agir, observe des retours réels, évalue le résultat, puis s'adapte ou s'arrête.
<Callout type="info" title="La Définition en Bref">
L'ingénierie de boucle est l'art de concevoir le cycle de rétroaction autour d'un système d'IA : l'objectif, les actions, les observations, l'évaluation, l'état, les garde-fous et les règles d'arrêt qui font avancer le travail vers un résultat vérifiable.
</Callout>
## D'un Bon Prompt à une Bonne Boucle
Un prompt peut produire une excellente première tentative. Une boucle devient utile quand le nombre d'étapes ne peut pas être connu à l'avance, quand l'environnement peut changer, ou quand la première tentative doit être confrontée à des preuves.
<Compare
before={{
label: "Prompt Unique",
content: "Demander → Générer → Rendre\n\nLe modèle produit une réponse. Une personne juge si cela a fonctionné et rédige le prompt suivant."
}}
after={{
label: "Boucle Conçue",
content: "Cadrer → Agir → Observer → Évaluer → Adapter\n ↑______________________↓\n\nLe système rassemble des preuves, enregistre l'état et ne continue que tant qu'un passage supplémentaire est utile."
}}
/>
Cette idée s'appuie sur des patterns d'agents plus anciens. L'[article ReAct](https://arxiv.org/abs/2210.03629) a montré l'intérêt d'entrelacer les actions avec des observations venues d'un environnement externe. Le [pattern évaluateur-optimiseur](https://www.anthropic.com/engineering/building-effective-agents) d'Anthropic ajoute une étape de rétroaction distincte, tandis que le [guide pratique des agents](https://openai.com/business/guides-and-resources/a-practical-guide-to-building-ai-agents/) d'OpenAI décrit l'exécution d'un agent comme une boucle régie par des conditions de sortie. Le terme plus récent d'**ingénierie de boucle** attire l'attention sur la conception délibérée de l'ensemble de ce cycle.
## Les Cinq Mouvements
<InfoGrid items={[
{ label: "1. Cadrer", description: "Traduisez l'intention en objectif, contraintes, critères de réussite et budget.", color: "blue" },
{ label: "2. Agir", description: "Choisissez une action délimitée : chercher, modifier, calculer, appeler un outil ou solliciter une personne.", color: "amber" },
{ label: "3. Observer", description: "Recueillez ce qui s'est réellement passé : sortie des tests, résultats d'API, citations ou retours des utilisateurs.", color: "cyan" },
{ label: "4. Évaluer", description: "Confrontez les preuves à des critères explicites — pas à la confiance du modèle.", color: "purple" },
{ label: "5. Adapter", description: "Mettez à jour l'état, changez de plan, réessayez sans risque, passez la main à un humain ou arrêtez.", color: "green" },
]} />
La boucle, ce ne sont pas les flèches. L'ingénierie se loge dans les **contrats entre les flèches** : ce qui compte comme une action, quelles observations sont dignes de confiance, qui les évalue, quel état survit, et à quel moment précis l'exécution s'arrête.
<LoopEngineeringLab content={{
eyebrow: "Contrôle de boucle / simulateur interactif",
title: "Parcourez une boucle de rétroaction en fonctionnement",
description: "Choisissez une tâche, puis avancez signal par signal. Observez comment la progression vient des preuves fournies par l'environnement et d'une évaluation explicite — pas du fait de demander au modèle s'il a l'impression d'avoir terminé.",
chooseScenarioLabel: "Choisissez une boucle",
goalLabel: "Objectif",
stopRuleLabel: "Règle d'arrêt",
evidenceLabel: "Preuves fiables",
iterationLabel: "Itération",
progressLabel: "Progression vérifiée",
openIssuesLabel: "Problèmes ouverts",
currentSignalLabel: "Signal actuel",
advanceLabel: "Avancer d'une étape",
nextIterationLabel: "Commencer l'itération suivante",
resetLabel: "Réinitialiser la boucle",
completeLabel: "Objectif vérifié",
completeDescription: "Les critères de réussite sont satisfaits, les preuves sont consignées, et la boucle s'arrête au lieu de dépenser un cycle de plus.",
stages: [
{ id: "frame", label: "Cadrer", verb: "Relire le contrat" },
{ id: "act", label: "Agir", verb: "Effectuer une action délimitée" },
{ id: "observe", label: "Observer", verb: "Lire le retour externe" },
{ id: "evaluate", label: "Évaluer", verb: "Appliquer la grille d'évaluation" },
{ id: "adapt", label: "Adapter", verb: "Ajuster la prochaine action" },
],
scenarios: [
{
id: "code",
label: "Réparer un bug de paiement",
goal: "Corriger les totaux au moment du paiement sans altérer le comportement des remises valides.",
stopRule: "Le test de régression ciblé passe, la suite complète du paiement passe et le lint est propre — ou les trois tentatives sont épuisées et la boucle passe la main à un humain.",
evidence: "Les étapes de reproduction, la sortie des tests, le diff du code et la suite de régression finale.",
cycles: [
{
action: "Reproduire le total signalé et ajouter un test en échec pour le cas taxe plus remise en pourcentage.",
observation: "Le test échoue d'un centime, uniquement quand la taxe est arrondie avant l'application de la remise.",
evaluation: "Le bug est reproduit avec un signal déterministe, mais sa cause n'est pas encore corrigée.",
adaptation: "Inspecter la frontière d'arrondi et ne modifier que le chemin de calcul du total de la commande.",
progress: 34,
openIssues: 2,
},
{
action: "Déplacer l'arrondi à la frontière monétaire finale et lancer les tests ciblés du paiement.",
observation: "La régression passe, mais un test d'intégration des coupons échoue désormais sur une remise à montant fixe.",
evaluation: "Le premier symptôme est corrigé, mais la modification est trop large. La règle d'arrêt n'est pas satisfaite.",
adaptation: "Restreindre le correctif et ajouter un cas qui sépare l'arrondi de la taxe de l'arrondi du coupon.",
progress: 71,
openIssues: 1,
},
{
action: "Appliquer le correctif de calcul restreint, puis lancer la régression, la suite complète du paiement et le lint.",
observation: "Tous les contrôles passent. Le diff ne touche qu'une fonction de calcul et le nouveau test de régression.",
evaluation: "Chaque critère de réussite dispose d'une preuve indépendante et aucune limite de budget n'a été dépassée.",
adaptation: "S'arrêter, conserver la sortie des tests et remettre ce petit diff à un relecteur humain.",
progress: 100,
openIssues: 0,
},
],
},
{
id: "research",
label: "Vérifier une affirmation de recherche",
goal: "Évaluer l'affirmation selon laquelle le télétravail augmente toujours la productivité des équipes.",
stopRule: "Une conclusion calibrée est étayée par au moins trois sources crédibles, désaccords et limites explicités.",
evidence: "Liens directs vers les sources, dates de publication, méthodes d'étude, tailles d'échantillon et chiffres cités.",
cycles: [
{
action: "Chercher des preuves récentes et remonter la statistique de productivité la plus citée jusqu'à sa source.",
observation: "La plupart des articles reprennent l'enquête d'un éditeur sans lien vers son questionnaire ni vers l'échantillon brut.",
evaluation: "La preuve est populaire, mais pas assez solide pour soutenir une affirmation absolue.",
adaptation: "Donner la priorité aux études évaluées par les pairs et aux jeux de données publics ; chercher aussi des résultats contraires.",
progress: 28,
openIssues: 3,
},
{
action: "Comparer deux études évaluées par les pairs avec un jeu de données national sur l'emploi.",
observation: "Les résultats varient selon le type de tâche, la méthode de mesure et le caractère entièrement à distance ou hybride du travail.",
evaluation: "Les preuves contredisent le mot « toujours ». Une conclusion conditionnelle devient défendable.",
adaptation: "Vérifier si les études distinguent la production, les heures travaillées et la productivité perçue.",
progress: 68,
openIssues: 1,
},
{
action: "Construire un tableau de preuves et vérifier chaque affirmation auprès de la source originale.",
observation: "Les sources indiquent des effets contrastés et identifient l'autonomie, la coordination et le type de tâche comme variables clés.",
evaluation: "La conclusion est étayée, l'incertitude est visible et le seuil de sources est atteint.",
adaptation: "S'arrêter sur une réponse nuancée et conserver le tableau de preuves pour relecture.",
progress: 100,
openIssues: 0,
},
],
},
{
id: "writing",
label: "Peaufiner un e-mail de lancement",
goal: "Produire un e-mail de lancement concis qui explique le bénéfice et génère des clics de démo qualifiés.",
stopRule: "L'e-mail satisfait la grille de ton, reste sous 140 mots, contient un seul appel à l'action clair et résiste à une relecture factuelle.",
evidence: "Le nombre de mots, les scores de la grille, la validation des liens, les faits produit d'origine et les notes des relecteurs.",
cycles: [
{
action: "Rédiger un premier jet à partir du brief produit et le noter avec la grille d'audience et de ton.",
observation: "Le brouillon fait 204 mots, s'ouvre sur les fonctionnalités et contient deux appels à l'action concurrents.",
evaluation: "Les faits sont exacts, mais les critères de hiérarchie et de longueur échouent.",
adaptation: "Ouvrir sur le bénéfice client, supprimer l'action secondaire et couper les détails d'implémentation.",
progress: 41,
openIssues: 3,
},
{
action: "Réécrire l'ouverture et condenser le corps en une seule séquence problème-bénéfice-preuve.",
observation: "L'e-mail fait 126 mots avec un seul CTA, mais la phrase de preuve exagère un résultat de la bêta.",
evaluation: "La structure passe. La calibration factuelle ne satisfait toujours pas la grille.",
adaptation: "Remplacer l'affirmation générale par le résultat mesuré de la bêta et demander une dernière vérification des faits.",
progress: 79,
openIssues: 1,
},
{
action: "Insérer la métrique vérifiée, valider le lien et repasser la grille complète une dernière fois.",
observation: "L'e-mail fait 132 mots, le lien fonctionne, les faits correspondent au brief et chaque critère de la grille passe.",
evaluation: "L'artefact atteint le niveau de qualité défini, preuves consultables à l'appui.",
adaptation: "S'arrêter et envoyer la version approuvée au responsable de la campagne.",
progress: 100,
openIssues: 0,
},
],
},
],
}} />
## Rédigez d'abord le Contrat de Boucle
Avant de choisir un modèle ou un framework, rédigez un petit contrat. Si ces champs restent vagues, la boucle transformera l'ambiguïté en coûts répétés.
```yaml
goal: "Quel état observable doit devenir vrai ?"
inputs: "Qu'est-ce qui déclenche la boucle ?"
state: "Quels faits et quelles tentatives persistent d'une itération à l'autre ?"
actions: "Quels outils le système peut-il utiliser, et avec quelles permissions ?"
observations: "Quels signaux externes reviennent de ces actions ?"
evaluator: "Quelle grille d'évaluation ou quels contrôles déterministes jugent le résultat ?"
success: "Quelles preuves démontrent que l'objectif est atteint ?"
failure: "Quelles conditions exigent une récupération ou l'aide d'un humain ?"
budget: "Maximum de tours, de temps, de tokens, d'argent ou d'effets de bord"
```
<Callout type="warning" title="Une Boucle Sans Sortie Est un Mode de Défaillance">
Définissez toujours trois sorties : le **succès** quand les preuves satisfont l'objectif, l'**échec** quand la récupération n'est plus utile, et le **budget épuisé** quand la boucle atteint sa limite de coût ou de risque.
</Callout>
## Les Observations Doivent Venir du Monde Réel
Le modèle qui déclare « cela semble correct » n'est pas une preuve solide. Une observation utile est produite par quelque chose d'extérieur à la réponse que l'on juge.
<table>
<thead>
<tr>
<th>Tâche</th>
<th>Observation faible</th>
<th>Observation forte</th>
</tr>
</thead>
<tbody>
<tr>
<td>Réparation de code</td>
<td>« Le correctif devrait fonctionner. »</td>
<td>L'échec d'origine est reproduit, puis le test de régression et la suite complète passent.</td>
</tr>
<tr>
<td>Recherche</td>
<td>« Plusieurs sources sont d'accord. »</td>
<td>Les affirmations pointent vers les sources originales, avec dates, méthodes et désaccords consignés.</td>
</tr>
<tr>
<td>Extraction de données</td>
<td>« Le JSON semble valide. »</td>
<td>La validation du schéma passe et les enregistrements échantillonnés correspondent à la source.</td>
</tr>
<tr>
<td>Contenu</td>
<td>« Le texte paraît clair. »</td>
<td>Il passe une grille d'évaluation nommée, une relecture factuelle, une vérification des liens et un test auprès de l'audience.</td>
</tr>
<tr>
<td>Opérations</td>
<td>« La requête a réussi. »</td>
<td>Le système externe renvoie l'état attendu et une trace d'audit existe.</td>
</tr>
</tbody>
</table>
Voilà pourquoi les outils comptent : tests, navigateurs, bases de données, validateurs et relecture humaine transforment une supposition interne en résultat observable.
## Séparez le Producteur du Vérificateur
Pour les travaux à faible enjeu, un même modèle peut rédiger et se relire. Pour les travaux importants, utilisez un vérificateur doté d'un rôle différent et d'une autorité limitée.
<InfoGrid columns={2} items={[
{ label: "Producteur", description: "Propose la modification, appelle les outils d'action et explique quelles preuves doivent être collectées.", color: "amber" },
{ label: "Vérificateur", description: "Reçoit l'objectif, l'artefact et les preuves ; applique la grille d'évaluation ; ne peut pas réécrire en douce le travail qu'il note.", color: "green" },
]} />
Le vérificateur n'est pas forcément une autre IA. Préférez l'évaluateur le plus déterministe disponible :
1. **Contrôles exacts** — types, schémas, contraintes, permissions, hachages
2. **Contrôles exécutables** — tests, linters, simulations, validation des liens
3. **Contrôles par grille** — un modèle indépendant ou un humain appliquant des critères nommés
4. **Contrôles par résultats** — comportement réel des utilisateurs ou métriques de production dans la durée
<Callout type="tip" title="La Confiance N'est Pas une Preuve">
Un score de confiance généré par le modèle qui a produit l'artefact reste une sortie du modèle. Traitez-le comme un indice d'aiguillage, pas comme une preuve.
</Callout>
## L'État Est la Colonne Vertébrale de la Boucle
Le contexte, c'est ce que le modèle voit **à ce tour-ci**. L'état, c'est l'enregistrement compact qui permet au tour suivant de continuer sans répéter ni oublier le travail accompli.
<Checklist title="Un État de Boucle Utile" items={[
{ text: "L'objectif courant et les critères d'acceptation" },
{ text: "Les actions déjà tentées et leurs résultats observables" },
{ text: "Les artefacts produits, avec leurs versions ou des références stables" },
{ text: "Les verdicts de l'évaluateur et les problèmes non résolus" },
{ text: "Le budget consommé et les permissions encore disponibles" },
{ text: "La raison de continuer, de s'arrêter ou de passer la main" },
]} />
Stockez des décisions et des preuves concises — pas la chaîne de pensée privée d'un modèle. Un bon état est petit, inspectable et peut être repris sans risque.
## Les Formes de Boucle Courantes
### La Boucle de Réparation
`reproduire → changer une seule chose → lancer les contrôles → diagnostiquer → répéter ou s'arrêter`
Idéale pour le code, la configuration, le nettoyage de données et toute tâche disposant d'un retour exécutable.
### La Boucle Évaluateur-Optimiseur
`générer → noter avec une grille → renvoyer un retour ciblé → réviser`
Idéale pour l'écriture, la traduction, la critique de design et les productions dont la qualité progresse grâce à un retour argumenté.
### La Boucle de Recherche
`chercher → inspecter les sources → repérer les lacunes ou les contradictions → chercher encore → synthétiser`
Idéale quand l'exhaustivité n'est pas connue d'avance. La règle d'arrêt doit mesurer la couverture des preuves, pas le nombre de résultats de recherche.
### La Boucle à Validation Humaine
`préparer → vérifier automatiquement → marquer une pause avant l'action à haut risque → un humain approuve ou réoriente`
Idéale pour les paiements, la publication, la suppression, les changements d'accès, les décisions médicales ou juridiques et les autres actions lourdes de conséquences.
## Les Modes de Défaillance à Éliminer par Conception
<table>
<thead>
<tr>
<th>Défaillance</th>
<th>Ce qui s'est passé</th>
<th>Réponse d'ingénierie</th>
</tr>
</thead>
<tbody>
<tr>
<td>Réessais infinis</td>
<td>La boucle n'a ni succès mesurable ni sortie de budget.</td>
<td>Ajoutez des états terminaux explicites et un plafond strict d'itérations.</td>
</tr>
<tr>
<td>Autosatisfaction</td>
<td>Le producteur accepte sa propre réponse plausible sans preuve.</td>
<td>Utilisez des contrôles déterministes ou un vérificateur indépendant.</td>
</tr>
<tr>
<td>Boule de neige de contexte</td>
<td>Chaque itération accumule tout jusqu'à ce que le modèle perde le signal.</td>
<td>Persistez un état structuré et ne reconstruisez que le contexte pertinent.</td>
</tr>
<tr>
<td>Oscillation</td>
<td>La boucle alterne sans fin entre deux correctifs.</td>
<td>Détectez les états répétés et exigez une stratégie différente ou une remontée à un humain.</td>
</tr>
<tr>
<td>Dérive de l'objectif</td>
<td>Des améliorations locales remplacent l'objectif initial.</td>
<td>Relisez à chaque cycle l'objectif immuable et les critères d'acceptation.</td>
</tr>
<tr>
<td>Répétition dangereuse</td>
<td>Une erreur réversible devient nuisible une fois répétée.</td>
<td>Limitez les permissions, les effets de bord, la cadence, les dépenses et le rayon d'impact.</td>
</tr>
</tbody>
</table>
## Une Implémentation Minimale
```typescript
let state = initialize(goal, acceptanceCriteria, budget);
while (state.budget.remaining > 0) {
const context = assembleRelevantContext(state);
const proposedAction = await maker.chooseAction(context);
const observation = await tools.executeWithinPolicy(proposedAction);
const verdict = await evaluator.check({ goal, observation, state });
state = recordIteration(state, { proposedAction, observation, verdict });
if (verdict.status === "passed") return complete(state);
if (verdict.status === "unsafe" || verdict.status === "blocked") {
return escalateToHuman(state);
}
state = adaptPlan(state, verdict.feedback);
}
return stopWithBudgetReport(state);
```
Le code est la partie facile. Les questions difficiles sont des questions de domaine : quel test prouve que le bug a disparu ? Quelle source fait autorité ? Quelle action est réversible ? Qui peut approuver l'étape finale ? Ces décisions constituent le véritable travail de l'ingénierie de boucle.
## Exercice : Concevez une Boucle
<TryIt
title="Rédigez un Contrat de Boucle"
description="Remplacez les variables par une tâche récurrente de votre propre travail. Demandez à l'IA de contester les preuves faibles et les règles d'arrêt ambiguës."
prompt={`Conçois une boucle de travail IA bornée pour cette tâche :
TÂCHE : \${task:trier les nouveaux tickets du support client chaque matin}
Définis :
1. L'objectif observable
2. Le déclencheur et les entrées requises
3. Les actions autorisées et les permissions des outils
4. Les observations fiables issues de l'environnement externe
5. L'évaluateur et sa grille d'évaluation
6. L'état qui persiste entre les itérations
7. Les sorties succès, échec et budget épuisé
8. Les points de validation humaine pour les actions risquées
9. Un format de trace qui rend chaque itération auditable
Identifie ensuite les trois modes de défaillance les plus probables de ta conception, puis révise la boucle pour les prévenir.`}
/>
<Quiz
question="Un agent modifie du code, relit le diff et déclare que le bug est corrigé. Quel est l'élément manquant le plus important de la boucle ?"
options={[
"Un prompt système plus long",
"Une observation externe évaluée au regard d'une règle d'arrêt",
"Une deuxième passe d'édition",
"Une fenêtre de contexte plus grande"
]}
correctIndex={1}
explanation="L'agent a produit et inspecté un artefact, mais il n'a rassemblé aucune preuve indépendante. Reproduire l'échec et lancer les tests pertinents créerait un signal observable qu'une règle d'arrêt peut évaluer."
/>
## Lectures Complémentaires
- [Loop Engineering — Addy Osmani](https://addyosmani.com/blog/loop-engineering/) — le cadrage récent qui remplace les prompts de suivi manuels par un système conçu à dessein, avec des mises en garde pratiques sur la vérification et la responsabilité humaine
- [Building Effective Agents — Anthropic](https://www.anthropic.com/engineering/building-effective-agents) — les flux évaluateur-optimiseur, le retour de l'environnement, les conditions d'arrêt et des repères pour savoir quand la complexité agentique se justifie
- [A Practical Guide to Building Agents — OpenAI](https://openai.com/business/guides-and-resources/a-practical-guide-to-building-ai-agents/) — les exécutions d'agents, les conditions de sortie, les outils, les garde-fous et l'intervention humaine
- [ReAct: Synergizing Reasoning and Acting in Language Models](https://arxiv.org/abs/2210.03629) — la recherche fondatrice sur l'entrelacement des actions et des observations d'un environnement externe
## Résumé
<Callout type="tip" title="Construisez la Rétroaction, Pas Seulement le Prompt">
Une boucle fiable a un objectif mesurable, des actions délimitées, des observations fiables, un évaluateur explicite, un état compact, des sorties sûres et un jugement humain là où les conséquences l'exigent. Le modèle est dans la boucle ; l'ingénieur reste responsable de la boucle.
</Callout>
@@ -1,405 +0,0 @@
הנדסת הקשר מחליטה **מה המודל יכול לראות**. הנדסת לולאות מחליטה **מה המערכת עושה הלאה**.
במקום שאדם יקרא שוב ושוב תשובה ויכתוב את הפרומפט הבא, לולאה הופכת את עבודת ההמשך למערכת מתוכננת. היא נותנת ל-AI מטרה, מאפשרת לו לפעול, צופה במשוב אמיתי, מעריכה את התוצאה, ואז מסתגלת או עוצרת.
<Callout type="info" title="ההגדרה הקצרה">
הנדסת לולאות היא הפרקטיקה של תכנון מחזור המשוב סביב מערכת בינה מלאכותית: המטרה, הפעולות, התצפיות, ההערכה, המצב, מעקות הבטיחות וכללי העצירה שמניעים את העבודה לעבר תוצאה הניתנת לאימות.
</Callout>
## מפרומפט טוב ללולאה טובה
פרומפט יכול לייצר ניסיון ראשון חזק. לולאה שימושית כאשר לא ניתן לדעת מראש את מספר השלבים, הסביבה יכולה להשתנות, או שיש לבדוק את הניסיון הראשון מול ראיות.
<Compare
before={{
label: "פרומפט חד-פעמי",
content: "שאל ← צור ← החזר\n\nהמודל מייצר תשובה. אדם מחליט אם זה עבד וכותב את הפרומפט הבא."
}}
after={{
label: "לולאה מהונדסת",
content: "מסגור ← פעולה ← תצפית ← הערכה ← הסתגלות\n ↑________________________________↓\n\nהמערכת אוספת ראיות, מתעדת מצב וממשיכה רק כאשר מעבר נוסף מועיל."
}}
/>
רעיון זה מתבסס על דפוסי סוכנים קודמים. [מאמר ReAct](https://arxiv.org/abs/2210.03629) הראה את הערך של שזירת פעולות עם תצפיות מסביבה חיצונית. [דפוס ה-evaluator-optimizer](https://www.anthropic.com/engineering/building-effective-agents) של Anthropic מוסיף שלב משוב מובהק, בעוד שה[מדריך המעשי לסוכנים](https://openai.com/business/guides-and-resources/a-practical-guide-to-building-ai-agents/) של OpenAI מתאר ריצות סוכנים כלולאות הנשלטות על ידי תנאי יציאה. המונח החדש יותר **הנדסת לולאות** ממקד את תשומת הלב בתכנון מכוון של כל המחזור הזה.
## חמשת המהלכים
<InfoGrid items={[
{ label: "1. מסגור", description: "הפוך כוונה למטרה, אילוצים, קריטריונים להצלחה ותקציב.", color: "blue" },
{ label: "2. פעולה", description: "בחר פעולה מוגבלת אחת: חפש, ערוך, חשב, קרא לכלי או שאל אדם.", color: "amber" },
{ label: "3. תצפית", description: "אסוף את מה שקרה בפועל: פלט בדיקות, תוצאות API, ציטוטים או משוב משתמשים.", color: "cyan" },
{ label: "4. הערכה", description: "השווה את הראיות עם קריטריונים מפורשים - לא עם הביטחון של המודל.", color: "purple" },
{ label: "5. הסתגלות", description: "עדכן מצב, שנה את התוכנית, נסה שוב בבטחה, הסלם או עצור.", color: "green" },
]} />
הלולאה היא לא החצים. ההנדסה חיה ב**חוזים שבין החצים**: מה נחשב כפעולה, אילו תצפיות אמינות, מי מעריך אותן, איזה מצב שורד ומתי בדיוק מסתיים הביצוע.
<LoopEngineeringLab content={{
eyebrow: "בקרת לולאה / סימולטור אינטראקטיבי",
title: "צעדו דרך לולאת משוב עובדת",
description: "בחרו משימה, ואז התקדמו אות אחד בכל פעם. שימו לב כיצד ההתקדמות מגיעה מראיות סביבתיות ומהערכה מפורשת - לא משאלת המודל אם הוא מרגיש שסיים.",
chooseScenarioLabel: "בחרו לולאה",
goalLabel: "מטרה",
stopRuleLabel: "כלל עצירה",
evidenceLabel: "ראיות מהימנות",
iterationLabel: "איטרציה",
progressLabel: "התקדמות מאומתת",
openIssuesLabel: "נושאים פתוחים",
currentSignalLabel: "אות נוכחי",
advanceLabel: "התקדמו צעד אחד",
nextIterationLabel: "התחילו את האיטרציה הבאה",
resetLabel: "אפסו את הלולאה",
completeLabel: "המטרה מאומתת",
completeDescription: "קריטריוני ההצלחה מתקיימים, הראיות מתועדות והלולאה נעצרת במקום לבזבז עוד מחזור.",
stages: [
{ id: "frame", label: "מסגור", verb: "קרא שוב את החוזה" },
{ id: "act", label: "פעולה", verb: "בצע מהלך מוגבל אחד" },
{ id: "observe", label: "תצפית", verb: "קרא משוב חיצוני" },
{ id: "evaluate", label: "הערכה", verb: "החל את הרובריקה" },
{ id: "adapt", label: "הסתגלות", verb: "עדכן את המהלך הבא" },
],
scenarios: [
{
id: "code",
label: "תקן באג בקופה",
goal: "תקן את הסכומים בקופה מבלי לשנות התנהגות הנחות תקינה.",
stopRule: "בדיקת הרגרסיה הממוקדת עוברת, חבילת בדיקות הקופה המלאה עוברת וה-lint נקי - או ששלושה ניסיונות מוצו והלולאה מסלימה.",
evidence: "שלבי שחזור, פלט בדיקות, ה-diff של הקוד וחבילת הרגרסיה הסופית.",
cycles: [
{
action: "שחזר את הסכום המדווח והוסף בדיקה נכשלת עבור מס בתוספת הנחה באחוזים.",
observation: "הבדיקה נכשלת בסנט אחד רק כאשר המס מעוגל לפני החלת ההנחה.",
evaluation: "הבאג משוחזר עם אות דטרמיניסטי, אך המקור שלו עדיין לא תוקן.",
adaptation: "בדוק את גבול העיגול ושנה רק את נתיב החישוב של סכום ההזמנה הכולל.",
progress: 34,
openIssues: 2,
},
{
action: "העבר את העיגול לגבול הכספי הסופי והרץ בדיקות קופה ממוקדות.",
observation: "הרגרסיה עוברת, אבל בדיקת אינטגרציה אחת של קופונים נכשלת כעת על הנחה בסכום קבוע.",
evaluation: "התסמין הראשון תוקן, אבל השינוי רחב מדי. כלל העצירה אינו מתקיים.",
adaptation: "צמצם את התיקון והוסף מקרה בדיקה שמפריד בין עיגול מס לעיגול קופון.",
progress: 71,
openIssues: 1,
},
{
action: "החל את תיקון החישוב הצר, ואז הרץ את הרגרסיה, את חבילת בדיקות הקופה המלאה ואת ה-lint.",
observation: "כל הבדיקות עוברות. ה-diff נוגע בפונקציית חישוב אחת ובבדיקת הרגרסיה החדשה.",
evaluation: "לכל קריטריון הצלחה יש ראיה עצמאית, ואף מגבלת תקציב לא נחרגה.",
adaptation: "עצור, שמור את פלט הבדיקות והעבר את ה-diff הקטן למבקר אנושי.",
progress: 100,
openIssues: 0,
},
],
},
{
id: "research",
label: "אמת טענה מחקרית",
goal: "הערך את הטענה שעבודה מרחוק תמיד מגבירה את הפרודוקטיביות של הצוות.",
stopRule: "מסקנה מכוילת נתמכת בלפחות שלושה מקורות אמינים, תוך ציון אי-הסכמות ומגבלות.",
evidence: "קישורי מקור ישירים, תאריכי פרסום, שיטות מחקר, גדלי מדגם ומדדים מצוטטים.",
cycles: [
{
action: "חפש ראיות עדכניות ועקוב אחר נתון הפרודוקטיביות החוזר ביותר עד למקורו.",
observation: "רוב המאמרים חוזרים על סקר של ספק מבלי לקשר לשאלון או למדגם הגולמי שלו.",
evaluation: "הראיות פופולריות אך אינן חזקות מספיק כדי לתמוך בטענה מוחלטת.",
adaptation: "תעדף מחקרים שעברו ביקורת עמיתים ומערכי נתונים ציבוריים; חפש גם ממצאים מנוגדים.",
progress: 28,
openIssues: 3,
},
{
action: "השווה שני מחקרים שעברו ביקורת עמיתים עם מערך נתונים לאומי על שוק העבודה.",
observation: "התוצאות משתנות לפי סוג המשימה, שיטת המדידה, והאם העבודה מרוחקת לחלוטין או היברידית.",
evaluation: "הראיות סותרות את המילה 'תמיד'. מסקנה מותנית נעשית ניתנת להגנה.",
adaptation: "בדוק האם המחקרים מבחינים בין תפוקה, שעות עבודה ופרודוקטיביות נתפסת.",
progress: 68,
openIssues: 1,
},
{
action: "בנה טבלת ראיות ואמת כל טענה מול המקור המקורי.",
observation: "המקורות תומכים באפקטים מעורבים ומזהים אוטונומיה, תיאום וסוג המשימה כמשתנים מרכזיים.",
evaluation: "המסקנה נתמכת, אי-הוודאות גלויה, וסף המקורות הושג.",
adaptation: "עצור עם תשובה מסויגת ושמור את טבלת הראיות לביקורת.",
progress: 100,
openIssues: 0,
},
],
},
{
id: "writing",
label: "לטש אימייל השקה",
goal: "צור אימייל השקה תמציתי שמסביר את התועלת ומניב הקלקות הדגמה איכותיות.",
stopRule: "האימייל עובר את רובריקת הקול, נשאר מתחת ל-140 מילים, מכיל קריאה ברורה אחת לפעולה ושורד סקירה עובדתית.",
evidence: "ספירת מילים, ציוני רובריקה, אימות קישורים, עובדות המוצר מהמקור והערות מבקרים.",
cycles: [
{
action: "נסח טיוטה מתוך בריף המוצר ודרג את התוצאה מול רובריקת הקהל והקול.",
observation: "הטיוטה בת 204 מילים, נפתחת בתכונות, ומכילה שתי קריאות מתחרות לפעולה.",
evaluation: "העובדות מדויקות, אך קריטריוני ההיררכיה והאורך נכשלים.",
adaptation: "פתח בתוצאה עבור הלקוח, הסר את הפעולה המשנית וקצץ את פרטי המימוש.",
progress: 41,
openIssues: 3,
},
{
action: "כתוב מחדש את הפתיחה ודחוס את הגוף לרצף אחד של בעיה-תועלת-הוכחה.",
observation: "האימייל בן 126 מילים ויש בו קריאה אחת לפעולה, אבל משפט ההוכחה מגזים בתוצאת הבטא.",
evaluation: "המבנה עובר. הכיול העובדתי עדיין נכשל ברובריקה.",
adaptation: "החלף את הטענה הרחבה בתוצאת הבטא שנמדדה ובקש בדיקת עובדות סופית.",
progress: 79,
openIssues: 1,
},
{
action: "הכנס את המדד המאומת, אמת את הקישור והרץ את הרובריקה המלאה פעם נוספת.",
observation: "האימייל בן 132 מילים, הקישור תקין, העובדות תואמות את הבריף וכל פריט ברובריקה עובר.",
evaluation: "התוצר עומד ברף האיכות שהוגדר, עם ראיות הניתנות לביקורת.",
adaptation: "עצור ושלח את הגרסה המאושרת לבעל הקמפיין.",
progress: 100,
openIssues: 0,
},
],
},
],
}} />
## כתבו קודם את חוזה הלולאה
לפני שבוחרים מודל או framework, כתבו חוזה קטן. אם השדות הללו מעורפלים, הלולאה תהפוך אי-בהירות לעלות חוזרת.
```yaml
goal: "איזה מצב ניתן לצפייה צריך להתממש?"
inputs: "מה מפעיל את הלולאה?"
state: "אילו עובדות וניסיונות נשמרים בין איטרציות?"
actions: "באילו כלים המערכת יכולה להשתמש, ועם אילו הרשאות?"
observations: "אילו אותות חיצוניים חוזרים מפעולות אלו?"
evaluator: "איזו רובריקה או בדיקות דטרמיניסטיות שופטות את התוצאה?"
success: "אילו ראיות מוכיחות שהמטרה הושלמה?"
failure: "אילו מצבים דורשים התאוששות או עזרה אנושית?"
budget: "מקסימום תורים, זמן, tokens, כסף או תופעות לוואי"
```
<Callout type="warning" title="לולאה ללא יציאה היא מצב כשל">
הגדירו תמיד שלוש יציאות: **הצלחה** כאשר הראיות מספקות את המטרה, **כישלון** כאשר התאוששות כבר אינה מועילה, ו**מיצוי תקציב** כאשר הלולאה מגיעה לגבול העלות או הסיכון המותר לה.
</Callout>
## תצפיות חייבות לבוא מהעולם
אמירה של המודל ש"זה נראה נכון" אינה ראיה חזקה. תצפית שימושית נוצרת על ידי משהו שמחוץ לתשובה הנשפטת.
<table>
<thead>
<tr>
<th>משימה</th>
<th>תצפית חלשה</th>
<th>תצפית חזקה</th>
</tr>
</thead>
<tbody>
<tr>
<td>תיקון קוד</td>
<td>"התיקון אמור לעבוד."</td>
<td>הכשל המקורי משוחזר, ואז הרגרסיה והחבילה המלאה עוברות.</td>
</tr>
<tr>
<td>מחקר</td>
<td>"כמה מקורות מסכימים."</td>
<td>הטענות מקושרות למקורות המקוריים, עם תאריכים, שיטות וחילוקי דעות מתועדים.</td>
</tr>
<tr>
<td>חילוץ נתונים</td>
<td>"נראה שה-JSON תקין."</td>
<td>אימות הסכימה עובר ורשומות שנדגמו תואמות למקור.</td>
</tr>
<tr>
<td>תוכן</td>
<td>"הטקסט מרגיש ברור."</td>
<td>הוא עובר רובריקה מוגדרת, סקירה עובדתית, בדיקות קישורים ובדיקת קהל.</td>
</tr>
<tr>
<td>תפעול</td>
<td>"הבקשה הצליחה."</td>
<td>המערכת החיצונית מחזירה את המצב הצפוי וקיימת רשומת ביקורת.</td>
</tr>
</tbody>
</table>
זו הסיבה שכלים חשובים: בדיקות, דפדפנים, מסדי נתונים, מאמתים וביקורת אנושית הופכים ניחוש פנימי לתוצאה הניתנת לצפייה.
## הפרידו בין היוצר לבודק
עבור עבודה בסיכון נמוך, מודל אחד יכול לנסח ולבדוק את עצמו. לעבודה חשובה, השתמשו בבודק בעל תפקיד שונה וסמכות מוגבלת.
<InfoGrid columns={2} items={[
{ label: "יוצר", description: "מציע את השינוי, קורא לכלי פעולה ומסביר אילו ראיות יש לאסוף.", color: "amber" },
{ label: "בודק", description: "מקבל את המטרה, התוצר והראיות; מחיל את הרובריקה; אינו יכול לשכתב בשקט את העבודה שהוא מדרג.", color: "green" },
]} />
הבודק לא חייב להיות AI אחר. העדיפו את המעריך הדטרמיניסטי ביותר שזמין:
1. **בדיקות מדויקות** - טיפוסים, סכימות, אילוצים, הרשאות, גיבובים
2. **בדיקות ניתנות להרצה** - בדיקות, לינטרים, סימולציות, אימות קישורים
3. **בדיקות רובריקה** - מודל בלתי תלוי או אדם שמשתמשים בקריטריונים מוגדרים
4. **בדיקות תוצאה** - התנהגות משתמשים אמיתית או מדדי פרודקשן לאורך זמן
<Callout type="tip" title="ביטחון הוא לא ראיה">
ציון ביטחון שנוצר על ידי אותו מודל שיצר את התוצר הוא עדיין פלט של מודל. התייחסו אליו כאל רמז לניתוב, לא כאל הוכחה.
</Callout>
## המצב הוא עמוד השדרה של הלולאה
ההקשר הוא מה שהמודל רואה **בתור הנוכחי**. המצב הוא הרשומה הקומפקטית שמאפשרת לתור הבא להמשיך מבלי לחזור על עבודה או לשכוח אותה.
<Checklist title="מצב לולאה שימושי" items={[
{ text: "המטרה הנוכחית וקריטריוני הקבלה" },
{ text: "פעולות שכבר נוסו והתוצאות הניתנות לצפייה" },
{ text: "תוצרים שנוצרו, עם גרסאות או הפניות יציבות" },
{ text: "הכרעות המעריך ובעיות שטרם נפתרו" },
{ text: "התקציב שנצרך וההרשאות שעדיין זמינות" },
{ text: "הסיבה להמשך, עצירה או הסלמה" },
]} />
אחסנו החלטות וראיות תמציתיות - לא את שרשרת המחשבה הפרטית של המודל. מצב טוב הוא קטן, ניתן לבדיקה ובטוח לחידוש.
## צורות לולאה נפוצות
### לולאת התיקון
`שחזר → שנה דבר אחד → הרץ בדיקות → אבחן → חזור או עצור`
הטובה ביותר עבור קוד, תצורה, ניקוי נתונים וכל משימה עם משוב שניתן להריץ.
### לולאת ה-Evaluator-Optimizer
`צור → דרג עם רובריקה → החזר משוב ממוקד → שכתב`
הטובה ביותר לכתיבה, תרגום, ביקורת עיצוב ותוצרים שאיכותם משתפרת באמצעות משוב מנוסח היטב.
### לולאת המחקר
`חפש → בדוק מקורות → זהה פערים או סתירות → חפש שוב → סנתז`
הטובה ביותר כאשר השלמות אינה ידועה מראש. כלל העצירה צריך למדוד את כיסוי הראיות, לא את מספר תוצאות החיפוש.
### הלולאה עם שער אנושי
`הכן → אמת אוטומטית → עצור לפני פעולה בסיכון גבוה → אדם מאשר או מכוון מחדש`
הטובה ביותר עבור תשלומים, פרסום, מחיקה, שינויי גישה, החלטות רפואיות או משפטיות ופעולות כבדות-משקל אחרות.
## מצבי כשל שיש למנוע בתכנון
<table>
<thead>
<tr>
<th>כשל</th>
<th>מה קרה</th>
<th>תגובה הנדסית</th>
</tr>
</thead>
<tbody>
<tr>
<td>ניסיון חוזר אינסופי</td>
<td>ללולאה אין יציאת הצלחה מדידה או יציאת תקציב.</td>
<td>הוסיפו מצבים סופיים מפורשים ותקרת איטרציות קשיחה.</td>
</tr>
<tr>
<td>שבח עצמי</td>
<td>היוצר מקבל את התשובה הסבירה של עצמו ללא ראיות.</td>
<td>השתמשו בבדיקות דטרמיניסטיות או בבודק בלתי תלוי.</td>
</tr>
<tr>
<td>כדור שלג של הקשר</td>
<td>כל איטרציה מצרפת הכול עד שהמודל מאבד את האות.</td>
<td>שמרו מצב מובנה ובנו מחדש רק את ההקשר הרלוונטי.</td>
</tr>
<tr>
<td>התנדנדות (thrashing)</td>
<td>הלולאה מתחלפת בין שני תיקונים.</td>
<td>זהו מצבים חוזרים ודרשו אסטרטגיה אחרת או הסלמה.</td>
</tr>
<tr>
<td>סחף מטרה</td>
<td>שיפורים מקומיים מחליפים את המטרה המקורית.</td>
<td>קראו שוב את המטרה הבלתי ניתנת לשינוי ואת קריטריוני הקבלה בכל מחזור.</td>
</tr>
<tr>
<td>חזרה לא בטוחה</td>
<td>טעות הפיכה הופכת מזיקה כאשר היא חוזרת על עצמה.</td>
<td>הגבילו הרשאות, תופעות לוואי, קצב, הוצאות ורדיוס פגיעה.</td>
</tr>
</tbody>
</table>
## יישום מינימלי
```typescript
let state = initialize(goal, acceptanceCriteria, budget);
while (state.budget.remaining > 0) {
const context = assembleRelevantContext(state);
const proposedAction = await maker.chooseAction(context);
const observation = await tools.executeWithinPolicy(proposedAction);
const verdict = await evaluator.check({ goal, observation, state });
state = recordIteration(state, { proposedAction, observation, verdict });
if (verdict.status === "passed") return complete(state);
if (verdict.status === "unsafe" || verdict.status === "blocked") {
return escalateToHuman(state);
}
state = adaptPlan(state, verdict.feedback);
}
return stopWithBudgetReport(state);
```
הקוד הוא החלק הקל. השאלות הקשות הן שאלות תחום: איזו בדיקה מוכיחה שהבאג נעלם? איזה מקור הוא סמכותי? איזו פעולה הפיכה? מי יכול לאשר את השלב האחרון? החלטות אלו הן העבודה האמיתית של הנדסת לולאות.
## תרגול: תכנון לולאה
<TryIt
title="נסחו חוזה לולאה"
description="החליפו את המשתנים במשימה חוזרת מהעבודה שלכם. בקשו מה-AI לערער על ראיות חלשות ועל כללי עצירה מעורפלים."
prompt={`תכנן לולאת עבודה מוגבלת של AI עבור המשימה הזו:
משימה: \${task:למיין פניות תמיכה חדשות מלקוחות בכל בוקר}
הגדר:
1. המטרה הניתנת לצפייה
2. הטריגר והקלטים הנדרשים
3. פעולות מותרות והרשאות כלים
4. תצפיות מהימנות מהסביבה החיצונית
5. המעריך והרובריקה שלו
6. מצב שנשמר בין איטרציות
7. יציאות של הצלחה, כישלון ומיצוי תקציב
8. שערי אישור אנושי לפעולות מסוכנות
9. פורמט מעקב שהופך כל איטרציה לניתנת לביקורת
לאחר מכן זהה את שלושת מצבי הכשל הסבירים ביותר בתכנון שלך ושנה את הלולאה כדי למנוע אותם.`}
/>
<Quiz
question="סוכן עורך קוד, קורא מחדש את ה-diff ואומר שהבאג תוקן. מהו החלק החסר החשוב ביותר בלולאה?"
options={[
"system prompt ארוך יותר",
"תצפית חיצונית שהוערכה מול כלל עצירה",
"מעבר עריכה שני",
"חלון הקשר גדול יותר"
]}
correctIndex={1}
explanation="הסוכן הפיק ובדק תוצר, אך לא אסף ראיות עצמאיות. שחזור הכשל והרצת בדיקות רלוונטיות ייצרו אות ניתן לצפייה שכלל עצירה יכול להעריך."
/>
## קריאה נוספת
- [הנדסת לולאות - Addy Osmani](https://addyosmani.com/blog/loop-engineering/) - המסגור העדכני של החלפת פרומפטי המשך ידניים במערכת מתוכננת, בתוספת אזהרות מעשיות לגבי אימות ואחריות אנושית
- [בניית סוכנים אפקטיביים - Anthropic](https://www.anthropic.com/engineering/building-effective-agents) - זרימות עבודה של evaluator-optimizer, משוב סביבתי, תנאי עצירה והכוונה מתי מורכבות סוכנית מוצדקת
- [מדריך מעשי לבניית סוכנים - OpenAI](https://openai.com/business/guides-and-resources/a-practical-guide-to-building-ai-agents/) - ריצות סוכנים, תנאי יציאה, כלים, מעקות בטיחות והתערבות אנושית
- [ReAct: Synergizing Reasoning and Acting in Language Models](https://arxiv.org/abs/2210.03629) - מחקר בסיסי על שילוב פעולות עם תצפיות מסביבה חיצונית
## סיכום
<Callout type="tip" title="בנו את המשוב, לא רק את הפרומפט">
ללולאה אמינה יש מטרה ניתנת למדידה, פעולות מוגבלות, תצפיות מהימנות, מעריך מפורש, מצב קומפקטי, יציאות בטוחות ושיקול דעת אנושי היכן שההשלכות דורשות זאת. המודל נמצא בתוך הלולאה; המהנדס נשאר אחראי על הלולאה.
</Callout>
@@ -1,405 +0,0 @@
L'ingegneria del contesto decide **cosa può vedere il modello**. L'ingegneria dei loop decide **cosa fa il sistema subito dopo**.
Invece di una persona che legge una risposta dopo l'altra e scrive il prompt successivo, un loop trasforma quel lavoro di follow-up in un sistema progettato. Assegna un obiettivo all'IA, la lascia agire, osserva feedback reale, valuta il risultato e poi si adatta oppure si ferma.
<Callout type="info" title="La Definizione in Breve">
L'ingegneria dei loop è la pratica di progettare il ciclo di feedback attorno a un sistema IA: l'obiettivo, le azioni, le osservazioni, la valutazione, lo stato, i guardrail e le regole di arresto che portano il lavoro verso un risultato verificabile.
</Callout>
## Da un Buon Prompt a un Buon Loop
Un prompt può produrre un ottimo primo tentativo. Un loop serve quando il numero di passi non si può conoscere in anticipo, l'ambiente può cambiare, o il primo tentativo va verificato rispetto alle evidenze.
<Compare
before={{
label: "Prompt One-Shot",
content: "Chiedi → Genera → Restituisci\n\nIl modello produce una risposta. Una persona decide se ha funzionato e scrive il prompt successivo."
}}
after={{
label: "Loop Ingegnerizzato",
content: "Inquadra → Agisci → Osserva → Valuta → Adatta\n ↑______________________↓\n\nIl sistema raccoglie evidenze, registra lo stato e continua solo finché un altro passaggio è utile."
}}
/>
Questa idea si fonda su pattern agentici precedenti. Il [paper ReAct](https://arxiv.org/abs/2210.03629) ha mostrato il valore di alternare azioni e osservazioni provenienti da un ambiente esterno. Il [pattern evaluator-optimizer](https://www.anthropic.com/engineering/building-effective-agents) di Anthropic aggiunge un passo di feedback distinto, mentre la [guida pratica agli agenti](https://openai.com/business/guides-and-resources/a-practical-guide-to-building-ai-agents/) di OpenAI descrive le esecuzioni degli agenti come loop governati da condizioni di uscita. Il termine più recente, **ingegneria dei loop** (loop engineering), porta l'attenzione sulla progettazione deliberata dell'intero ciclo.
## Le Cinque Mosse
<InfoGrid items={[
{ label: "1. Inquadra", description: "Trasforma l'intento in un obiettivo, vincoli, criteri di successo e un budget.", color: "blue" },
{ label: "2. Agisci", description: "Scegli una singola azione delimitata: cercare, modificare, calcolare, chiamare uno strumento o chiedere a una persona.", color: "amber" },
{ label: "3. Osserva", description: "Raccogli ciò che è realmente accaduto: output dei test, risposte delle API, citazioni o feedback degli utenti.", color: "cyan" },
{ label: "4. Valuta", description: "Confronta le evidenze con criteri espliciti — non con la sicurezza del modello.", color: "purple" },
{ label: "5. Adatta", description: "Aggiorna lo stato, cambia il piano, riprova in sicurezza, coinvolgi un umano o fermati.", color: "green" },
]} />
Il loop non sono le frecce. L'ingegneria vive nei **contratti tra le frecce**: cosa conta come azione, quali osservazioni sono affidabili, chi le valuta, quale stato sopravvive ed esattamente quando l'esecuzione termina.
<LoopEngineeringLab content={{
eyebrow: "Controllo del loop / simulatore interattivo",
title: "Percorri passo dopo passo un ciclo di feedback funzionante",
description: "Scegli un task, poi avanza un segnale alla volta. Nota come il progresso nasce da evidenze ambientali e valutazioni esplicite — non dal chiedere al modello se ritiene di aver finito.",
chooseScenarioLabel: "Scegli un loop",
goalLabel: "Obiettivo",
stopRuleLabel: "Regola di arresto",
evidenceLabel: "Evidenze affidabili",
iterationLabel: "Iterazione",
progressLabel: "Progresso verificato",
openIssuesLabel: "Problemi aperti",
currentSignalLabel: "Segnale corrente",
advanceLabel: "Avanza di un passo",
nextIterationLabel: "Inizia l'iterazione successiva",
resetLabel: "Reimposta il loop",
completeLabel: "Obiettivo verificato",
completeDescription: "I criteri di successo sono soddisfatti, le evidenze sono registrate e il loop si ferma invece di spendere un altro ciclo.",
stages: [
{ id: "frame", label: "Inquadra", verb: "Rileggi il contratto" },
{ id: "act", label: "Agisci", verb: "Fai una mossa delimitata" },
{ id: "observe", label: "Osserva", verb: "Leggi il feedback esterno" },
{ id: "evaluate", label: "Valuta", verb: "Applica la griglia di valutazione" },
{ id: "adapt", label: "Adatta", verb: "Aggiorna la prossima mossa" },
],
scenarios: [
{
id: "code",
label: "Riparare un bug nel checkout",
goal: "Correggere i totali del checkout senza alterare il comportamento corretto degli sconti.",
stopRule: "Il test di regressione mirato passa, l'intera suite del checkout passa e il lint è pulito — oppure i tre tentativi sono esauriti e il loop passa la mano a un umano.",
evidence: "Passi di riproduzione, output dei test, il diff del codice e la suite di regressione finale.",
cycles: [
{
action: "Riprodurre il totale segnalato e aggiungere un test che fallisce per il caso imposta più sconto percentuale.",
observation: "Il test fallisce di un centesimo solo quando l'imposta viene arrotondata prima dell'applicazione dello sconto.",
evaluation: "Il bug è riprodotto con un segnale deterministico, ma la sua origine non è ancora corretta.",
adaptation: "Ispezionare il punto di arrotondamento e modificare solo il percorso di calcolo del totale dell'ordine.",
progress: 34,
openIssues: 2,
},
{
action: "Spostare l'arrotondamento al confine monetario finale ed eseguire i test mirati del checkout.",
observation: "La regressione passa, ma un test di integrazione dei coupon ora fallisce su uno sconto a importo fisso.",
evaluation: "Il primo sintomo è risolto, ma la modifica è troppo ampia. La regola di arresto non è soddisfatta.",
adaptation: "Restringere la patch e aggiungere un caso che separi l'arrotondamento delle imposte da quello dei coupon.",
progress: 71,
openIssues: 1,
},
{
action: "Applicare la correzione mirata al calcolo, poi eseguire la regressione, l'intera suite del checkout e il lint.",
observation: "Tutti i controlli passano. Il diff tocca una sola funzione di calcolo e il nuovo test di regressione.",
evaluation: "Ogni criterio di successo ha evidenze indipendenti e nessun limite di budget è stato superato.",
adaptation: "Fermarsi, conservare l'output dei test e consegnare il piccolo diff a un revisore umano.",
progress: 100,
openIssues: 0,
},
],
},
{
id: "research",
label: "Verificare un'affermazione di ricerca",
goal: "Valutare l'affermazione secondo cui il lavoro da remoto aumenta sempre la produttività del team.",
stopRule: "Una conclusione calibrata è supportata da almeno tre fonti credibili, con disaccordi e limiti dichiarati.",
evidence: "Link diretti alle fonti, date di pubblicazione, metodologie degli studi, dimensioni dei campioni e metriche citate.",
cycles: [
{
action: "Cercare evidenze recenti e risalire alla fonte della statistica più ripetuta sulla produttività.",
observation: "La maggior parte degli articoli ripete un sondaggio di un vendor senza linkare il questionario o il campione grezzo.",
evaluation: "L'evidenza è popolare, ma non abbastanza solida da sostenere un'affermazione assoluta.",
adaptation: "Dare priorità a studi peer-reviewed e dataset pubblici; cercare anche risultati contrari.",
progress: 28,
openIssues: 3,
},
{
action: "Confrontare due studi peer-reviewed con un dataset nazionale sul lavoro.",
observation: "I risultati variano in base al tipo di attività, al metodo di misurazione e al fatto che il lavoro sia interamente remoto o ibrido.",
evaluation: "Le evidenze contraddicono la parola 'sempre'. Una conclusione condizionata sta diventando difendibile.",
adaptation: "Verificare se gli studi distinguono tra output, ore lavorate e produttività percepita.",
progress: 68,
openIssues: 1,
},
{
action: "Costruire una tabella delle evidenze e verificare ogni affermazione sulla fonte originale.",
observation: "Le fonti indicano effetti misti e identificano autonomia, coordinamento e tipo di attività come variabili chiave.",
evaluation: "La conclusione è supportata, l'incertezza è visibile e la soglia di fonti è raggiunta.",
adaptation: "Fermarsi con una risposta formulata con le dovute riserve e conservare la tabella delle evidenze per la revisione.",
progress: 100,
openIssues: 0,
},
],
},
{
id: "writing",
label: "Rifinire un'email di lancio",
goal: "Creare un'email di lancio concisa che spieghi il beneficio e ottenga clic qualificati verso la demo.",
stopRule: "L'email supera la griglia sul tono di voce, resta sotto le 140 parole, contiene una sola call to action chiara e regge una verifica fattuale.",
evidence: "Conteggio parole, punteggi della griglia, validazione dei link, dati di prodotto di partenza e note del revisore.",
cycles: [
{
action: "Scrivere una bozza dal brief di prodotto e valutarla con la griglia su pubblico e tono di voce.",
observation: "La bozza è di 204 parole, si apre con le funzionalità e contiene due call to action in concorrenza tra loro.",
evaluation: "I fatti sono accurati, ma i criteri di gerarchia e lunghezza falliscono.",
adaptation: "Aprire con il risultato per il cliente, rimuovere l'azione secondaria e tagliare i dettagli implementativi.",
progress: 41,
openIssues: 3,
},
{
action: "Riscrivere l'apertura e comprimere il corpo in un'unica sequenza problema-beneficio-prova.",
observation: "L'email è di 126 parole e ha una sola CTA, ma la frase di prova esagera un risultato della beta.",
evaluation: "La struttura passa. La calibrazione fattuale non supera ancora la griglia.",
adaptation: "Sostituire l'affermazione generica con il risultato misurato della beta e richiedere una verifica fattuale finale.",
progress: 79,
openIssues: 1,
},
{
action: "Inserire la metrica verificata, validare il link ed eseguire un'ultima volta la griglia completa.",
observation: "L'email è di 132 parole, il link funziona, i fatti corrispondono al brief e ogni voce della griglia passa.",
evaluation: "L'artefatto soddisfa l'asticella di qualità definita, con evidenze verificabili.",
adaptation: "Fermarsi e inviare la versione approvata al responsabile della campagna.",
progress: 100,
openIssues: 0,
},
],
},
],
}} />
## Scrivi Prima il Contratto del Loop
Prima di scegliere un modello o un framework, scrivi un piccolo contratto. Se questi campi sono vaghi, il loop trasformerà l'ambiguità in costi ripetuti.
```yaml
goal: "Quale stato osservabile deve diventare vero?"
inputs: "Cosa avvia il loop?"
state: "Quali fatti e tentativi persistono tra le iterazioni?"
actions: "Quali strumenti può usare il sistema, e con quali permessi?"
observations: "Quali segnali esterni tornano indietro da quelle azioni?"
evaluator: "Quale griglia di valutazione o quali controlli deterministici giudicano il risultato?"
success: "Quali evidenze dimostrano che l'obiettivo è raggiunto?"
failure: "Quali condizioni richiedono un recupero o l'aiuto di un umano?"
budget: "Massimo di turni, tempo, token, denaro o effetti collaterali"
```
<Callout type="warning" title="Un Loop Senza Uscita È una Modalità di Fallimento">
Definisci sempre tre uscite: **successo** quando le evidenze soddisfano l'obiettivo, **fallimento** quando il recupero non è più utile, e **budget esaurito** quando il loop raggiunge il limite di costo o di rischio consentito.
</Callout>
## Le Osservazioni Devono Venire dal Mondo
Il modello che dice "questo sembra corretto" non è un'evidenza forte. Un'osservazione utile è prodotta da qualcosa di esterno alla risposta che si sta giudicando.
<table>
<thead>
<tr>
<th>Task</th>
<th>Osservazione debole</th>
<th>Osservazione forte</th>
</tr>
</thead>
<tbody>
<tr>
<td>Riparazione di codice</td>
<td>"La correzione dovrebbe funzionare."</td>
<td>Il fallimento originale viene riprodotto, poi la regressione e l'intera suite passano.</td>
</tr>
<tr>
<td>Ricerca</td>
<td>"Diverse fonti concordano."</td>
<td>Le affermazioni rimandano alle fonti originali, con date, metodologie e disaccordi registrati.</td>
</tr>
<tr>
<td>Estrazione di dati</td>
<td>"Il JSON sembra valido."</td>
<td>La validazione dello schema passa e i record campionati corrispondono alla fonte.</td>
</tr>
<tr>
<td>Contenuti</td>
<td>"Il testo sembra chiaro."</td>
<td>Supera una griglia di valutazione definita, una verifica fattuale, il controllo dei link e i test con il pubblico.</td>
</tr>
<tr>
<td>Operazioni</td>
<td>"La richiesta è andata a buon fine."</td>
<td>Il sistema esterno restituisce lo stato atteso ed esiste un record di audit.</td>
</tr>
</tbody>
</table>
Ecco perché gli strumenti contano: test, browser, database, validatori e revisione umana trasformano una supposizione interna in un risultato osservabile.
## Separa Chi Produce da Chi Verifica
Per il lavoro a basso rischio, un solo modello può scrivere e auto-revisionarsi. Per il lavoro importante, usa un verificatore con un compito diverso e un'autorità limitata.
<InfoGrid columns={2} items={[
{ label: "Autore", description: "Propone la modifica, chiama gli strumenti di azione e spiega quali evidenze andrebbero raccolte.", color: "amber" },
{ label: "Verificatore", description: "Riceve l'obiettivo, l'artefatto e le evidenze; applica la griglia di valutazione; non può riscrivere in silenzio il lavoro che giudica.", color: "green" },
]} />
Il verificatore non deve per forza essere un'altra IA. Preferisci il valutatore più deterministico disponibile:
1. **Controlli esatti** — tipi, schemi, vincoli, permessi, hash
2. **Controlli eseguibili** — test, linter, simulazioni, validazione dei link
3. **Controlli a griglia** — un modello indipendente o un umano che applica criteri espliciti
4. **Controlli sugli esiti** — comportamento reale degli utenti o metriche di produzione nel tempo
<Callout type="tip" title="La Sicurezza Non È un'Evidenza">
Un punteggio di confidenza generato dallo stesso modello che ha prodotto l'artefatto è comunque un output del modello. Trattalo come un indizio per l'instradamento, non come una prova.
</Callout>
## Lo Stato È la Spina Dorsale del Loop
Il contesto è ciò che il modello vede **in questo turno**. Lo stato è il registro compatto che permette al turno successivo di proseguire senza ripetere né dimenticare il lavoro.
<Checklist title="Stato Utile del Loop" items={[
{ text: "L'obiettivo corrente e i criteri di accettazione" },
{ text: "Le azioni già tentate e i loro risultati osservabili" },
{ text: "Gli artefatti prodotti, con versioni o riferimenti stabili" },
{ text: "I verdetti del valutatore e i problemi irrisolti" },
{ text: "Il budget consumato e i permessi ancora disponibili" },
{ text: "La ragione per continuare, fermarsi o passare la mano a un umano" },
]} />
Conserva decisioni ed evidenze concise — non la catena di pensiero privata di un modello. Un buono stato è piccolo, ispezionabile e sicuro da riprendere.
## Forme Comuni di Loop
### Il Loop di Riparazione
`riproduci → cambia una cosa sola → esegui i controlli → diagnostica → ripeti o fermati`
Ideale per codice, configurazioni, pulizia dei dati e qualsiasi task con feedback eseguibile.
### Il Loop Evaluator-Optimizer
`genera → assegna un punteggio con una griglia → restituisci feedback mirato → rivedi`
Ideale per scrittura, traduzione, critica di design e output la cui qualità migliora grazie a un feedback ben articolato.
### Il Loop di Ricerca
`cerca → esamina le fonti → individua lacune o conflitti → cerca di nuovo → sintetizza`
Ideale quando la completezza non è nota in anticipo. La regola di arresto dovrebbe misurare la copertura delle evidenze, non il numero di risultati di ricerca.
### Il Loop con Approvazione Umana
`prepara → verifica automaticamente → metti in pausa prima dell'azione ad alto rischio → un umano approva o reindirizza`
Ideale per pagamenti, pubblicazioni, cancellazioni, modifiche degli accessi, decisioni mediche o legali e altre azioni con conseguenze importanti.
## Modalità di Fallimento da Eliminare in Fase di Progetto
<table>
<thead>
<tr>
<th>Fallimento</th>
<th>Cosa è successo</th>
<th>Risposta ingegneristica</th>
</tr>
</thead>
<tbody>
<tr>
<td>Retry infinito</td>
<td>Il loop non ha un'uscita misurabile per successo o budget.</td>
<td>Aggiungi stati terminali espliciti e un tetto rigido alle iterazioni.</td>
</tr>
<tr>
<td>Auto-compiacimento</td>
<td>L'autore accetta la propria risposta plausibile senza evidenze.</td>
<td>Usa controlli deterministici o un verificatore indipendente.</td>
</tr>
<tr>
<td>Valanga di contesto</td>
<td>Ogni iterazione accumula tutto finché il modello perde il segnale.</td>
<td>Rendi persistente uno stato strutturato e ricostruisci solo il contesto rilevante.</td>
</tr>
<tr>
<td>Oscillazione</td>
<td>Il loop oscilla tra due correzioni.</td>
<td>Rileva gli stati ripetuti e imponi una strategia diversa o il passaggio a un umano.</td>
</tr>
<tr>
<td>Deriva dell'obiettivo</td>
<td>I miglioramenti locali prendono il posto dell'obiettivo originale.</td>
<td>Rileggi a ogni ciclo l'obiettivo immutabile e i criteri di accettazione.</td>
</tr>
<tr>
<td>Ripetizione non sicura</td>
<td>Un errore reversibile diventa dannoso se ripetuto.</td>
<td>Limita permessi, effetti collaterali, frequenza, spesa e raggio d'impatto.</td>
</tr>
</tbody>
</table>
## Un'Implementazione Minima
```typescript
let state = initialize(goal, acceptanceCriteria, budget);
while (state.budget.remaining > 0) {
const context = assembleRelevantContext(state);
const proposedAction = await maker.chooseAction(context);
const observation = await tools.executeWithinPolicy(proposedAction);
const verdict = await evaluator.check({ goal, observation, state });
state = recordIteration(state, { proposedAction, observation, verdict });
if (verdict.status === "passed") return complete(state);
if (verdict.status === "unsafe" || verdict.status === "blocked") {
return escalateToHuman(state);
}
state = adaptPlan(state, verdict.feedback);
}
return stopWithBudgetReport(state);
```
Il codice è la parte facile. Le domande difficili sono domande di dominio: quale test dimostra che il bug è sparito? Quale fonte è autorevole? Quale azione è reversibile? Chi può approvare il passo finale? Quelle decisioni sono il vero lavoro dell'ingegneria dei loop.
## Pratica: Progetta un Loop
<TryIt
title="Scrivi la Bozza di un Contratto di Loop"
description="Sostituisci le variabili con un task ricorrente del tuo lavoro. Chiedi all'IA di mettere in discussione le evidenze deboli e le regole di arresto ambigue."
prompt={`Progetta un loop di lavoro IA delimitato per questo task:
TASK: \${task:smistare ogni mattina le nuove richieste di assistenza clienti}
Definisci:
1. L'obiettivo osservabile
2. Il trigger e gli input richiesti
3. Le azioni consentite e i permessi degli strumenti
4. Le osservazioni affidabili provenienti dall'ambiente esterno
5. Il valutatore e la sua griglia di valutazione
6. Lo stato che persiste tra le iterazioni
7. Le uscite per successo, fallimento e budget esaurito
8. I punti di approvazione umana per le azioni rischiose
9. Un formato di trace che renda verificabile ogni iterazione
Poi individua le tre modalità di fallimento più probabili nel tuo progetto e rivedi il loop per prevenirle.`}
/>
<Quiz
question="Un agente modifica il codice, rilegge il diff e dice che il bug è risolto. Qual è la parte mancante più importante del loop?"
options={[
"Un system prompt più lungo",
"Un'osservazione esterna valutata rispetto a una regola di arresto",
"Un secondo passaggio di editing",
"Una finestra di contesto più grande"
]}
correctIndex={1}
explanation="L'agente ha prodotto e ispezionato un artefatto, ma non ha raccolto evidenze indipendenti. Riprodurre il fallimento ed eseguire i test pertinenti creerebbe un segnale osservabile che una regola di arresto può valutare."
/>
## Letture di Approfondimento
- [Loop Engineering — Addy Osmani](https://addyosmani.com/blog/loop-engineering/) — la recente formulazione dell'idea di sostituire i prompt di follow-up manuali con un sistema progettato, più avvertenze pratiche su verifica e responsabilità umana
- [Building Effective Agents — Anthropic](https://www.anthropic.com/engineering/building-effective-agents) — workflow evaluator-optimizer, feedback dall'ambiente, condizioni di arresto e indicazioni su quando la complessità agentica è giustificata
- [A Practical Guide to Building Agents — OpenAI](https://openai.com/business/guides-and-resources/a-practical-guide-to-building-ai-agents/) — esecuzioni degli agenti, condizioni di uscita, strumenti, guardrail e intervento umano
- [ReAct: Synergizing Reasoning and Acting in Language Models](https://arxiv.org/abs/2210.03629) — la ricerca fondativa sull'alternanza tra azioni e osservazioni provenienti da un ambiente esterno
## Riepilogo
<Callout type="tip" title="Costruisci il Feedback, Non Solo il Prompt">
Un loop affidabile ha un obiettivo misurabile, azioni delimitate, osservazioni affidabili, un valutatore esplicito, uno stato compatto, uscite sicure e giudizio umano dove le conseguenze lo richiedono. Il modello è dentro il loop; l'ingegnere resta responsabile del loop.
</Callout>
@@ -1,405 +0,0 @@
コンテキストエンジニアリングが決めるのは、**モデルに何を見せるか**です。ループエンジニアリングが決めるのは、**システムが次に何をするか**です。
人間が答えを読んでは次のプロンプトを書く、という作業を繰り返す代わりに、ループはそのフォローアップ作業自体を設計されたシステムに変えます。AIに目標を与え、行動させ、実際のフィードバックを観察し、結果を評価し、そして適応するか停止するかを決めるのです。
<Callout type="info" title="ひとことで言うと">
ループエンジニアリングとは、AIシステムを取り巻くフィードバックサイクル──目標、アクション、観察、評価、状態、ガードレール、そして作業を検証可能な結果へと導く停止ルール──を設計する実践のことです。
</Callout>
## 良いプロンプトから良いループへ
プロンプトだけでも、優れた「最初の一手」は作れます。ループが役立つのは、必要なステップ数が事前にわからないとき、環境が変化しうるとき、あるいは最初の試みを証拠と突き合わせて確認しなければならないときです。
<Compare
before={{
label: "ワンショットプロンプト",
content: "質問 → 生成 → 返答\n\nモデルが答えを出します。うまくいったかどうかを人間が判断し、次のプロンプトを書きます。"
}}
after={{
label: "設計されたループ",
content: "フレーム → 行動 → 観察 → 評価 → 適応\n ↑______________________↓\n\nシステムが証拠を集め、状態を記録し、もう一周する価値がある間だけ続行します。"
}}
/>
この考え方は、これまでのエージェントパターンの延長線上にあります。[ReAct論文](https://arxiv.org/abs/2210.03629)は、外部環境からの観察とアクションを交互に織り交ぜることの価値を示しました。Anthropicの[評価者・最適化者パターン](https://www.anthropic.com/engineering/building-effective-agents)は独立したフィードバックステップを加え、OpenAIの[エージェント構築の実践ガイド](https://openai.com/business/guides-and-resources/a-practical-guide-to-building-ai-agents/)は、エージェントの実行を終了条件で制御されるループとして説明しています。**ループエンジニアリング**という新しい用語は、このサイクル全体を意図的に設計することに焦点を当てたものです。
## 5つの基本動作
<InfoGrid items={[
{ label: "1. フレーム", description: "意図を、目標・制約・成功基準・予算に変換します。", color: "blue" },
{ label: "2. 行動", description: "範囲を限定したアクションを1つ選びます:検索、編集、計算、ツール呼び出し、または人への質問。", color: "amber" },
{ label: "3. 観察", description: "実際に起きたことを収集します:テスト出力、APIの結果、出典、ユーザーからのフィードバック。", color: "cyan" },
{ label: "4. 評価", description: "証拠を明示的な基準と照らし合わせます。モデルの自信と比べるのではありません。", color: "purple" },
{ label: "5. 適応", description: "状態を更新し、計画を変え、安全に再試行し、人間にエスカレーションするか、停止します。", color: "green" },
]} />
ループの本質は矢印そのものではありません。エンジニアリングが宿るのは**矢印と矢印の間の取り決め**です。何をアクションと見なすか、どの観察を信頼できるか、誰がそれを評価するか、どの状態を引き継ぐか、そして実行を正確にいつ終えるか──これらの契約こそが設計の中身です。
<LoopEngineeringLab content={{
eyebrow: "ループ制御 / インタラクティブシミュレーター",
title: "動くフィードバックループを一歩ずつ体験する",
description: "タスクを選び、シグナルを1つずつ進めてみてください。進捗が「終わった気がするか」をモデルに尋ねることからではなく、環境からの証拠と明示的な評価から生まれる様子に注目しましょう。",
chooseScenarioLabel: "ループを選ぶ",
goalLabel: "目標",
stopRuleLabel: "停止ルール",
evidenceLabel: "信頼できる証拠",
iterationLabel: "イテレーション",
progressLabel: "検証済みの進捗",
openIssuesLabel: "未解決の問題",
currentSignalLabel: "現在のシグナル",
advanceLabel: "1ステップ進める",
nextIterationLabel: "次のイテレーションを開始",
resetLabel: "ループをリセット",
completeLabel: "目標を検証済み",
completeDescription: "成功基準が満たされ、証拠が記録されました。ループはもう1サイクル費やす代わりに、ここで停止します。",
stages: [
{ id: "frame", label: "フレーム", verb: "契約を読み直す" },
{ id: "act", label: "行動", verb: "限定された一手を打つ" },
{ id: "observe", label: "観察", verb: "外部からのフィードバックを読む" },
{ id: "evaluate", label: "評価", verb: "ルーブリックを適用する" },
{ id: "adapt", label: "適応", verb: "次の一手を更新する" },
],
scenarios: [
{
id: "code",
label: "チェックアウトのバグを修正する",
goal: "有効な割引の挙動を変えずに、チェックアウトの合計金額を正しくする。",
stopRule: "対象の回帰テストが通り、チェックアウトの全テストスイートが通り、lintがクリーンであること。または3回の試行を使い切ったらループを止めて人間にエスカレーションする。",
evidence: "再現手順、テスト出力、コードの差分、最終的な回帰テストスイート。",
cycles: [
{
action: "報告された合計金額を再現し、税と割合割引の組み合わせで失敗するテストを追加する。",
observation: "割引適用の前に税を丸めた場合に限り、テストが1セントの誤差で失敗する。",
evaluation: "バグは決定的なシグナルで再現できたが、原因はまだ修正されていない。",
adaptation: "丸め処理の境界を調べ、注文合計の計算パスだけを変更する。",
progress: 34,
openIssues: 2,
},
{
action: "丸め処理を金額計算の最終境界に移し、チェックアウト関連の対象テストを実行する。",
observation: "回帰テストは通ったが、定額割引を扱うクーポン統合テストが1つ新たに失敗した。",
evaluation: "最初の症状は直ったが、変更の範囲が広すぎる。停止ルールはまだ満たされていない。",
adaptation: "パッチの範囲を絞り、税の丸めとクーポンの丸めを切り分けるテストケースを追加する。",
progress: 71,
openIssues: 1,
},
{
action: "計算部分だけの絞り込んだ修正を適用し、回帰テスト、チェックアウトの全スイート、lintを実行する。",
observation: "すべてのチェックが通った。差分が触れているのは計算関数1つと新しい回帰テストだけ。",
evaluation: "すべての成功基準に独立した証拠が揃い、予算の上限も超えていない。",
adaptation: "停止し、テスト出力を保存して、小さな差分を人間のレビュアーに引き渡す。",
progress: 100,
openIssues: 0,
},
],
},
{
id: "research",
label: "リサーチの主張を検証する",
goal: "「リモートワークは常にチームの生産性を高める」という主張を評価する。",
stopRule: "少なくとも3つの信頼できる情報源に裏付けられ、見解の相違と限界を明記した、慎重に調整された結論に到達すること。",
evidence: "一次情報源への直接リンク、公開日、研究手法、サンプルサイズ、引用された指標。",
cycles: [
{
action: "最近の根拠を検索し、最も頻繁に引用される生産性の統計を出典までさかのぼる。",
observation: "ほとんどの記事が、質問票や生のサンプルへのリンクを示さないまま、同じベンダー調査を孫引きしている。",
evaluation: "この根拠は広く出回ってはいるが、「常に」という絶対的な主張を支えるほど強くはない。",
adaptation: "査読済みの研究と公開データセットを優先し、反対の結果を示す研究も検索する。",
progress: 28,
openIssues: 3,
},
{
action: "査読済みの研究2件を、国レベルの労働データセットと比較する。",
observation: "結果はタスクの種類、測定方法、完全リモートかハイブリッドかによって異なっている。",
evaluation: "根拠は「常に」という言葉と矛盾している。条件付きの結論なら擁護できる形になりつつある。",
adaptation: "各研究が、成果物・労働時間・主観的な生産性を区別しているかどうかを確認する。",
progress: 68,
openIssues: 1,
},
{
action: "エビデンス表を作成し、すべての主張を元の情報源と照合して検証する。",
observation: "情報源は効果がまちまちであることを示し、自律性・連携・タスクの種類が主要な変数だと特定している。",
evaluation: "結論は裏付けられ、不確実性も明示され、情報源数のしきい値も満たされた。",
adaptation: "条件付きの回答で停止し、レビュー用にエビデンス表を保存する。",
progress: 100,
openIssues: 0,
},
],
},
{
id: "writing",
label: "ローンチメールを磨き上げる",
goal: "メリットを伝え、質の高いデモ申し込みクリックを獲得できる、簡潔なローンチメールを作る。",
stopRule: "メールが文体ルーブリックに合格し、140語以内に収まり、明確なCTA(行動喚起)を1つだけ含み、ファクトチェックを通過すること。",
evidence: "語数、ルーブリックのスコア、リンクの検証結果、製品情報の一次資料、レビュアーのメモ。",
cycles: [
{
action: "製品ブリーフから草稿を書き、読者像と文体のルーブリックに照らして採点する。",
observation: "草稿は204語で、機能の説明から始まっており、競合するCTAが2つ含まれている。",
evaluation: "事実関係は正確だが、構成の優先順位と長さの基準を満たしていない。",
adaptation: "顧客が得られる成果を冒頭に据え、2つ目のCTAを削除し、実装の詳細を削る。",
progress: 41,
openIssues: 3,
},
{
action: "冒頭を書き直し、本文を「課題→メリット→根拠」の一続きの流れに圧縮する。",
observation: "メールは126語でCTAは1つになったが、根拠の一文がベータ版の結果を誇張している。",
evaluation: "構成は合格。しかし事実の正確さの調整が、まだルーブリックを満たしていない。",
adaptation: "大ざっぱな主張を実測されたベータ版の数値に置き換え、最終ファクトチェックを依頼する。",
progress: 79,
openIssues: 1,
},
{
action: "検証済みの数値を挿入し、リンクを検証し、ルーブリック全体をもう一度実行する。",
observation: "メールは132語、リンクは正しく開き、事実はブリーフと一致し、ルーブリックの全項目に合格した。",
evaluation: "成果物は、レビュー可能な証拠とともに、定義された品質基準を満たしている。",
adaptation: "停止し、承認済みのバージョンをキャンペーン担当者に送る。",
progress: 100,
openIssues: 0,
},
],
},
],
}} />
## まずループ契約を書く
モデルやフレームワークを選ぶ前に、小さな契約を書きましょう。これらの項目が曖昧なままだと、ループは曖昧さをそのまま繰り返しのコストに変えてしまいます。
```yaml
goal: "どんな観察可能な状態が実現されるべきか?"
inputs: "何がループを開始するのか?"
state: "どの事実と試行の記録をイテレーション間で引き継ぐのか?"
actions: "システムはどのツールを、どの権限で使えるのか?"
observations: "それらのアクションからどんな外部シグナルが返ってくるのか?"
evaluator: "どのルーブリック、あるいはどの決定的なチェックが結果を判定するのか?"
success: "目標の達成を証明する証拠は何か?"
failure: "どの状態になったらリカバリーや人間の助けが必要か?"
budget: "ターン数・時間・トークン・費用・副作用の上限"
```
<Callout type="warning" title="出口のないループは、それ自体が失敗モード">
出口は必ず3つ定義しましょう。証拠が目標を満たしたときの**成功**、リカバリーがもはや有効でなくなったときの**失敗**、そしてループが許容されたコストやリスクの限界に達したときの**予算切れ**です。
</Callout>
## 観察は現実世界から得る
モデルが「これは正しそうです」と言うだけでは、強い証拠にはなりません。有用な観察とは、判定対象の答えの外側にある何かによって生み出されるものです。
<table>
<thead>
<tr>
<th>タスク</th>
<th>弱い観察</th>
<th>強い観察</th>
</tr>
</thead>
<tbody>
<tr>
<td>コード修正</td>
<td>「この修正で動くはずです。」</td>
<td>元の不具合を再現したうえで、回帰テストと全スイートが通る。</td>
</tr>
<tr>
<td>リサーチ</td>
<td>「複数の情報源が一致しています。」</td>
<td>各主張が一次情報源にリンクされ、日付・手法・見解の相違が記録されている。</td>
</tr>
<tr>
<td>データ抽出</td>
<td>「JSONは有効なようです。」</td>
<td>スキーマ検証に合格し、サンプリングしたレコードが元データと一致する。</td>
</tr>
<tr>
<td>コンテンツ</td>
<td>「この文章はわかりやすい気がします。」</td>
<td>名前の付いたルーブリック、ファクトチェック、リンク確認、読者テストに合格している。</td>
</tr>
<tr>
<td>オペレーション</td>
<td>「リクエストは成功しました。」</td>
<td>外部システムが期待どおりの状態を返し、監査記録が存在する。</td>
</tr>
</tbody>
</table>
だからこそツールが重要なのです。テスト、ブラウザ、データベース、バリデーター、そして人間のレビューが、内部の推測を観察可能な結果に変えてくれます。
## 作り手と検証者を分ける
リスクの低い作業なら、1つのモデルが草稿を書いてセルフレビューしても構いません。重要な作業では、別の役割と限定された権限を持つ検証者(チェッカー)を使いましょう。
<InfoGrid columns={2} items={[
{ label: "作り手(メーカー)", description: "変更を提案し、アクション用のツールを呼び出し、どんな証拠を集めるべきかを説明します。", color: "amber" },
{ label: "検証者(チェッカー)", description: "目標・成果物・証拠を受け取り、ルーブリックを適用します。自分が採点する作業物を、黙って書き換えることはできません。", color: "green" },
]} />
検証者は別のAIである必要はありません。使える中で最も決定的な評価者を優先しましょう:
1. **厳密なチェック** — 型、スキーマ、制約、権限、ハッシュ
2. **実行可能なチェック** — テスト、リンター、シミュレーション、リンク検証
3. **ルーブリックによるチェック** — 明示された基準を使う、独立したモデルまたは人間
4. **成果によるチェック** — 実際のユーザー行動や、時間をかけて測る本番環境の指標
<Callout type="tip" title="自信は証拠ではない">
成果物を作ったのと同じモデルが生成した確信度スコアも、やはりモデルの出力にすぎません。証明としてではなく、処理を振り分けるためのヒントとして扱いましょう。
</Callout>
## 状態はループの背骨
コンテキストとは、モデルが**このターンに**見るものです。状態とは、次のターンが作業を繰り返したり忘れたりせずに続行できるようにする、コンパクトな記録です。
<Checklist title="役に立つループの状態" items={[
{ text: "現在の目標と受け入れ基準" },
{ text: "すでに試したアクションと、その観察可能な結果" },
{ text: "生成した成果物と、そのバージョンや安定した参照" },
{ text: "評価者の判定と、未解決の問題" },
{ text: "消費した予算と、まだ使える権限" },
{ text: "続行・停止・エスカレーションの理由" },
]} />
保存すべきは簡潔な意思決定と証拠であって、モデル内部の思考の連鎖ではありません。良い状態とは、小さく、検査可能で、安全に再開できるものです。
## よくあるループの形
### 修復ループ
`再現する → 一つだけ変える → チェックを実行する → 診断する → 繰り返すか停止する`
コード、設定、データクリーンアップなど、実行可能なフィードバックが得られるあらゆるタスクに最適です。
### 評価者・最適化者ループ
`生成する → ルーブリックで採点する → 的を絞ったフィードバックを返す → 修正する`
執筆、翻訳、デザイン批評など、言語化されたフィードバックによって品質が上がる成果物に最適です。
### リサーチループ
`検索する → 情報源を精査する → 欠落や矛盾を特定する → 再検索する → 統合する`
どこまで調べれば十分かが事前にわからないときに最適です。停止ルールは検索結果の件数ではなく、証拠のカバー率を測るべきです。
### 人間の承認を挟むループ
`準備する → 自動で検証する → リスクの高いアクションの前で一時停止する → 人間が承認または軌道修正する`
支払い、公開、削除、アクセス権の変更、医療や法律に関わる判断など、重大な結果を伴うアクションに最適です。
## 設計段階で潰しておくべき失敗モード
<table>
<thead>
<tr>
<th>失敗</th>
<th>何が起きたか</th>
<th>エンジニアリングによる対策</th>
</tr>
</thead>
<tbody>
<tr>
<td>無限リトライ</td>
<td>ループに測定可能な成功条件も、予算による出口もない。</td>
<td>明示的な終了状態と、イテレーション回数の絶対的な上限を追加する。</td>
</tr>
<tr>
<td>自画自賛</td>
<td>作り手が、証拠なしに自分のもっともらしい答えを受け入れる。</td>
<td>決定的なチェックか、独立した検証者を使う。</td>
</tr>
<tr>
<td>コンテキストの雪だるま</td>
<td>イテレーションのたびにすべてを追記し続け、モデルがシグナルを見失う。</td>
<td>構造化された状態を永続化し、関連するコンテキストだけを組み立て直す。</td>
</tr>
<tr>
<td>スラッシング</td>
<td>ループが2つの修正案の間を行ったり来たりする。</td>
<td>状態の繰り返しを検知し、別の戦略への切り替えか人間へのエスカレーションを必須にする。</td>
</tr>
<tr>
<td>目標ドリフト</td>
<td>局所的な改善が、本来の目的に取って代わってしまう。</td>
<td>サイクルごとに、不変の目標と受け入れ基準を読み直す。</td>
</tr>
<tr>
<td>危険な繰り返し</td>
<td>元に戻せるはずのミスも、繰り返されると害になる。</td>
<td>権限、副作用、実行頻度、支出、影響範囲を制限する。</td>
</tr>
</tbody>
</table>
## 最小限の実装
```typescript
let state = initialize(goal, acceptanceCriteria, budget);
while (state.budget.remaining > 0) {
const context = assembleRelevantContext(state);
const proposedAction = await maker.chooseAction(context);
const observation = await tools.executeWithinPolicy(proposedAction);
const verdict = await evaluator.check({ goal, observation, state });
state = recordIteration(state, { proposedAction, observation, verdict });
if (verdict.status === "passed") return complete(state);
if (verdict.status === "unsafe" || verdict.status === "blocked") {
return escalateToHuman(state);
}
state = adaptPlan(state, verdict.feedback);
}
return stopWithBudgetReport(state);
```
コードは簡単な部分です。難しいのはドメイン固有の問いのほうです。どのテストがバグの解消を証明するのか?どの情報源が信頼に足るのか?どのアクションなら元に戻せるのか?最終ステップを承認できるのは誰か?──こうした判断こそが、ループエンジニアリングの本当の仕事です。
## 実践:ループを設計する
<TryIt
title="ループ契約の草案を書く"
description="変数の部分を、あなた自身の仕事で繰り返し発生するタスクに置き換えてください。弱い証拠や曖昧な停止ルールがないか、AIに指摘させてみましょう。"
prompt={`次のタスクのために、上限のあるAI作業ループを設計してください:
タスク: \${task:毎朝、新しいカスタマーサポートの問い合わせをトリアージする}
以下を定義してください:
1. 観察可能な目標
2. トリガーと必要な入力
3. 許可されるアクションとツールの権限
4. 外部環境から得られる信頼できる観察
5. 評価者とそのルーブリック
6. イテレーション間で引き継ぐ状態
7. 成功・失敗・予算切れの3つの出口
8. リスクの高いアクションに対する人間の承認ゲート
9. すべてのイテレーションを監査可能にするトレースの形式
そのうえで、この設計で最も起こりやすい失敗モードを3つ特定し、それらを防ぐようにループを修正してください。`}
/>
<Quiz
question="エージェントがコードを編集し、差分を読み直して「バグは修正済みです」と言いました。このループに欠けている最も重要な要素は何でしょうか?"
options={[
"より長いシステムプロンプト",
"停止ルールに照らして評価される外部の観察",
"2回目の編集パス",
"より大きなコンテキストウィンドウ"
]}
correctIndex={1}
explanation="エージェントは成果物を作って自分で眺めただけで、独立した証拠を集めていません。不具合を再現し、関連するテストを実行すれば、停止ルールで評価できる観察可能なシグナルが得られます。"
/>
## さらに学ぶために
- [Loop Engineering — Addy Osmani](https://addyosmani.com/blog/loop-engineering/) — 手作業のフォローアッププロンプトを設計されたシステムに置き換える、という近年の枠組みの提唱。検証と人間の責任に関する実践的な注意点も
- [Building Effective Agents — Anthropic](https://www.anthropic.com/engineering/building-effective-agents) — 評価者・最適化者ワークフロー、環境からのフィードバック、停止条件、そしてエージェント的な複雑さが正当化されるのはいつかの指針
- [A Practical Guide to Building Agents — OpenAI](https://openai.com/business/guides-and-resources/a-practical-guide-to-building-ai-agents/) — エージェントの実行、終了条件、ツール、ガードレール、人間の介入
- [ReAct: Synergizing Reasoning and Acting in Language Models](https://arxiv.org/abs/2210.03629) — 外部環境からの観察とアクションを交互に織り交ぜることに関する基礎研究
## まとめ
<Callout type="tip" title="プロンプトだけでなく、フィードバックを作り込む">
信頼できるループには、測定可能な目標、範囲の限定されたアクション、信頼できる観察、明示的な評価者、コンパクトな状態、安全な出口、そして重大な結果が伴う場面での人間の判断が備わっています。モデルはループの中にいますが、ループそのものに責任を負うのは、あくまでエンジニアです。
</Callout>
@@ -1,405 +0,0 @@
컨텍스트 엔지니어링이 **모델이 무엇을 볼 수 있는지**를 결정한다면, 루프 엔지니어링은 **시스템이 다음에 무엇을 할지**를 결정합니다.
사람이 답변을 읽고 다음 프롬프트를 쓰는 일을 반복하는 대신, 루프는 그 후속 작업 자체를 설계된 시스템으로 바꿉니다. AI에게 목표를 주고, 행동하게 하고, 실제 피드백을 관찰하고, 결과를 평가한 뒤, 적응하거나 멈추게 하는 것입니다.
<Callout type="info" title="한 줄 정의">
루프 엔지니어링은 AI 시스템을 둘러싼 피드백 사이클, 즉 목표, 행동, 관찰, 평가, 상태, 가드레일, 중지 규칙을 설계하여 작업이 검증 가능한 결과를 향해 나아가게 만드는 실천법입니다.
</Callout>
## 좋은 프롬프트에서 좋은 루프로
프롬프트는 훌륭한 첫 시도를 만들어낼 수 있습니다. 루프가 유용해지는 것은 단계 수를 미리 알 수 없을 때, 환경이 바뀔 수 있을 때, 또는 첫 시도를 증거에 비추어 검증해야 할 때입니다.
<Compare
before={{
label: "원샷 프롬프트",
content: "질문 → 생성 → 반환\n\n모델이 답변을 내놓습니다. 그것이 통했는지는 사람이 판단하고, 다음 프롬프트도 사람이 작성합니다."
}}
after={{
label: "설계된 루프",
content: "프레이밍 → 행동 → 관찰 → 평가 → 적응\n ↑______________________↓\n\n시스템이 증거를 수집하고 상태를 기록하며, 한 번 더 도는 것이 유용할 때만 계속합니다."
}}
/>
이 아이디어는 앞서 나온 에이전트 패턴들 위에 서 있습니다. [ReAct 논문](https://arxiv.org/abs/2210.03629)은 행동과 외부 환경의 관찰을 번갈아 수행하는 것의 가치를 보여주었습니다. Anthropic의 [평가자-최적화자 패턴](https://www.anthropic.com/engineering/building-effective-agents)은 여기에 별도의 피드백 단계를 더했고, OpenAI의 [에이전트 구축 실전 가이드](https://openai.com/business/guides-and-resources/a-practical-guide-to-building-ai-agents/)는 에이전트 실행을 종료 조건이 통제하는 루프로 설명합니다. 비교적 새로운 용어인 **루프 엔지니어링**은 이 사이클 전체를 의도적으로 설계하는 데 초점을 맞춥니다.
## 다섯 가지 동작
<InfoGrid items={[
{ label: "1. 프레이밍", description: "의도를 목표, 제약 조건, 성공 기준, 예산으로 구체화합니다.", color: "blue" },
{ label: "2. 행동", description: "검색, 편집, 계산, 도구 호출, 사람에게 질문하기 등 범위가 한정된 행동 하나를 선택합니다.", color: "amber" },
{ label: "3. 관찰", description: "테스트 출력, API 결과, 인용 출처, 사용자 피드백 등 실제로 일어난 일을 수집합니다.", color: "cyan" },
{ label: "4. 평가", description: "모델의 자신감이 아니라 명시적인 기준에 비추어 증거를 비교합니다.", color: "purple" },
{ label: "5. 적응", description: "상태를 갱신하고, 계획을 바꾸고, 안전하게 재시도하고, 사람에게 이관하거나 멈춥니다.", color: "green" },
]} />
루프의 본질은 화살표가 아닙니다. 엔지니어링은 **화살표 사이의 계약**에 있습니다. 무엇을 행동으로 인정할지, 어떤 관찰을 신뢰할 수 있는지, 누가 그것을 평가하는지, 어떤 상태가 살아남는지, 그리고 실행이 정확히 언제 끝나는지 말입니다.
<LoopEngineeringLab content={{
eyebrow: "루프 제어 / 인터랙티브 시뮬레이터",
title: "실제 피드백 루프를 한 단계씩 따라가 보세요",
description: "작업을 하나 고른 뒤 신호를 하나씩 진행해 보세요. 진전이 모델에게 다 됐냐고 물어보는 데서가 아니라, 환경의 증거와 명시적인 평가에서 나온다는 점에 주목하세요.",
chooseScenarioLabel: "루프 선택",
goalLabel: "목표",
stopRuleLabel: "중지 규칙",
evidenceLabel: "신뢰하는 증거",
iterationLabel: "반복 회차",
progressLabel: "검증된 진행률",
openIssuesLabel: "미해결 이슈",
currentSignalLabel: "현재 신호",
advanceLabel: "한 단계 진행",
nextIterationLabel: "다음 반복 시작",
resetLabel: "루프 초기화",
completeLabel: "목표 검증 완료",
completeDescription: "성공 기준이 충족되고 증거가 기록되었으므로, 루프는 한 사이클을 더 소비하는 대신 여기서 멈춥니다.",
stages: [
{ id: "frame", label: "프레이밍", verb: "계약을 다시 읽기" },
{ id: "act", label: "행동", verb: "범위가 한정된 행동 하나 실행" },
{ id: "observe", label: "관찰", verb: "외부 피드백 읽기" },
{ id: "evaluate", label: "평가", verb: "루브릭 적용" },
{ id: "adapt", label: "적응", verb: "다음 행동 갱신" },
],
scenarios: [
{
id: "code",
label: "결제 버그 수정",
goal: "정상적인 할인 동작은 바꾸지 않으면서 결제 총액을 바로잡습니다.",
stopRule: "대상 회귀 테스트가 통과하고, 전체 결제 테스트 스위트가 통과하고, 린트가 깨끗해야 합니다. 세 번의 시도가 소진되면 루프는 사람에게 이관합니다.",
evidence: "재현 절차, 테스트 출력, 코드 diff, 최종 회귀 테스트 스위트.",
cycles: [
{
action: "보고된 총액을 재현하고, 세금과 퍼센트 할인 조합에 대해 실패하는 테스트를 추가합니다.",
observation: "할인 적용 전에 세금을 반올림한 경우에만 테스트가 1센트 차이로 실패합니다.",
evaluation: "버그가 결정론적 신호로 재현되었지만, 원인은 아직 고쳐지지 않았습니다.",
adaptation: "반올림 경계를 조사하고 주문 총액 계산 경로만 변경합니다.",
progress: 34,
openIssues: 2,
},
{
action: "반올림을 최종 금액 경계로 옮기고 대상 결제 테스트를 실행합니다.",
observation: "회귀 테스트는 통과했지만, 이제 정액 할인에 대한 쿠폰 통합 테스트 하나가 실패합니다.",
evaluation: "첫 증상은 고쳐졌지만 변경 범위가 너무 넓습니다. 중지 규칙이 충족되지 않았습니다.",
adaptation: "패치 범위를 좁히고 세금 반올림과 쿠폰 반올림을 분리하는 테스트 케이스를 추가합니다.",
progress: 71,
openIssues: 1,
},
{
action: "범위를 좁힌 계산 수정을 적용한 뒤 회귀 테스트, 전체 결제 스위트, 린트를 실행합니다.",
observation: "모든 검사가 통과합니다. diff는 계산 함수 하나와 새 회귀 테스트만 건드립니다.",
evaluation: "모든 성공 기준에 독립적인 증거가 있고, 어떤 예산 한도도 초과하지 않았습니다.",
adaptation: "멈추고, 테스트 출력을 보존하고, 작은 diff를 사람 리뷰어에게 넘깁니다.",
progress: 100,
openIssues: 0,
},
],
},
{
id: "research",
label: "연구 주장 검증",
goal: "원격 근무가 항상 팀 생산성을 높인다는 주장을 평가합니다.",
stopRule: "신뢰할 수 있는 출처 세 개 이상이 뒷받침하는 균형 잡힌 결론에 도달하고, 이견과 한계가 명시되어야 합니다.",
evidence: "원본 출처 링크, 발행일, 연구 방법, 표본 크기, 인용된 지표.",
cycles: [
{
action: "최근 근거를 검색하고, 가장 자주 반복되는 생산성 통계를 원출처까지 추적합니다.",
observation: "대부분의 기사가 설문 문항이나 원자료 표본 링크 없이 한 벤더의 설문조사를 그대로 반복하고 있습니다.",
evaluation: "이 근거는 널리 퍼져 있지만 절대적인 주장을 뒷받침할 만큼 강하지 않습니다.",
adaptation: "동료 심사 연구와 공개 데이터셋을 우선하고, 반대되는 결과도 함께 검색합니다.",
progress: 28,
openIssues: 3,
},
{
action: "동료 심사를 거친 두 연구를 국가 노동 데이터셋과 비교합니다.",
observation: "결과가 작업 유형, 측정 방식, 완전 원격인지 하이브리드인지에 따라 달라집니다.",
evaluation: "근거가 '항상'이라는 단어와 모순됩니다. 조건부 결론이 점점 설득력을 얻고 있습니다.",
adaptation: "각 연구가 산출량, 근무 시간, 체감 생산성을 구분하는지 확인합니다.",
progress: 68,
openIssues: 1,
},
{
action: "증거 표를 만들고 모든 주장을 원본 출처와 대조해 검증합니다.",
observation: "출처들은 효과가 엇갈린다는 것을 뒷받침하며, 자율성, 협업 조율, 작업 유형을 핵심 변수로 지목합니다.",
evaluation: "결론이 뒷받침되고, 불확실성이 드러나 있으며, 출처 기준치가 충족되었습니다.",
adaptation: "조건을 명시한 답변으로 멈추고, 검토를 위해 증거 표를 보존합니다.",
progress: 100,
openIssues: 0,
},
],
},
{
id: "writing",
label: "출시 이메일 다듬기",
goal: "혜택을 명확히 설명하고 유효한 데모 신청 클릭을 이끌어내는 간결한 출시 이메일을 만듭니다.",
stopRule: "이메일이 문체 루브릭을 통과하고, 140단어 이내를 유지하고, 명확한 행동 유도 문구 하나를 담고, 사실 검토를 통과해야 합니다.",
evidence: "단어 수, 루브릭 점수, 링크 검증 결과, 제품 브리프의 원본 사실, 리뷰어 메모.",
cycles: [
{
action: "제품 브리프를 바탕으로 초안을 쓰고, 결과를 독자·문체 루브릭에 비추어 채점합니다.",
observation: "초안은 204단어이고, 기능 나열로 시작하며, 서로 경쟁하는 행동 유도 문구가 두 개 들어 있습니다.",
evaluation: "사실은 정확하지만, 정보 우선순위와 길이 기준이 통과하지 못했습니다.",
adaptation: "고객이 얻는 결과로 시작하고, 부차적인 행동 유도를 제거하고, 구현 세부 사항을 덜어냅니다.",
progress: 41,
openIssues: 3,
},
{
action: "도입부를 다시 쓰고 본문을 문제-혜택-근거의 한 흐름으로 압축합니다.",
observation: "이메일은 126단어에 CTA도 하나뿐이지만, 근거 문장이 베타 결과를 과장하고 있습니다.",
evaluation: "구조는 통과했습니다. 그러나 사실의 정확한 표현은 여전히 루브릭을 통과하지 못합니다.",
adaptation: "포괄적인 주장을 실측된 베타 결과로 바꾸고 최종 사실 확인을 요청합니다.",
progress: 79,
openIssues: 1,
},
{
action: "검증된 지표를 넣고, 링크를 확인하고, 전체 루브릭을 한 번 더 돌립니다.",
observation: "이메일은 132단어이고, 링크가 정상 작동하고, 사실이 브리프와 일치하며, 루브릭의 모든 항목이 통과합니다.",
evaluation: "결과물이 검토 가능한 증거와 함께 정의된 품질 기준을 충족합니다.",
adaptation: "멈추고 승인된 버전을 캠페인 담당자에게 보냅니다.",
progress: 100,
openIssues: 0,
},
],
},
],
}} />
## 루프 계약부터 작성하세요
모델이나 프레임워크를 고르기 전에 작은 계약서를 먼저 쓰세요. 이 항목들이 모호하면, 루프는 그 모호함을 반복되는 비용으로 바꿔 버립니다.
```yaml
goal: "관찰 가능한 어떤 상태가 참이 되어야 하는가?"
inputs: "무엇이 루프를 시작시키는가?"
state: "어떤 사실과 시도 기록이 반복 사이에 유지되는가?"
actions: "시스템은 어떤 도구를 어떤 권한으로 사용할 수 있는가?"
observations: "그 행동들로부터 어떤 외부 신호가 돌아오는가?"
evaluator: "어떤 루브릭이나 결정론적 검사가 결과를 판정하는가?"
success: "목표가 달성되었음을 어떤 증거가 증명하는가?"
failure: "어떤 조건에서 복구나 사람의 도움이 필요한가?"
budget: "최대 턴 수, 시간, 토큰, 비용, 또는 부수 효과"
```
<Callout type="warning" title="출구 없는 루프는 그 자체가 실패 모드입니다">
항상 세 가지 출구를 정의하세요. 증거가 목표를 충족하면 **성공**, 복구가 더 이상 유용하지 않으면 **실패**, 루프가 허용된 비용이나 위험 한계에 도달하면 **예산 소진**입니다.
</Callout>
## 관찰은 바깥세상에서 와야 합니다
모델이 “이건 맞아 보입니다”라고 말하는 것은 강한 증거가 아닙니다. 유용한 관찰은 판정 대상인 답변 바깥에 있는 무언가가 만들어냅니다.
<table>
<thead>
<tr>
<th>작업</th>
<th>약한 관찰</th>
<th>강한 관찰</th>
</tr>
</thead>
<tbody>
<tr>
<td>코드 수정</td>
<td>“이 수정이면 될 겁니다.”</td>
<td>원래 실패를 재현한 뒤, 회귀 테스트와 전체 스위트가 통과합니다.</td>
</tr>
<tr>
<td>리서치</td>
<td>“여러 출처가 동의합니다.”</td>
<td>각 주장이 날짜, 방법, 이견까지 기록된 원본 출처로 연결됩니다.</td>
</tr>
<tr>
<td>데이터 추출</td>
<td>“JSON이 유효해 보입니다.”</td>
<td>스키마 검증이 통과하고, 표본 레코드가 원본과 일치합니다.</td>
</tr>
<tr>
<td>콘텐츠</td>
<td>“카피가 명확한 느낌입니다.”</td>
<td>이름이 명시된 루브릭, 사실 검토, 링크 확인, 독자 테스트를 통과합니다.</td>
</tr>
<tr>
<td>운영</td>
<td>“요청이 성공했습니다.”</td>
<td>외부 시스템이 기대한 상태를 반환하고, 감사 기록이 존재합니다.</td>
</tr>
</tbody>
</table>
도구가 중요한 이유가 바로 이것입니다. 테스트, 브라우저, 데이터베이스, 검증기, 사람의 검토가 내부의 추측을 관찰 가능한 결과로 바꿔 줍니다.
## 작성자와 검증자를 분리하세요
위험이 낮은 작업이라면 모델 하나가 초안을 쓰고 스스로 검토해도 됩니다. 중요한 작업이라면 역할이 다르고 권한이 제한된 검증자를 두세요.
<InfoGrid columns={2} items={[
{ label: "작성자(Maker)", description: "변경을 제안하고, 행동 도구를 호출하고, 어떤 증거를 수집해야 하는지 설명합니다.", color: "amber" },
{ label: "검증자(Checker)", description: "목표, 결과물, 증거를 받아 루브릭을 적용합니다. 자신이 채점하는 작업물을 몰래 고쳐 쓸 수 없습니다.", color: "green" },
]} />
검증자가 반드시 또 다른 AI일 필요는 없습니다. 사용할 수 있는 것 중 가장 결정론적인 평가자를 우선하세요.
1. **정확성 검사** — 타입, 스키마, 제약 조건, 권한, 해시
2. **실행 가능한 검사** — 테스트, 린터, 시뮬레이션, 링크 검증
3. **루브릭 검사** — 명시된 기준을 적용하는 독립적인 모델이나 사람
4. **결과 검사** — 시간에 걸친 실제 사용자 행동이나 프로덕션 지표
<Callout type="tip" title="자신감은 증거가 아닙니다">
결과물을 만든 바로 그 모델이 생성한 신뢰도 점수는 여전히 모델의 출력일 뿐입니다. 증명이 아니라 라우팅 힌트로 취급하세요.
</Callout>
## 상태는 루프의 뼈대입니다
컨텍스트는 모델이 **이번 턴에** 보는 것입니다. 상태는 다음 턴이 이미 한 작업을 반복하지도, 잊지도 않고 이어가게 해 주는 압축된 기록입니다.
<Checklist title="유용한 루프 상태" items={[
{ text: "현재 목표와 인수 기준" },
{ text: "이미 시도한 행동과 그 관찰 가능한 결과" },
{ text: "생성된 산출물과 그 버전 또는 안정적인 참조" },
{ text: "평가자의 판정과 미해결 이슈" },
{ text: "소진한 예산과 아직 사용할 수 있는 권한" },
{ text: "계속할지, 멈출지, 사람에게 이관할지에 대한 이유" },
]} />
간결한 결정과 증거를 저장하세요. 모델의 내부 사고 과정을 통째로 저장하는 것이 아닙니다. 좋은 상태는 작고, 들여다볼 수 있으며, 안전하게 재개할 수 있습니다.
## 흔한 루프 형태
### 수리 루프
`재현 → 한 가지만 변경 → 검사 실행 → 진단 → 반복 또는 중지`
코드, 설정, 데이터 정리 등 실행 가능한 피드백이 있는 모든 작업에 가장 적합합니다.
### 평가자-최적화자 루프
`생성 → 루브릭으로 채점 → 구체적인 피드백 반환 → 수정`
글쓰기, 번역, 디자인 비평처럼 언어로 표현된 피드백을 통해 품질이 좋아지는 산출물에 가장 적합합니다.
### 리서치 루프
`검색 → 출처 검토 → 공백이나 모순 식별 → 재검색 → 종합`
완결 시점을 미리 알 수 없을 때 가장 좋습니다. 중지 규칙은 검색 결과의 개수가 아니라 증거가 얼마나 충분히 확보되었는지를 측정해야 합니다.
### 사람 승인 게이트 루프
`준비 → 자동 검증 → 고위험 행동 직전에 일시 정지 → 사람이 승인하거나 방향 전환`
결제, 게시, 삭제, 접근 권한 변경, 의료·법률 관련 결정 등 파급이 큰 행동에 가장 적합합니다.
## 설계로 없애야 할 실패 모드
<table>
<thead>
<tr>
<th>실패</th>
<th>무슨 일이 일어났나</th>
<th>엔지니어링 대응</th>
</tr>
</thead>
<tbody>
<tr>
<td>무한 재시도</td>
<td>루프에 측정 가능한 성공 출구도, 예산 출구도 없습니다.</td>
<td>명시적인 종료 상태와 엄격한 반복 횟수 상한을 추가합니다.</td>
</tr>
<tr>
<td>자화자찬</td>
<td>작성자가 증거 없이 그럴듯한 자기 답변을 그대로 받아들입니다.</td>
<td>결정론적 검사나 독립적인 검증자를 사용합니다.</td>
</tr>
<tr>
<td>컨텍스트 눈덩이</td>
<td>매 반복마다 모든 것을 덧붙이다가 모델이 핵심 신호를 잃습니다.</td>
<td>구조화된 상태를 유지하고, 관련 있는 컨텍스트만 다시 조립합니다.</td>
</tr>
<tr>
<td>스래싱</td>
<td>루프가 두 가지 수정 사이를 하염없이 오갑니다.</td>
<td>반복되는 상태를 감지하고, 다른 전략이나 사람 이관을 강제합니다.</td>
</tr>
<tr>
<td>목표 이탈</td>
<td>국지적인 개선이 원래 목표를 대체해 버립니다.</td>
<td>매 사이클마다 변경 불가능한 목표와 인수 기준을 다시 읽습니다.</td>
</tr>
<tr>
<td>위험한 반복</td>
<td>되돌릴 수 있는 실수도 반복되면 해로워집니다.</td>
<td>권한, 부수 효과, 실행 빈도, 지출, 영향 범위를 제한합니다.</td>
</tr>
</tbody>
</table>
## 최소한의 구현
```typescript
let state = initialize(goal, acceptanceCriteria, budget);
while (state.budget.remaining > 0) {
const context = assembleRelevantContext(state);
const proposedAction = await maker.chooseAction(context);
const observation = await tools.executeWithinPolicy(proposedAction);
const verdict = await evaluator.check({ goal, observation, state });
state = recordIteration(state, { proposedAction, observation, verdict });
if (verdict.status === "passed") return complete(state);
if (verdict.status === "unsafe" || verdict.status === "blocked") {
return escalateToHuman(state);
}
state = adaptPlan(state, verdict.feedback);
}
return stopWithBudgetReport(state);
```
코드는 쉬운 부분입니다. 어려운 질문은 도메인의 질문입니다. 어떤 테스트가 버그가 사라졌음을 증명하는가? 어떤 출처가 권위 있는가? 어떤 행동이 되돌릴 수 있는가? 마지막 단계는 누가 승인할 수 있는가? 이런 결정이 바로 루프 엔지니어링의 진짜 작업입니다.
## 연습: 루프 설계하기
<TryIt
title="루프 계약 초안 작성하기"
description="변수를 여러분의 업무에서 반복되는 작업으로 바꿔 보세요. 그리고 AI에게 허술한 증거와 모호한 중지 규칙을 지적해 달라고 요청하세요."
prompt={`다음 작업을 위한 범위가 한정된 AI 작업 루프를 설계해 주세요:
작업: \${task:매일 아침 새로 들어온 고객 지원 문의 분류하기}
다음을 정의하세요:
1. 관찰 가능한 목표
2. 트리거와 필수 입력
3. 허용되는 행동과 도구 권한
4. 외부 환경에서 오는 신뢰할 수 있는 관찰
5. 평가자와 그 루브릭
6. 반복 사이에 유지되는 상태
7. 성공, 실패, 예산 소진이라는 세 가지 출구
8. 위험한 행동에 대한 사람 승인 게이트
9. 모든 반복을 감사할 수 있게 만드는 추적 기록 형식
그런 다음 이 설계에서 가장 발생 가능성이 높은 실패 모드 세 가지를 찾고, 이를 방지하도록 루프를 수정하세요.`}
/>
<Quiz
question="에이전트가 코드를 수정하고, 자기가 만든 diff를 다시 읽어 본 뒤 버그가 고쳐졌다고 말합니다. 이 루프에서 가장 중요한 빠진 부분은 무엇일까요?"
options={[
"더 긴 시스템 프롬프트",
"중지 규칙에 비추어 평가되는 외부 관찰",
"두 번째 편집 패스",
"더 큰 컨텍스트 윈도우"
]}
correctIndex={1}
explanation="에이전트는 결과물을 만들고 살펴보긴 했지만, 독립적인 증거를 수집하지 않았습니다. 실패를 재현하고 관련 테스트를 실행하면 중지 규칙이 평가할 수 있는 관찰 가능한 신호가 만들어집니다."
/>
## 추가 자료
- [Loop Engineering — Addy Osmani](https://addyosmani.com/blog/loop-engineering/) — 수동으로 후속 프롬프트를 쓰는 일을 설계된 시스템으로 대체하자는 최근의 프레이밍과, 검증 및 사람의 책임에 대한 실용적인 주의사항
- [Building Effective Agents — Anthropic](https://www.anthropic.com/engineering/building-effective-agents) — 평가자-최적화자 워크플로, 환경 피드백, 중지 조건, 그리고 에이전트 수준의 복잡성이 언제 정당화되는지에 대한 지침
- [A Practical Guide to Building Agents — OpenAI](https://openai.com/business/guides-and-resources/a-practical-guide-to-building-ai-agents/) — 에이전트 실행, 종료 조건, 도구, 가드레일, 사람의 개입
- [ReAct: Synergizing Reasoning and Acting in Language Models](https://arxiv.org/abs/2210.03629) — 행동과 외부 환경의 관찰을 번갈아 수행하는 것에 대한 기초 연구
## 요약
<Callout type="tip" title="프롬프트만이 아니라 피드백을 설계하세요">
신뢰할 수 있는 루프에는 측정 가능한 목표, 범위가 한정된 행동, 신뢰할 수 있는 관찰, 명시적인 평가자, 압축된 상태, 안전한 출구, 그리고 결과가 중대한 곳에는 사람의 판단이 있습니다. 모델은 루프 안에 있지만, 루프에 대한 책임은 여전히 엔지니어에게 있습니다.
</Callout>
@@ -1,405 +0,0 @@
Context engineering bepaalt **wat het model kan zien**. Loop engineering bepaalt **wat het systeem daarna doet**.
In plaats van dat iemand telkens opnieuw een antwoord leest en de volgende prompt schrijft, maakt een loop van dat vervolgwerk een ontworpen systeem. Het geeft een AI een doel, laat hem handelen, observeert echte feedback, evalueert het resultaat en past de aanpak aan — of stopt.
<Callout type="info" title="De Korte Definitie">
Loop engineering is het bewust ontwerpen van de feedbackcyclus rond een AI-systeem: het doel, de acties, observaties, evaluatie, state, guardrails en stopregels die het werk richting een verifieerbaar resultaat bewegen.
</Callout>
## Van een goede prompt naar een goede loop
Een prompt kan een sterke eerste poging opleveren. Een loop is nuttig wanneer het aantal stappen vooraf niet bekend is, de omgeving kan veranderen, of de eerste poging aan bewijs getoetst moet worden.
<Compare
before={{
label: "Eenmalige prompt",
content: "Vraag → Genereer → Antwoord\n\nHet model produceert een antwoord. Een mens beoordeelt of het gelukt is en schrijft de volgende prompt."
}}
after={{
label: "Ontworpen loop",
content: "Kaderen → Handelen → Observeren → Evalueren → Aanpassen\n ↑______________________↓\n\nHet systeem verzamelt bewijs, legt state vast en gaat alleen door zolang een volgende ronde nuttig is."
}}
/>
Dit idee bouwt voort op eerdere agent-patronen. De [ReAct-paper](https://arxiv.org/abs/2210.03629) liet zien hoe waardevol het is om acties af te wisselen met observaties uit een externe omgeving. Het [evaluator-optimizer-patroon](https://www.anthropic.com/engineering/building-effective-agents) van Anthropic voegt daar een aparte feedbackstap aan toe, en de [praktische gids voor agents](https://openai.com/business/guides-and-resources/a-practical-guide-to-building-ai-agents/) van OpenAI beschrijft agent-runs als loops die worden begrensd door exitcondities. De nieuwere term **loop engineering** richt de aandacht op het bewust ontwerpen van die hele cyclus.
## De vijf zetten
<InfoGrid items={[
{ label: "1. Kaderen", description: "Vertaal de intentie naar een doel, randvoorwaarden, succescriteria en een budget.", color: "blue" },
{ label: "2. Handelen", description: "Kies één begrensde actie: zoeken, bewerken, rekenen, een tool aanroepen of een mens iets vragen.", color: "amber" },
{ label: "3. Observeren", description: "Verzamel wat er werkelijk gebeurd is: testuitvoer, API-resultaten, bronvermeldingen of gebruikersfeedback.", color: "cyan" },
{ label: "4. Evalueren", description: "Leg het bewijs naast expliciete criteria — niet naast het zelfvertrouwen van het model.", color: "purple" },
{ label: "5. Aanpassen", description: "Werk de state bij, wijzig het plan, probeer veilig opnieuw, escaleer of stop.", color: "green" },
]} />
De loop zit niet in de pijlen. Het echte engineeringwerk zit in de **contracten tussen de pijlen**: wat telt als actie, welke observaties betrouwbaar zijn, wie ze beoordeelt, welke state bewaard blijft en wanneer de uitvoering precies eindigt.
<LoopEngineeringLab content={{
eyebrow: "Loopbesturing / interactieve simulator",
title: "Doorloop stap voor stap een werkende feedbackloop",
description: "Kies een taak en ga telkens één signaal verder. Let op hoe de voortgang voortkomt uit bewijs uit de omgeving en expliciete evaluatie — niet uit de vraag aan het model of het zich klaar voelt.",
chooseScenarioLabel: "Kies een loop",
goalLabel: "Doel",
stopRuleLabel: "Stopregel",
evidenceLabel: "Vertrouwd bewijs",
iterationLabel: "Iteratie",
progressLabel: "Geverifieerde voortgang",
openIssuesLabel: "Open punten",
currentSignalLabel: "Huidig signaal",
advanceLabel: "Eén stap verder",
nextIterationLabel: "Start de volgende iteratie",
resetLabel: "Loop resetten",
completeLabel: "Doel geverifieerd",
completeDescription: "Aan de succescriteria is voldaan, het bewijs is vastgelegd en de loop stopt in plaats van nog een cyclus te verbruiken.",
stages: [
{ id: "frame", label: "Kaderen", verb: "Herlees het contract" },
{ id: "act", label: "Handelen", verb: "Doe één begrensde zet" },
{ id: "observe", label: "Observeren", verb: "Lees de externe feedback" },
{ id: "evaluate", label: "Evalueren", verb: "Pas de rubric toe" },
{ id: "adapt", label: "Aanpassen", verb: "Stel de volgende zet bij" },
],
scenarios: [
{
id: "code",
label: "Repareer een bug in de checkout",
goal: "Corrigeer de ordertotalen in de checkout zonder geldig kortingsgedrag te veranderen.",
stopRule: "De gerichte regressietest slaagt, de volledige checkout-suite slaagt en lint is schoon — of drie pogingen zijn verbruikt en de loop escaleert.",
evidence: "Reproductiestappen, testuitvoer, de code-diff en de afsluitende regressiesuite.",
cycles: [
{
action: "Reproduceer het gerapporteerde totaal en voeg een falende test toe voor btw plus procentuele korting.",
observation: "De test faalt met precies één cent, maar alleen wanneer de btw wordt afgerond vóórdat de korting wordt toegepast.",
evaluation: "De bug is gereproduceerd met een deterministisch signaal, maar de oorzaak is nog niet verholpen.",
adaptation: "Onderzoek de afrondingsgrens en wijzig alleen het berekeningspad van het ordertotaal.",
progress: 34,
openIssues: 2,
},
{
action: "Verplaats de afronding naar de laatste monetaire grens en draai gerichte checkout-tests.",
observation: "De regressietest slaagt, maar één integratietest voor coupons faalt nu op een korting met een vast bedrag.",
evaluation: "Het eerste symptoom is verholpen, maar de wijziging is te breed. Aan de stopregel is niet voldaan.",
adaptation: "Maak de patch smaller en voeg een testcase toe die btw-afronding scheidt van couponafronding.",
progress: 71,
openIssues: 1,
},
{
action: "Pas de smalle rekenfix toe en draai daarna de regressietest, de volledige checkout-suite en lint.",
observation: "Alle checks slagen. De diff raakt één berekeningsfunctie en de nieuwe regressietest.",
evaluation: "Elk succescriterium heeft onafhankelijk bewijs en geen enkele budgetlimiet is overschreden.",
adaptation: "Stop, bewaar de testuitvoer en geef de kleine diff door aan een menselijke reviewer.",
progress: 100,
openIssues: 0,
},
],
},
{
id: "research",
label: "Verifieer een onderzoeksclaim",
goal: "Beoordeel de bewering dat werken op afstand de teamproductiviteit altijd verhoogt.",
stopRule: "Een gekalibreerde conclusie wordt onderbouwd door minstens drie geloofwaardige bronnen, met vermelding van tegenstrijdigheden en beperkingen.",
evidence: "Directe bronlinks, publicatiedata, onderzoeksmethoden, steekproefgroottes en geciteerde cijfers.",
cycles: [
{
action: "Zoek naar recent bewijs en herleid de meest herhaalde productiviteitsstatistiek tot de oorspronkelijke bron.",
observation: "De meeste artikelen herhalen een leveranciersenquête zonder link naar de vragenlijst of de ruwe steekproef.",
evaluation: "Het bewijs is populair, maar niet sterk genoeg om een absolute claim te dragen.",
adaptation: "Geef voorrang aan peer-reviewed studies en openbare datasets; zoek ook naar tegengestelde bevindingen.",
progress: 28,
openIssues: 3,
},
{
action: "Vergelijk twee peer-reviewed studies met een nationale arbeidsmarktdataset.",
observation: "De resultaten verschillen per taaktype, meetmethode en of er volledig remote dan wel hybride wordt gewerkt.",
evaluation: "Het bewijs spreekt het woord 'altijd' tegen. Een voorwaardelijke conclusie begint verdedigbaar te worden.",
adaptation: "Controleer of de studies onderscheid maken tussen output, gewerkte uren en ervaren productiviteit.",
progress: 68,
openIssues: 1,
},
{
action: "Stel een bewijstabel op en verifieer elke claim aan de hand van de oorspronkelijke bron.",
observation: "De bronnen wijzen op gemengde effecten en noemen autonomie, coördinatie en taaktype als sleutelvariabelen.",
evaluation: "De conclusie is onderbouwd, de onzekerheid is zichtbaar en de brondrempel is gehaald.",
adaptation: "Stop met een genuanceerd antwoord en bewaar de bewijstabel voor review.",
progress: 100,
openIssues: 0,
},
],
},
{
id: "writing",
label: "Verfijn een lancerings-e-mail",
goal: "Schrijf een beknopte lancerings-e-mail die het voordeel uitlegt en gekwalificeerde demokliks oplevert.",
stopRule: "De e-mail doorstaat de tone-of-voice-rubric, blijft onder de 140 woorden, bevat één duidelijke call-to-action en overleeft een feitencheck.",
evidence: "Woordenaantal, rubric-scores, linkvalidatie, productfeiten uit de briefing en notities van de reviewer.",
cycles: [
{
action: "Schrijf een eerste versie op basis van de productbriefing en scoor het resultaat op de doelgroep- en tone-of-voice-rubric.",
observation: "Het concept telt 204 woorden, opent met features en bevat twee concurrerende calls-to-action.",
evaluation: "De feiten kloppen, maar de criteria voor hiërarchie en lengte falen.",
adaptation: "Open met het resultaat voor de klant, schrap de secundaire actie en snijd implementatiedetails weg.",
progress: 41,
openIssues: 3,
},
{
action: "Herschrijf de opening en comprimeer de bodytekst tot één opbouw van probleem, voordeel en bewijs.",
observation: "De e-mail telt 126 woorden en heeft één CTA, maar de bewijszin overdrijft een bètaresultaat.",
evaluation: "De structuur voldoet nu. De feitelijke onderbouwing zakt nog steeds voor de rubric.",
adaptation: "Vervang de brede claim door het gemeten bètaresultaat en vraag om een laatste feitencheck.",
progress: 79,
openIssues: 1,
},
{
action: "Voeg het geverifieerde cijfer in, valideer de link en loop de volledige rubric nog één keer na.",
observation: "De e-mail telt 132 woorden, de link werkt, de feiten kloppen met de briefing en elk rubric-onderdeel slaagt.",
evaluation: "Het artefact haalt de gedefinieerde kwaliteitslat, met controleerbaar bewijs.",
adaptation: "Stop en stuur de goedgekeurde versie naar de campagne-eigenaar.",
progress: 100,
openIssues: 0,
},
],
},
],
}} />
## Schrijf eerst het loopcontract
Schrijf eerst een klein contract, nog vóór je een model of framework kiest. Zijn deze velden vaag, dan vertaalt de loop die vaagheid in herhaalde kosten.
```yaml
goal: "Welke waarneembare toestand moet waar worden?"
inputs: "Wat start de loop?"
state: "Welke feiten en pogingen blijven tussen iteraties bewaard?"
actions: "Welke tools mag het systeem gebruiken, en met welke permissies?"
observations: "Welke externe signalen komen er van die acties terug?"
evaluator: "Welke rubric of deterministische checks beoordelen het resultaat?"
success: "Welk bewijs toont aan dat het doel bereikt is?"
failure: "Welke omstandigheden vragen om herstel of menselijke hulp?"
budget: "Maximum aantal beurten, tijd, tokens, geld of neveneffecten"
```
<Callout type="warning" title="Een Loop Zonder Uitgang Is een Faalmodus">
Definieer altijd drie uitgangen: **succes** wanneer het bewijs aan het doel voldoet, **falen** wanneer herstel niet langer zinvol is, en **budget op** wanneer de loop zijn toegestane kosten- of risicogrens bereikt.
</Callout>
## Observaties moeten uit de wereld komen
Dat het model zegt “dit ziet er correct uit”, is geen sterk bewijs. Een bruikbare observatie wordt geproduceerd door iets buiten het antwoord dat beoordeeld wordt.
<table>
<thead>
<tr>
<th>Taak</th>
<th>Zwakke observatie</th>
<th>Sterke observatie</th>
</tr>
</thead>
<tbody>
<tr>
<td>Code repareren</td>
<td>“De fix zou moeten werken.”</td>
<td>De oorspronkelijke fout wordt gereproduceerd, waarna de regressietest en de volledige suite slagen.</td>
</tr>
<tr>
<td>Onderzoek</td>
<td>“Meerdere bronnen zijn het erover eens.”</td>
<td>Claims linken naar de oorspronkelijke bronnen, met datums, methoden en tegenstrijdigheden vastgelegd.</td>
</tr>
<tr>
<td>Data-extractie</td>
<td>“De JSON lijkt geldig.”</td>
<td>De schemavalidatie slaagt en steekproefsgewijs gecontroleerde records komen overeen met de bron.</td>
</tr>
<tr>
<td>Content</td>
<td>“De tekst voelt helder.”</td>
<td>De tekst doorstaat een benoemde rubric, een feitencheck, linkcontroles en doelgroeptests.</td>
</tr>
<tr>
<td>Operations</td>
<td>“Het verzoek is gelukt.”</td>
<td>Het externe systeem meldt de verwachte toestand en er is een auditspoor vastgelegd.</td>
</tr>
</tbody>
</table>
Daarom doen tools ertoe: tests, browsers, databases, validators en menselijke review maken van een interne gok een waarneembaar resultaat.
## Scheid de maker van de controleur
Voor werk met weinig risico kan één model zowel schrijven als zichzelf nakijken. Voor belangrijk werk gebruik je een controleur met een andere taak en beperkte bevoegdheden.
<InfoGrid columns={2} items={[
{ label: "Maker", description: "Stelt de wijziging voor, roept actietools aan en legt uit welk bewijs verzameld moet worden.", color: "amber" },
{ label: "Controleur", description: "Ontvangt het doel, het artefact en het bewijs; past de rubric toe; mag het werk dat hij beoordeelt niet stilletjes herschrijven.", color: "green" },
]} />
De controleur hoeft geen tweede AI te zijn. Kies bij voorkeur de meest deterministische beoordelaar die beschikbaar is:
1. **Exacte checks** — types, schema's, constraints, permissies, hashes
2. **Uitvoerbare checks** — tests, linters, simulaties, linkvalidatie
3. **Rubric-checks** — een onafhankelijk model of mens dat benoemde criteria hanteert
4. **Uitkomstchecks** — echt gebruikersgedrag of productiemetrics over langere tijd
<Callout type="tip" title="Zelfvertrouwen Is Geen Bewijs">
Een confidencescore van hetzelfde model dat het artefact maakte, is nog steeds modeluitvoer. Behandel die als een hint voor de routering, niet als bewijs.
</Callout>
## State is de ruggengraat van de loop
Context is wat het model **deze beurt** ziet. State is het compacte verslag waarmee de volgende beurt verder kan zonder werk te herhalen of te vergeten.
<Checklist title="Nuttige loop-state" items={[
{ text: "Het huidige doel en de acceptatiecriteria" },
{ text: "Al geprobeerde acties en hun waarneembare resultaten" },
{ text: "Geproduceerde artefacten, met versies of stabiele verwijzingen" },
{ text: "Oordelen van de beoordelaar en onopgeloste punten" },
{ text: "Verbruikt budget en nog beschikbare permissies" },
{ text: "De reden om door te gaan, te stoppen of te escaleren" },
]} />
Bewaar beknopte beslissingen en bewijs — niet de interne gedachtegang van een model. Goede state is klein, inspecteerbaar en veilig om mee te hervatten.
## Veelvoorkomende loopvormen
### De reparatieloop
`reproduceer → verander één ding → draai de checks → stel een diagnose → herhaal of stop`
Ideaal voor code, configuratie, dataopschoning en elke taak met uitvoerbare feedback.
### De evaluator-optimizer-loop
`genereer → scoor met een rubric → geef gerichte feedback → herzie`
Ideaal voor schrijven, vertalen, designkritiek en output waarvan de kwaliteit verbetert door verwoorde feedback.
### De onderzoeksloop
`zoek → inspecteer bronnen → vind hiaten of conflicten → zoek opnieuw → synthetiseer`
Ideaal wanneer de volledigheid vooraf niet bekend is. De stopregel moet de bewijsdekking meten, niet het aantal zoekresultaten.
### De loop met menselijke goedkeuring
`bereid voor → verifieer automatisch → pauzeer vóór risicovolle acties → een mens keurt goed of stuurt bij`
Ideaal voor betalingen, publiceren, verwijderen, toegangswijzigingen, medische of juridische beslissingen en andere acties met grote gevolgen.
## Faalmodi die je wegontwerpt
<table>
<thead>
<tr>
<th>Faalmodus</th>
<th>Wat er gebeurt</th>
<th>Engineeringantwoord</th>
</tr>
</thead>
<tbody>
<tr>
<td>Eindeloos opnieuw proberen</td>
<td>De loop heeft geen meetbare succes- of budgetuitgang.</td>
<td>Voeg expliciete eindtoestanden en een harde iteratielimiet toe.</td>
</tr>
<tr>
<td>Zelffelicitatie</td>
<td>De maker accepteert zijn eigen plausibele antwoord zonder bewijs.</td>
<td>Gebruik deterministische checks of een onafhankelijke controleur.</td>
</tr>
<tr>
<td>Contextsneeuwbal</td>
<td>Elke iteratie plakt alles erbij totdat het model het signaal kwijtraakt.</td>
<td>Bewaar gestructureerde state en bouw alleen relevante context opnieuw op.</td>
</tr>
<tr>
<td>Pingpongen</td>
<td>De loop wisselt heen en weer tussen twee fixes.</td>
<td>Detecteer herhaalde toestanden en eis een andere strategie of escalatie.</td>
</tr>
<tr>
<td>Doelverschuiving</td>
<td>Lokale verbeteringen verdringen het oorspronkelijke doel.</td>
<td>Herlees elke cyclus het onveranderlijke doel en de acceptatiecriteria.</td>
</tr>
<tr>
<td>Onveilige herhaling</td>
<td>Een omkeerbare fout wordt schadelijk zodra hij wordt herhaald.</td>
<td>Beperk permissies, neveneffecten, tempo, uitgaven en de blast radius.</td>
</tr>
</tbody>
</table>
## Een minimale implementatie
```typescript
let state = initialize(goal, acceptanceCriteria, budget);
while (state.budget.remaining > 0) {
const context = assembleRelevantContext(state);
const proposedAction = await maker.chooseAction(context);
const observation = await tools.executeWithinPolicy(proposedAction);
const verdict = await evaluator.check({ goal, observation, state });
state = recordIteration(state, { proposedAction, observation, verdict });
if (verdict.status === "passed") return complete(state);
if (verdict.status === "unsafe" || verdict.status === "blocked") {
return escalateToHuman(state);
}
state = adaptPlan(state, verdict.feedback);
}
return stopWithBudgetReport(state);
```
De code is het makkelijke deel. De moeilijke vragen zijn domeinvragen: welke test bewijst dat de bug weg is? Welke bron is gezaghebbend? Welke actie is omkeerbaar? Wie mag de laatste stap goedkeuren? Die beslissingen zijn het eigenlijke werk van loop engineering.
## Oefening: ontwerp een loop
<TryIt
title="Stel een loopcontract op"
description="Vervang de variabelen door een terugkerende taak uit je eigen werk. Vraag de AI om zwak bewijs en vage stopregels ter discussie te stellen."
prompt={`Ontwerp een begrensde AI-werkloop voor deze taak:
TAAK: \${task:elke ochtend nieuwe supporttickets triëren}
Definieer:
1. Het waarneembare doel
2. De trigger en de vereiste input
3. Toegestane acties en toolpermissies
4. Vertrouwde observaties uit de externe omgeving
5. De beoordelaar en zijn rubric
6. De state die tussen iteraties bewaard blijft
7. Uitgangen voor succes, falen en een uitgeput budget
8. Menselijke goedkeuringsmomenten voor risicovolle acties
9. Een traceformaat dat elke iteratie controleerbaar maakt
Benoem daarna de drie meest waarschijnlijke faalmodi in je ontwerp en pas de loop aan om ze te voorkomen.`}
/>
<Quiz
question="Een agent bewerkt code, leest de diff terug en zegt dat de bug is opgelost. Wat is het belangrijkste ontbrekende onderdeel van de loop?"
options={[
"Een langere system prompt",
"Een externe observatie, getoetst aan een stopregel",
"Een tweede bewerkingsronde",
"Een groter contextvenster"
]}
correctIndex={1}
explanation="De agent heeft een artefact geproduceerd en bekeken, maar geen onafhankelijk bewijs verzameld. Door de fout te reproduceren en relevante tests te draaien ontstaat een waarneembaar signaal dat een stopregel kan toetsen."
/>
## Verder lezen
- [Loop Engineering — Addy Osmani](https://addyosmani.com/blog/loop-engineering/) — de recente framing waarin handmatige vervolgprompts plaatsmaken voor een ontworpen systeem, plus praktische waarschuwingen over verificatie en menselijke verantwoordelijkheid
- [Building Effective Agents — Anthropic](https://www.anthropic.com/engineering/building-effective-agents) — evaluator-optimizer-workflows, feedback uit de omgeving, stopcondities en richtlijnen voor wanneer agentische complexiteit gerechtvaardigd is
- [A Practical Guide to Building Agents — OpenAI](https://openai.com/business/guides-and-resources/a-practical-guide-to-building-ai-agents/) — agent-runs, exitcondities, tools, guardrails en menselijk ingrijpen
- [ReAct: Synergizing Reasoning and Acting in Language Models](https://arxiv.org/abs/2210.03629) — fundamenteel onderzoek naar het afwisselen van acties met observaties uit een externe omgeving
## Samenvatting
<Callout type="tip" title="Bouw de Feedback, Niet Alleen de Prompt">
Een betrouwbare loop heeft een meetbaar doel, begrensde acties, vertrouwde observaties, een expliciete beoordelaar, compacte state, veilige uitgangen en menselijk oordeel waar de gevolgen daarom vragen. Het model zit in de loop; de engineer blijft verantwoordelijk voor de loop.
</Callout>
@@ -1,405 +0,0 @@
A engenharia de contexto decide **o que o modelo pode ver**. A engenharia de loop decide **o que o sistema faz em seguida**.
Em vez de uma pessoa ler a resposta e escrever o próximo prompt repetidas vezes, um loop transforma esse trabalho de acompanhamento em um sistema projetado. Ele dá um objetivo a uma IA, deixa que ela aja, observa o feedback real, avalia o resultado e então se adapta ou para.
<Callout type="info" title="A Definição Curta">
Engenharia de loop é a prática de projetar o ciclo de feedback em torno de um sistema de IA: o objetivo, as ações, as observações, a avaliação, o estado, as salvaguardas e as regras de parada que movem o trabalho rumo a um resultado verificável.
</Callout>
## De um Bom Prompt a um Bom Loop
Um prompt pode produzir uma primeira tentativa forte. Um loop é útil quando o número de passos não pode ser conhecido de antemão, o ambiente pode mudar ou a primeira tentativa precisa ser checada contra evidências.
<Compare
before={{
label: "Prompt Único",
content: "Perguntar → Gerar → Retornar\n\nO modelo produz uma resposta. Uma pessoa decide se funcionou e escreve o próximo prompt."
}}
after={{
label: "Loop Projetado",
content: "Enquadrar → Agir → Observar → Avaliar → Adaptar\n ↑______________________↓\n\nO sistema reúne evidências, registra o estado e continua apenas enquanto mais uma passagem for útil."
}}
/>
Essa ideia se apoia em padrões de agentes anteriores. O [artigo do ReAct](https://arxiv.org/abs/2210.03629) mostrou o valor de intercalar ações com observações de um ambiente externo. O [padrão avaliador-otimizador](https://www.anthropic.com/engineering/building-effective-agents) da Anthropic adiciona uma etapa de feedback distinta, enquanto o [guia prático de agentes](https://openai.com/business/guides-and-resources/a-practical-guide-to-building-ai-agents/) da OpenAI descreve execuções de agentes como loops governados por condições de saída. O termo mais recente, **engenharia de loop**, concentra a atenção em projetar deliberadamente esse ciclo inteiro.
## Os Cinco Movimentos
<InfoGrid items={[
{ label: "1. Enquadrar", description: "Transforme a intenção em objetivo, restrições, critérios de sucesso e um orçamento.", color: "blue" },
{ label: "2. Agir", description: "Escolha uma ação delimitada: buscar, editar, calcular, chamar uma ferramenta ou perguntar a uma pessoa.", color: "amber" },
{ label: "3. Observar", description: "Colete o que de fato aconteceu: saída de testes, resultados de API, citações ou feedback de usuários.", color: "cyan" },
{ label: "4. Avaliar", description: "Compare as evidências com critérios explícitos — não com a confiança do modelo.", color: "purple" },
{ label: "5. Adaptar", description: "Atualize o estado, mude o plano, tente de novo com segurança, escale para um humano ou pare.", color: "green" },
]} />
O loop não são as setas. A engenharia mora nos **contratos entre as setas**: o que conta como ação, quais observações merecem confiança, quem as avalia, qual estado sobrevive e exatamente quando a execução termina.
<LoopEngineeringLab content={{
eyebrow: "Controle de loop / simulador interativo",
title: "Percorra um loop de feedback em funcionamento",
description: "Escolha uma tarefa e avance um sinal de cada vez. Repare como o progresso vem de evidências do ambiente e de avaliação explícita — não de perguntar ao modelo se ele acha que terminou.",
chooseScenarioLabel: "Escolha um loop",
goalLabel: "Objetivo",
stopRuleLabel: "Regra de parada",
evidenceLabel: "Evidências confiáveis",
iterationLabel: "Iteração",
progressLabel: "Progresso verificado",
openIssuesLabel: "Questões em aberto",
currentSignalLabel: "Sinal atual",
advanceLabel: "Avançar um passo",
nextIterationLabel: "Iniciar a próxima iteração",
resetLabel: "Reiniciar o loop",
completeLabel: "Objetivo verificado",
completeDescription: "Os critérios de sucesso foram atendidos, as evidências estão registradas e o loop para em vez de gastar mais um ciclo.",
stages: [
{ id: "frame", label: "Enquadrar", verb: "Reler o contrato" },
{ id: "act", label: "Agir", verb: "Fazer um movimento delimitado" },
{ id: "observe", label: "Observar", verb: "Ler o feedback externo" },
{ id: "evaluate", label: "Avaliar", verb: "Aplicar a rubrica" },
{ id: "adapt", label: "Adaptar", verb: "Atualizar o próximo movimento" },
],
scenarios: [
{
id: "code",
label: "Consertar um bug de checkout",
goal: "Corrigir os totais do checkout sem alterar o comportamento válido dos descontos.",
stopRule: "O teste de regressão direcionado passa, a suíte completa de checkout passa e o lint está limpo — ou as três tentativas se esgotam e o loop escala para um humano.",
evidence: "Passos de reprodução, saída dos testes, o diff do código e a suíte de regressão final.",
cycles: [
{
action: "Reproduzir o total reportado e adicionar um teste que falha para imposto mais desconto percentual.",
observation: "O teste falha por um centavo apenas quando o imposto é arredondado antes de o desconto ser aplicado.",
evaluation: "O bug foi reproduzido com um sinal determinístico, mas sua origem ainda não foi corrigida.",
adaptation: "Inspecionar a fronteira de arredondamento e alterar apenas o caminho de cálculo do total do pedido.",
progress: 34,
openIssues: 2,
},
{
action: "Mover o arredondamento para a fronteira monetária final e rodar os testes direcionados de checkout.",
observation: "A regressão passa, mas um teste de integração de cupom agora falha com desconto de valor fixo.",
evaluation: "O primeiro sintoma foi corrigido, mas a mudança é ampla demais. A regra de parada não foi satisfeita.",
adaptation: "Restringir o patch e adicionar um caso que separe o arredondamento do imposto do arredondamento do cupom.",
progress: 71,
openIssues: 1,
},
{
action: "Aplicar a correção restrita de cálculo e, em seguida, rodar a regressão, a suíte completa de checkout e o lint.",
observation: "Todas as verificações passam. O diff toca em uma única função de cálculo e no novo teste de regressão.",
evaluation: "Cada critério de sucesso tem evidência independente e nenhum limite de orçamento foi excedido.",
adaptation: "Parar, preservar a saída dos testes e entregar o diff pequeno a um revisor humano.",
progress: 100,
openIssues: 0,
},
],
},
{
id: "research",
label: "Verificar uma afirmação de pesquisa",
goal: "Avaliar a afirmação de que o trabalho remoto sempre aumenta a produtividade da equipe.",
stopRule: "Uma conclusão calibrada é sustentada por pelo menos três fontes confiáveis, com divergências e limitações explicitadas.",
evidence: "Links diretos para as fontes, datas de publicação, métodos dos estudos, tamanhos de amostra e métricas citadas.",
cycles: [
{
action: "Buscar evidências recentes e rastrear a estatística de produtividade mais repetida até sua fonte.",
observation: "A maioria dos artigos repete uma pesquisa de fornecedor sem linkar o questionário nem a amostra bruta.",
evaluation: "A evidência é popular, mas não é forte o bastante para sustentar uma afirmação absoluta.",
adaptation: "Priorizar estudos revisados por pares e conjuntos de dados públicos; buscar também achados contrários.",
progress: 28,
openIssues: 3,
},
{
action: "Comparar dois estudos revisados por pares com um conjunto de dados nacional sobre trabalho.",
observation: "Os resultados variam conforme o tipo de tarefa, o método de medição e se o trabalho é totalmente remoto ou híbrido.",
evaluation: "As evidências contradizem a palavra 'sempre'. Uma conclusão condicional está se tornando defensável.",
adaptation: "Verificar se os estudos distinguem produção, horas trabalhadas e produtividade percebida.",
progress: 68,
openIssues: 1,
},
{
action: "Montar uma tabela de evidências e verificar cada afirmação contra a fonte original.",
observation: "As fontes apontam efeitos mistos e identificam autonomia, coordenação e tipo de tarefa como variáveis-chave.",
evaluation: "A conclusão está sustentada, a incerteza está visível e o limiar de fontes foi atingido.",
adaptation: "Parar com uma resposta qualificada e guardar a tabela de evidências para revisão.",
progress: 100,
openIssues: 0,
},
],
},
{
id: "writing",
label: "Lapidar um e-mail de lançamento",
goal: "Criar um e-mail de lançamento conciso que explique o benefício e gere cliques qualificados para a demonstração.",
stopRule: "O e-mail passa na rubrica de voz, fica abaixo de 140 palavras, contém uma única chamada para ação clara e sobrevive a uma revisão factual.",
evidence: "Contagem de palavras, notas da rubrica, validação de links, fatos do produto na fonte e anotações do revisor.",
cycles: [
{
action: "Redigir a partir do briefing do produto e pontuar o resultado contra a rubrica de público e de voz.",
observation: "O rascunho tem 204 palavras, abre falando de recursos e contém duas chamadas para ação concorrentes.",
evaluation: "Os fatos estão corretos, mas os critérios de hierarquia e de extensão falham.",
adaptation: "Começar pelo resultado para o cliente, remover a ação secundária e cortar detalhes de implementação.",
progress: 41,
openIssues: 3,
},
{
action: "Reescrever a abertura e comprimir o corpo em uma única sequência problema-benefício-prova.",
observation: "O e-mail tem 126 palavras e uma só chamada para ação, mas a frase de prova exagera um resultado do beta.",
evaluation: "A estrutura passa. A calibragem factual ainda falha na rubrica.",
adaptation: "Substituir a afirmação genérica pelo resultado medido no beta e pedir uma checagem final dos fatos.",
progress: 79,
openIssues: 1,
},
{
action: "Inserir a métrica verificada, validar o link e rodar a rubrica completa mais uma vez.",
observation: "O e-mail tem 132 palavras, o link funciona, os fatos batem com o briefing e todos os itens da rubrica passam.",
evaluation: "O artefato atende ao padrão de qualidade definido, com evidências revisáveis.",
adaptation: "Parar e enviar a versão aprovada ao responsável pela campanha.",
progress: 100,
openIssues: 0,
},
],
},
],
}} />
## Escreva o Contrato do Loop Primeiro
Antes de escolher modelo ou framework, escreva um pequeno contrato. Se esses campos ficarem vagos, o loop vai transformar ambiguidade em custo repetido.
```yaml
goal: "Qual estado observável deve se tornar verdadeiro?"
inputs: "O que dispara o loop?"
state: "Quais fatos e tentativas persistem entre as iterações?"
actions: "Quais ferramentas o sistema pode usar, e com quais permissões?"
observations: "Quais sinais externos retornam dessas ações?"
evaluator: "Qual rubrica ou quais verificações determinísticas julgam o resultado?"
success: "Que evidência prova que o objetivo foi cumprido?"
failure: "Quais condições exigem recuperação ou ajuda humana?"
budget: "Máximo de turnos, tempo, tokens, dinheiro ou efeitos colaterais"
```
<Callout type="warning" title="Um Loop Sem Saída é um Modo de Falha">
Sempre defina três saídas: **sucesso**, quando as evidências satisfazem o objetivo; **falha**, quando a recuperação deixa de ser útil; e **orçamento esgotado**, quando o loop atinge seu limite de custo ou de risco.
</Callout>
## As Observações Devem Vir do Mundo
O modelo dizer que “isso parece correto” não é uma evidência forte. Uma observação útil é produzida por algo externo à resposta que está sendo julgada.
<table>
<thead>
<tr>
<th>Tarefa</th>
<th>Observação fraca</th>
<th>Observação forte</th>
</tr>
</thead>
<tbody>
<tr>
<td>Reparo de código</td>
<td>“A correção deve funcionar.”</td>
<td>A falha original é reproduzida e, em seguida, a regressão e a suíte completa passam.</td>
</tr>
<tr>
<td>Pesquisa</td>
<td>“Várias fontes concordam.”</td>
<td>As afirmações linkam para as fontes originais, com datas, métodos e divergências registradas.</td>
</tr>
<tr>
<td>Extração de dados</td>
<td>“O JSON parece válido.”</td>
<td>A validação do esquema passa e registros amostrados batem com a fonte.</td>
</tr>
<tr>
<td>Conteúdo</td>
<td>“O texto parece claro.”</td>
<td>Ele passa por uma rubrica nomeada, revisão factual, verificação de links e teste com o público.</td>
</tr>
<tr>
<td>Operações</td>
<td>“A requisição foi bem-sucedida.”</td>
<td>O sistema externo retorna o estado esperado e existe um registro de auditoria.</td>
</tr>
</tbody>
</table>
É por isso que as ferramentas importam: testes, navegadores, bancos de dados, validadores e revisão humana transformam um palpite interno em um resultado observável.
## Separe o Criador do Verificador
Para trabalhos de baixo risco, um mesmo modelo pode redigir e se autorrevisar. Para trabalhos importantes, use um verificador com uma função diferente e autoridade limitada.
<InfoGrid columns={2} items={[
{ label: "Criador", description: "Propõe a mudança, chama as ferramentas de ação e explica quais evidências devem ser coletadas.", color: "amber" },
{ label: "Verificador", description: "Recebe o objetivo, o artefato e as evidências; aplica a rubrica; não pode reescrever silenciosamente o trabalho que avalia.", color: "green" },
]} />
O verificador não precisa ser outra IA. Prefira o avaliador mais determinístico disponível:
1. **Verificações exatas** — tipos, esquemas, restrições, permissões, hashes
2. **Verificações executáveis** — testes, linters, simulações, validação de links
3. **Verificações por rubrica** — um modelo independente ou um humano usando critérios nomeados
4. **Verificações de resultado** — comportamento real de usuários ou métricas de produção ao longo do tempo
<Callout type="tip" title="Confiança Não é Evidência">
Uma pontuação de confiança gerada pelo mesmo modelo que criou o artefato continua sendo uma saída do modelo. Trate-a como uma dica de roteamento, não como prova.
</Callout>
## O Estado é a Espinha Dorsal do Loop
Contexto é o que o modelo vê **neste turno**. Estado é o registro compacto que permite que o próximo turno continue sem repetir nem esquecer o trabalho.
<Checklist title="Estado de Loop Útil" items={[
{ text: "O objetivo atual e os critérios de aceitação" },
{ text: "Ações já tentadas e seus resultados observáveis" },
{ text: "Artefatos produzidos, com versões ou referências estáveis" },
{ text: "Veredictos do avaliador e questões não resolvidas" },
{ text: "Orçamento consumido e permissões ainda disponíveis" },
{ text: "O motivo para continuar, parar ou escalar" },
]} />
Armazene decisões e evidências concisas — não a cadeia de pensamento privada de um modelo. Um bom estado é pequeno, inspecionável e seguro de retomar.
## Formas Comuns de Loop
### O Loop de Reparo
`reproduzir → mudar uma coisa → rodar as verificações → diagnosticar → repetir ou parar`
Ideal para código, configuração, limpeza de dados e qualquer tarefa com feedback executável.
### O Loop Avaliador-Otimizador
`gerar → pontuar com uma rubrica → devolver feedback direcionado → revisar`
Ideal para escrita, tradução, crítica de design e resultados cuja qualidade melhora com feedback articulado.
### O Loop de Pesquisa
`buscar → inspecionar fontes → identificar lacunas ou conflitos → buscar de novo → sintetizar`
Ideal quando a completude não é conhecida de antemão. A regra de parada deve medir a cobertura das evidências, não o número de resultados de busca.
### O Loop com Aprovação Humana
`preparar → verificar automaticamente → pausar antes de ações de alto risco → humano aprova ou redireciona`
Ideal para pagamentos, publicação, exclusão, mudanças de acesso, decisões médicas ou jurídicas e outras ações de grande consequência.
## Modos de Falha para Eliminar no Projeto
<table>
<thead>
<tr>
<th>Falha</th>
<th>O que aconteceu</th>
<th>Resposta de engenharia</th>
</tr>
</thead>
<tbody>
<tr>
<td>Tentativas infinitas</td>
<td>O loop não tem saída mensurável de sucesso nem de orçamento.</td>
<td>Adicione estados terminais explícitos e um teto rígido de iterações.</td>
</tr>
<tr>
<td>Autocongratulação</td>
<td>O criador aceita a própria resposta plausível sem evidências.</td>
<td>Use verificações determinísticas ou um verificador independente.</td>
</tr>
<tr>
<td>Bola de neve de contexto</td>
<td>Cada iteração anexa tudo até o modelo perder o sinal.</td>
<td>Persista estado estruturado e reconstrua apenas o contexto relevante.</td>
</tr>
<tr>
<td>Vaivém entre correções</td>
<td>O loop fica alternando entre duas correções.</td>
<td>Detecte estados repetidos e exija uma estratégia diferente ou escalada para um humano.</td>
</tr>
<tr>
<td>Desvio de objetivo</td>
<td>Melhorias locais substituem o objetivo original.</td>
<td>Releia o objetivo imutável e os critérios de aceitação a cada ciclo.</td>
</tr>
<tr>
<td>Repetição insegura</td>
<td>Um erro reversível se torna danoso quando repetido.</td>
<td>Limite permissões, efeitos colaterais, frequência, gastos e raio de impacto.</td>
</tr>
</tbody>
</table>
## Uma Implementação Mínima
```typescript
let state = initialize(goal, acceptanceCriteria, budget);
while (state.budget.remaining > 0) {
const context = assembleRelevantContext(state);
const proposedAction = await maker.chooseAction(context);
const observation = await tools.executeWithinPolicy(proposedAction);
const verdict = await evaluator.check({ goal, observation, state });
state = recordIteration(state, { proposedAction, observation, verdict });
if (verdict.status === "passed") return complete(state);
if (verdict.status === "unsafe" || verdict.status === "blocked") {
return escalateToHuman(state);
}
state = adaptPlan(state, verdict.feedback);
}
return stopWithBudgetReport(state);
```
O código é a parte fácil. As perguntas difíceis são perguntas de domínio: qual teste prova que o bug sumiu? Qual fonte tem autoridade? Qual ação é reversível? Quem pode aprovar a etapa final? Essas decisões são o verdadeiro trabalho da engenharia de loop.
## Prática: Projete um Loop
<TryIt
title="Elabore um Contrato de Loop"
description="Substitua as variáveis por uma tarefa recorrente do seu próprio trabalho. Peça à IA para questionar evidências fracas e regras de parada ambíguas."
prompt={`Projete um loop de trabalho de IA delimitado para esta tarefa:
TAREFA: \${task:fazer a triagem dos novos chamados de suporte ao cliente toda manhã}
Defina:
1. O objetivo observável
2. O gatilho e as entradas necessárias
3. As ações permitidas e as permissões de ferramentas
4. As observações confiáveis vindas do ambiente externo
5. O avaliador e sua rubrica
6. O estado que persiste entre as iterações
7. As saídas de sucesso, falha e orçamento esgotado
8. Os pontos de aprovação humana para ações arriscadas
9. Um formato de registro que torne cada iteração auditável
Depois, identifique os três modos de falha mais prováveis no seu projeto e revise o loop para evitá-los.`}
/>
<Quiz
question="Um agente edita o código, relê o diff e diz que o bug foi corrigido. Qual é a peça mais importante que falta no loop?"
options={[
"Um prompt de sistema mais longo",
"Uma observação externa avaliada contra uma regra de parada",
"Uma segunda passada de edição",
"Uma janela de contexto maior"
]}
correctIndex={1}
explanation="O agente produziu e inspecionou um artefato, mas não coletou evidências independentes. Reproduzir a falha e rodar os testes relevantes criaria um sinal observável que uma regra de parada pode avaliar."
/>
## Leitura Adicional
- [Loop Engineering — Addy Osmani](https://addyosmani.com/blog/loop-engineering/) — o enquadramento recente de substituir prompts manuais de acompanhamento por um sistema projetado, com alertas práticos sobre verificação e responsabilidade humana
- [Building Effective Agents — Anthropic](https://www.anthropic.com/engineering/building-effective-agents) — fluxos avaliador-otimizador, feedback do ambiente, condições de parada e orientações sobre quando a complexidade de agentes se justifica
- [A Practical Guide to Building Agents — OpenAI](https://openai.com/business/guides-and-resources/a-practical-guide-to-building-ai-agents/) — execuções de agentes, condições de saída, ferramentas, salvaguardas e intervenção humana
- [ReAct: Synergizing Reasoning and Acting in Language Models](https://arxiv.org/abs/2210.03629) — a pesquisa fundacional sobre intercalar ações com observações de um ambiente externo
## Resumo
<Callout type="tip" title="Construa o Feedback, Não Apenas o Prompt">
Um loop confiável tem um objetivo mensurável, ações delimitadas, observações confiáveis, um avaliador explícito, estado compacto, saídas seguras e julgamento humano onde as consequências exigirem. O modelo está dentro do loop; o engenheiro continua responsável pelo loop.
</Callout>
@@ -1,405 +0,0 @@
Контекстная инженерия определяет, **что видит модель**. Инженерия циклов определяет, **что система сделает дальше**.
Вместо того чтобы человек раз за разом читал ответ и писал следующий промпт, цикл превращает эту доводку в спроектированную систему. Она ставит перед AI цель, даёт ему действовать, наблюдает за реальной обратной связью, оценивает результат и либо адаптируется, либо останавливается.
<Callout type="info" title="Короткое определение">
Инженерия циклов — это практика проектирования цикла обратной связи вокруг AI-системы: цели, действий, наблюдений, оценки, состояния, защитных ограничений и правил остановки, которые ведут работу к проверяемому результату.
</Callout>
## От хорошего промпта к хорошему циклу
Промпт может дать сильную первую попытку. Цикл нужен, когда число шагов заранее неизвестно, среда может меняться или первую попытку нужно сверить с доказательствами.
<Compare
before={{
label: "Одиночный промпт",
content: "Спросить → Сгенерировать → Вернуть\n\nМодель выдаёт ответ. Человек решает, сработало ли, и пишет следующий промпт."
}}
after={{
label: "Спроектированный цикл",
content: "Постановка → Действие → Наблюдение → Оценка → Адаптация\n ↑______________________↓\n\nСистема собирает доказательства, фиксирует состояние и продолжает работу, только пока очередной проход приносит пользу."
}}
/>
Эта идея опирается на более ранние агентные паттерны. [Статья о ReAct](https://arxiv.org/abs/2210.03629) показала ценность чередования действий с наблюдениями из внешней среды. [Паттерн «оценщик-оптимизатор»](https://www.anthropic.com/engineering/building-effective-agents) от Anthropic добавляет отдельный шаг обратной связи, а [практическое руководство по созданию агентов](https://openai.com/business/guides-and-resources/a-practical-guide-to-building-ai-agents/) от OpenAI описывает работу агента как цикл, управляемый условиями выхода. Более новый термин — **инженерия циклов** — сосредотачивает внимание на осознанном проектировании всего этого цикла.
## Пять ходов
<InfoGrid items={[
{ label: "1. Постановка", description: "Превратите замысел в цель, ограничения, критерии успеха и бюджет.", color: "blue" },
{ label: "2. Действие", description: "Выберите одно ограниченное действие: поиск, правка, вычисление, вызов инструмента или вопрос человеку.", color: "amber" },
{ label: "3. Наблюдение", description: "Соберите то, что произошло на самом деле: вывод тестов, ответы API, ссылки на источники или отзывы пользователей.", color: "cyan" },
{ label: "4. Оценка", description: "Сравните доказательства с явными критериями — а не с уверенностью модели.", color: "purple" },
{ label: "5. Адаптация", description: "Обновите состояние, скорректируйте план, безопасно повторите попытку, передайте задачу человеку или остановитесь.", color: "green" },
]} />
Цикл — это не стрелки. Инженерия живёт в **контрактах между стрелками**: что считается действием, каким наблюдениям можно доверять, кто их оценивает, какое состояние сохраняется и в какой именно момент выполнение заканчивается.
<LoopEngineeringLab content={{
eyebrow: "Управление циклом / интерактивный симулятор",
title: "Пройдите рабочий цикл обратной связи по шагам",
description: "Выберите задачу и продвигайтесь по одному сигналу за раз. Обратите внимание: прогресс складывается из доказательств внешней среды и явной оценки — а не из вопросов к модели, считает ли она работу завершённой.",
chooseScenarioLabel: "Выберите цикл",
goalLabel: "Цель",
stopRuleLabel: "Правило остановки",
evidenceLabel: "Доверенные доказательства",
iterationLabel: "Итерация",
progressLabel: "Подтверждённый прогресс",
openIssuesLabel: "Открытые проблемы",
currentSignalLabel: "Текущий сигнал",
advanceLabel: "Продвинуться на шаг",
nextIterationLabel: "Начать следующую итерацию",
resetLabel: "Сбросить цикл",
completeLabel: "Цель подтверждена",
completeDescription: "Критерии успеха выполнены, доказательства зафиксированы, и цикл останавливается вместо того, чтобы тратить ещё одну итерацию.",
stages: [
{ id: "frame", label: "Постановка", verb: "Перечитать контракт" },
{ id: "act", label: "Действие", verb: "Сделать один ограниченный ход" },
{ id: "observe", label: "Наблюдение", verb: "Прочитать внешнюю обратную связь" },
{ id: "evaluate", label: "Оценка", verb: "Применить рубрику" },
{ id: "adapt", label: "Адаптация", verb: "Скорректировать следующий ход" },
],
scenarios: [
{
id: "code",
label: "Починить баг в оформлении заказа",
goal: "Исправить итоговые суммы заказа, не изменив корректное поведение скидок.",
stopRule: "Целевой регрессионный тест проходит, весь набор тестов оформления заказа проходит, линтер не выдаёт замечаний — либо три попытки исчерпаны, и цикл передаёт задачу человеку.",
evidence: "Шаги воспроизведения, вывод тестов, дифф кода и финальный прогон регрессионных тестов.",
cycles: [
{
action: "Воспроизвести сумму из баг-репорта и добавить падающий тест для налога в сочетании с процентной скидкой.",
observation: "Тест падает с расхождением в один цент только тогда, когда налог округляется до применения скидки.",
evaluation: "Баг воспроизведён с детерминированным сигналом, но его источник ещё не устранён.",
adaptation: "Изучить границу округления и менять только путь расчёта итоговой суммы заказа.",
progress: 34,
openIssues: 2,
},
{
action: "Перенести округление на финальную денежную границу и запустить целевые тесты оформления заказа.",
observation: "Регрессионный тест проходит, но один интеграционный тест купонов теперь падает на скидке с фиксированной суммой.",
evaluation: "Первый симптом устранён, но правка слишком широкая. Правило остановки не выполнено.",
adaptation: "Сузить патч и добавить кейс, разделяющий округление налога и округление купона.",
progress: 71,
openIssues: 1,
},
{
action: "Применить точечное исправление расчёта, затем запустить регрессионный тест, весь набор тестов оформления заказа и линтер.",
observation: "Все проверки проходят. Дифф затрагивает одну расчётную функцию и новый регрессионный тест.",
evaluation: "У каждого критерия успеха есть независимое подтверждение, и ни один лимит бюджета не превышен.",
adaptation: "Остановиться, сохранить вывод тестов и передать компактный дифф на ревью человеку.",
progress: 100,
openIssues: 0,
},
],
},
{
id: "research",
label: "Проверить утверждение из исследований",
goal: "Оценить утверждение, что удалённая работа всегда повышает продуктивность команды.",
stopRule: "Взвешенный вывод подкреплён минимум тремя заслуживающими доверия источниками, а разногласия и ограничения явно указаны.",
evidence: "Прямые ссылки на источники, даты публикаций, методы исследований, размеры выборок и цитируемые показатели.",
cycles: [
{
action: "Найти свежие данные и проследить самую растиражированную статистику продуктивности до её первоисточника.",
observation: "Большинство статей повторяют опрос одного вендора, не давая ссылок на его анкету и исходную выборку.",
evaluation: "Эти данные популярны, но недостаточно сильны, чтобы подтвердить абсолютное утверждение.",
adaptation: "Отдать приоритет рецензируемым исследованиям и открытым датасетам; искать в том числе противоположные результаты.",
progress: 28,
openIssues: 3,
},
{
action: "Сравнить два рецензируемых исследования с национальным датасетом по рынку труда.",
observation: "Результаты зависят от типа задач, метода измерения и того, идёт ли речь о полностью удалённой или гибридной работе.",
evaluation: "Данные противоречат слову «всегда». Условный вывод становится обоснованным.",
adaptation: "Проверить, различают ли исследования объём результатов, отработанные часы и субъективно воспринимаемую продуктивность.",
progress: 68,
openIssues: 1,
},
{
action: "Составить таблицу доказательств и сверить каждое утверждение с первоисточником.",
observation: "Источники говорят о смешанных эффектах и выделяют автономию, координацию и тип задач как ключевые переменные.",
evaluation: "Вывод подтверждён, неопределённость показана, порог по числу источников достигнут.",
adaptation: "Остановиться на выводе с оговорками и сохранить таблицу доказательств для проверки.",
progress: 100,
openIssues: 0,
},
],
},
{
id: "writing",
label: "Отшлифовать письмо о запуске",
goal: "Написать лаконичное письмо о запуске, которое объясняет пользу и приносит клики на демо от целевой аудитории.",
stopRule: "Письмо проходит рубрику тона, укладывается в 140 слов, содержит один чёткий призыв к действию и выдерживает проверку фактов.",
evidence: "Число слов, баллы по рубрике, проверка ссылок, факты о продукте из брифа и заметки рецензента.",
cycles: [
{
action: "Написать черновик по продуктовому брифу и оценить его по рубрике аудитории и тона.",
observation: "В черновике 204 слова, он начинается с перечисления функций и содержит два конкурирующих призыва к действию.",
evaluation: "Факты точны, но критерии иерархии и длины не выполнены.",
adaptation: "Начать с результата для клиента, убрать второй призыв к действию и сократить детали реализации.",
progress: 41,
openIssues: 3,
},
{
action: "Переписать начало и сжать основную часть в одну связку «проблема — польза — доказательство».",
observation: "В письме 126 слов и один призыв к действию, но фраза-доказательство преувеличивает результат бета-теста.",
evaluation: "Структура проходит. Точность фактов всё ещё не дотягивает до рубрики.",
adaptation: "Заменить общее утверждение измеренным результатом бета-теста и запросить финальную проверку фактов.",
progress: 79,
openIssues: 1,
},
{
action: "Вставить проверенную метрику, провалидировать ссылку и ещё раз прогнать полную рубрику.",
observation: "В письме 132 слова, ссылка открывается, факты совпадают с брифом, и каждый пункт рубрики выполнен.",
evaluation: "Артефакт соответствует заданной планке качества, и доказательства можно проверить.",
adaptation: "Остановиться и отправить утверждённую версию владельцу кампании.",
progress: 100,
openIssues: 0,
},
],
},
],
}} />
## Сначала напишите контракт цикла
Прежде чем выбирать модель или фреймворк, напишите небольшой контракт. Если эти поля расплывчаты, цикл превратит неоднозначность в повторяющиеся расходы.
```yaml
goal: "Какое наблюдаемое состояние должно стать истинным?"
inputs: "Что запускает цикл?"
state: "Какие факты и попытки сохраняются между итерациями?"
actions: "Какими инструментами может пользоваться система и с какими правами?"
observations: "Какие внешние сигналы возвращаются после этих действий?"
evaluator: "Какая рубрика или детерминированные проверки оценивают результат?"
success: "Какие доказательства подтверждают, что цель достигнута?"
failure: "Какие условия требуют восстановления или помощи человека?"
budget: "Максимум ходов, времени, токенов, денег или побочных эффектов"
```
<Callout type="warning" title="Цикл без выхода — это готовый сценарий отказа">
Всегда определяйте три выхода: **успех**, когда доказательства подтверждают достижение цели; **неудача**, когда восстановление уже не имеет смысла; и **исчерпание бюджета**, когда цикл достигает допустимого предела затрат или риска.
</Callout>
## Наблюдения должны приходить из внешнего мира
Слова модели «это выглядит правильно» — слабое доказательство. Полезное наблюдение порождается чем-то за пределами того ответа, который оценивается.
<table>
<thead>
<tr>
<th>Задача</th>
<th>Слабое наблюдение</th>
<th>Сильное наблюдение</th>
</tr>
</thead>
<tbody>
<tr>
<td>Исправление кода</td>
<td>«Исправление должно сработать».</td>
<td>Исходный сбой воспроизведён, затем проходят регрессионный тест и весь набор тестов.</td>
</tr>
<tr>
<td>Исследование</td>
<td>«Несколько источников согласны».</td>
<td>Утверждения ссылаются на первоисточники; даты, методы и разногласия зафиксированы.</td>
</tr>
<tr>
<td>Извлечение данных</td>
<td>«JSON вроде бы валидный».</td>
<td>Валидация по схеме проходит, а выборочные записи совпадают с источником.</td>
</tr>
<tr>
<td>Контент</td>
<td>«Текст кажется понятным».</td>
<td>Он проходит именованную рубрику, проверку фактов, проверку ссылок и тестирование на аудитории.</td>
</tr>
<tr>
<td>Операции</td>
<td>«Запрос выполнен успешно».</td>
<td>Внешняя система возвращает ожидаемое состояние, и существует запись в журнале аудита.</td>
</tr>
</tbody>
</table>
Именно поэтому важны инструменты: тесты, браузеры, базы данных, валидаторы и ревью человеком превращают внутреннюю догадку в наблюдаемый результат.
## Разделите исполнителя и проверяющего
Для задач с низким риском одна модель может и писать черновик, и проверять сама себя. Для важной работы используйте проверяющего с другой ролью и ограниченными полномочиями.
<InfoGrid columns={2} items={[
{ label: "Исполнитель", description: "Предлагает изменение, вызывает инструменты действий и объясняет, какие доказательства нужно собрать.", color: "amber" },
{ label: "Проверяющий", description: "Получает цель, артефакт и доказательства; применяет рубрику; не может втихую переписать работу, которую оценивает.", color: "green" },
]} />
Проверяющим не обязательно должен быть другой AI. Предпочитайте самый детерминированный из доступных оценщиков:
1. **Точные проверки** — типы, схемы, ограничения, права доступа, хеши
2. **Исполняемые проверки** — тесты, линтеры, симуляции, валидация ссылок
3. **Проверки по рубрике** — независимая модель или человек, работающие по именованным критериям
4. **Проверки по результату** — реальное поведение пользователей или продакшен-метрики во времени
<Callout type="tip" title="Уверенность — это не доказательство">
Оценка уверенности, сгенерированная той же моделью, которая создала артефакт, — это всё ещё вывод модели. Считайте её подсказкой для маршрутизации, а не доказательством.
</Callout>
## Состояние — позвоночник цикла
Контекст — это то, что модель видит **на текущем ходу**. Состояние — это компактная запись, которая позволяет следующему ходу продолжить работу, ничего не повторяя и не забывая.
<Checklist title="Полезное состояние цикла" items={[
{ text: "Текущая цель и критерии приёмки" },
{ text: "Уже предпринятые действия и их наблюдаемые результаты" },
{ text: "Созданные артефакты с версиями или стабильными ссылками" },
{ text: "Вердикты оценщика и нерешённые проблемы" },
{ text: "Израсходованный бюджет и всё ещё доступные права" },
{ text: "Причина продолжить, остановиться или передать задачу человеку" },
]} />
Храните сжатые решения и доказательства, а не внутреннюю цепочку рассуждений модели. Хорошее состояние — маленькое, прозрачное для проверки и безопасное для возобновления работы.
## Типичные формы циклов
### Цикл исправления
`воспроизвести → внести одно изменение → запустить проверки → диагностировать → повторить или остановиться`
Лучше всего подходит для кода, конфигурации, чистки данных и любых задач с исполняемой обратной связью.
### Цикл «оценщик-оптимизатор»
`сгенерировать → оценить по рубрике → вернуть адресную обратную связь → доработать`
Лучше всего подходит для текстов, перевода, критики дизайна и результатов, качество которых растёт от внятно сформулированной обратной связи.
### Исследовательский цикл
`искать → изучить источники → найти пробелы или противоречия → искать снова → синтезировать`
Лучше всего, когда полнота заранее неизвестна. Правило остановки должно измерять покрытие доказательствами, а не число результатов поиска.
### Цикл с одобрением человека
`подготовить → проверить автоматически → сделать паузу перед рискованным действием → человек одобряет или перенаправляет`
Лучше всего подходит для платежей, публикаций, удаления данных, изменения прав доступа, медицинских и юридических решений и других действий с серьёзными последствиями.
## Отказы, которые нужно устранять на этапе проектирования
<table>
<thead>
<tr>
<th>Отказ</th>
<th>Что произошло</th>
<th>Инженерный ответ</th>
</tr>
</thead>
<tbody>
<tr>
<td>Бесконечные повторы</td>
<td>У цикла нет измеримого выхода по успеху или бюджету.</td>
<td>Добавьте явные конечные состояния и жёсткий лимит итераций.</td>
</tr>
<tr>
<td>Самоодобрение</td>
<td>Исполнитель принимает собственный правдоподобный ответ без доказательств.</td>
<td>Используйте детерминированные проверки или независимого проверяющего.</td>
</tr>
<tr>
<td>Снежный ком контекста</td>
<td>Каждая итерация дописывает всё подряд, пока модель не теряет сигнал.</td>
<td>Храните структурированное состояние и пересобирайте только релевантный контекст.</td>
</tr>
<tr>
<td>Метания</td>
<td>Цикл мечется между двумя исправлениями.</td>
<td>Обнаруживайте повторяющиеся состояния и требуйте смены стратегии или передачи задачи человеку.</td>
</tr>
<tr>
<td>Дрейф цели</td>
<td>Локальные улучшения подменяют исходную задачу.</td>
<td>Перечитывайте неизменную цель и критерии приёмки на каждой итерации.</td>
</tr>
<tr>
<td>Небезопасные повторы</td>
<td>Обратимая ошибка становится вредной при многократном повторении.</td>
<td>Ограничьте права, побочные эффекты, частоту, расходы и масштаб возможного ущерба.</td>
</tr>
</tbody>
</table>
## Минимальная реализация
```typescript
let state = initialize(goal, acceptanceCriteria, budget);
while (state.budget.remaining > 0) {
const context = assembleRelevantContext(state);
const proposedAction = await maker.chooseAction(context);
const observation = await tools.executeWithinPolicy(proposedAction);
const verdict = await evaluator.check({ goal, observation, state });
state = recordIteration(state, { proposedAction, observation, verdict });
if (verdict.status === "passed") return complete(state);
if (verdict.status === "unsafe" || verdict.status === "blocked") {
return escalateToHuman(state);
}
state = adaptPlan(state, verdict.feedback);
}
return stopWithBudgetReport(state);
```
Код — самая простая часть. Сложные вопросы — это вопросы предметной области: какой тест доказывает, что баг исчез? Какой источник авторитетен? Какое действие обратимо? Кто вправе одобрить финальный шаг? Эти решения и есть настоящая работа инженерии циклов.
## Практика: спроектируйте цикл
<TryIt
title="Набросайте контракт цикла"
description="Подставьте вместо переменных повторяющуюся задачу из вашей собственной работы. Попросите AI оспорить слабые доказательства и расплывчатые правила остановки."
prompt={`Спроектируйте ограниченный рабочий цикл AI для этой задачи:
ЗАДАЧА: \${task:каждое утро разбирать новые обращения в службу поддержки}
Определите:
1. Наблюдаемую цель
2. Триггер и необходимые входные данные
3. Разрешённые действия и права на инструменты
4. Доверенные наблюдения из внешней среды
5. Оценщика и его рубрику
6. Состояние, сохраняющееся между итерациями
7. Выходы: успех, неудача и исчерпание бюджета
8. Точки одобрения человеком для рискованных действий
9. Формат трассировки, делающий каждую итерацию проверяемой
Затем определите три самых вероятных сценария отказа в своём проекте и доработайте цикл, чтобы их предотвратить.`}
/>
<Quiz
question="Агент правит код, перечитывает дифф и говорит, что баг исправлен. Какой самой важной части цикла здесь не хватает?"
options={[
"Более длинного системного промпта",
"Внешнего наблюдения, оценённого по правилу остановки",
"Второго прохода редактирования",
"Более крупного контекстного окна"
]}
correctIndex={1}
explanation="Агент создал артефакт и осмотрел его, но не собрал независимых доказательств. Воспроизведение сбоя и запуск релевантных тестов дали бы наблюдаемый сигнал, который можно оценить по правилу остановки."
/>
## Дополнительные материалы
- [Loop Engineering — Addy Osmani](https://addyosmani.com/blog/loop-engineering/) — свежая постановка идеи о замене ручных повторных промптов спроектированной системой, а также практические предостережения о верификации и ответственности человека
- [Building Effective Agents — Anthropic](https://www.anthropic.com/engineering/building-effective-agents) — рабочие процессы «оценщик-оптимизатор», обратная связь из среды, условия остановки и рекомендации о том, когда агентная сложность оправдана
- [A Practical Guide to Building Agents — OpenAI](https://openai.com/business/guides-and-resources/a-practical-guide-to-building-ai-agents/) — запуски агентов, условия выхода, инструменты, защитные ограничения и вмешательство человека
- [ReAct: Synergizing Reasoning and Acting in Language Models](https://arxiv.org/abs/2210.03629) — основополагающее исследование о чередовании действий с наблюдениями из внешней среды
## Резюме
<Callout type="tip" title="Проектируйте обратную связь, а не только промпт">
У надёжного цикла есть измеримая цель, ограниченные действия, доверенные наблюдения, явный оценщик, компактное состояние, безопасные выходы и человеческое суждение там, где этого требуют последствия. Модель находится внутри цикла — но ответственность за цикл остаётся на инженере.
</Callout>
@@ -1,405 +0,0 @@
Bağlam mühendisliği **modelin neyi görebileceğine** karar verir. Döngü mühendisliği ise **sistemin bir sonraki adımda ne yapacağına** karar verir.
Bir kişinin yanıtı tekrar tekrar okuyup bir sonraki promptu yazması yerine, döngü bu takip işini tasarlanmış bir sisteme dönüştürür. Yapay zekaya bir hedef verir, harekete geçmesine izin verir, gerçek geri bildirimi gözlemler, sonucu değerlendirir ve ya uyum sağlar ya da durur.
<Callout type="info" title="Kısa Tanım">
Döngü mühendisliği, bir yapay zeka sisteminin etrafındaki geri bildirim döngüsünü tasarlama pratiğidir: işi doğrulanabilir bir sonuca taşıyan hedef, eylemler, gözlemler, değerlendirme, durum, güvenlik bariyerleri ve durdurma kuralları.
</Callout>
## İyi Bir Prompttan İyi Bir Döngüye
Bir prompt güçlü bir ilk deneme üretebilir. Döngü ise adım sayısının önceden bilinemediği, ortamın değişebildiği ya da ilk denemenin kanıtla doğrulanması gerektiği durumlarda işe yarar.
<Compare
before={{
label: "Tek Seferlik Prompt",
content: "Sor → Üret → Yanıtla\n\nModel bir yanıt üretir. İşe yarayıp yaramadığına bir insan karar verir ve bir sonraki promptu yazar."
}}
after={{
label: "Tasarlanmış Döngü",
content: "Çerçeve → Eylem → Gözlem → Değerlendirme → Uyarlama\n ↑______________________↓\n\nSistem kanıt toplar, durumu kaydeder ve yalnızca bir tur daha yararlı olacaksa devam eder."
}}
/>
Bu fikir, daha önceki ajan desenlerinin üzerine kuruludur. [ReAct makalesi](https://arxiv.org/abs/2210.03629), eylemleri dış ortamdan gelen gözlemlerle iç içe yürütmenin değerini gösterdi. Anthropic'in [değerlendirici-optimize edici deseni](https://www.anthropic.com/engineering/building-effective-agents) buna ayrı bir geri bildirim adımı eklerken, OpenAI'ın [ajan geliştirmeye dair pratik rehberi](https://openai.com/business/guides-and-resources/a-practical-guide-to-building-ai-agents/) ajan çalıştırmalarını çıkış koşullarıyla yönetilen döngüler olarak tanımlar. Daha yeni bir terim olan **döngü mühendisliği** ise dikkati bu döngünün tamamını bilinçli olarak tasarlamaya yöneltir.
## Beş Hamle
<InfoGrid items={[
{ label: "1. Çerçeve", description: "Niyeti bir hedefe, kısıtlara, başarı ölçütlerine ve bir bütçeye dönüştürün.", color: "blue" },
{ label: "2. Eylem", description: "Sınırları belli tek bir eylem seçin: arayın, düzenleyin, hesaplayın, bir araç çağırın veya bir insana danışın.", color: "amber" },
{ label: "3. Gözlem", description: "Gerçekte ne olduğunu toplayın: test çıktısı, API sonuçları, kaynak alıntıları veya kullanıcı geri bildirimi.", color: "cyan" },
{ label: "4. Değerlendirme", description: "Kanıtı modelin kendine güveniyle değil, açıkça tanımlanmış ölçütlerle karşılaştırın.", color: "purple" },
{ label: "5. Uyarlama", description: "Durumu güncelleyin, planı değiştirin, güvenle yeniden deneyin, işi bir insana devredin veya durun.", color: "green" },
]} />
Döngü, oklardan ibaret değildir. Mühendislik **oklar arasındaki sözleşmelerde** yatar: neyin eylem sayıldığı, hangi gözlemlerin güvenilir olduğu, onları kimin değerlendirdiği, hangi durumun kalıcı olduğu ve yürütmenin tam olarak ne zaman sona ereceği.
<LoopEngineeringLab content={{
eyebrow: "Döngü kontrolü / etkileşimli simülatör",
title: "Çalışan bir geri bildirim döngüsünde adım adım ilerleyin",
description: "Bir görev seçin, ardından her seferinde tek bir sinyal ilerletin. İlerlemenin, modele kendini bitmiş hissedip hissetmediğini sormaktan değil, ortamdan gelen kanıtlardan ve açık değerlendirmeden geldiğine dikkat edin.",
chooseScenarioLabel: "Bir döngü seçin",
goalLabel: "Hedef",
stopRuleLabel: "Durdurma kuralı",
evidenceLabel: "Güvenilir kanıt",
iterationLabel: "İterasyon",
progressLabel: "Doğrulanmış ilerleme",
openIssuesLabel: "Açık sorunlar",
currentSignalLabel: "Güncel sinyal",
advanceLabel: "Bir adım ilerle",
nextIterationLabel: "Sonraki iterasyona başla",
resetLabel: "Döngüyü sıfırla",
completeLabel: "Hedef doğrulandı",
completeDescription: "Başarı ölçütleri karşılandı, kanıt kayıt altında ve döngü bir tur daha harcamak yerine duruyor.",
stages: [
{ id: "frame", label: "Çerçeve", verb: "Sözleşmeyi yeniden okuyun" },
{ id: "act", label: "Eylem", verb: "Sınırları belli tek bir hamle yapın" },
{ id: "observe", label: "Gözlem", verb: "Dış geri bildirimi okuyun" },
{ id: "evaluate", label: "Değerlendirme", verb: "Rubriği uygulayın" },
{ id: "adapt", label: "Uyarlama", verb: "Sonraki hamleyi güncelleyin" },
],
scenarios: [
{
id: "code",
label: "Ödeme akışındaki hatayı onarma",
goal: "Geçerli indirim davranışını bozmadan ödeme akışındaki toplam tutarları düzeltmek.",
stopRule: "Hedeflenen regresyon testi geçer, ödeme akışının tüm test paketi geçer ve lint temiz çıkar — ya da üç deneme hakkı tükenir ve döngü işi bir insana devreder.",
evidence: "Hatayı yeniden üretme adımları, test çıktısı, kod diff'i ve son regresyon paketi.",
cycles: [
{
action: "Bildirilen toplam tutarı yeniden üretin ve vergi artı yüzde indirimi senaryosu için başarısız olan bir test ekleyin.",
observation: "Test, yalnızca vergi indirimden önce yuvarlandığında bir sent farkla başarısız oluyor.",
evaluation: "Hata deterministik bir sinyalle yeniden üretildi, ancak kaynağı henüz düzeltilmedi.",
adaptation: "Yuvarlama sınırını inceleyin ve yalnızca sipariş toplamının hesaplandığı yolu değiştirin.",
progress: 34,
openIssues: 2,
},
{
action: "Yuvarlamayı en son parasal sınıra taşıyın ve ödeme akışının hedefli testlerini çalıştırın.",
observation: "Regresyon testi geçiyor, ancak bir kupon entegrasyon testi artık sabit tutarlı indirimde başarısız oluyor.",
evaluation: "İlk belirti giderildi, ama değişiklik fazla geniş kapsamlı. Durdurma kuralı henüz karşılanmıyor.",
adaptation: "Yamayı daraltın ve vergi yuvarlamasını kupon yuvarlamasından ayıran bir test senaryosu ekleyin.",
progress: 71,
openIssues: 1,
},
{
action: "Daraltılmış hesaplama düzeltmesini uygulayın; ardından regresyonu, ödeme akışının tüm test paketini ve lint'i çalıştırın.",
observation: "Tüm kontroller geçiyor. Diff yalnızca bir hesaplama fonksiyonuna ve yeni regresyon testine dokunuyor.",
evaluation: "Her başarı ölçütünün bağımsız kanıtı var ve hiçbir bütçe sınırı aşılmadı.",
adaptation: "Durun, test çıktısını saklayın ve küçük diff'i incelemesi için bir insana teslim edin.",
progress: 100,
openIssues: 0,
},
],
},
{
id: "research",
label: "Bir araştırma iddiasını doğrulama",
goal: "Uzaktan çalışmanın ekip verimliliğini her zaman artırdığı iddiasını değerlendirmek.",
stopRule: "Kalibre edilmiş bir sonuç en az üç güvenilir kaynakla desteklenir; görüş ayrılıkları ve sınırlamalar açıkça belirtilir.",
evidence: "Doğrudan kaynak bağlantıları, yayın tarihleri, araştırma yöntemleri, örneklem büyüklükleri ve alıntılanan metrikler.",
cycles: [
{
action: "Güncel kanıtları arayın ve en çok tekrarlanan verimlilik istatistiğinin izini kaynağına kadar sürün.",
observation: "Makalelerin çoğu, anket sorularına veya ham örneklemine bağlantı vermeyen bir tedarikçi anketini tekrarlıyor.",
evaluation: "Kanıt yaygın, ama mutlak bir iddiayı destekleyecek kadar güçlü değil.",
adaptation: "Hakemli çalışmalara ve kamuya açık veri kümelerine öncelik verin; karşıt bulguları da arayın.",
progress: 28,
openIssues: 3,
},
{
action: "Hakemli iki çalışmayı ulusal bir işgücü veri kümesiyle karşılaştırın.",
observation: "Sonuçlar görev türüne, ölçüm yöntemine ve çalışmanın tamamen uzaktan mı yoksa hibrit mi olduğuna göre değişiyor.",
evaluation: "Kanıt, 'her zaman' sözcüğüyle çelişiyor. Koşullu bir sonuç savunulabilir hale geliyor.",
adaptation: "Çalışmaların üretilen çıktıyı, çalışılan saatleri ve algılanan verimliliği birbirinden ayırıp ayırmadığını kontrol edin.",
progress: 68,
openIssues: 1,
},
{
action: "Bir kanıt tablosu oluşturun ve her iddiayı orijinal kaynağıyla doğrulayın.",
observation: "Kaynaklar karma etkileri destekliyor; özerklik, koordinasyon ve görev türünü temel değişkenler olarak gösteriyor.",
evaluation: "Sonuç kanıtla destekleniyor, belirsizlik görünür durumda ve kaynak eşiği karşılandı.",
adaptation: "Koşullara bağlı, ihtiyatlı bir yanıtla durun ve kanıt tablosunu inceleme için saklayın.",
progress: 100,
openIssues: 0,
},
],
},
{
id: "writing",
label: "Lansman e-postasını parlatma",
goal: "Faydayı net biçimde anlatan ve nitelikli demo tıklamaları kazandıran kısa bir lansman e-postası oluşturmak.",
stopRule: "E-posta ton ve üslup rubriğinden geçer, 140 kelimenin altında kalır, tek bir net eylem çağrısı içerir ve olgusal incelemeden geçer.",
evidence: "Kelime sayısı, rubrik puanları, bağlantı doğrulaması, ürüne dair kaynak bilgiler ve gözden geçiren notları.",
cycles: [
{
action: "Ürün özetinden bir taslak yazın ve sonucu hedef kitle ile ton ve üslup rubriğine göre puanlayın.",
observation: "Taslak 204 kelime, özellik listesiyle açılıyor ve birbiriyle yarışan iki eylem çağrısı içeriyor.",
evaluation: "Bilgiler doğru, ancak hiyerarşi ve uzunluk ölçütleri karşılanmıyor.",
adaptation: "Müşterinin elde edeceği sonuçla açın, ikincil eylem çağrısını kaldırın ve uygulama ayrıntılarını kırpın.",
progress: 41,
openIssues: 3,
},
{
action: "Girişi yeniden yazın ve gövdeyi tek bir sorun-fayda-kanıt dizisine sıkıştırın.",
observation: "E-posta 126 kelime ve tek bir eylem çağrısı var, ancak kanıt cümlesi bir beta sonucunu abartıyor.",
evaluation: "Yapı ölçütleri geçiyor. Olgusal kalibrasyon ise rubrikte hâlâ başarısız.",
adaptation: "Genel iddiayı ölçülmüş beta sonucuyla değiştirin ve son bir olgu kontrolü isteyin.",
progress: 79,
openIssues: 1,
},
{
action: "Doğrulanmış metriği ekleyin, bağlantıyı doğrulayın ve rubriğin tamamını bir kez daha uygulayın.",
observation: "E-posta 132 kelime, bağlantı çalışıyor, bilgiler ürün özetiyle eşleşiyor ve her rubrik maddesi geçiyor.",
evaluation: "Çıktı, tanımlanan kalite çıtasını incelenebilir kanıtlarla karşılıyor.",
adaptation: "Durun ve onaylanan sürümü kampanya sahibine gönderin.",
progress: 100,
openIssues: 0,
},
],
},
],
}} />
## Önce Döngü Sözleşmesini Yazın
Bir model veya framework seçmeden önce küçük bir sözleşme yazın. Bu alanlar muğlaksa döngü, belirsizliği tekrar tekrar ödenen bir maliyete dönüştürür.
```yaml
goal: "Hangi gözlemlenebilir durum gerçekleşmiş olmalı?"
inputs: "Döngüyü ne başlatır?"
state: "İterasyonlar arasında hangi bilgiler ve denemeler kalıcı olur?"
actions: "Sistem hangi araçları, hangi izinlerle kullanabilir?"
observations: "Bu eylemlerden hangi dış sinyaller döner?"
evaluator: "Sonucu hangi rubrik veya deterministik kontroller yargılar?"
success: "Hedefe ulaşıldığını hangi kanıt ispatlar?"
failure: "Hangi koşullar kurtarma veya insan yardımı gerektirir?"
budget: "En fazla tur, süre, token, para veya yan etki"
```
<Callout type="warning" title="Çıkışı Olmayan Döngü Başlı Başına Bir Hata Kalıbıdır">
Her zaman üç çıkış tanımlayın: kanıt hedefi karşıladığında **başarı**, kurtarma çabası artık işe yaramadığında **başarısızlık** ve döngü izin verilen maliyet veya risk sınırına dayandığında **bütçe tükendi**.
</Callout>
## Gözlemler Gerçek Dünyadan Gelmeli
Modelin “bu doğru görünüyor” demesi güçlü bir kanıt değildir. İşe yarar bir gözlem, yargılanan yanıtın dışındaki bir şey tarafından üretilir.
<table>
<thead>
<tr>
<th>Görev</th>
<th>Zayıf gözlem</th>
<th>Güçlü gözlem</th>
</tr>
</thead>
<tbody>
<tr>
<td>Kod onarımı</td>
<td>“Düzeltmenin çalışması gerekir.”</td>
<td>Önce orijinal hata yeniden üretilir; ardından regresyon testi ve tüm test paketi geçer.</td>
</tr>
<tr>
<td>Araştırma</td>
<td>“Birçok kaynak hemfikir.”</td>
<td>İddialar; tarihleri, yöntemleri ve görüş ayrılıkları kaydedilmiş orijinal kaynaklara bağlanır.</td>
</tr>
<tr>
<td>Veri çıkarma</td>
<td>“JSON geçerli görünüyor.”</td>
<td>Şema doğrulaması geçer ve örneklenen kayıtlar kaynakla eşleşir.</td>
</tr>
<tr>
<td>İçerik</td>
<td>“Metin yeterince açık hissettiriyor.”</td>
<td>Adlandırılmış bir rubrikten, olgusal incelemeden, bağlantı kontrollerinden ve hedef kitle testinden geçer.</td>
</tr>
<tr>
<td>Operasyonlar</td>
<td>“İstek başarılı oldu.”</td>
<td>Dış sistem beklenen durumu döndürür ve ortada bir denetim kaydı vardır.</td>
</tr>
</tbody>
</table>
Araçların önemi tam da burada: testler, tarayıcılar, veritabanları, doğrulayıcılar ve insan incelemesi, içeriden yapılan bir tahmini gözlemlenebilir bir sonuca dönüştürür.
## Üreticiyi Denetçiden Ayırın
Düşük riskli işlerde tek bir model hem taslağı yazabilir hem de kendi işini gözden geçirebilir. Önemli işlerde ise görevi farklı, yetkisi sınırlı bir denetçi kullanın.
<InfoGrid columns={2} items={[
{ label: "Üretici", description: "Değişikliği önerir, eylem araçlarını çağırır ve hangi kanıtların toplanması gerektiğini açıklar.", color: "amber" },
{ label: "Denetçi", description: "Hedefi, çıktıyı ve kanıtı alır; rubriği uygular; notlandırdığı işi sessizce yeniden yazamaz.", color: "green" },
]} />
Denetçinin başka bir yapay zeka olması gerekmez. Elinizdeki en deterministik değerlendiriciyi tercih edin:
1. **Kesin kontroller** — tipler, şemalar, kısıtlar, izinler, hash'ler
2. **Çalıştırılabilir kontroller** — testler, linter'lar, simülasyonlar, bağlantı doğrulaması
3. **Rubrik kontrolleri** — adlandırılmış ölçütleri kullanan bağımsız bir model veya insan
4. **Sonuç kontrolleri** — zaman içinde gerçek kullanıcı davranışı veya canlı ortam metrikleri
<Callout type="tip" title="Özgüven Kanıt Değildir">
Çıktıyı üreten modelin kendisinin ürettiği bir güven puanı da sonuçta bir model çıktısıdır. Bunu kanıt olarak değil, yönlendirme ipucu olarak değerlendirin.
</Callout>
## Durum, Döngünün Omurgasıdır
Bağlam, modelin **bu turda** gördüğü şeydir. Durum ise bir sonraki turun işi tekrarlamadan ve unutmadan devam etmesini sağlayan derli toplu kayıttır.
<Checklist title="İşe Yarar Döngü Durumu" items={[
{ text: "Güncel hedef ve kabul ölçütleri" },
{ text: "Şimdiye kadar denenen eylemler ve gözlemlenebilir sonuçları" },
{ text: "Üretilen çıktılar; sürümleri veya kalıcı referanslarıyla birlikte" },
{ text: "Değerlendirici kararları ve çözülmemiş sorunlar" },
{ text: "Harcanan bütçe ve hâlâ kullanılabilir olan izinler" },
{ text: "Devam etme, durma veya insana devretme gerekçesi" },
]} />
Modelin kendi iç düşünce zincirini değil, özlü kararları ve kanıtları saklayın. İyi durum küçüktür, incelenebilir ve güvenle kaldığı yerden devam ettirilebilir.
## Yaygın Döngü Biçimleri
### Onarım Döngüsü
`yeniden üret → tek bir şeyi değiştir → kontrolleri çalıştır → teşhis et → tekrarla veya dur`
Kod, yapılandırma, veri temizliği ve çalıştırılabilir geri bildirimi olan her görev için en uygunudur.
### Değerlendirici-Optimize Edici Döngüsü
`üret → rubrikle puanla → hedefli geri bildirim ver → gözden geçir`
Yazı, çeviri, tasarım eleştirisi ve kalitesi açıkça dile getirilmiş geri bildirimle artan çıktılar için en uygunudur.
### Araştırma Döngüsü
`ara → kaynakları incele → boşlukları veya çelişkileri belirle → yeniden ara → sentezle`
Kapsamın önceden bilinmediği durumlar için en uygunudur. Durdurma kuralı arama sonuçlarının sayısını değil, kanıtın kapsayıcılığını ölçmelidir.
### İnsan Onaylı Döngü
`hazırla → otomatik olarak doğrula → yüksek riskli eylemden önce durakla → insan onaylar veya yön değiştirir`
Ödemeler, yayınlama, silme, erişim değişiklikleri, tıbbi veya hukuki kararlar ve sonuçları ağır diğer eylemler için en uygunudur.
## Tasarımla Önlenecek Hata Kalıpları
<table>
<thead>
<tr>
<th>Hata</th>
<th>Ne oldu</th>
<th>Mühendislik yanıtı</th>
</tr>
</thead>
<tbody>
<tr>
<td>Sonsuz yeniden deneme</td>
<td>Döngünün ölçülebilir bir başarı veya bütçe çıkışı yok.</td>
<td>Açık uç durumlar ve kesin bir iterasyon üst sınırı ekleyin.</td>
</tr>
<tr>
<td>Kendi kendini onaylama</td>
<td>Üretici, kendi makul görünen yanıtını kanıt olmadan kabul ediyor.</td>
<td>Deterministik kontroller veya bağımsız bir denetçi kullanın.</td>
</tr>
<tr>
<td>Bağlam kartopu</td>
<td>Her iterasyon her şeyi eklemeye devam ediyor ve model sonunda sinyali kaybediyor.</td>
<td>Yapılandırılmış durumu kalıcı tutun ve her turda yalnızca ilgili bağlamı yeniden kurun.</td>
</tr>
<tr>
<td>Bocalama</td>
<td>Döngü iki düzeltme arasında gidip geliyor.</td>
<td>Tekrarlanan durumları tespit edin; farklı bir strateji ya da insana devretme şartı koyun.</td>
</tr>
<tr>
<td>Hedef kayması</td>
<td>Yerel iyileştirmeler asıl hedefin yerini alıyor.</td>
<td>Değişmez hedefi ve kabul ölçütlerini her turda yeniden okuyun.</td>
</tr>
<tr>
<td>Güvensiz tekrar</td>
<td>Geri alınabilir bir hata, tekrarlandığında zarar vermeye başlıyor.</td>
<td>İzinleri, yan etkileri, hızı, harcamayı ve olası hasarın kapsamını sınırlayın.</td>
</tr>
</tbody>
</table>
## Minimal Bir Uygulama
```typescript
let state = initialize(goal, acceptanceCriteria, budget);
while (state.budget.remaining > 0) {
const context = assembleRelevantContext(state);
const proposedAction = await maker.chooseAction(context);
const observation = await tools.executeWithinPolicy(proposedAction);
const verdict = await evaluator.check({ goal, observation, state });
state = recordIteration(state, { proposedAction, observation, verdict });
if (verdict.status === "passed") return complete(state);
if (verdict.status === "unsafe" || verdict.status === "blocked") {
return escalateToHuman(state);
}
state = adaptPlan(state, verdict.feedback);
}
return stopWithBudgetReport(state);
```
Kod işin kolay kısmı. Zor sorular alanın kendisine ait: Hatanın giderildiğini hangi test kanıtlar? Hangi kaynak güvenilir bir otoritedir? Hangi eylem geri alınabilir? Son adımı kim onaylayabilir? Döngü mühendisliğinin asıl işi bu kararlardır.
## Alıştırma: Bir Döngü Tasarlayın
<TryIt
title="Bir Döngü Sözleşmesi Taslağı Hazırlayın"
description="Değişkenleri kendi işinizden yinelenen bir görevle değiştirin. Yapay zekadan zayıf kanıtlara ve muğlak durdurma kurallarına itiraz etmesini isteyin."
prompt={`Şu görev için sınırları belli bir yapay zeka çalışma döngüsü tasarla:
GÖREV: \${task:her sabah yeni müşteri destek taleplerini önceliklendir}
Şunları tanımla:
1. Gözlemlenebilir hedef
2. Tetikleyici ve gerekli girdiler
3. İzin verilen eylemler ve araç izinleri
4. Dış ortamdan gelen güvenilir gözlemler
5. Değerlendirici ve kullanacağı rubrik
6. İterasyonlar arasında kalıcı olan durum
7. Başarı, başarısızlık ve bütçe tükendi çıkışları
8. Riskli eylemler için insan onayı kapıları
9. Her iterasyonu denetlenebilir kılan bir kayıt formatı
Ardından tasarımındaki en olası üç hata kalıbını belirle ve döngüyü bunları önleyecek şekilde gözden geçir.`}
/>
<Quiz
question="Bir ajan kodu düzenliyor, diff'i yeniden okuyor ve hatanın giderildiğini söylüyor. Döngünün en önemli eksik parçası nedir?"
options={[
"Daha uzun bir sistem promptu",
"Bir durdurma kuralına göre değerlendirilen dışsal bir gözlem",
"İkinci bir düzenleme turu",
"Daha büyük bir bağlam penceresi"
]}
correctIndex={1}
explanation="Ajan bir çıktı üretip incelemiştir, ancak bağımsız kanıt toplamamıştır. Hatayı yeniden üretmek ve ilgili testleri çalıştırmak, bir durdurma kuralının değerlendirebileceği gözlemlenebilir bir sinyal oluşturur."
/>
## Ek Okuma
- [Loop Engineering — Addy Osmani](https://addyosmani.com/blog/loop-engineering/) — elle yazılan takip promptlarını tasarlanmış bir sistemle değiştirme fikrinin güncel çerçevesi; doğrulama ve insan sorumluluğuna dair pratik uyarılarla birlikte
- [Building Effective Agents — Anthropic](https://www.anthropic.com/engineering/building-effective-agents) — değerlendirici-optimize edici iş akışları, ortamdan gelen geri bildirim, durdurma koşulları ve ajan karmaşıklığının ne zaman yerinde olduğuna dair rehberlik
- [A Practical Guide to Building Agents — OpenAI](https://openai.com/business/guides-and-resources/a-practical-guide-to-building-ai-agents/) — ajan çalıştırmaları, çıkış koşulları, araçlar, güvenlik bariyerleri ve insan müdahalesi
- [ReAct: Synergizing Reasoning and Acting in Language Models](https://arxiv.org/abs/2210.03629) — eylemleri dış ortamdan gelen gözlemlerle iç içe yürütmek üzerine temel araştırma
## Özet
<Callout type="tip" title="Sadece Promptu Değil, Geri Bildirimi de Kurun">
Güvenilir bir döngünün ölçülebilir bir hedefi, sınırları belli eylemleri, güvenilir gözlemleri, açık bir değerlendiricisi, derli toplu bir durumu, güvenli çıkışları ve sonuçların ağır olduğu yerlerde insan muhakemesi vardır. Model döngünün içindedir; döngünün sorumlusu ise mühendis olmaya devam eder.
</Callout>
@@ -1,405 +0,0 @@
上下文工程决定**模型能看到什么**。循环工程决定**系统接下来做什么**。
循环不再让人反复阅读答案、再动手写下一条提示词,而是把这种后续跟进工作变成一个精心设计的系统。它给 AI 一个目标,让它行动,观察真实反馈,评估结果,然后要么调整、要么停止。
<Callout type="info" title="一句话定义">
循环工程是围绕 AI 系统设计反馈周期的实践:目标、行动、观察、评估、状态、护栏和停止规则,共同推动工作走向一个可验证的结果。
</Callout>
## 从好提示词到好循环
一条提示词可以产出出色的第一稿。但当步骤数量无法预先确定、环境可能变化、或者第一次尝试必须对照证据检验时,循环才真正派上用场。
<Compare
before={{
label: "一次性提示词",
content: "提问 → 生成 → 返回\n\n模型给出一个答案。由人来判断它是否有效,并写出下一条提示词。"
}}
after={{
label: "工程化循环",
content: "界定 → 行动 → 观察 → 评估 → 调整\n ↑______________________↓\n\n系统收集证据、记录状态,只有当再跑一轮仍有价值时才继续。"
}}
/>
这一思想建立在更早的智能体模式之上。[ReAct 论文](https://arxiv.org/abs/2210.03629)展示了将行动与来自外部环境的观察交替进行的价值。Anthropic 的[评估器-优化器模式](https://www.anthropic.com/engineering/building-effective-agents)增加了一个独立的反馈步骤,而 OpenAI 的[智能体构建实用指南](https://openai.com/business/guides-and-resources/a-practical-guide-to-building-ai-agents/)则把智能体的运行描述为受退出条件约束的循环。较新的术语**循环工程**把注意力聚焦到有意识地设计整个循环这件事上。
## 五个动作
<InfoGrid items={[
{ label: "1. 界定", description: "把意图转化为目标、约束、成功标准和预算。", color: "blue" },
{ label: "2. 行动", description: "选择一个有边界的动作:搜索、编辑、计算、调用工具,或询问人类。", color: "amber" },
{ label: "3. 观察", description: "收集实际发生了什么:测试输出、API 结果、引用来源或用户反馈。", color: "cyan" },
{ label: "4. 评估", description: "拿证据对照明确的标准——而不是对照模型的自信程度。", color: "purple" },
{ label: "5. 调整", description: "更新状态、修改计划、安全地重试、上报人工,或者停止。", color: "green" },
]} />
循环的关键不在那些箭头,而在**箭头之间的契约**里:什么算一次行动,哪些观察值得信赖,由谁来评估,哪些状态需要保留,以及执行究竟在什么时候结束。
<LoopEngineeringLab content={{
eyebrow: "循环控制 / 交互式模拟器",
title: "逐步走完一个真实的反馈循环",
description: "选择一个任务,然后一次推进一个信号。注意进展是如何来自环境证据和明确的评估——而不是来自询问模型它是否觉得已经做完了。",
chooseScenarioLabel: "选择一个循环",
goalLabel: "目标",
stopRuleLabel: "停止规则",
evidenceLabel: "可信证据",
iterationLabel: "迭代",
progressLabel: "已验证的进展",
openIssuesLabel: "未决问题",
currentSignalLabel: "当前信号",
advanceLabel: "推进一步",
nextIterationLabel: "开始下一次迭代",
resetLabel: "重置循环",
completeLabel: "目标已验证",
completeDescription: "成功标准已满足,证据已记录在案,循环随即停止,而不是再白白消耗一个周期。",
stages: [
{ id: "frame", label: "界定", verb: "重读契约" },
{ id: "act", label: "行动", verb: "执行一个有边界的动作" },
{ id: "observe", label: "观察", verb: "读取外部反馈" },
{ id: "evaluate", label: "评估", verb: "套用评分标准" },
{ id: "adapt", label: "调整", verb: "更新下一步行动" },
],
scenarios: [
{
id: "code",
label: "修复结账 bug",
goal: "修正结账总额的计算错误,同时不改变正常的折扣行为。",
stopRule: "针对性的回归测试通过、完整的结账测试套件通过、lint 无告警——或者三次尝试用尽后,循环上报人工。",
evidence: "复现步骤、测试输出、代码 diff,以及最终的回归测试套件结果。",
cycles: [
{
action: "复现被报告的错误总额,并针对『税费加百分比折扣』的场景添加一个会失败的测试。",
observation: "只有当税费在应用折扣之前被四舍五入时,测试才会出现一美分的偏差。",
evaluation: "bug 已通过确定性信号成功复现,但根因尚未修复。",
adaptation: "检查舍入发生的边界,只修改订单总额的计算路径。",
progress: 34,
openIssues: 2,
},
{
action: "把四舍五入移到最终的金额边界处,并运行针对性的结账测试。",
observation: "回归测试通过了,但一个优惠券集成测试现在在固定金额折扣上失败。",
evaluation: "最初的症状已消除,但改动范围过大。停止规则尚未满足。",
adaptation: "收窄补丁范围,并新增一个把税费舍入与优惠券舍入区分开的测试用例。",
progress: 71,
openIssues: 1,
},
{
action: "应用收窄后的计算修复,然后运行回归测试、完整的结账套件和 lint。",
observation: "所有检查全部通过。diff 只涉及一个计算函数和新增的回归测试。",
evaluation: "每条成功标准都有独立证据支持,且没有超出任何预算限制。",
adaptation: "停止循环,保留测试输出,把这个小 diff 交给人工审阅者。",
progress: 100,
openIssues: 0,
},
],
},
{
id: "research",
label: "核实研究结论",
goal: "评估『远程办公总能提升团队生产力』这一说法。",
stopRule: "得出一个经过校准的结论,至少有三个可信来源支持,并明确说明分歧和局限。",
evidence: "原始来源链接、发表日期、研究方法、样本量,以及引用的具体指标。",
cycles: [
{
action: "搜索近期证据,并把被转引最多的那条生产力统计数据追溯到它的原始出处。",
observation: "大多数文章都在转述某厂商的一份调查,却没有附上问卷或原始样本。",
evaluation: "这份证据流传很广,但不足以支撑一个绝对化的断言。",
adaptation: "优先查找同行评审研究和公开数据集,同时也搜索相反的结论。",
progress: 28,
openIssues: 3,
},
{
action: "把两项同行评审研究与一份国家级劳动力数据集进行对比。",
observation: "结果因任务类型、测量方法,以及是完全远程还是混合办公而各不相同。",
evaluation: "证据与『总能』这个词相矛盾。一个带条件的结论正变得站得住脚。",
adaptation: "核查这些研究是否区分了产出、工作时长和主观感知的生产力。",
progress: 68,
openIssues: 1,
},
{
action: "建立一张证据表,把每条论断都对照原始来源逐一核实。",
observation: "这些来源支持效果好坏不一的结论,并指出自主性、协调和任务类型是关键变量。",
evaluation: "结论有据可依,不确定性清晰可见,来源数量也达到了门槛。",
adaptation: "以一个带限定条件的答案收尾,并保留证据表以备审查。",
progress: 100,
openIssues: 0,
},
],
},
{
id: "writing",
label: "打磨发布邮件",
goal: "写一封简洁的产品发布邮件,讲清价值,并带来高质量的演示预约点击。",
stopRule: "邮件通过语气风格评分标准、篇幅控制在 140 词以内、只包含一个明确的行动号召,并通过事实审查。",
evidence: "字数统计、评分标准得分、链接校验结果、产品事实依据,以及审阅者的批注。",
cycles: [
{
action: "根据产品简报起草初稿,并按受众和语气风格评分标准给结果打分。",
observation: "初稿长达 204 词,开头堆砌功能,还包含两个互相竞争的行动号召。",
evaluation: "事实准确无误,但信息层次和篇幅两项标准不达标。",
adaptation: "开头改为客户收益,删掉次要的行动号召,并砍掉实现细节。",
progress: 41,
openIssues: 3,
},
{
action: "重写开头,把正文压缩成『问题—收益—佐证』的单一序列。",
observation: "邮件缩到 126 词,只剩一个 CTA,但佐证那句话夸大了 beta 测试的结果。",
evaluation: "结构达标了。事实表述的分寸仍不符合评分标准。",
adaptation: "把宽泛的说法替换成实测的 beta 数据,并申请最后一轮事实核查。",
progress: 79,
openIssues: 1,
},
{
action: "填入核实过的指标,校验链接,再完整跑一遍评分标准。",
observation: "邮件为 132 词,链接可正常打开,事实与简报一致,评分标准逐项通过。",
evaluation: "成品达到了预先定义的质量门槛,且证据可供复查。",
adaptation: "停止循环,把批准通过的版本发给活动负责人。",
progress: 100,
openIssues: 0,
},
],
},
],
}} />
## 先写循环契约
在挑选模型或框架之前,先写一份小小的契约。如果这些字段含糊不清,循环只会把模糊性变成一轮又一轮的成本。
```yaml
goal: "哪个可观察的状态应当变为真?"
inputs: "什么触发这个循环?"
state: "哪些事实和尝试记录要在迭代之间保留?"
actions: "系统可以使用哪些工具,拥有哪些权限?"
observations: "这些行动会返回哪些外部信号?"
evaluator: "由哪套评分标准或确定性检查来裁定结果?"
success: "什么证据能证明目标已经完成?"
failure: "哪些情况需要恢复措施或人工介入?"
budget: "轮次、时间、token、金钱或副作用的上限"
```
<Callout type="warning" title="没有出口的循环本身就是一种故障模式">
永远定义三个出口:证据满足目标时的**成功**,恢复已不再有意义时的**失败**,以及循环触及允许的成本或风险边界时的**预算耗尽**。
</Callout>
## 观察必须来自真实世界
模型说一句"这看起来是对的",并不是有力的证据。有用的观察,必须由被评判的答案之外的东西产生。
<table>
<thead>
<tr>
<th>任务</th>
<th>弱观察</th>
<th>强观察</th>
</tr>
</thead>
<tbody>
<tr>
<td>代码修复</td>
<td>"这个修复应该有效。"</td>
<td>先复现原始故障,然后回归测试和完整测试套件全部通过。</td>
</tr>
<tr>
<td>研究</td>
<td>"好几个来源都这么说。"</td>
<td>每条论断都链接到原始来源,并记录了日期、方法和分歧。</td>
</tr>
<tr>
<td>数据提取</td>
<td>"这段 JSON 看起来是合法的。"</td>
<td>Schema 校验通过,且抽样记录与源数据一致。</td>
</tr>
<tr>
<td>内容创作</td>
<td>"文案读起来挺清楚的。"</td>
<td>通过了一套明确命名的评分标准、事实审查、链接检查和受众测试。</td>
</tr>
<tr>
<td>运维操作</td>
<td>"请求成功了。"</td>
<td>外部系统返回了预期状态,并且留有审计记录。</td>
</tr>
</tbody>
</table>
这正是工具重要的原因:测试、浏览器、数据库、校验器和人工审查,把内部的猜测变成了可观察的结果。
## 把生成者和检查者分开
低风险的工作可以让同一个模型起草并自查。重要的工作则要用一个职责不同、权限受限的检查者。
<InfoGrid columns={2} items={[
{ label: "生成者", description: "提出修改方案,调用行动类工具,并说明应当收集哪些证据。", color: "amber" },
{ label: "检查者", description: "接收目标、产出物和证据;套用评分标准;不能悄悄改写自己正在评判的工作。", color: "green" },
]} />
检查者不一定非得是另一个 AI。优先选择手头最具确定性的评估器:
1. **精确检查** — 类型、schema、约束、权限、哈希值
2. **可执行检查** — 测试、linter、模拟、链接校验
3. **评分标准检查** — 使用明确标准的独立模型或人类
4. **结果检查** — 真实的用户行为,或长期的生产环境指标
<Callout type="tip" title="自信不等于证据">
由制造产出物的同一个模型生成的置信度分数,依然只是模型输出。把它当作路由提示,而不是证明。
</Callout>
## 状态是循环的脊梁
上下文是模型**这一轮**看到的东西。状态则是一份精简的记录,让下一轮得以继续,而不必重复工作,也不会遗忘进展。
<Checklist title="有用的循环状态" items={[
{ text: "当前的目标和验收标准" },
{ text: "已经尝试过的行动及其可观察的结果" },
{ text: "已产出的成果,附版本号或稳定引用" },
{ text: "评估器的裁定和尚未解决的问题" },
{ text: "已消耗的预算和仍然可用的权限" },
{ text: "继续、停止或上报人工的理由" },
]} />
存储简明的决策和证据——而不是模型私有的思维链。好的状态体量小、可审查、可以安全地恢复运行。
## 常见的循环形态
### 修复循环
`复现 → 只改一处 → 运行检查 → 诊断 → 重复或停止`
最适合代码、配置、数据清理,以及任何有可执行反馈的任务。
### 评估器-优化器循环
`生成 → 按评分标准打分 → 返回针对性反馈 → 修改`
最适合写作、翻译、设计评审,以及那些通过清晰表述的反馈就能提升质量的产出。
### 研究循环
`搜索 → 检视来源 → 找出缺口或矛盾 → 再次搜索 → 综合归纳`
最适合完整性无法预先知晓的场景。停止规则应当衡量证据覆盖度,而不是搜索结果的数量。
### 人工把关循环
`准备 → 自动验证 → 在高风险动作前暂停 → 人工批准或调整方向`
最适合付款、发布、删除、权限变更、医疗或法律决策,以及其他后果重大的行动。
## 需要在设计中排除的故障模式
<table>
<thead>
<tr>
<th>故障</th>
<th>发生了什么</th>
<th>工程上的应对</th>
</tr>
</thead>
<tbody>
<tr>
<td>无限重试</td>
<td>循环没有可衡量的成功出口,也没有预算出口。</td>
<td>添加明确的终止状态和硬性的迭代上限。</td>
</tr>
<tr>
<td>自我表扬</td>
<td>生成者在没有证据的情况下就接受了自己那个看似合理的答案。</td>
<td>使用确定性检查或独立的检查者。</td>
</tr>
<tr>
<td>上下文滚雪球</td>
<td>每次迭代都往上下文里追加所有内容,直到模型丢失信号。</td>
<td>持久化结构化状态,每轮只重建相关的上下文。</td>
</tr>
<tr>
<td>来回摇摆</td>
<td>循环在两个修复方案之间来回切换。</td>
<td>检测重复出现的状态,强制换用不同策略或上报人工。</td>
</tr>
<tr>
<td>目标漂移</td>
<td>局部优化悄悄取代了最初的目标。</td>
<td>每个周期都重读那份不可变更的目标和验收标准。</td>
</tr>
<tr>
<td>不安全的重复</td>
<td>一个本可挽回的错误,在反复发生后变得有害。</td>
<td>限制权限、副作用、频率、开销和影响范围。</td>
</tr>
</tbody>
</table>
## 一个最小实现
```typescript
let state = initialize(goal, acceptanceCriteria, budget);
while (state.budget.remaining > 0) {
const context = assembleRelevantContext(state);
const proposedAction = await maker.chooseAction(context);
const observation = await tools.executeWithinPolicy(proposedAction);
const verdict = await evaluator.check({ goal, observation, state });
state = recordIteration(state, { proposedAction, observation, verdict });
if (verdict.status === "passed") return complete(state);
if (verdict.status === "unsafe" || verdict.status === "blocked") {
return escalateToHuman(state);
}
state = adaptPlan(state, verdict.feedback);
}
return stopWithBudgetReport(state);
```
代码是最容易的部分。真正难的是领域问题:哪个测试能证明 bug 已经消失?哪个来源是权威的?哪个动作是可逆的?谁有权批准最后一步?这些决定才是循环工程的真正工作。
## 练习:设计一个循环
<TryIt
title="起草一份循环契约"
description="把变量替换成你自己工作中反复出现的任务。让 AI 挑战薄弱的证据和含糊的停止规则。"
prompt={`为下面这个任务设计一个有边界的 AI 工作循环:
任务:\${task:每天早上对新的客户支持工单进行分级}
请定义:
1. 可观察的目标
2. 触发条件和所需输入
3. 允许的行动和工具权限
4. 来自外部环境的可信观察
5. 评估器及其评分标准
6. 在迭代之间保留的状态
7. 成功、失败和预算耗尽三种出口
8. 高风险行动的人工审批关卡
9. 一种让每次迭代都可审计的追踪记录格式
然后指出你的设计中最可能出现的三种故障模式,并修改循环来预防它们。`}
/>
<Quiz
question="一个智能体编辑了代码、重读了 diff,然后声称 bug 已经修复。这个循环最重要的缺失环节是什么?"
options={[
"更长的系统提示词",
"一个对照停止规则进行评估的外部观察",
"再编辑一遍",
"更大的上下文窗口"
]}
correctIndex={1}
explanation="这个智能体生成并检视了自己的产出物,但没有收集任何独立证据。复现故障并运行相关测试,才能产生一个可供停止规则评估的可观察信号。"
/>
## 延伸阅读
- [Loop Engineering — Addy Osmani](https://addyosmani.com/blog/loop-engineering/) — 用设计好的系统取代人工后续提示词的最新提法,以及关于验证和人类责任的实用告诫
- [Building Effective Agents — Anthropic](https://www.anthropic.com/engineering/building-effective-agents) — 评估器-优化器工作流、环境反馈、停止条件,以及智能体复杂度何时才算物有所值的指导
- [A Practical Guide to Building Agents — OpenAI](https://openai.com/business/guides-and-resources/a-practical-guide-to-building-ai-agents/) — 智能体运行、退出条件、工具、护栏和人工干预
- [ReAct: Synergizing Reasoning and Acting in Language Models](https://arxiv.org/abs/2210.03629) — 关于将行动与外部环境观察交替进行的奠基性研究
## 小结
<Callout type="tip" title="构建反馈机制,而不只是提示词">
一个可靠的循环拥有可衡量的目标、有边界的行动、可信的观察、明确的评估器、精简的状态、安全的出口,以及在后果重大之处保留的人类判断。模型在循环之内;对循环负责的始终是工程师。
</Callout>
-1
View File
@@ -58,7 +58,6 @@ export const parts: Part[] = [
{ slug: "12-handling-edge-cases", title: "Handling Edge Cases", part: "Advanced", partNumber: 3, chapterNumber: 12, description: "Dealing with unexpected inputs" },
{ slug: "13-multimodal-prompting", title: "Multimodal Prompting", part: "Advanced", partNumber: 3, chapterNumber: 13, description: "Working with images, audio, and video" },
{ slug: "14-context-engineering", title: "Context Engineering", part: "Advanced", partNumber: 3, chapterNumber: 14, description: "RAG, embeddings, function calling, and MCP" },
{ slug: "14a-loop-engineering", title: "The Loop Engineering", part: "Advanced", partNumber: 3, chapterNumber: 26, description: "Designing feedback cycles that act, verify, adapt, and know when to stop" },
{ slug: "25-agents-and-skills", title: "Agents & Skills", part: "Advanced", partNumber: 3, chapterNumber: 25, description: "Building AI agents with reusable skill packages" },
],
},
-2
View File
@@ -6,8 +6,6 @@ export const githubPlugin: AuthPlugin = {
name: "GitHub",
getProvider: () =>
GitHub({
// GitHub includes this issuer in OAuth authorization responses.
issuer: "https://github.com/login/oauth",
clientId: process.env.GITHUB_CLIENT_ID!,
clientSecret: process.env.GITHUB_CLIENT_SECRET!,
profile(profile) {
-4
View File
@@ -32,10 +32,6 @@ export const AI_MODELS = {
"grok-4": { name: "Grok 4", provider: "xAI" },
"grok-3": { name: "Grok 3", provider: "xAI" },
// MiniMax
"minimax-m3": { name: "MiniMax-M3", provider: "MiniMax" },
"minimax-m2-7": { name: "MiniMax-M2.7", provider: "MiniMax" },
// Image Generation
"nano-banana": { name: "Nano Banana", provider: "Google" },
"nano-banana-pro": { name: "Nano Banana Pro", provider: "Google" },
+1 -1
View File
@@ -30,5 +30,5 @@
".next/dev/types/**/*.ts",
"**/*.mts"
],
"exclude": ["node_modules", "packages"]
"exclude": ["node_modules"]
}