Corso
Quando una dashboard viene distribuita con un bug, il ciclo di debug è sempre lo stesso. Guardi lo schermo, trovi il file responsabile, lo modifichi, riesegui i test, ricarichi la pagina e ricontrolli. È tedioso, e metà delle prove vive negli screenshot più che negli stack trace.
Ho iniziato questo esperimento subito dopo il rilascio di DeepSeek V4.1 Flash. È il membro più piccolo della nuova famiglia di architetture e accetta input di immagini. Volevo capire se potesse ispezionare una web app rotta, applicare patch al codice e sapere quando aveva finito.
Questo tutorial si concentra su un progetto: una piccola dashboard Flask chiamata Nimbus Analytics Launch Metrics con tre bug che un agente deve trovare e correggere tramite l'implementazione di DeepSeek del formato Responses API. La sessione registrata mette anche in evidenza una lacuna negli strumenti dell'agente.
Vedremo come:
-
Effettuare una prima chiamata a DeepSeek V4.1 Flash tramite la Responses API
-
Fornire al modello uno screenshot di riferimento, poi alimentarlo con nuovi screenshot di Playwright come output degli strumenti
-
Dare all'agente strumenti per elencare file, leggere file, eseguire pytest e applicare patch al codice su più file in un'unica chiamata con
apply_patch -
Memorizzare e reinviare la cronologia della conversazione perché l'API è stateless
-
Restituire un report di riparazione JSON strutturato
-
Calcolare i costi da token di input, ragionamento e output in cache
TL;DR
La Responses API di DeepSeek V4.1 Flash è stateless, quindi il codice Python memorizza la conversazione e la reinvia a ogni turno. Lo stesso loop usa la visione per l'immagine di riferimento e gli screenshot degli strumenti, la modalità di ragionamento per ispezionare diversi file e apply_patch per le modifiche. Quattro dettagli della sessione hanno cambiato come costruirei la prossima versione.
- Un'unica patch ha corretto tutti e tre i bug: una singola chiamata a apply_patch ha toccato in sequenza i file CSS, JavaScript e Python, rientrando in un budget di quattordici turni.
- La cache del contesto ha coperto la maggior parte dei token di input: 137.088 su 156.724 token di input sono stati messi in cache, con un tasso di hit dell'87%.
- La diagnosi corretta non ha garantito una verifica completa: l'agente ha identificato correttamente il processo Flask obsoleto, ma non aveva uno strumento per riavviarlo, quindi non poteva confermare autonomamente la corrispondenza visiva.
- Il costo misurato dell'API è stato circa $0,0103: quattordici turni nel loop di riparazione più la richiesta finale del report JSON.
Questi numeri provengono da una singola esecuzione su una piccola dashboard, non da un benchmark. Numero di turni, tasso di hit della cache e costo cambierebbero con un'app più grande o una diversa serie di bug.
Che cos'è DeepSeek V4.1 Flash?
DeepSeek offre V4.1 Flash tramite l'API con l'ID modello deepseek-flash. Accetta input di immagini, supporta modalità con e senza ragionamento, ha una finestra di contesto da 1M di token e può restituire fino a 384K token tramite Chat Completions e la Responses API.
La nostra panoramica di DeepSeek V4.1 Flash copre il lancio, l'architettura e i benchmark.
Come funziona DeepSeek V4.1 Flash?
DeepSeek descrive V4.1 Flash come un backbone MoE da 552B parametri, mentre Hugging Face riporta 763B parametri per il checkpoint pubblicato. Il divario è dovuto principalmente alla memoria condizionale Engram da 196B parametri, più l'encoder e il proiettore di visione, componenti che vengono forniti nel checkpoint ma che si trovano al di fuori del backbone MoE.
Il design Encoder-Decoder Causale riutilizza stati dell'encoder in cache, con 8B parametri attivi per token durante l'elaborazione dell'input e 16B durante l'output.
Cosa c'è di nuovo in DeepSeek V4.1 Flash?
V4.1 Flash è il primo modello della nuova famiglia di architetture V4.1, con comprensione delle immagini integrata nativamente. Gli embedding visivi e testuali sono addestrati congiuntamente fin dall'inizio del pre-addestramento, invece di essere aggiunti successivamente come nel V4-Flash-Vision-Exp sperimentale.
La Responses API è precedente a V4.1 Flash; DeepSeek ha aggiunto il supporto nativo durante il rollout della precedente V4. I nomi dei modelli ritirati deepseek-v4-flash e deepseek-v4-flash-vision-exp ora instradano a V4.1 Flash.
Quanto costa DeepSeek V4.1 Flash?
La tariffazione di DeepSeek è basata sulle ore di punta, con tariffe fuori punta fissate al 50% delle tariffe di punta. Quando ho eseguito l'agente, l'input in cache costava $0,003 per milione di token fuori punta e $0,006 in punta, l'input non in cache costava $0,15 fuori punta e $0,30 in punta, e l'output costava $0,60 fuori punta e $1,20 in punta, per la pagina dei prezzi di DeepSeek.
Le ore di punta vanno dalle 01:00 alle 04:00 e dalle 06:00 alle 10:00 UTC, dal lunedì al venerdì, escluse le festività pubbliche cinesi. Tutte le altre ore sono fuori punta e le festività pubbliche cinesi sono interamente fuori punta.
Cosa costruiremo: il Visual Repair Agent per Launch Metrics
Nimbus Analytics Launch Metrics è una dashboard Flask per visitatori totali, iscrizioni, tasso di conversione, ricavi e iscrizioni giornaliere. Ho inserito tre bug su tre file senza dire all'agente quali fossero. Il codice e la dashboard rotta sono in questo repository GitHub.

