Mirwan Akaygün
Mirwan Akaygün

Hi, I am Mirwan.

AI Engineer · Munich · remote worldwide

AI systems that run in production.
Not in a prototype.

I design, build and operate LLM systems in Python, from retrieval, agents and evaluation to the infrastructure underneath. One engineer from the requirement to 24/7 operation, with every model call measured, capped and traceable.

  • Available now
  • 100 % remote, permanent or freelance
  • German and English

Open for · AI Developer · LLM Engineer · GenAI Engineer · AI Engineer (LLM) · AI Automation Engineer · Prompt Engineer

running
question 3a91 → grounded answer
Every answer is filtered, retrieved, reranked, cited and verified before it ships.

Models

Anthropic Claude, OpenAI GPT, Google Gemini, Alibaba Qwen, AWS Bedrock

Core stack

Python, FastAPI, Pydantic, PostgreSQL and pgvector, Docker, Linux

Tools

Claude Code, Playwright, Langfuse, LangGraph, promptfoo

Working model

Structured outputs, evals with gold set, cost caps, traces on every run

A prompt is a request, not a guarantee. Reliability comes from the structure around the model.

Context scoped to the decision at hand, a deliberately bounded tool surface, schema-enforced output and a validation gate every result has to clear before it moves downstream. These are the rules I build by.

Selected work

Systems in production

Own products and client systems, described without names. Numbers are measured, not estimated.

01in production

Unattended LLM pipeline

Content had to be generated, checked and shipped continuously without a person in the loop.

Multi-stage Python pipeline with structured outputs, Pydantic validation and an automated expected-versus-actual check before every delivery. Hard cost ceilings per run, every model call logged and priced, a gold holdout that catches overfitting, automatic restart on failure.

700+
production runs
94 %
first-pass rate, up from 42 %
< 2 ct
per run

Python, Anthropic API, Pydantic, PostgreSQL, Playwright, systemd

02in production

Multi-API process automation

Orders, stock and shipment data across several partner and supplier systems had to stay in sync around the clock.

Integrations over REST and OAuth 2.0 with token lifecycle, rate limiting, backoff with jitter, idempotency keys and deduplication. Automated reconciliation across a six-figure catalogue, with a model adjusting control settings from live signals.

24/7
unattended operation
0
manual interventions in daily operation
6-figure
catalogue reconciled

Python, httpx, OAuth 2.0, SQLite, PostgreSQL, cron

03in production

Web extraction and browser automation

Websites had to be read, checked and acted on continuously without a person watching.

Playwright pipelines with BeautifulSoup extraction, image checks with OpenCV and PIL, and a self-check gate before every action, abort instead of a wrong step. Every step is logged, so a failure is diagnosed from the trace, not from memory.

Self-gated
abort instead of a wrong action
Unattended
runs without a person
Traced
every step logged

Python, Playwright, BeautifulSoup, OpenCV, PIL

04in production

Self-operated production infrastructure

Every system above needed a home that I control end to end, without managed hosting in between.

Ubuntu servers with Docker, Caddy with wildcard TLS, a full mail stack (Postfix, Dovecot, OpenDKIM with SPF, DKIM and DMARC), fail2ban with custom filters, SSH hardening, systemd services, backups, log rotation and monitoring.

All
projects run on it
Key-only
SSH, no passwords
Own
mail, TLS, monitoring

Linux, Docker, Caddy, Postfix, fail2ban, systemd

How a run works

From a raw document to an answer you can audit

Nine stages, each one measurable on its own. When an answer is wrong, the trace shows which stage failed, and in most cases it is the search, not the model.

stage 01 / 09

  1. 01 · ingest

    Parse and OCR

    PDF layout, tables and scans handled before anything is indexed. A scanned page without OCR is an empty index with no visible error, so the ingest is tested on the real documents first.

  2. 02 · chunk

    Chunk with structure

    Headings stay with their text, overlap protects sentence boundaries, parent documents are kept for context. Chunk size is measured against retrieval recall, not guessed.

  3. 03 · embed

    Embed and index

    pgvector with HNSW for the semantic pass, a tsvector index for exact codes and names. Metadata carries tenant, visibility, date and version for every chunk.

  4. 04 · filter

    Enforce access in the query

    Visibility is a WHERE clause on the rows, evaluated on every request. A prompt is a request, not a lock, so rights never depend on the model.

  5. 05 · retrieve

    Hybrid search

    BM25 and vectors run side by side and are merged with reciprocal rank fusion. Agreement between two independent methods beats a single top rank.

  6. 06 · rerank

    Rerank the candidates

    A cross-encoder reads question and passage together and cuts 50 candidates to 5. This is the coarse-to-fine step that fixes ranking problems, and it also keeps the context short.

  7. 07 · generate

    Generate with schema and citations

    The model answers inside a schema with a citation per claim. The strongest passages sit at the start and end of the context, never in the middle.

  8. 08 · verify

    Verify mechanically

    Every quote is checked verbatim against the source, every field against Pydantic rules. Whatever fails is marked unsure and routed to a person instead of shipped.

  9. 09 · ship

    Trace, price, ship

    Each run is traced with prompt, model version, tokens, cost and duration, then written asynchronously to Langfuse. Every production failure becomes a new eval case.

