AI-agenter · leksjon

Sløyfer for refleksjon og selvkritikk

Agenter som vurderer sine egne resultater og genererer forslag til forbedringer.

Leksjon 2 av 413 trinn

Sløyfer for refleksjon og selvkritikk er en gratis leksjon i AI-agenter på CoddyKit. Dette er leksjon 2 av 4. Du kan lese hele leksjonen gratis nedenfor – og deretter øve praktisk i nettleseren med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i AI-agenter, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i AI-agenter inneholder totalt 4 leksjoner.

Hva er agentens selvrefleksjon?

Selvrefleksjon er praksisen med å be agenten vurdere sitt eget nettopp fullførte resultat før det returneres til brukeren, eller umiddelbart etterpå. Agenten fungerer som sin egen kritiker.

Dette gjenspeiler hvordan eksperter gjennomgår eget arbeid: utkast → kritikk → revisjon. Når denne løkken legges til agenter, forbedres ofte kvaliteten på resultatene uten endringer i den underliggende modellen.

Mønsteret for refleksjonsinstrukser

Etter at agenten har laget et svar, sendes svaret tilbake til modellen sammen med en strukturert refleksjonsinstruks. Modellen identifiserer deretter svakheter og foreslår forbedringer.

import anthropic

client = anthropic.Anthropic(api_key='YOUR_API_KEY')

def reflect_on_response(task: str, response: str) -> str:
    reflection_prompt = (
        'You just completed the following task:\n\n'
        f'TASK: {task}\n\n'
        f'YOUR RESPONSE:\n{response}\n\n'
        'Please reflect on your performance by answering:\n'
        '1. What did you do well?\n'
        '2. What could be improved?\n'
        '3. What would you do differently if you had to redo this?\n'
        'Be specific and honest.'
    )
    result = client.messages.create(
        model='claude-opus-4-5',
        max_tokens=512,
        messages=[{'role': 'user', 'content': reflection_prompt}]
    )
    return result.content[0].text

Strukturert refleksjonsresultat

Ustrukturert refleksjonstekst er vanskelig å behandle programmatisk. Be modellen produsere en strukturert JSON-refleksjon, slik at du kan hente ut poengsummer og tiltak på en pålitelig måte.

STRUCTURED_REFLECTION_PROMPT = '''
Reflect on the task and response above. Return ONLY valid JSON:
{
  "strengths": ["..."],
  "weaknesses": ["..."],
  "alternative_approach": "...",
  "quality_score": 0.0,
  "retry_recommended": false
}
quality_score: 0.0 (terrible) to 1.0 (excellent).
retry_recommended: true if quality_score < 0.6.
'''

import json

def structured_reflect(task: str, response: str, client) -> dict:
    prompt = f'TASK: {task}\n\nRESPONSE: {response}\n\n{STRUCTURED_REFLECTION_PROMPT}'
    result = client.messages.create(
        model='claude-opus-4-5',
        max_tokens=512,
        messages=[{'role': 'user', 'content': prompt}]
    )
    text = result.content[0].text.strip()
    # strip markdown code fences if present
    if text.startswith('```'):
        text = text.split('```')[1].lstrip('json').strip()
    return json.loads(text)

if __name__ == '__main__':
    class FakeContent:
        def __init__(self, text):
            self.text = text

    class FakeResponse:
        def __init__(self, text):
            self.content = [FakeContent(text)]

    class FakeMessages:
        def create(self, **kwargs):
            return FakeResponse(
                '{"strengths": ["clear"], "weaknesses": ["too long"], '
                '"alternative_approach": "be more concise", '
                '"quality_score": 0.7, "retry_recommended": false}'
            )

    class FakeClient:
        def __init__(self):
            self.messages = FakeMessages()

    result = structured_reflect('Summarize the article', 'A very long response...', FakeClient())
    print('quality_score:', result['quality_score'])
    print('weaknesses:', result['weaknesses'])

Selvkritikkløkke: Prøv på nytt ved lav poengsum

Når refleksjonspoengsummen faller under en terskel, prøves oppgaven automatisk på nytt ved å bruke svakhetene og den alternative tilnærmingen fra refleksjonen som ekstra kontekst. Dette oppretter en tilbakemeldingsdrevet forbedringsløkke i én enkelt agentkjøring.