Dashboard rotta accanto al design di riferimento. Immagine dell'autore.
I tre bug richiedono prove diverse. Uno appare nello screenshot, uno influisce sul comportamento del browser e uno fallisce i test pytest. L'agente non riceve alcun elenco di bug.
Prima di affidarlo all'agente, definisco cosa significa "corretto": la suite pytest deve passare e uno screenshot aggiornato deve corrispondere visivamente a un'immagine di riferimento. L'opinione del modello da sola non basta, quindi il runner controlla entrambe le forme di evidenza.
Come funziona il loop di riparazione
Il loop alterna una richiesta al modello e l'esecuzione locale degli strumenti. V4.1 Flash restituisce ragionamento, un messaggio o chiamate a strumenti; Python esegue gli strumenti richiesti e aggiunge i risultati alla cronologia. Il loop si ferma quando il modello risponde senza un'altra chiamata a strumenti o raggiunge il limite di quattordici turni.

Loop di riparazione che collega modello, strumenti e browser. Immagine dell'autore.
Come configurare la DeepSeek V4.1 Flash API
Ti serviranno Python 3.10 o superiore e una chiave API DeepSeek con credito. L'API di DeepSeek segue il formato di richiesta di OpenAI, quindi questo progetto usa il pacchetto openai Python con base_url impostato su DeepSeek.
Crea un ambiente virtuale e installa ciò che serve al progetto.
python3 -m venv .venv
source .venv/bin/activate
pip install openai flask playwright pytest python-dotenv requests streamlit
playwright install chromium
Ho testato questo con openai 3.14.1, flask 3.1.3 e playwright 1.63.0. Salva la chiave in un file .env nella root del progetto come DEEPSEEK_API_KEY=sk-... e caricala con python-dotenv. Se la tua chiave funziona già con la Responses API, salta il prossimo blocco di codice; altrimenti, la richiesta verifica chiave e base URL.
from openai import OpenAI
import os
from dotenv import load_dotenv
load_dotenv()
client = OpenAI(api_key=os.environ["DEEPSEEK_API_KEY"], base_url="https://api.deepseek.com")
response = client.responses.create(model="deepseek-flash", input="Say hi in five words.")
print(response.output_text)
Se stampa un breve saluto, la chiave e il base URL funzionano.
Step 1: Mostra al modello come appare "corretto"
Il primo input dell'agente contiene uno screenshot di riferimento, un breve task e l'URL live. Questa è l'unica immagine inviata in un messaggio utente. Ogni screenshot successivo proviene da uno strumento.
Il runner invia l'immagine di riferimento come data URL base64 con ogni richiesta. DeepSeek consiglia la Files API quando un'immagine viene riutilizzata. Un file_id evita di inviare ogni volta gli stessi dati dell'immagine.
Ottenere una reazione iniziale prima di consentire modifiche
Nell'immagine allegata, ho chiesto cosa avrebbe controllato per prima il modello, ma non c'erano strumenti. Questo mi ha permesso di ispezionarne il piano prima che potesse modificare qualcosa. La risposta proponeva di elencare i file del progetto, tracciare le variabili CSS e scattare uno screenshot; ho usato reasoning: {"effort": "high"}, il livello di ragionamento predefinito di DeepSeek.
Step 2: Dai all'agente gli strumenti che può usare
L'agente riceve quattro function tool e uno strumento personalizzato.
-
list_fileseread_fileispezionano il progetto, entrambi limitati adashboard/etests/. -
run_testsesegue pytest. -
capture_dashboard_screenshotavvia Chromium headless tramite Playwright.
Lo strumento personalizzato è apply_patch, dichiarato come {"type": "custom", "name": "apply_patch"} ed accettato "per compatibilità con Codex." Qualsiasi altro nome di strumento personalizzato restituisce un errore 400, mentre i tipi integrati come web search e computer use vengono ignorati silenziosamente.
Gli argomenti delle function arrivano come testo JSON e vengono verificati prima che Python li esegua. apply_patch arriva come input di uno strumento personalizzato, quindi il codice lo gestisce separatamente e controlla la patch prima di scrivere i file. Gli errori degli strumenti vengono restituiti al modello invece di interrompere il loop.
Inviare gli screenshot di Playwright come output dello strumento
Quando capture_dashboard_screenshot viene eseguito, il suo risultato non viene salvato su disco. Python lo restituisce come una parte input_image all'interno di function_call_output. DeepSeek quindi legge lo screenshot come immagine invece che come descrizione testuale.
history.append({
"type": "function_call_output",
"call_id": item.call_id,
"output": [{"type": "input_image", "image_url": f"data:image/png;base64,{png_b64}"}],
})
L'agente può correggere il CSS, scattare un altro screenshot e verificare se i numeri sono leggibili.
Step 3: Costruisci il loop dell'agente e gestisci tu stesso la cronologia
La cronologia vive in una lista Python perché l'API non supporta previous_response_id o conversazioni lato server. La modalità di ragionamento richiede anche ogni elemento di ragionamento dai turni di strumenti precedenti.
Importante: se l'output dello strumento viene inserito tra due chiamate dello stesso turno, la richiesta successiva restituisce un errore 400. Aggiungi ogni elemento da response.output in ordine, poi esegui gli strumenti e aggiungi i loro risultati.
Il runner limita l'agente a quattordici turni e alle directory dashboard/ e tests/. Non fornisce accesso alla shell, controlla gli argomenti degli strumenti e usa pytest per la verifica.
DeepSeek V4.1 Flash supporta output strutturati?
Sì, tramite la Responses API, DeepSeek V4.1 Flash accetta uno schema JSON attraverso text.format. Le Chat Completions response_format supportano la modalità JSON ma non gli schemi. Dopo che il loop si ferma, la richiesta finale registra bug, correzioni, risultati dei test, risultati degli screenshot e metodo di verifica.
Il progetto include anche un'app Streamlit in app_streamlit.py. Lo stesso agente gira come generatore con stream=True, quindi la pagina mostra il testo di ragionamento e le chiamate agli strumenti man mano che arrivano. La sidebar modifica lo sforzo di ragionamento e il dettaglio dell'immagine.
L'interfaccia Streamlit esegue in streaming l'esecuzione dell'agente. Video dell'autore.
Step 4: Esegui l'agente di correzione bug visiva
L'esecuzione sembrava conclusa dopo una patch, ma la pagina live non era d'accordo.
Trovare e correggere i bug
L'agente ha usato i primi due turni per guardare prima di toccare qualcosa: il primo turno ha elencato i file e scattato uno screenshot di baseline, il secondo turno ha letto app.py, index.html, style.css e il file di test.
Il terzo turno ha eseguito pytest, poi il quarto ha applicato una patch che ha corretto la formula di conversione, cambiato il colore della metrica e allineato il lookup JavaScript all'ID del canvas.
- conversion_rate = data["conversions"] / data["signups"] * 100
+ conversion_rate = data["conversions"] / data["total_visitors"] * 100
L'esecuzione dei test al quinto turno ha mostrato tutti e cinque in passaggio. Qui l'esecuzione ha smesso di essere ordinata. Ogni nuovo screenshot mostrava ancora un tasso di conversione del 15% e un grafico vuoto.
Scoprire la staleness del sistema e risolverla
L'agente ha confermato che i file su disco contenevano le correzioni, ha riprovato lo screenshot e ha verificato se il server stesse caricando i file Python e i template modificati. Anche due controlli temporanei di freschezza non sono comparsi nella pagina live.
Al quattordicesimo turno, il loop aveva raggiunto il budget e identificato la causa: run_tests controlla il codice su disco, mentre lo screenshot controlla un processo in esecuzione con uno stato obsoleto. Flask è stato avviato con debug=False, quindi nessun reloader ha caricato il modulo Python modificato e l'auto-reload dei template non era attivo.
La modifica CSS è apparsa mentre il valore derivato da Python e il grafico basato sul template sono rimasti obsoleti. Pytest ha importato app.py da disco, quindi i test verdi non garantivano una pagina aggiornata.
Dopo che ho riavviato Flask, la dashboard ha corrisposto all'immagine di riferimento. Il pezzo mancante era uno strumento restart_server, non un'altra patch di codice.

