DeepSeek släppte i slutet av juli 2026 en ny produktionsversion av sin snabba modell, kallad DeepSeek-V4-Flash-0731, och två veckor senare följde storebror DeepSeek-V4-Pro-0813. Båda delar samma grundegenskap: ett kontextfönster på 1 miljon tokens, tillgängligt via ett API som är kompatibelt med både OpenAI:s och Anthropics SDK:er. För svenska utvecklare som vill bygga en agent som läser hela loggfiler, kontrakt eller supportärenden i ett enda anrop, utan att chunka texten i småbitar, är det här ett praktiskt verktyg snarare än ett labbexperiment.

Den här guiden går igenom hur du bygger en fungerande dokument- och logganalysagent med DeepSeek V4-Flash, från API-nyckel till en komplett Python-fil du kan köra direkt. Du får kod för varje steg, en kostnadskalkyl baserad på DeepSeeks officiella prislista, och en lista på fel du sannolikt stöter på första gången du testar allt själv.

För svenska och nordiska utvecklingsteam är prisbilden extra relevant. Kronkursen gör att API-priser satta i dollar svänger med valutan, och ett projekt som ser billigt ut i augusti kan kosta annorlunda i december. Just därför bygger guiden in en konkret kostnadskalkyl längre ner, baserad på DeepSeeks officiella dollarpriser, så att du kan räkna om till din egen budget istället för att bara lita på ett runt marknadsföringstal.

Vad du bygger i den här guiden

Slutresultatet är ett kommandoradsverktyg skrivet i Python som tar emot en lång textfil (till exempel en serverlogg, ett PDF-extrakt eller ett helt supportarkiv), skickar hela innehållet till DeepSeek V4-Flash i ett anrop, och låter modellen använda ett par egna verktyg (function calling) för att söka i texten, räkna förekomster och sammanfatta resultatet strukturerat. Du bygger inte en chatbot med minne mellan sessioner, utan en enskild agent-loop som är tillräckligt robust för att köras i ett skript, ett cron-jobb eller en enkel webhook.

Guiden är skriven för utvecklare som redan kan Python på en grundnivå. Du behöver inte ha jobbat med LLM-API:er tidigare, men det hjälper om du känner igen begrepp som JSON, miljövariabler och HTTP-anrop. Alla kodexempel är testade mot DeepSeeks officiella API-dokumentation och använder standardbiblioteket openai, eftersom DeepSeek har valt att göra sitt API OpenAI-kompatibelt istället för att kräva ett eget SDK.

Vad är DeepSeek V4-Flash och varför 1 miljon tokens förändrar spelplanen

DeepSeek V4-Flash är en Mixture-of-Experts-modell (MoE) med omkring 284 miljarder parametrar totalt, men bara cirka 13 miljarder aktiva parametrar per beräkning, enligt öppna sammanställningar av modellarkitekturer från augusti 2026. Det är den tekniska anledningen till att modellen är både snabb och billig att köra jämfört med sin större syskonmodell V4-Pro, som istället landar på ungefär 1,6 biljoner totala parametrar och 49 miljarder aktiva. Båda modellerna distribueras med MIT-licens och öppna vikter, vilket betyder att du kan ladda ner och självhosta dem om du har hårdvaran för det, eller helt enkelt använda det hostade API:et som den här guiden fokuserar på.

Det som gör V4-Flash intressant för agentbygge är inte bara priset, utan kontextfönstret. Enligt DeepSeeks egen API-dokumentation stödjer alla tre modellerna i familjen, deepseek-v4-flash, deepseek-v4-pro och deepseek-v4-flash-vision-exp, ett indata-fönster på 1 miljon tokens med upp till 384 000 tokens i utdata. I praktiken betyder det att du kan mata in en hel årslogg från en applikationsserver, ett helt kontrakt på 300 sidor, eller flera hundra supportärenden, i ett enda anrop utan att först dela upp texten i mindre bitar och riskera att modellen tappar sammanhanget mellan delarna.

Juli-versionen av V4-Flash beskrivs i uppdaterade jämförelser som en omtränad modell där DeepSeek har lagt extra fokus på kodgenerering, verktygsanvändning och resonemang, utan att ändra själva MoE-arkitekturen. Det märks i praktiken genom att modellen är påtagligt bättre på att följa strukturerade instruktioner och anropa funktioner korrekt än tidigare V4-förhandsversioner, vilket är precis den egenskap en agent behöver för att fungera tillförlitligt.

Förutsättningar: det här behöver du innan du börjar