def agent_with_self_critique(task: str, client, max_retries: int = 2) -> str:
    response = run_agent(task, client)

    for attempt in range(max_retries):
        reflection = structured_reflect(task, response, client)
        print(f'Attempt {attempt+1} quality: {reflection["quality_score"]:.2f}')

        if not reflection['retry_recommended']:
            break

        # Enrich the task with reflection insights
        improved_task = (
            f'{task}\n\n'
            'Previous attempt weaknesses:\n'
            + '\n'.join(f'- {w}' for w in reflection['weaknesses'])
            + f'\n\nSuggested approach: {reflection["alternative_approach"]}'
        )
        response = run_agent(improved_task, client)

    return response

def run_agent(task: str, client) -> str:
    result = client.messages.create(
        model='claude-opus-4-5',
        max_tokens=1024,
        messages=[{'role': 'user', 'content': task}]
    )
    return result.content[0].text

Episodisk minne for refleksjoner

En enkelt refleksjon er nyttig én gang; lagrede refleksjoner blir til episodisk minne som hjelper agenten med å lære på tvers av økter. Hver refleksjon er en episode: oppgavekontekst + hva som skjedde + hva agenten lærte.

from datetime import datetime
from dataclasses import dataclass, asdict
from typing import Optional

@dataclass
class ReflectionEpisode:
    episode_id: str
    task_type: str          # e.g. 'summarize', 'code_review', 'translate'
    task_summary: str       # short description (not full text)
    quality_score: float
    strengths: list
    weaknesses: list
    alternative_approach: str
    timestamp: str = ''

    def __post_init__(self):
        if not self.timestamp:
            self.timestamp = datetime.utcnow().isoformat()

    def to_dict(self) -> dict:
        return asdict(self)

# Example
episode = ReflectionEpisode(
    episode_id='ep_001',
    task_type='summarize',
    task_summary='Summarize a 5-page financial report',
    quality_score=0.55,
    strengths=['Identified key figures'],
    weaknesses=['Too verbose', 'Missed conclusion'],
    alternative_approach='Lead with the executive summary first'
)
print(episode.to_dict())

Lagre refleksjoner permanent

Lagre refleksjonsepisoder i en JSON-fil eller database. Ved oppstart laster du inn nylige episoder for samme oppgavetype og legger dem inn som kontekst – agenten lærer av sin egen tidligere ytelse.

import json
import os

MEMORY_FILE = 'agent_episodic_memory.json'

def save_episode(episode: ReflectionEpisode):
    episodes = load_all_episodes()
    episodes.append(episode.to_dict())
    with open(MEMORY_FILE, 'w') as f:
        json.dump(episodes, f, indent=2)

def load_all_episodes() -> list:
    if not os.path.exists(MEMORY_FILE):
        return []
    with open(MEMORY_FILE) as f:
        return json.load(f)

def load_recent_episodes(task_type: str, n: int = 3) -> list:
    all_ep = load_all_episodes()
    matching = [e for e in all_ep if e['task_type'] == task_type]
    # Sort by timestamp descending, take most recent n
    matching.sort(key=lambda e: e['timestamp'], reverse=True)
    return matching[:n]

Sette inn tidligere refleksjoner som kontekst

Før en oppgave startes, hentes de nyeste episodiske refleksjonene for oppgavetypen, og de inkluderes i systemprompten. Agenten vet nå hvilke feil den gjorde sist, og kan proaktivt unngå dem.

def build_system_prompt_with_memory(task_type: str) -> str:
    base = 'You are a helpful AI assistant. Complete the task carefully.'
    episodes = load_recent_episodes(task_type, n=3)

    if not episodes:
        return base

    memory_block = '\n\nYour recent performance on similar tasks:\n'
    for ep in episodes:
        memory_block += (
            f'- Score {ep["quality_score"]:.2f}: '
            f'Weaknesses: {ep["weaknesses"]}. '
            f'Better approach: {ep["alternative_approach"]}\n'
        )
    memory_block += '\nApply these lessons to your current response.'
    return base + memory_block

# Before each task:
system_prompt = build_system_prompt_with_memory('summarize')
print(system_prompt[:300])

Refleksjon over verktøybruk

Refleksjoner er enda mer verdifulle for agenter som bruker verktøy, fordi agenten kan reflektere over strategien for verktøykallene: brukte den riktige verktøy, i riktig rekkefølge og med riktige parametere?

