Il tuo primo flow
Un flow writer → reviewer, eseguito dall'inizio alla fine sulla tua macchina, senza nessuna chiave di modello.
- Python 3.12+ e
uv. git.- nient'altro: l'esecuzione usa l'harness dry e non serve nessuna chiave di modello.
- una cartella con il flow writer → reviewer dello scenario S1.
- una configurazione che valida.
- un ticket finito: il writer scrive, il reviewer controlla, tu approvi.
Passi
-
Clona il repository, installa le dipendenze e metti
afenel path:git clone <repository-url> afecd afeuv syncsource .venv/bin/activate -
Crea una cartella per il tutorial e una cartella
config/dentro:mkdir -p afe-first-flow/config/promptscd afe-first-flow -
Scrivi il flow,
config/flow.yaml. È un ciclo writer → reviewer. Il writer produce iltext. Il reviewer rispondeokoko. Unkorimanda il testo come feedback, e il nodo umanoapprovechiude il flow:config/flow.yaml# yaml-language-server: $schema=../../../../schemas/afe.dev-v1alpha1.jsonapiVersion: afe.dev/v1alpha1kind: Flowmetadata:name: writer-reviewerannotations:afe.dev/description: Scenario S1, a text written, reviewed and approvedlabels:scenario: S1spec:input:artifact: text-requestbudget:costUsd: 0.5wallTime: 30mnodes:writer:type: agentagent: writerreviewer:type: agentagent: reviewerapprove:type: humanactions:- approve- rejectrequireComment:- rejectwrites: decisionmessage: Publish "{text.title}"?edges:- from: STARTto: writer- from: writerto: reviewer- from: reviewerwhen: review.outcome == 'ko'to: writerfeedback: truemaxRounds: 2- from: reviewerto: approve- from: approvewhen: decision.action == 'reject'to: writernewRound: truemaxRounds: 2- from: approveto: END -
Scrivi i due agenti,
config/agents.yaml:config/agents.yaml# yaml-language-server: $schema=../../../../schemas/afe.dev-v1alpha1.jsonapiVersion: afe.dev/v1alpha1kind: Agentmetadata:name: writerspec:model: cheapsystemPromptFile: prompts/writer.mdreads:- text-request- review?- decision?writes: textbudget:tokens: 20000costUsd: 0.1wallTime: 5m---apiVersion: afe.dev/v1alpha1kind: Agentmetadata:name: reviewerspec:model: cheapsystemPromptFile: prompts/reviewer.mdreads:- text-request- textwrites: reviewbudget:tokens: 20000toolCalls: 3costUsd: 0.1wallTime: 5mlimits:maxSubmitRetries: 2 -
Scrivi gli artefatti,
config/schemas.yaml:config/schemas.yaml# yaml-language-server: $schema=../../../../schemas/afe.dev-v1alpha1.jsonapiVersion: afe.dev/v1alpha1kind: Schemametadata:name: text-requestspec:fields:topic:type: stringlength:type: enum[short|medium|long]---apiVersion: afe.dev/v1alpha1kind: Schemametadata:name: textspec:fields:title:type: stringbody:type: string---apiVersion: afe.dev/v1alpha1kind: Schemametadata:name: reviewspec:fields:outcome:type: enum[ok|ko]notes:type: list[string]optional: true---apiVersion: afe.dev/v1alpha1kind: Schemametadata:name: decisionspec:fields:action:type: enum[approve|reject]comment:type: stringoptional: true -
Scrivi l'alias di modello,
config/models.yaml. L'harness dry non lo chiama mai, quindi oggi la chiave non serve:config/models.yaml# yaml-language-server: $schema=../../../../schemas/afe.dev-v1alpha1.jsonapiVersion: afe.dev/v1alpha1kind: Modelmetadata:name: cheapannotations:afe.dev/description: A cheap model for drafts and reviewsspec:provider: openroutermodel: deepseek/deepseek-chatapiKeyEnv: OPENROUTER_API_KEY -
Scrivi i due prompt,
config/prompts/writer.mdeconfig/prompts/reviewer.md:config/prompts/writer.mdWrite the text the request asks for. If a review or a rejection is present, address it.config/prompts/reviewer.mdCheck the text against the request. Answer ok, or ko with concrete notes. -
Scrivi l'input del ticket,
request.yaml, accanto aconfig/:request.yamltopic: beeslength: short -
Valida la configurazione:
afe validate -c config/Stampa
8 manifests, no errors. -
Rompi un riferimento per vedere l'errore, poi correggilo. Cambia
agent: reviewerinagent: reviewrinconfig/flow.yamle valida di nuovo. Il report nomina l'Agent sconosciuto e il percorsospec.nodes.reviewer.agent. Rimettireviewer. -
Esegui il flow con l'harness dry:
afe run writer-reviewer -i request.yaml -c config/ --local --dry -
Rispondi all'approvazione al prompt: scrivi
approvee premi Invio due volte. Gli eventi scorrono e l'esecuzione finisce conT-0001 ticket_done.
Il motore --local non tiene nulla dopo la fine del comando. Gli eventi stampati sono tutto il
risultato: dopo non resta nulla da ispezionare.
Ora leggi Nella web UI per eseguire lo stesso flow attraverso il server. Il tutorial successivo, Su un modello reale, chiama un modello vero.
Risoluzione dei problemi
Sintomo: la shell stampa afe: command not found.
Causa: l'ambiente virtuale del passo 1 non è attivo in questa shell.
Rimedio: esegui di nuovo source .venv/bin/activate. Non resta attivo in una nuova scheda del
terminale.
Sintomo: afe run termina subito con codice 2 e non stampa nessun prompt.
Causa: il comando non ha un terminale collegato, per esempio dentro uno script o un job di CI.
Rimedio: usa il comando afe resume che stampa, con l'azione che vuoi rispondere.