Du behöver inte mycket för att komma igång, men se till att följande finns på plats innan du går vidare till steg 1. Att sakna ett av dessa är den vanligaste orsaken till att guider som denna känns svårare än de borde vara.

  • Python 3.10 eller senare installerat (kontrollera med python3 --version)
  • pip eller uv för pakethantering
  • Ett DeepSeek-konto på platform.deepseek.com med betalningsuppgifter kopplade, eftersom API:et inte har en gratisnivå för produktionsanvändning
  • Paketet openai version 1.50 eller senare (DeepSeek använder OpenAI:s klientbibliotek genom sitt kompatibla API-format)
  • Ett terminal- eller kommandoradsverktyg (bash, zsh eller PowerShell fungerar alla)
  • Ett textdokument att testa med, till exempel en loggfil på några hundra kilobyte, eller en PDF du konverterat till text

Hela guiden går att genomföra på cirka 75 minuter om du kopierar kodblocken direkt, eller något längre om du vill förstå varje rad innan du kör den. Räkna med extra tid om du testar mot ett riktigt stort dokument, eftersom anrop med nära 1 miljon tokens kan ta mellan 30 och 90 sekunder att svara beroende på belastning.

Du behöver heller inte redan ha ett Redis-kluster, en molnserver eller något orkestreringsverktyg för att följa med. Allt kodexempel körs lokalt på din egen dator eller laptop, och det enda som lämnar din maskin är själva API-anropen till DeepSeek. Det gör guiden lämplig även som en fredagseftermiddags-övning innan du bestämmer dig för att bygga ut lösningen till något mer permanent.

Steg 1–3: Skaffa API-nyckel, sätt upp projektet och installera SDK:t

Steg 1: Skapa konto och generera en API-nyckel

Gå till DeepSeeks utvecklarportal och skapa ett konto om du inte redan har ett. Under sektionen för API-nycklar genererar du en ny nyckel och kopierar den direkt, eftersom den bara visas en gång. Ladda sedan på ditt konto med krediter, DeepSeek fakturerar per token snarare än via en fast månadskostnad, vilket gör det enkelt att testa för några kronor innan du bygger något större.

Verifiera att nyckeln fungerar direkt från terminalen innan du skriver någon Python-kod. Det sparar dig från att felsöka fel kod när problemet egentligen ligger i själva nyckeln eller kontot.

export DEEPSEEK_API_KEY="din-nyckel-har"

curl https://api.deepseek.com/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DEEPSEEK_API_KEY" \
  -d '{
    "model": "deepseek-v4-flash",
    "messages": [{"role": "user", "content": "Svara bara med ordet OK"}]
  }'

Får du tillbaka ett JSON-svar med “OK” i innehållet är nyckeln aktiv och kontot har krediter. Ett 401-fel betyder att nyckeln är fel formaterad eller inaktiverad, ett 402-fel betyder att kontot saknar krediter.

Steg 2–3: Projektmapp, virtuell miljö och beroenden

Skapa en ny projektmapp och en virtuell miljö för att hålla beroenden separata från resten av systemet. Installera sedan openai-paketet, som DeepSeek använder som klientbibliotek eftersom API-formatet är kompatibelt.

mkdir deepseek-agent && cd deepseek-agent
python3 -m venv venv
source venv/bin/activate

pip install openai python-dotenv

echo "DEEPSEEK_API_KEY=din-nyckel-har" > .env

Lägg .env i din .gitignore direkt, innan du glömmer det. Att av misstag committa en API-nyckel till ett publikt repo är ett av de vanligaste sätten utvecklare tappar kontroll över sina API-kostnader, och DeepSeek fakturerar löpande tills nyckeln spärras manuellt.

Steg 4–5: Gör ditt första API-anrop mot DeepSeek

Nästa steg är att bekräfta att Python-klienten pratar med DeepSeek korrekt innan du bygger något mer avancerat. Skapa en fil som heter test_call.py med följande innehåll.

import os
from dotenv import load_dotenv
from openai import OpenAI

load_dotenv()

client = OpenAI(
    api_key=os.environ["DEEPSEEK_API_KEY"],
    base_url="https://api.deepseek.com",
)

response = client.chat.completions.create(
    model="deepseek-v4-flash",
    messages=[
        {"role": "system", "content": "Du är en teknisk assistent som svarar kortfattat på svenska."},
        {"role": "user", "content": "Förklara vad ett kontextfönster på 1 miljon tokens innebär i praktiken."},
    ],
    max_tokens=300,
)

print(response.choices[0].message.content)
print("Tokens använda:", response.usage.total_tokens)

Kör filen med python test_call.py. Det enda som skiljer detta anrop från ett vanligt OpenAI-anrop är raden base_url="https://api.deepseek.com", resten av kodmönstret är identiskt eftersom DeepSeek medvetet har byggt API:et för att vara en drop-in-ersättning. Byter du redan befintlig OpenAI-kod till DeepSeek räcker det oftast att ändra just den raden och modellnamnet.

Exempel på utdata:

Ett kontextfönster på 1 miljon tokens motsvarar grovt räknat 700 000-750 000
ord svensk text, vilket täcker en hel bokserie eller flera tusen sidor
loggdata i ett enda anrop utan att texten behöver delas upp.
Tokens använda: 187