TOOL_REFLECTION_PROMPT = '''
You completed a multi-step task using tools. Reflect on your tool usage:

Tool call log:
{tool_log}

Final result: {result}

Answer:
1. Were all tool calls necessary?
2. Were there redundant or incorrect calls?
3. What is the optimal tool sequence for this task type?

Return JSON:
{{
  "redundant_calls": [],
  "incorrect_calls": [],
  "optimal_sequence": [],
  "efficiency_score": 0.0
}}
'''

def reflect_on_tool_use(tool_log: list, result: str, client) -> dict:
    import json
    log_str = json.dumps(tool_log, indent=2)
    prompt = TOOL_REFLECTION_PROMPT.format(
        tool_log=log_str, result=result
    )
    response = client.messages.create(
        model='claude-opus-4-5',
        max_tokens=512,
        messages=[{'role': 'user', 'content': prompt}]
    )
    return json.loads(response.content[0].text)

if __name__ == '__main__':
    class FakeContent:
        def __init__(self, text):
            self.text = text

    class FakeResponse:
        def __init__(self, text):
            self.content = [FakeContent(text)]

    class FakeMessages:
        def create(self, **kwargs):
            return FakeResponse(
                '{"redundant_calls": ["search(x)"], "incorrect_calls": [], '
                '"optimal_sequence": ["search", "summarize"], "efficiency_score": 0.8}'
            )

    class FakeClient:
        def __init__(self):
            self.messages = FakeMessages()

    tool_log = [{'tool': 'search', 'args': {'q': 'x'}}, {'tool': 'search', 'args': {'q': 'x'}}]
    reflection = reflect_on_tool_use(tool_log, 'Found the answer', FakeClient())
    print('Efficiency score:', reflection['efficiency_score'])
    print('Redundant calls:', reflection['redundant_calls'])

Utdater­ing og beskjæring av episodisk minne

Gamle refleksjoner blir utdaterte hvis verden endrer seg eller modellen oppdateres. Implementer forvitring: vektlegg nyere episoder tyngre, og fjern episoder som er eldre enn en terskel eller har svært lave kvalitetspoeng (de kan ha vært avvik).

from datetime import datetime, timedelta

def prune_old_episodes(
    episodes: list,
    max_age_days: int = 30,
    min_quality: float = 0.0
) -> list:
    cutoff = datetime.utcnow() - timedelta(days=max_age_days)
    kept = []
    for ep in episodes:
        ep_time = datetime.fromisoformat(ep['timestamp'])
        if ep_time >= cutoff and ep['quality_score'] >= min_quality:
            kept.append(ep)
    return kept

def weighted_episodes(episodes: list) -> list:
    now = datetime.utcnow()
    for ep in episodes:
        age_days = (now - datetime.fromisoformat(ep['timestamp'])).days
        # Recency weight: 1.0 today, halves every 7 days
        ep['weight'] = 0.5 ** (age_days / 7)
    return sorted(episodes, key=lambda e: e['weight'], reverse=True)

if __name__ == '__main__':
    now = datetime.utcnow()
    episodes = [
        {'timestamp': (now - timedelta(days=2)).isoformat(), 'quality_score': 0.9, 'content': 'recent good episode'},
        {'timestamp': (now - timedelta(days=45)).isoformat(), 'quality_score': 0.8, 'content': 'old episode'},
        {'timestamp': (now - timedelta(days=10)).isoformat(), 'quality_score': 0.3, 'content': 'low quality episode'},
    ]
    kept = prune_old_episodes(episodes, max_age_days=30, min_quality=0.5)
    print(f'Kept {len(kept)} of {len(episodes)} episodes after pruning')
    for ep in weighted_episodes(kept):
        print(f"  weight={ep['weight']:.3f} content={ep['content']}")

Måle hvor effektiv refleksjonen er

Følg med på om selvkritikken faktisk forbedrer resultatene, ved å sammenligne kvalitetspoengene for første forsøk med det endelige forsøket (etter refleksjon). Hvis forbedringen er liten eller negativ, kan refleksjonsinstruksen trenge justering.