Proof in code

The patterns behind every system I ship

Seven excerpts from the way I build. Extraction that cannot guess, retries that know what to retry, retrieval with access rights in the query, an agent loop with real brakes, delivery patterns, evals in CI and an image that belongs in a registry.

from datetime import date
from pydantic import BaseModel, Field, model_validator
import anthropic


class Invoice(BaseModel):
    number: str = Field(pattern=r"^[A-Z0-9-]{4,}$")   # visible to the model in the schema
    issued: date
    due: date | None = None          # optional on purpose: a required field forces a guess
    total_gross: float = Field(gt=0)
    evidence: dict[str, str]         # verbatim quote per field, verified below

    @model_validator(mode="after")   # cross-field rule: invisible to the model, so it is in the prompt too
    def due_after_issued(self) -> "Invoice":
        if self.due and self.due < self.issued:
            raise ValueError("due before issued")
        return self


client = anthropic.Anthropic()


def extract(text: str) -> Invoice:
    msg = client.messages.parse(
        model="claude-haiku-4-5",          # smallest model that passes the eval, pinned
        max_tokens=2000,
        system=SYSTEM,                     # "never guess, set null, quote every value verbatim"
        messages=[{"role": "user", "content": text}],
        output_format=Invoice,
    )
    inv = msg.parsed_output
    missing = [k for k, quote in inv.evidence.items() if quote not in text]
    if missing:
        raise Unsure(inv, missing)         # routed to a person, never into the database
    return inv

Stack

Hands-on and working knowledge, nothing else

The same list as in my CV, split the way I would say it in an interview. Hands-on is what I run every day. Working knowledge means I understand the principle and can place and apply the tools.

Hands-onin daily useWorking knowledgeprinciple understood, tools placed

AI engineering (LLM / GenAI)

Hands-on

LLM integration via API

Anthropic Claude, OpenAI GPT, Google Gemini, Alibaba Qwen (qwen3-vl, qwen3.7), OpenRouter, vision models, Whisper (transcription)

Structured outputs and Pydantic

extraction into enforced schemas, JSON Schema, tool calling, validation, hallucination control, streaming (SSE)

Prompt and context engineering

system prompts, few-shot, chain-of-thought, prompt caching, prompt versioning, temperature 0, pinned models and prompts

LLM pipelines in production

multi-stage chains, cost caps per call and per day, token budgets, response cache, failure-class register

Evals

gold set and holdout, regression measurement, overfitting detection, deterministic checks versus LLM-as-a-judge

Hallucination-free generation

by architecture, the model describes, the code decides, slots accept only source IDs

Agentic coding

Claude Code as the daily working model, Cursor, GitHub Copilot, specification, review, steering of AI-generated code

Web extraction and browser automation

Playwright, BeautifulSoup, Firecrawl, OpenCV and PIL for image checks

AI engineering (LLM / GenAI)

Working knowledge

RAG

chunking, embeddings (OpenAI text-embedding-3, Voyage, Cohere, BGE, E5), vector databases (pgvector, Qdrant, Weaviate, Pinecone, Milvus, Chroma, FAISS), hybrid search (BM25 and vector, RRF, Elasticsearch, OpenSearch), reranking (Cohere, bge-reranker), ANN indexes (HNSW, IVFFlat), Recall@k, LlamaIndex

Documents and OCR

PDF parsing (Docling, Unstructured, PyMuPDF), OCR (Tesseract, AWS Textract, Azure Document Intelligence)

Agents

tool calling, agent loop, guardrails, checkpointing, human-in-the-loop, multi-agent patterns, MCP (Model Context Protocol, own servers with FastMCP), LangGraph and LangChain, LlamaIndex, Pydantic AI, DSPy, Claude Agent SDK, OpenAI Agents SDK, CrewAI, AutoGen, Temporal

Observability

Langfuse, LangSmith, Arize Phoenix, Helicone, OpenTelemetry, traces and spans, cost measurement

Eval tooling

promptfoo, Ragas, DeepEval, Braintrust

Guardrails

Guardrails AI, NeMo Guardrails, Llama Guard, PII masking (Presidio, NER)

Model strategy

model routing, escalation, Batch API, fine-tuning versus RAG