Steg 6–7: Bygg dokumentläsaren för långa loggar och rapporter

Nu bygger du funktionen som faktiskt läser in ett stort dokument och skickar det till modellen. Poängen med 1 miljon tokens kontext är att du kan skippa det klassiska mönstret där du delar upp texten i överlappande chunks och kör flera anrop, ett mönster som ofta gör att modellen tappar sammanhang mellan bitarna. Istället läser du in hela filen och skickar den i ett enda meddelande.

def load_document(path: str) -> str:
    with open(path, "r", encoding="utf-8", errors="ignore") as f:
        text = f.read()

    # Grov uppskattning: 1 token motsvarar ungefär 3,5-4 tecken i svensk text
    estimated_tokens = len(text) / 3.7
    if estimated_tokens > 950_000:
        raise ValueError(
            f"Dokumentet är för stort ({estimated_tokens:,.0f} uppskattade tokens). "
            "Max ligger runt 950 000 för att lämna plats åt system- och verktygsmeddelanden."
        )

    return text


def analyze_document(client: OpenAI, document_text: str, question: str) -> str:
    response = client.chat.completions.create(
        model="deepseek-v4-flash",
        messages=[
            {
                "role": "system",
                "content": (
                    "Du är en logg- och dokumentanalytiker. Svara strukturerat med "
                    "rubriker och punktlistor på svenska. Citera radnummer eller "
                    "tidsstämplar när du hänvisar till specifika händelser."
                ),
            },
            {"role": "user", "content": f"DOKUMENT:\n\n{document_text}\n\nFRÅGA: {question}"},
        ],
        max_tokens=4000,
        temperature=0.2,
    )
    return response.choices[0].message.content

Notera temperature=0.2. För analysuppgifter där du vill ha konsekventa, faktabaserade svar snarare än kreativa formuleringar bör temperaturen ligga lågt. En hög temperatur på ett dokumentanalysjobb ger dig ofta svar som låter säkra men som hittar på detaljer som inte finns i källtexten.

Steg 8–9: Ge agenten verktyg med function calling

En ren fråga-svar-funktion är användbar, men en agent behöver kunna agera, inte bara svara. Här definierar du två enkla verktyg: ett som räknar förekomster av ett sökord i dokumentet, och ett som extraherar alla rader som matchar ett mönster. DeepSeek V4-Flash stödjer function calling via samma format som OpenAI, vilket dokumenteras i DeepSeeks egen guide för verktygsanrop. Vikterna för hela V4-familjen finns även publicerade öppet på DeepSeeks GitHub-organisation för den som senare vill utvärdera självhostning.

import json
import re

tools = [
    {
        "type": "function",
        "function": {
            "name": "count_occurrences",
            "description": "Räknar hur många gånger ett ord eller mönster förekommer i dokumentet",
            "parameters": {
                "type": "object",
                "properties": {
                    "pattern": {"type": "string", "description": "Ordet eller mönstret att söka efter"},
                },
                "required": ["pattern"],
            },
        },
    },
    {
        "type": "function",
        "function": {
            "name": "extract_matching_lines",
            "description": "Hämtar alla rader i dokumentet som innehåller ett visst mönster",
            "parameters": {
                "type": "object",
                "properties": {
                    "pattern": {"type": "string"},
                    "max_lines": {"type": "integer", "description": "Max antal rader att returnera"},
                },
                "required": ["pattern"],
            },
        },
    },
]


def execute_tool(name: str, args: dict, document_text: str) -> str:
    lines = document_text.splitlines()
    if name == "count_occurrences":
        count = len(re.findall(re.escape(args["pattern"]), document_text, re.IGNORECASE))
        return json.dumps({"pattern": args["pattern"], "count": count})
    if name == "extract_matching_lines":
        max_lines = args.get("max_lines", 20)
        matches = [l for l in lines if args["pattern"].lower() in l.lower()][:max_lines]
        return json.dumps({"matches": matches})
    return json.dumps({"error": f"Okänt verktyg: {name}"})

Verktygen körs lokalt i din egen Python-process, modellen skickar bara tillbaka vilket verktyg den vill anropa och med vilka argument. Det är samma säkerhetsmodell som all function calling bygger på: modellen föreslår, din kod bestämmer om och hur anropet faktiskt körs.

Steg 10: Prompt-cache, så sänker du kostnaden drastiskt

Det här är steget de flesta hoppar över första gången, och det är misstaget som gör långkontext-agenter dyra i onödan. DeepSeeks officiella prislista skiljer kraftigt mellan cache hit och cache miss på indata. Skickar du samma dokument flera gånger i följd, till exempel när agenten ställer flera följdfrågor mot samma logg, cachas den inlästa texten automatiskt på DeepSeeks sida och du betalar en bråkdel av priset för de token som redan setts.

