Cursus
Als een dashboard met een bug wordt verscheept, is de debugcyclus altijd hetzelfde. Je kijkt naar het scherm, zoekt het verantwoordelijke bestand, bewerkt het, voert de tests opnieuw uit, laadt de pagina opnieuw en controleert weer. Het is tijdrovend, en de helft van het bewijs staat in schermafbeeldingen in plaats van stacktraces.
Ik begon dit experiment vlak nadat DeepSeek DeepSeek V4.1 Flash uitbracht. Het is het kleinste lid van de nieuwe architectuurfamilie en accepteert afbeeldingsinput. Ik wilde weten of het een kapotte webapp kon inspecteren, de code kon patchen en wist wanneer het klaar was.
Deze tutorial richt zich op één project: een klein Flask-dashboard genaamd Nimbus Analytics Launch Metrics met drie bugs die een agent moet vinden en fixen via DeepSeek’s implementatie van het Responses API-formaat. De opgenomen run toont ook een gat in de hulpmiddelen van de agent.
We behandelen hoe je:
-
Een eerste call naar DeepSeek V4.1 Flash maakt via de Responses API
-
Het model een referentieschermafbeelding geeft en het daarna verse Playwright-screenshots voert als tooloutput
-
De agent tools geeft om bestanden te lijsten, te lezen, pytest te draaien en code over meerdere bestanden te patchen in één call met
apply_patch -
Gespreksgeschiedenis opslaat en opnieuw verzendt omdat de API stateless is
-
Een gestructureerd JSON-reparatierapport retourneert
-
Kosten berekent op basis van gecachte input-, redeneer- en outputtokens
TL;DR
De Responses API van DeepSeek V4.1 Flash is stateless, dus de Python-code bewaart het gesprek en verzendt het bij elke beurt opnieuw. Dezelfde loop gebruikt vision voor de referentieafbeelding en toolscreenshots, thinking-modus om meerdere bestanden te inspecteren, en apply_patch voor edits. Vier details uit de run veranderden hoe ik de volgende versie zou bouwen.
- Eén patch fixte alle drie de bugs in één keer: een enkele apply_patch-call raakte het CSS-, JavaScript- en Python-bestand achtereenvolgens, binnen een budget van veertien beurten.
- Contextcaching dekte de meeste inputtokens: 137.088 van 156.724 inputtokens waren gecachet, een hitrate van 87%.
- Juiste diagnose garandeerde geen volledige verificatie: de agent identificeerde het stagnerende Flask-proces correct, maar had geen tool om het te herstarten en kon de visuele match dus niet zelf bevestigen.
- Gemeten API-kosten waren ongeveer $0,0103: veertien beurten in de reparatieloop plus het verzoek voor het finale JSON-rapport.
Die cijfers komen uit één enkele run op één klein dashboard, geen benchmark. Aantal beurten, cachehitrate en kosten verschuiven bij een grotere app of een andere bugset.
Wat is DeepSeek V4.1 Flash?
DeepSeek levert V4.1 Flash via de API onder het model-ID deepseek-flash. Het accepteert afbeeldingsinput, ondersteunt thinking- en non-thinking-modi, heeft een contextvenster van 1M tokens en kan tot 384K tokens teruggeven via Chat Completions en de Responses API.
Onze DeepSeek V4.1 Flash-overzicht behandelt de lancering, architectuur en benchmarks.
Hoe werkt DeepSeek V4.1 Flash?
DeepSeek beschrijft V4.1 Flash als een 552B-parameter MoE-backbone, terwijl Hugging Face 763B parameters meldt voor de gepubliceerde checkpoint. Het verschil zit grotendeels in het 196B-parameter Engram conditional memory, plus de vision encoder en projector: allemaal componenten die in de checkpoint zitten maar buiten de MoE-backbone vallen.
Het Causal Encoder-Decoder-ontwerp hergebruikt gecachte encoderstates, met 8B actieve parameters per token tijdens inputverwerking en 16B tijdens output.
Wat is er nieuw in DeepSeek V4.1 Flash?
V4.1 Flash is het eerste model in de nieuwe V4.1-architectuurfamilie, met native ingebouwde beeldbegrip. Visuele en tekstembeddings worden vanaf het begin van de pretraining gezamenlijk getraind, in plaats van achteraf toegevoegd zoals in de experimentele V4-Flash-Vision-Exp.
De Responses API gaat vooraf aan V4.1 Flash; DeepSeek voegde native ondersteuning toe tijdens de eerdere V4-uitrol. De uitgefaseerde modelnamen deepseek-v4-flash en deepseek-v4-flash-vision-exp verwijzen nu door naar V4.1 Flash.
Hoeveel kost DeepSeek V4.1 Flash?
De prijzen van DeepSeek zijn gebaseerd op piekuren, met daluren die op 50% van piek zijn gezet. Toen ik de agent draaide, kostte gecachte input $0,003 per miljoen tokens in daluren en $0,006 in piek, niet-gecachte input $0,15 in daluren en $0,30 in piek, en output $0,60 in daluren en $1,20 in piek, per DeepSeek’s prijspagina.
Piekuren lopen van 01:00 tot 04:00 en 06:00 tot 10:00 UTC, maandag t/m vrijdag, met uitzondering van Chinese feestdagen. Alle andere uren zijn daluren, en Chinese feestdagen zijn volledig daluren.
Wat We Gaan Bouwen: de Launch Metrics Visual Repair Agent
Nimbus Analytics Launch Metrics is een Flask-dashboard voor totale bezoekers, aanmeldingen, conversieratio, omzet en dagelijkse aanmeldingen. Ik verstopte drie bugs in drie bestanden en vertelde de agent niet wat ze waren. De code en het kapotte dashboard staan in deze GitHub-repository.