def measure_reflection_gain(run_log: list) -> dict:
    """
    run_log: list of dicts with keys 'attempt', 'quality_score'
    e.g. [{'attempt': 1, 'quality_score': 0.55}, {'attempt': 2, 'quality_score': 0.78}]
    """
    if not run_log:
        return {}

    first_score = run_log[0]['quality_score']
    best_score = max(r['quality_score'] for r in run_log)
    final_score = run_log[-1]['quality_score']

    return {
        'first_attempt_score': first_score,
        'final_score': final_score,
        'best_score': best_score,
        'absolute_gain': final_score - first_score,
        'relative_gain_pct': ((final_score - first_score) / max(first_score, 0.001)) * 100,
        'retries': len(run_log) - 1
    }

log = [
    {'attempt': 1, 'quality_score': 0.55},
    {'attempt': 2, 'quality_score': 0.78}
]
print(measure_reflection_gain(log))

Sikkerhetstiltak for refleksjonsløkker

Uten begrensninger kan en refleksjonsløkke kjøre på ubestemt tid. Håndhev alltid et maksimalt antall nye forsøk, en minimumsterskel for poengsum ved tidlig avslutning og et tidsbudsjett. Logg alle refleksjoner, slik at du kan revidere løkkens atferd.

import time

def safe_reflection_loop(
    task: str,
    client,
    max_retries: int = 3,
    quality_target: float = 0.75,
    time_budget_seconds: float = 30.0
) -> dict:
    start = time.time()
    response = run_agent(task, client)
    run_log = []

    for attempt in range(max_retries + 1):
        if time.time() - start > time_budget_seconds:
            print('Time budget exceeded, returning best result')
            break
        reflection = structured_reflect(task, response, client)
        run_log.append({'attempt': attempt + 1,
                        'quality_score': reflection['quality_score']})

        if reflection['quality_score'] >= quality_target:
            print(f'Quality target reached at attempt {attempt + 1}')
            break
        if attempt < max_retries:
            response = run_agent(task + '\n' + reflection['alternative_approach'], client)

    return {'response': response, 'run_log': run_log,
            'gain': measure_reflection_gain(run_log)}

Kunnskapssjekk

Hva er den viktigste fordelen ved å lagre refleksjonsepisoder som episodisk minne?

Oppsummering: Refleksjons- og selvkritikkløkker

Utmerket! Her er det du gikk gjennom i denne leksjonen:

  • Refleksjonsinstruks: strukturert JSON med styrker, svakheter, kvalitetspoeng og flagg for nytt forsøk
  • Selvkritikkløkke: nytt forsøk ved lav poengsum, der oppgaven berikes med innsikt fra refleksjonen
  • Episodisk minne: lagring av refleksjoner som tidsstemplede episoder per oppgavetype
  • Innsetting av minne: lasting av nylige episoder i systemprompten før hver kjøring
  • Sikkerhetstiltak: maksimalt antall nye forsøk, tidsbudsjett og tidlig avslutning når kvalitetsmålet er nådd

Neste leksjon handler om hvordan vellykkede og mislykkede forløp kan brukes til dypere selvforbedring.

Gratis å komme i gang

Lær deg AI-agenter med en AI-veileder – gratis

Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.

Kurs
60
Leksjoner
239

Ofte stilte spørsmål

Er leksjonen «Sløyfer for refleksjon og selvkritikk» gratis?

Ja – hele teksten i «Sløyfer for refleksjon og selvkritikk» er gratis å lese her på nettet. For å øve interaktivt med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt, og for å låse opp resten av AI-agenter-kurset, kan du oppgradere til CoddyKit PRO. Kurset i AI-agenter inneholder totalt 4 leksjoner.

Hva lærer jeg i «Sløyfer for refleksjon og selvkritikk»?

Agenter som vurderer sine egne resultater og genererer forslag til forbedringer. Du øver på AI-agenter med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.

Trenger jeg erfaring for å begynne med AI-agenter?

Ingen tidligere erfaring er nødvendig. AI-agenter på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 2 av 4.

Hvor lang tid tar leksjonen «Sløyfer for refleksjon og selvkritikk»?

De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.

Kan jeg skrive og kjøre kode i denne AI-agenter-leksjonen?

Ja. Alle AI-agenter-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.

Alle leksjonene i dette kurset

  1. Innsamling og lagring av tilbakemeldinger
  2. Sløyfer for refleksjon og selvkritikk
  3. Selvforbedring basert på handlingsforløp
  4. Når selvforbedring går galt
← Tilbake til AI-agenter