ModellIndata, cache hit (lågtrafik)Indata, cache miss (lågtrafik)Utdata (lågtrafik)
deepseek-v4-flash0,007 dollar / 1M tokens0,22 dollar / 1M tokens0,66 dollar / 1M tokens
deepseek-v4-pro0,022 dollar / 1M tokens0,66 dollar / 1M tokens1,98 dollar / 1M tokens
deepseek-v4-flash-vision-exp0,007 dollar / 1M tokens0,22 dollar / 1M tokens0,66 dollar / 1M tokens

Enligt DeepSeeks prisdokumentation dubbleras samtliga priser under högtrafik, som infaller 01:00-04:00 och 06:00-10:00 UTC på vardagar. Kör din agent som ett schemalagt jobb kan du alltså halvera kostnaden bara genom att undvika de tidsfönstren, exempelvis genom att köra batch-analyser sen svensk kväll istället för på morgonen.

För att dra nytta av cachen i praktiken, håll samma dokumenttext identisk mellan anrop och lägg den i samma position i meddelandelistan varje gång. Ändrar du en enda bokstav i systemprompten eller dokumentet mellan anrop bryts cachen och du betalar fullt pris igen.

Steg 11: Streaming, timeouts och robust felhantering

Ett anrop med nära en miljon tokens indata tar tid, ibland över en minut. Utan streaming och rimliga timeouts riskerar ditt skript att se ut som att det hänger sig. Lägg till en wrapper med återförsök och exponentiell backoff, samt en tydlig timeout, innan du kör agenten mot riktiga dokument.

import time
from openai import APITimeoutError, APIError, RateLimitError

def call_with_retry(client, **kwargs):
    max_attempts = 4
    for attempt in range(1, max_attempts + 1):
        try:
            return client.chat.completions.create(timeout=120, **kwargs)
        except RateLimitError:
            wait = 2 ** attempt
            print(f"Rate limit, väntar {wait}s (försök {attempt}/{max_attempts})")
            time.sleep(wait)
        except APITimeoutError:
            print(f"Timeout på försök {attempt}, dokumentet kan vara för stort för snabbt svar")
            if attempt == max_attempts:
                raise
        except APIError as e:
            print(f"API-fel: {e}")
            if attempt == max_attempts:
                raise
            time.sleep(2 ** attempt)
    raise RuntimeError("Alla återförsök misslyckades")

Sätt alltid en explicit timeout, standardvärdet i klientbiblioteket är ofta för kort för anrop med hundratusentals tokens indata. 120 sekunder är en rimlig startpunkt för dokument nära gränsen på 1 miljon tokens, men justera efter egen erfarenhet.

Om du bygger agenten in i en webbtjänst snarare än ett fristående skript, undvik att låta en HTTP-förfrågan vänta hela minuten på ett svar. Kör istället anropet i en bakgrundsprocess eller en kö, och låt klienten polla ett status-endpoint för resultatet. Det är samma mönster som gäller för alla långsamma bakgrundsjobb, men det är lätt att glömma just här eftersom testerna lokalt sällan avslöjar hur en riktig webbserver med timeout på 30 sekunder reagerar på ett anrop som tar dubbelt så lång tid.

Steg 12–13: Testa agenten mot ett riktigt exempeldokument

Nu sätter du ihop stegen till en fungerande agent-loop och testar mot ett exempel. Anta att du har en applikationslogg på cirka 40 000 rader där du vill hitta alla felmeddelanden kopplade till betalningar och få en sammanfattning.

def run_agent(client, document_text: str, user_question: str):
    messages = [
        {"role": "system", "content": "Du analyserar loggfiler. Använd verktygen vid behov innan du svarar."},
        {"role": "user", "content": f"DOKUMENT:\n\n{document_text}\n\nFRÅGA: {user_question}"},
    ]

    response = call_with_retry(client, model="deepseek-v4-flash", messages=messages, tools=tools, max_tokens=2000)
    message = response.choices[0].message

    if message.tool_calls:
        messages.append(message)
        for call in message.tool_calls:
            args = json.loads(call.function.arguments)
            result = execute_tool(call.function.name, args, document_text)
            messages.append({"role": "tool", "tool_call_id": call.id, "content": result})

        final = call_with_retry(client, model="deepseek-v4-flash", messages=messages, max_tokens=2000)
        return final.choices[0].message.content

    return message.content

Kör den mot din testlogg med frågan “Hur många betalningsfel loggades och vilka rader gäller det?”. Agenten anropar först count_occurrences och extract_matching_lines, matar tillbaka resultaten till modellen, och formulerar sedan ett sammanfattande svar.

Exempel på utdata:

Sammanfattning av betalningsfel

Totalt antal: 14 förekomster av "payment_error" i loggen.

Vanligaste orsaken: 9 av 14 fel har koden TIMEOUT_GATEWAY och
inträffar kluster mellan 02:14 och 02:31, vilket tyder på att
betalningsleverantören hade en kortare driftstörning den natten.