Kapot dashboard naast het referentieontwerp. Afbeelding door de auteur.
De drie bugs vereisen verschillend bewijs. Eén is zichtbaar in de screenshot, één beïnvloedt browsergedrag en één laat pytest falen. De agent krijgt geen buglijst.
Voordat ik dit aan de agent geef, definieer ik wat “gerepareerd” betekent: de pytest-suite moet slagen en een nieuwe schermafbeelding moet visueel overeenkomen met een referentieafbeelding. Alleen de mening van het model is niet genoeg, dus de runner controleert beide vormen van bewijs.
Hoe de reparatieloop werkt
De loop wisselt af tussen een modelverzoek en lokale toolexecutie. V4.1 Flash retourneert redenering, een bericht of toolcalls; Python draait de gevraagde tools en voegt de resultaten toe aan de geschiedenis. De loop stopt wanneer het model antwoordt zonder nieuwe toolcall of de limiet van veertien beurten bereikt.

Reparatieloop die model, tools en browser verbindt. Afbeelding door de auteur.
Hoe je de DeepSeek V4.1 Flash API instelt
Je hebt Python 3.10 of nieuwer nodig en een DeepSeek API-sleutel met tegoed. De API van DeepSeek volgt het OpenAI-verzoekformaat, dus dit project gebruikt het openai Python-pakket met base_url ingesteld op DeepSeek.
Maak een virtuele omgeving en installeer wat het project nodig heeft.
python3 -m venv .venv
source .venv/bin/activate
pip install openai flask playwright pytest python-dotenv requests streamlit
playwright install chromium
Ik testte dit met openai 3.14.1, flask 3.1.3 en playwright 1.63.0. Sla de sleutel op in een .env-bestand in de projectroot als DEEPSEEK_API_KEY=sk-... en laad hem met python-dotenv. Als je sleutel al werkt met de Responses API, sla dan het volgende codeblok over; anders controleert het verzoek de sleutel en de 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)
Als dat een korte begroeting print, werken de sleutel en de base-URL.
Stap 1: Laat het model zien hoe “gerepareerd” eruitziet
De eerste input van de agent bevat een referentieschermafbeelding, een korte taak en de live-URL. Dit is de enige afbeelding die in een gebruikersbericht wordt verzonden. Elke latere screenshot komt uit een tool.
De runner stuurt de referentieafbeelding als een base64 data-URL mee met elk verzoek. DeepSeek raadt de Files API aan wanneer een afbeelding wordt hergebruikt. Een file_id voorkomt dat je telkens dezelfde afbeeldingsdata verstuurt.
Een eerste reactie krijgen voordat je wijzigingen toestaat
In de meegegeven afbeelding vroeg ik wat het model eerst zou controleren, maar er waren geen tools. Zo kon ik het plan bekijken voordat het iets kon aanpassen. De response stelde voor om de projectbestanden te lijsten, CSS-variabelen te traceren en een screenshot te nemen; ik gebruikte reasoning: {"effort": "high"}, DeepSeek’s standaard denkniveau.
Stap 2: Geef de agent bruikbare tools
De agent krijgt vier function tools en één custom tool.
-
list_filesenread_fileinspecteren het project, beide beperkt totdashboard/entests/. -
run_testsdraait pytest. -
capture_dashboard_screenshotstart headless Chromium via Playwright.
De custom tool is apply_patch, gedeclareerd als {"type": "custom", "name": "apply_patch"} en geaccepteerd “voor Codex-compatibiliteit.” Elke andere custom tool-naam geeft een 400-fout, terwijl ingebouwde types zoals web search en computer use stilzwijgend worden genegeerd.
Functieargumenten komen binnen als JSON-tekst en worden gecontroleerd voordat Python ze draait. apply_patch komt binnen als custom tool-input, dus de code handelt dit apart af en controleert de patch voordat er naar bestanden wordt geschreven. Toolfouten worden teruggegeven aan het model in plaats van de loop te stoppen.
Playwright-screenshots terugsturen als tooloutput
Wanneer capture_dashboard_screenshot draait, wordt het resultaat niet op schijf opgeslagen. Python retourneert het als een input_image-onderdeel binnen function_call_output. DeepSeek leest de screenshot dan als afbeelding in plaats van als tekstbeschrijving.
history.append({
"type": "function_call_output",
"call_id": item.call_id,
"output": [{"type": "input_image", "image_url": f"data:image/png;base64,{png_b64}"}],
})
De agent kan de CSS patchen, een nieuwe screenshot nemen en controleren of de cijfers leesbaar zijn.
Stap 3: Bouw de agentloop en beheer de geschiedenis zelf
Geschiedenis leeft in een Python-lijst omdat de API geen previous_response_id of server-side conversaties ondersteunt. Thinking-modus vereist ook elk redeneerelement uit eerdere toolbeurten.
Belangrijk: Als de tooloutput wordt ingevoegd tussen twee calls van dezelfde beurt, geeft het volgende verzoek een 400-fout. Voeg elk item uit response.output in volgorde toe, draai dan de tools en voeg hun resultaten toe.
De runner beperkt de agent tot veertien beurten en de mappen dashboard/ en tests/ . Er is geen shelltoegang, toolargumenten worden gecontroleerd en pytest wordt gebruikt voor verificatie.
Ondersteunt DeepSeek V4.1 Flash gestructureerde output?
Ja, via de Responses API accepteert DeepSeek V4.1 Flash een JSON Schema via text.format. De Chat Completions- response_format ondersteunt JSON-modus maar geen schema’s. Nadat de loop stopt, legt het laatste verzoek de bugs, fixes, testresultaten, screenshotresultaten en verificatiemethode vast.
Het project bevat ook een Streamlit-app in app_streamlit.py. Dezelfde agent draait als generator met stream=True, zodat de pagina redeneringstekst en toolcalls toont zodra ze binnenkomen. De sidebar past de reasoning effort en afbeeldingsdetail aan.
Streamlit-UI streamt de agent-run. Video door de auteur.
Stap 4: Run de visuele bugfix-agent
De run leek klaar na één patch, maar de livepagina was het daar niet mee eens.
De bugs vinden en fixen
De agent gebruikte de eerste twee beurten om te kijken voordat er iets werd aangeraakt: beurt één liste de bestanden en nam een baseline-screenshot, beurt twee las app.py, index.html, style.css en het testbestand.
Beurt drie draaide pytest, waarna beurt vier één patch toepaste die de conversieformule corrigeerde, de metrische kleur wijzigde en de JavaScript-lookup liet overeenkomen met het canvas-ID.
- conversion_rate = data["conversions"] / data["signups"] * 100
+ conversion_rate = data["conversions"] / data["total_visitors"] * 100
Het draaien van de tests in beurt vijf liet alle vijf slagen zien. Hier werd de run minder netjes. Elke nieuwe screenshot liet nog steeds 15% conversieratio en een leeg diagram zien.
Systeemstagnatie ontdekken en oplossen
De agent bevestigde dat de bestanden op schijf de fixes bevatten, probeerde de screenshot opnieuw en onderzocht of de server de gewijzigde Python- en templatebestanden laadde. Twee tijdelijke freshness-checks verschenen ook niet op de livepagina.
Tegen beurt veertien had de loop zijn budget bereikt en de oorzaak geïdentificeerd: run_tests controleert code op schijf, terwijl de screenshot een draaiend proces met een stagnerende staat controleert. Flask startte met debug=False, dus geen reloader laadde de gewijzigde Python-module, en template auto-reload stond niet aan.
De CSS-wijziging verscheen, terwijl de Python-afgeleide waarde en de templategestuurde grafiek verouderd bleven. Pytest importeerde app.py vanaf schijf, dus groene tests garandeerden geen verse pagina.
Nadat ik Flask had herstart, kwam het dashboard overeen met de referentieafbeelding. Het missende stuk was een restart_server-tool, niet nog een codepatch.