Fine-tuning

LoRA and QLoRA, PEFT, SFT, distillation, behaviour versus knowledge

Cloud AI

AWS Bedrock, Azure OpenAI, Google Vertex AI, Groq, local models (Ollama, vLLM, Hugging Face, Llama, Mistral)

Demo interfaces

Streamlit, Gradio

Low-code automation

n8n, Make, Zapier, where they fit and where they stop

Backend and operations

Hands-on

Python

Python 3, uv, ruff, Pydantic, argparse, asyncio, httpx, pytest

Docker

Dockerfile, multi-stage, Compose, non-root, pinned images

System

Linux and WSL2 (Ubuntu), Bash, Git and GitHub

Email infrastructure

SPF, DKIM, DMARC, domain warm-up, deliverability testing, CAN-SPAM

APIs and services

REST, OAuth 2.0, webhooks, Stripe, Resend, Twilio, Google APIs (Search Console, Gmail), IMAP and SMTP

Web and mobile

TypeScript, Next.js, React, Tailwind CSS, React Native, Expo

Hosting

Hetzner, Contabo, Vercel, Cloudflare, Caddy

Backend and operations

Working knowledge

Delivery

FastAPI, SSE streaming, health checks (liveness and readiness), statelessness

Concurrency

async and await, semaphores, backoff with jitter, idempotency, rate limits

CI/CD

GitHub Actions, cassette tests (VCR.py, pytest-recording)

Operations

Kubernetes, AWS (ECS and Fargate, S3, Lambda, IAM), load balancers (Nginx, Traefik), message queues (Celery, RabbitMQ, SQS)

Architecture

hexagonal and clean architecture, immutable infrastructure

Databases

PostgreSQL, MongoDB, MySQL, Redis, Supabase, SQLite

Cloud security

IAM, least privilege, secrets management

Prompt injection

direct and indirect, architectural defence, OWASP Top 10 for LLM applications

Legal and compliance (AI)

Working knowledge

Data protection and regulation

GDPR (DPA, data residency, data minimisation), EU AI Act (risk classes), PII handling

Earlier experience

Hands-on

Web and Java

Angular, Java, JavaScript (around 2016)

Process

How a project runs

Async by default, in German or English. Works the same for a ten-hour fix and a multi-month build.

  1. Brief by email

    You send the scope in writing. I reply with clarifying questions within 24 hours on business days, and with the failure modes I expect before a line of code exists.

  2. Written estimate

    Approach, timeline and an hourly breakdown, or a fixed price for a clearly scoped deliverable. Model cost is measured on real requests and stated separately. No discovery call needed.

  3. Weekly pull requests

    Code lands in your repository with reviewable diffs, tests that run against recorded responses, and short architecture notes. You review, I iterate.

  4. Ship and hand over

    Production-ready, documented, traced and monitored, with an eval suite your team can extend. Zero dependency on me after handover unless you want ongoing operation.

Mirwan Akaygün

About

Ten years in software, two of them building for models

In software since 2016. Vocational training as an IT specialist for application development at Crealogix near Munich, self-employed since 2019 running my own businesses and the systems behind them, AI engineering full time since 2024. Several of my own products run unattended around the clock.

Registered self-employed in Germany, invoicing worldwide, also open to a permanent remote role.

Common questions

What do you actually deliver?+

A system that runs. The pipeline or agent, the eval suite that proves it works, the tracing that shows what it costs, and the deployment it runs on. Not a notebook and not a demo.

How do you keep us from being locked into one model provider?+

Model access sits behind one interface in the code. Anthropic, OpenAI, Bedrock and a test double are interchangeable implementations of it, so a provider change touches one file, not forty.

Does our data end up in a model?+

No. API traffic is not used for training, and RAG works precisely because documents enter the prompt fresh on every request and leave again. Retention periods are in the DPA, which we read together for your case.

How fast do you respond to a brief?+

Within 24 hours on business days, with clarifying questions, the risks I see, a written estimate and a proposed timeline.

How do you bill?+

Hourly from 110 EUR for ongoing work, a day rate of 880 EUR for full-day blocks, or a fixed price for a clearly scoped deliverable. Invoices monthly, net 14. For permanent roles, salary expectations on request.

Do you sign NDAs?+

Yes. NDAs, master agreements and statements of work are routine. I invoice as a registered self-employed professional in Germany with an EU VAT ID.

Remote only?+

Yes, fully remote. Time zones from Europe to the US East Coast work without friction.

Who owns the code?+

You do. Your repository, your pipelines, your infrastructure. Everything is documented so the next engineer can take over.

Have a project or a role in mind?

info@akayguen.dev

Send the scope or the job description by email. I reply within 24 hours on business days with questions, the risks I see and a written estimate. No call required.