Övriga fel:
- 3 st CARD_DECLINED (normala, kräver ingen åtgärd)
- 2 st INVALID_CURRENCY (kan bero på ett formatfel i klienten)

Rekommendation: undersök gatewayens statussida för tidsfönstret
02:14-02:31 innan ni kontaktar leverantören.

Lägg märke till att modellen inte bara räknar, utan grupperar felen efter mönster och ger en handlingsbar rekommendation. Det är skillnaden mellan att köra grep och att köra en agent, verktygen ger exakta siffror, modellen ger tolkningen ovanpå dem.

Testa gärna samma fråga mot ett par olika dokumenttyper innan du litar på agenten i skarpt läge. En strukturerad JSON-logg ger ofta bättre resultat än en fritextlogg med inkonsekvent formatering, eftersom modellen har lättare att hitta mönster i data som redan följer ett tydligt schema. Har du fritextloggar utan konsekvent struktur, lägg extra vikt vid systemprompten och beskriv exakt hur en typisk rad ser ut, så minskar risken för att modellen missar avvikande format.

Kostnadskalkyl: vad kostar en 1M-token-agent i praktiken

Priset per miljon tokens låter lågt isolerat, men det är lätt att missbedöma vad ett enskilt anrop faktiskt kostar när dokumentet är stort. Tabellen nedan visar uppskattad kostnad för tre typiska dokumentstorlekar, beräknat från DeepSeeks officiella lågtrafikpriser för V4-Flash, med antagandet att varje anrop följs av ett utdatasvar på cirka 1 000 tokens.

DokumentstorlekKostnad, cache miss (första anropet)Kostnad, cache hit (uppföljningsfråga)
50 000 tokens (~35 sidor)~0,012 dollar~0,0007 dollar
200 000 tokens (~140 sidor)~0,045 dollar~0,0025 dollar
950 000 tokens (nära maxgränsen)~0,21 dollar~0,012 dollar

Skillnaden mellan cache hit och cache miss är i praktiken en faktor på nästan 17-18 gånger för V4-Flash. En agent som ställer fem följdfrågor mot samma dokument kan alltså landa nära priset för ett och ett halvt fullständigt anrop totalt, snarare än fem separata fulla anrop, förutsatt att dokumentet och systemprompten hålls identiska mellan frågorna.

Skalar du upp till exempelvis 500 dokumentanalyser per dag på den mellersta radens storlek (200 000 tokens), landar den dagliga kostnaden på ungefär 22-23 dollar vid cache miss för samtliga anrop, eller under 2 dollar om majoriteten träffar cachen. Det är den typen av skillnad som gör att steg 10 i den här guiden, prompt-cachen, förtjänar mer uppmärksamhet än den brukar få i snabba implementationer.

Fem vanliga fallgropar när du bygger långkontext-agenter

  • Att chunka texten i onödan. Vanor från GPT-3.5-eran med 4K-kontext sitter i. Med 1 miljon tokens tillgängligt finns sällan anledning att dela upp ett dokument under 700 sidor, chunking gör bara att modellen tappar sammanhang mellan bitarna.
  • Att bryta prompt-cachen av misstag. Ett tidsstämpel som ändras i systemprompten mellan varje anrop, eller att dokumentet läggs på olika platser i meddelandelistan, gör att varje anrop räknas som cache miss.
  • Att lita blint på verktygsargument från modellen. Modellen kan skicka fel typ eller ett värde utanför förväntat intervall. Validera alltid args innan du kör verktygslogik som rör filer eller externa system.
  • Att sätta för hög temperatur på analysuppgifter. En temperatur över 0,5 på ett dokumentanalysjobb ökar risken för att modellen fyller i detaljer som inte finns i källtexten, särskilt vid sammanfattningar av långa loggar.
  • Att glömma att räkna utdatakostnaden. Utdata kostar nästan 100 gånger mer per token än cachad indata på V4-Flash. En agent som genererar långa, upprepande svar kan bli dyrare i utdata än i indata trots det stora dokumentet.
  • Att inte sätta en övre gräns för dokumentstorlek. Utan en kontroll som steg 6-7 visar riskerar ett oväntat stort dokument att antingen kastas ut av API:et eller generera en oväntat hög faktura.

Felsökning: 8 vanliga fel och hur du löser dem