Herstart maakt gepatchte dashboardwijzigingen zichtbaar. Afbeelding door de auteur.
Heeft de agent het dashboard gefixt?
Ja, de agent fixte het dashboard op schijf. Het wijzigde alleen de drie foutieve bestanden en pytest ging van vier failures naar vijf slagen. De livepagina toonde elke fix nadat Flask opnieuw was gestart.
Stap 5: Meet gebruik, caching en kosten
Omdat de agent zijn geschiedenis opnieuw verzendt, herhalen latere verzoeken veel van de input van eerdere beurten. DeepSeek vergelijkt dit herhaalde prefix met zijn automatische cache. De cache werkt op best-effortbasis, dus deze cijfers gelden alleen voor deze run.
Over veertien reparatiebeurten en het laatste JSON-rapportverzoek rapporteerde de API 156.724 inputtokens, waaronder 137.088 gecachte tokens, een hitrate van 87%. Output kwam uit op 11.497 tokens, waaronder 9.362 redeneertokens. De run viel in daluren, dus alle vijftien verzoeken kostten in totaal ongeveer $0,0103.

Reasoning-output is de grootste kostencategorie. Afbeelding door de auteur.
Een grotere codebase, meer screenshots of minder cachehits zouden zowel het aantal tokens als de kosten veranderen.
Beperkingen van de DeepSeek V4.1 Flash API om te kennen
Drie API-limieten zijn belangrijk voordat deze runner verder groeit dan de demo.
-
Achtergrondresponses worden niet ondersteund, dus lange beurten blokkeren tot ze klaar zijn.
-
parallel_tool_callsenmax_tool_callsworden genegeerd; parallelle toolcalls blijven ingeschakeld. -
Automatische truncatie wordt niet ondersteund, dus verzoeken die de contextlimiet overschrijden geven een 400-fout.
DeepSeek V4.1 Flash agent-deploymentchecklist
Plaats de controles in applicatiecode in plaats van in modelinstructies voordat je dit patroon in een live service gebruikt.
- Handhaaf beurt- en kostenlimieten, en waarschuw wanneer een van beide is bereikt
- Beperk bestandstoegang en controleer elk toolargument
- Tools om de service te herstarten en te controleren, zodat verificatie de huidige code gebruikt
- Log tokengebruik, toolcalls, testresultaten en eindstatus
Wanneer gebruik je apply_patch vs gewone function tools?
Gebruik apply_patch wanneer één wijziging meerdere bestanden moet updaten, zoals hier. Draai tests na de patch, omdat één verkeerde call meerdere bestanden kan beschadigen.
Gebruik read_file en write_file wanneer elke edit een aparte check of goedkeuring nodig heeft. Ze kosten meer beurten, maar een slechte edit treft één bestand tegelijk.
Tot slot
De visuele reparatieloop fixte alle drie de bugs in één patch, maar de run was geen schone overwinning. Pytest slaagde terwijl Flask nog steeds de oude Python- en template-output serveerde, dus de agent kon de uiteindelijke pagina niet bevestigen totdat ik de server herstartte.
Ik zou een restart_server tool en een pixelvergelijking toevoegen voordat ik een grotere app test. Ik zou de bestandsgrens en beurtlimiet behouden, en pytest en de screenshotvergelijking als aparte checks behandelen. Het slagen van de ene mag nooit in de plaats komen van het slagen van de andere.
FAQs
Kan DeepSeek V4.1 Flash een afbeelding vanaf een URL lezen?
Ja. De Responses API accepteert een publieke afbeeldings-URL, een base64 data-URL of een Files API-file_id.
Wat als de patch van de agent meer testfails veroorzaakt?
De volgende run_tests call toont de regressie en de loop gaat door totdat hij stopt of zijn beurtlimiet bereikt. De applicatie moet ook een kopie bewaren die ze kan herstellen.
Wordt DeepSeek V4 Pro uitgefaseerd?
DeepSeek was van plan V4 Pro uit te faseren kort na de lancering van V4.1 Flash, maar draaide die beslissing terug na gebruikersvraag. V4 Pro blijft beschikbaar met dezelfde billing.
Kun je apply_patch met andere modellen dan DeepSeek gebruiken?
Het formaat komt van de tools van OpenAI’s Codex, en DeepSeek beschrijft de ondersteuning als “voor Codex-compatibiliteit.” Een andere API accepteert {"type": "custom", "name": "apply_patch"} alleen als die hetzelfde toolstatement ondersteunt.
Kan ik DeepSeek V4.1 Flash lokaal draaien?
Ja. De modelgewichten zijn beschikbaar op Hugging Face onder de MIT-licentie. Deze tutorial gebruikt de gehoste API van DeepSeek en behandelt geen modelserving of hardwarevereisten.
Ik ben een data-engineer en communitybouwer die werkt aan datapijplijnen, cloud en AI-tools, en tegelijkertijd praktische, impactvolle tutorials schrijft voor DataCamp en beginnende developers.