Il riavvio rende visibili le modifiche alla dashboard patchata. Immagine dell'autore.
L'agente ha corretto la dashboard?
Sì, l'agente ha corretto la dashboard su disco. Ha modificato solo i tre file difettosi e pytest è passato da quattro errori a cinque test superati. La pagina live ha mostrato ogni correzione dopo il riavvio di Flask.
Step 5: Misura utilizzo, caching e costo
Poiché l'agente reinvia la sua cronologia, le richieste successive ripetono gran parte dell'input dei turni precedenti. DeepSeek confronta questo prefisso ripetuto con la sua cache automatica. La cache funziona al meglio delle possibilità, quindi queste cifre valgono solo per questa esecuzione.
Su quattordici turni di riparazione e la richiesta finale del report JSON, l'API ha riportato 156.724 token di input, inclusi 137.088 token in cache, un tasso di hit dell'87%. L'output è stato di 11.497 token, inclusi 9.362 token di ragionamento. L'esecuzione è avvenuta in ore fuori punta, quindi tutte e quindici le richieste sono costate circa $0,0103.

Il ragionamento è la categoria di costo più grande. Immagine dell'autore.
Un codebase più grande, più screenshot o meno hit della cache cambierebbero sia il conteggio dei token sia il costo.
Limitazioni della DeepSeek V4.1 Flash API da conoscere
Tre limiti dell'API contano prima che questo runner cresca oltre la demo.
-
Le risposte in background non sono supportate, quindi i turni lunghi bloccano finché non finiscono.
-
parallel_tool_callsemax_tool_callssono ignorati; le chiamate agli strumenti in parallelo restano abilitate. -
Il troncamento automatico non è supportato, quindi le richieste che superano il limite di contesto restituiscono un errore 400.
Checklist di deployment per l'agente DeepSeek V4.1 Flash
Prima di usare questo pattern in un servizio live, inserisci i controlli nel codice dell'applicazione invece che nelle istruzioni del modello.
- Imponi limiti di turni e costi e avvisa quando uno dei due viene raggiunto
- Restringi l'accesso ai file e verifica ogni argomento degli strumenti
- strumenti per riavviare e controllare il servizio, così la verifica usa il codice corrente
- Logga utilizzo dei token, chiamate agli strumenti, risultati dei test e stato finale
Quando usare apply_patch vs semplici function tool?
Usa apply_patch quando una singola modifica deve aggiornare più file, come in questo caso. Esegui i test dopo la patch, perché una singola chiamata difettosa può danneggiare diversi file.
Usa read_file e write_file quando ogni modifica richiede un controllo o un'approvazione separata. Richiedono più turni, ma una modifica errata colpisce un file alla volta.
Considerazioni finali
Il loop di riparazione visiva ha corretto tutti e tre i bug con un'unica patch, ma l'esecuzione non è stata un successo pulito. Pytest è passato mentre Flask serviva ancora il vecchio output di Python e del template, quindi l'agente non ha potuto confermare la pagina finale finché non ho riavviato il server.
Aggiungerei uno strumento restart_server e un confronto pixel-by-pixel prima di testare un'app più grande. Manterrei il confine sui file e il limite di turni, quindi tratterei pytest e il confronto degli screenshot come controlli separati. Superarne uno non dovrebbe mai sostituire l'altro.
FAQ
DeepSeek V4.1 Flash può leggere un'immagine da un URL?
Sì. La Responses API accetta un URL immagine pubblico, un data URL base64 o un file_id della Files API.
Cosa succede se la patch dell'agente causa più errori nei test?
La successiva chiamata a run_tests mostra la regressione, e il loop continua finché non si ferma o raggiunge il limite di turni. L'applicazione dovrebbe anche conservare una copia da poter ripristinare.
DeepSeek V4 Pro sta per essere ritirato?
DeepSeek aveva pianificato di eliminare gradualmente V4 Pro poco dopo il lancio di V4.1 Flash, poi ha invertito la decisione dopo le richieste degli utenti. V4 Pro rimane disponibile con la stessa tariffazione.
Posso usare apply_patch con altri modelli oltre a DeepSeek?
Il formato proviene dagli strumenti di Codex di OpenAI, e DeepSeek descrive il suo supporto come "per compatibilità con Codex." Un'altra API accetterà {"type": "custom", "name": "apply_patch"} solo se supporta la stessa dichiarazione dello strumento.
Posso eseguire DeepSeek V4.1 Flash in locale?
Sì. I pesi del modello sono disponibili su Hugging Face con licenza MIT. Questo tutorial usa l'API hosted di DeepSeek e non tratta il serving del modello o i requisiti hardware.
Sono un data engineer e community builder: lavoro su pipeline dati, cloud e strumenti di AI, e scrivo tutorial pratici e ad alto impatto per DataCamp e per sviluppatori alle prime armi.