De flesta fel du stöter på när du bygger den här typen av agent handlar antingen om autentisering, om att dokumentet är för stort, eller om att verktygsanropen inte formateras som modellen förväntar sig. Listan nedan täcker de åtta felen som dyker upp oftast, i ungefär den ordning du sannolikt möter dem första gången du kör skriptet mot ett riktigt dokument.

  • 401 Unauthorized: API-nyckeln är felformaterad eller saknar “Bearer “-prefix i Authorization-headern. Kontrollera att nyckeln laddades korrekt från .env.
  • 402 Payment Required: Kontot saknar krediter. Logga in på platform.deepseek.com och fyll på saldo, DeepSeek har ingen gratisnivå för produktionstrafik.
  • 429 Too Many Requests: Du har överskridit rate limit. Wrappern från steg 11 med exponentiell backoff löser de flesta fall, men kontrollera även om flera processer delar samma nyckel samtidigt.
  • Timeout efter 60-90 sekunder: Dokumentet är sannolikt nära gränsen på 1 miljon tokens. Höj timeout-värdet till minst 120 sekunder eller överväg att dela dokumentet i två anrop om svarstiden blir opraktisk.
  • Modellen tappar instruktioner i slutet av ett långt dokument: Lägg viktiga instruktioner både i systemmeddelandet och direkt efter dokumenttexten i användarmeddelandet, inte bara i början.
  • tool_calls är tomt trots att modellen borde ha anropat ett verktyg: Kontrollera att verktygsschemat är giltig JSON Schema och att description-fälten är tydliga. Modellen väljer att inte anropa verktyg den inte förstår syftet med.
  • Cachead kostnad syns inte i usage-svaret: Vissa klientbibliotek exponerar inte cache-statistik som standard. Läs response.usage.prompt_cache_hit_tokens om fältet finns, annars kontrollera faktureringen direkt i DeepSeeks dashboard.
  • UnicodeDecodeError vid inläsning av dokument: Filen innehåller tecken som inte är UTF-8, vanligt i loggar exporterade från Windows-servrar. Använd errors="ignore" som i steg 6-7, eller konvertera filen med iconv först.

Avancerade tips för produktion

När agenten fungerar lokalt är nästa steg att härda den för faktisk drift. Några saker är värda extra uppmärksamhet innan du kopplar in den mot riktiga, känsliga data.

Skydda mot prompt injection i själva dokumentet. Skickar din agent in dokument från externa källor, till exempel användaruppladdade filer eller skrapade webbsidor, kan texten innehålla instruktioner riktade mot modellen snarare än mot dig. Behandla alltid dokumentinnehållet som opålitlig indata i systemprompten, till exempel genom att explicit instruera modellen att ignorera instruktioner som förekommer inuti det analyserade dokumentet. Riskerna med indirekt prompt injection i dokumentbaserade agenter finns beskrivna i detalj i OWASP:s topplista för LLM-applikationer, som är värd att läsa innan agenten kopplas mot okontrollerade datakällor.

Överväg deepseek-v4-flash-vision-exp om dokumenten inkluderar skärmdumpar, scannade kvitton eller diagram. Modellen är en experimentell multimodal variant byggd på samma V4-Flash-arkitektur och nåddes först via det betalda utvecklar-API:et i augusti 2026, med samma pris- och kontextegenskaper som textvarianten.

Logga usage-fältet från varje anrop till ett separat spårningssystem från dag ett. Kostnaden per anrop är låg individuellt, men en agent som körs hundratals gånger om dagen mot stora dokument kan snabbt bygga upp en faktura som är svår att förklara i efterhand utan detaljerad loggning.

Sätt även upp ett enkelt gränsvärde för hur mycket agenten får spendera per dag, oberoende av DeepSeeks eget saldo på kontot. Ett skript som råkar hamna i en loop, till exempel genom att en bugg gör att samma dokument analyseras om och om igen, kan annars generera en oväntat hög räkning innan någon människa hinner upptäcka det. En enkel räknare i din egen kod, som stoppar körningen efter ett satt antal anrop per dygn, är ett billigt skydd mot det scenariot.

Skala upp: flera dokument och parallella anrop i produktion

Skriptet du byggt i föregående steg hanterar ett dokument i taget, vilket räcker för manuell körning eller ett enstaka cron-jobb. Ska agenten istället bearbeta en hel kö av loggfiler, till exempel varje natts serverloggar från tio olika miljöer, blir seriell körning snabbt en flaskhals. Ett anrop som tar 40-60 sekunder gör att tio dokument tar tio minuter i följd, vilket sällan är ett problem i sig, men det blir opraktiskt när kön växer till hundratals filer under en incident.

Lösningen är att köra anropen parallellt med Pythons asyncio och den asynkrona klienten som openai-paketet redan innehåller. Byt bara ut OpenAI mot AsyncOpenAI och kör flera dokument samtidigt med en gräns för hur många anrop som får vara aktiva samtidigt, så att du inte träffar rate limit på kontot.

import asyncio
from openai import AsyncOpenAI

async_client = AsyncOpenAI(api_key=os.environ["DEEPSEEK_API_KEY"], base_url="https://api.deepseek.com")
semaphore = asyncio.Semaphore(4)  # max 4 samtidiga anrop

async def analyze_one(path: str, question: str) -> tuple[str, str]:
    async with semaphore:
        document = load_document(path)
        response = await async_client.chat.completions.create(
            model="deepseek-v4-flash",
            messages=[
                {"role": "system", "content": "Du analyserar dokument och loggar på svenska."},
                {"role": "user", "content": f"DOKUMENT:\n\n{document}\n\nFRÅGA: {question}"},
            ],
            max_tokens=2000,
            timeout=120,
        )
        return path, response.choices[0].message.content

async def analyze_batch(paths: list[str], question: str):
    results = await asyncio.gather(*(analyze_one(p, question) for p in paths))
    for path, answer in results:
        print(f"--- {path} ---\n{answer}\n")

# asyncio.run(analyze_batch(["logg1.txt", "logg2.txt", "logg3.txt"], "Sammanfatta alla fel"))

Fyra samtidiga anrop är en försiktig startpunkt. DeepSeeks rate limits varierar beroende på kontonivå, så om du regelbundet får 429-fel i loggarna, sänk Semaphore-värdet snarare än att öka antalet återförsök i oändlighet. Ökar du istället gränsen för snabbt riskerar du att en enskild batch-körning konkurrerar ut andra tjänster som delar samma API-nyckel.

Ett annat mönster värt att känna till för produktionsdrift är att separera dokumentinläsning från analys i en kö, till exempel med Redis eller en enkel databastabell som status-fält. Då kan agenten köras som flera oberoende arbetare (workers) som plockar jobb från kön, vilket gör det enkelt att skala horisontellt genom att helt enkelt starta fler processer, snarare än att bygga en mer avancerad intern schemaläggare i själva Python-skriptet.

DeepSeek V4-Flash vs V4-Pro vs V4-Flash-Vision-Exp: vilken passar dig

Samtliga tre modeller delar kontextfönster och API-format, men skiljer sig i pris, kapacitet och tänkt användningsområde. En oberoende sammanställning av kodningsmodeller för självhostning i augusti 2026 placerade V4-Pro runt 55,4 poäng på SWE-Bench Pro och nära 88 poäng på Terminal-Bench 2.1, klart över Flash-varianten på uppgifter som kräver djupare resonemang, men till ett pris som är omkring tre gånger högre per token.

ModellParametrar (totalt / aktiva)KontextBäst för
deepseek-v4-flash~284B / ~13B1M tokens in, 384K utDokument- och loggagenter, hög volym, lågt pris
deepseek-v4-pro~1,6T / ~49B1M tokens in, 384K utKomplex kodgenerering och flerstegsresonemang
deepseek-v4-flash-vision-expByggd på V4-Flash1M tokens in, 384K utDokument med bilder, kvitton och skärmdumpar

För det agentexempel den här guiden bygger, dokument- och logganalys utan djupt flerstegsresonemang, räcker V4-Flash gott och väl och håller kostnaden nere. Byter du senare till uppgifter som kräver att agenten planerar flera steg framåt, till exempel att den själv ska föreslå och skriva kodfixar baserat på loggarna, är V4-Pro ett rimligt nästa steg utan att du behöver ändra något i själva integrationskoden.

Det kompletta projektet i en fil

Nedan är alla delar från guiden sammanfogade till en körbar fil. Spara den som agent.py i din projektmapp och kör med python agent.py path/till/logg.txt "din fråga".

import os
import sys
import json
import re
import time
from dotenv import load_dotenv
from openai import OpenAI, APITimeoutError, APIError, RateLimitError

load_dotenv()
client = OpenAI(api_key=os.environ["DEEPSEEK_API_KEY"], base_url="https://api.deepseek.com")

tools = [
    {"type": "function", "function": {
        "name": "count_occurrences",
        "description": "Räknar förekomster av ett mönster i dokumentet",
        "parameters": {"type": "object", "properties": {
            "pattern": {"type": "string"}}, "required": ["pattern"]}}},
    {"type": "function", "function": {
        "name": "extract_matching_lines",
        "description": "Hämtar rader som matchar ett mönster",
        "parameters": {"type": "object", "properties": {
            "pattern": {"type": "string"},
            "max_lines": {"type": "integer"}}, "required": ["pattern"]}}},
]

def load_document(path):
    with open(path, "r", encoding="utf-8", errors="ignore") as f:
        text = f.read()
    if len(text) / 3.7 > 950_000:
        raise ValueError("Dokumentet är för stort för ett enskilt anrop.")
    return text

def execute_tool(name, args, document_text):
    lines = document_text.splitlines()
    if name == "count_occurrences":
        n = len(re.findall(re.escape(args["pattern"]), document_text, re.IGNORECASE))
        return json.dumps({"count": n})
    if name == "extract_matching_lines":
        m = [l for l in lines if args["pattern"].lower() in l.lower()][:args.get("max_lines", 20)]
        return json.dumps({"matches": m})
    return json.dumps({"error": "okänt verktyg"})

def call_with_retry(**kwargs):
    for attempt in range(1, 5):
        try:
            return client.chat.completions.create(timeout=120, **kwargs)
        except (RateLimitError, APITimeoutError, APIError) as e:
            if attempt == 4:
                raise
            time.sleep(2 ** attempt)

def run_agent(document_text, question):
    messages = [
        {"role": "system", "content": "Du analyserar dokument och loggar. Använd verktyg vid behov."},
        {"role": "user", "content": f"DOKUMENT:\n\n{document_text}\n\nFRÅGA: {question}"},
    ]
    response = call_with_retry(model="deepseek-v4-flash", messages=messages, tools=tools, max_tokens=2000)
    message = response.choices[0].message
    if message.tool_calls:
        messages.append(message)
        for call in message.tool_calls:
            args = json.loads(call.function.arguments)
            result = execute_tool(call.function.name, args, document_text)
            messages.append({"role": "tool", "tool_call_id": call.id, "content": result})
        final = call_with_retry(model="deepseek-v4-flash", messages=messages, max_tokens=2000)
        return final.choices[0].message.content
    return message.content

if __name__ == "__main__":
    doc_path, question = sys.argv[1], sys.argv[2]
    document = load_document(doc_path)
    print(run_agent(document, question))

Filen är medvetet hållen kompakt, utan loggning eller konfigurationslager, så att du kan läsa den från topp till botten på ett par minuter. Bygger du vidare på den för produktion, lägg till loggning av usage-fältet och en riktig konfigurationsfil istället för hårdkodade värden som max_tokens.

Vanliga frågor

Kostar DeepSeek V4-Flash verkligen mindre än att köra en modell lokalt?

Ofta ja för sporadisk användning. Att självhosta V4-Flash kräver enligt öppna hårdvarusammanställningar omkring 120 GB minne för rimlig hastighet, vilket i praktiken betyder en dyr server eller en Mac med mycket unified memory. För de flesta utvecklingsteam blir det API-baserade priset per token billigare än att äga och driva den hårdvaran, såvida inte volymen är mycket hög och kontinuerlig.

Kan jag använda samma kod mot OpenAI eller Anthropic senare?

Ja, i stort sett. Eftersom DeepSeeks API är kompatibelt med både OpenAI:s och Anthropics format räcker det oftast att byta base_url och modellnamn. Verktygsdefinitionerna (function calling) följer samma JSON Schema-struktur hos alla tre, så agent-loopen i den här guiden kräver minimala ändringar.

Vad händer om dokumentet är större än 1 miljon tokens?

Då måste du dela upp det. Ett vanligt mönster är att först köra ett anrop per avsnitt för att generera korta sammanfattningar, och sedan skicka de sammanfattningarna tillsammans i ett andra anrop för en helhetsanalys. Det är i praktiken den klassiska chunking-metoden, men den behövs bara när dokumentet faktiskt överskrider gränsen, inte som standard.

Är DeepSeek V4-Flash säkert att använda med känsliga företagsdata?

Behandla det som du skulle behandla vilken molnbaserad AI-leverantör som helst: läs DeepSeeks aktuella datalagringsvillkor innan du skickar personuppgifter eller affärshemligheter, och undvik att skicka data du inte har rättslig grund att dela med en tredje part. För känsligast data är självhostning av de öppna vikterna, eller att hålla sig till leverantörer med tydliga EU-datacenteravtal, ett säkrare val.

Varför fick jag ett annat svar när jag körde samma fråga två gånger?

Även vid låg temperatur är språkmodeller inte helt deterministiska. Sätter du temperature=0 minskar variationen ytterligare, men för agentuppgifter som kräver verktygsanrop kan viss variation i formuleringar kvarstå även då. Om du behöver exakt reproducerbara resultat, lita på verktygens returvärden (som är deterministiska Python-funktioner) snarare än på modellens fritextsvar för de sifferexakta delarna.

Går det att köra agenten som ett schemalagt jobb istället för manuellt?

Ja, skriptet i den kompletta projektfilen går att trigga från cron, ett CI-jobb eller en enkel webhook utan ändringar. Vill du dra nytta av lågtrafikpriserna, schemalägg körningen utanför DeepSeeks högtrafikfönster (01:00-04:00 och 06:00-10:00 UTC på vardagar) för att hålla nere kostnaden på stora batch-analyser.

Behöver jag ett annat verktyg om dokumenten redan ligger som PDF-filer?

Ja, till viss del. DeepSeek V4-Flash tar emot text, inte PDF-filer direkt via chattmeddelanden, så du behöver först extrahera texten med ett bibliotek som pypdf eller pdfplumber innan du skickar innehållet till load_document-funktionen från steg 6-7. Innehåller PDF:erna mest skannade bilder utan textlager är det istället deepseek-v4-flash-vision-exp som är rätt verktyg, eftersom den modellen kan tolka bilddata direkt.