Last night (Tuesday 15 September 2026) I attended the ClickHouse Amsterdam Meetup @ Adyen, hosted at Adyenâs Amsterdam office. The screens in the room carried the Adyen Ă ClickHouse logos and the eveningâs theme, âHow AI is changing the fintech landscapeâ: from an autonomous agent in production at a payments company to what you can do with a few hundred million vector embeddings in the worldâs fastest analytical database.
About 236 attendees turned out, a mix of engineers, data practitioners and fintech builders. The agenda on screen read: doors and food and drinks by Adyen from 17:15, a welcome from Kwok He Chu (Developer Relations @ Adyen) and Tyler Hannan (Global Advocate @ ClickHouse) at 18:15, Iftach Arbel (Senior AI Research Engineer, Adyen) at 18:20, Alexey Milovidov (Co-founder & CTO, ClickHouse) at 19:00, each talk followed by Q&A, then drinks and networking from 19:40.
Almost a year earlier I spent a day at ClickHouse Open House Amsterdam 2025, where Picnic and Langfuse showed ClickHouse in production. This evening was smaller and much more focused on AI.
The Theme: AI Meets Real-Time Analytics in Fintech
The central question driving the evening was simple but profound: how do you build AI systems that operate reliably in production environments where correctness matters more than creativity? The two talks answered it from opposite ends: one from the agent side (what to pin down in code), one from the data side (how to store and search embeddings cheaply enough to do it at all).
Talk 1: Skills First, Structure Later
Iftach Arbel, Senior AI Research Engineer at Adyen, opened with a talk titled âSkills First, Structure Laterâ, subtitled âDeveloping autonomous agents · Ship an agent using skillsâ. It was a grounded, no-nonsense account of building an autonomous fee agent for production. The talk had four parts: the problem, skills first, the restructure, and proving it.

Iftach Arbel opening âSkills First, Structure Laterâ at the ClickHouse Amsterdam Meetup at Adyen.
From the abstract:
âWe built an autonomous agent for a task where reliability mattered most. We will describe agent design patterns to explain our decisions: deterministic vs. agentic behavior, predictability vs. flexibility, auditability vs. adaptiveness, and routing vs. parallelization.â
The four trade-offs
The slide âFour trade-offs we keep coming back toâ defined each axis, and the rest of the talk kept returning to it (âWatch which side of each axis every decision lands onâ):
- Deterministic â agentic: fix behaviour in code and tools, or leave it to the model.
- Predictable â flexible: constrain the agentâs actions; keep its prose and reasoning free-form.
- Auditable â adaptive: reproduce the outcome; let the exploration path vary from run to run.
- Routing â parallelization: commit the task to one chosen path, or split it across different paths running at once.
The problem: a wrong match is worse than no match
The task: card schemes publish fee bulletins (one example on screen was a Visa Business News item announcing modified rates in the UK). The agent has to read a bulletin, find the fees it affects in Adyenâs database, and work out the impact. The slide âA wrong match is worse than no matchâ explained why that is hard:
- Terminology never matches. Bulletin fee names are marketing language; the database stores internal program names, so a naive name query returns zero rows and looks like âno matchâ.
- The schema is ambiguous. Deprecated and duplicate programs stay by design, and regional quirks silently drop data.
- The failure is silent. A wrong database match doesnât raise an error; it reaches production billing as a misconfiguration. Loud bugs are safe; silent ones arenât.
The footer made it explicit: a wrong match is a compliance risk, not a quality-of-analysis question. That confidence policy drove every trade-off above.

âThe problemâ: why fee matching is risky, next to the ClickHouse âThe leading database for AIâ banner.
Skills first: 7 phases in one skill
The first version was built the âskills firstâ way. After a primer on what an Agent Skill is (progressive disclosure: roughly 100 tokens of metadata always loaded, the SKILL.md body loaded when needed, and docs, templates and schemas loaded on demand), Iftach showed what the skill actually did, in 7 phases:
- Find and confirm the fee: 1 · Verify metadata â 2 · Catalog lookup â 3 · Exploration scan (terminology mapping, with Strategies A, B and C running inside phase 3) â 4 · Targeted rate pull.
- Judge, report and validate: 5 · Classify change â 6 · Invoice validation â 7 · Impact report.

The seven phases of the original fee-agent skill. Phase 3 runs three matching strategies in parallel.
It worked, but âThe limits of the skill-driven agentâ slide listed three problems:
- Not predictable enough. The flow was driven by 2,400 lines of skill prose, so behaviour moved with prompt wording and model run.
- Hard to debug. There was no structured record of what the agent queried or why.
- Hard to extend. Changing one behaviour meant editing one giant skill.
Underneath, this showed up as duplication: the same query built twice (once to run, once to audit), and the same rule written in three places.
One rule, enforced three times
That last point got its own slide. The rule: in a historical simulation, never read data dated after the bulletin, because it leaks the answer. In the skill-driven version it was enforced in three layers:
- Prose:
SKILL.mdspells it out (âFORBIDDEN â a hard data-leakage rule, not a guidelineâ). The weakest guard: the model can simply not follow it. - PreToolUse hook: a regex hook parses every Bash call and denies it when
--as-of-dateis missing or past the ceiling. Brittle, because it guesses intent from a string. - Query builder: raises
ValueErrorifpost_cutovermeetsas_of_date, independent of prompt and hook. The last line of defence.
The slideâs conclusion: âOne rule, three places to keep in sync â the cost of writing guardrails as text. [âŠ] Make the action typed and the illegal state canât be built at all.â

âWhen prose isnât enoughâ: the same data-leakage rule written as prose, as a hook and as code.
The restructure: one skill becomes four
The restructure moved routing into code. The mega-skill was split into four skills: Index (scope, the temporal model, the output template and the routing table), fee-resolution (matching, classification and the full schema, âthe heaviest tacit knowledge, kept together on purposeâ), invoice-validation, and match-verifier (a verification matrix over five signals in code; the LLM rubric fires only when signals conflict).
Typed tools replaced Bash. Before, the model invoked a Bash tool that ran a SQL query wrapped in Python, and downstream code had to re-parse that string to recover the query. After, the model calls the same queries as tools through the SDKâs @tool interface: function arguments in, a {sql, rows, context} triplet out. The âSame SDK, a different shapeâ slide summed up the result: code builds the guards (such as the temporal ceiling), the agent runs code-orchestrated phases with one skill loaded per phase, tool calls provide the records for the audit, and code assembles the audit and confidence.
Eval: prove itâs a refactor, not a rewrite
How do you show that the restructured agent still does what the old one did? The âProving itâ slide had three parts:
- Built as refactor step 0. The system was already tested, so no tool or skill change ships until it passes the harness first, much like a unit test.
- A golden baseline. Curated, human-validated prior output. A divergence from golden is a real quality signal, compared on structured data rather than raw Markdown.
- Align fees first. Pair golden and candidate results by database and bulletin identity. Unpaired golden results count against recall; unpaired candidates count against precision.

The eval strategy: a golden baseline and fee alignment before any comparison.
The talk ended with a live demo of the bulletin analysis agent on a Mastercard Canada bulletin (mapping the database landscape, finding the matching fees, validating against real invoices and writing the impact report). The wrap-up slide, âFour principles to keepâ, mapped back to the four trade-offs:
- Draw the line per rule (deterministic â agentic): decide per rule whether itâs pinned in code or left to the model, by how expensive a violation is.
- Typed actions, free-form outputs (predictable â flexible): constrain what the agent does, but leave its reasoning free-form where flexibility improves quality.
- Orchestrate, donât constrain (auditable â adaptive): a single mega-skill is adaptive but unauditable; four skills plus an orchestrator make the path reproducible while each skill stays adaptive.
- Cut skills by knowledge, not by generic responsibility (routing â parallelization): matching and classification look separable, but the tacit judgment ties them together, so they stayed one skill.
My take: this is the clearest public account Iâve seen of why you start with a skill and then harden it. The skill is how you discover the workflow; the code is how you guarantee it. For practitioners building agents in regulated domains, this talk is essential viewing.
Talk 2: What to Do with Vectors?
Alexey Milovidov, co-founder and CTO of ClickHouse, Inc., followed with âWhat to do with vectors?â. Alexey has 17 years of experience designing, developing and operating data-intensive applications; before ClickHouse, he created the data processing engine of the worldâs second-largest web analytics system.
His answer came on the second slide: âStore them in ClickHouse and have fun!â, with a link to embeddings.info, the Embeddings Explorer he built for the talk. The rest of the talk showed how.
The corpus: a web crawl, photos and Hacker News
Alexey started with the data. For âThe Internet: a web crawlâ he took the list of top websites from the Chrome UX Report (CrUX), 18,988,131 websites, and wrote a script that requests each front page, records as much metadata as possible, saves the content and takes a screenshot with headless Chrome and Playwright. It ran in AWS Lambda for a few weeks. Result: 395 TB, 189 TB compressed. âAWS security kindly asked me what Iâm doingâ, said the slide. Alongside the crawl he used Hacker News comments and a set of about 99 million photos (the Explorer credits Multimedia Commons, under CC licences).

Alexey Milovidov on the web-crawl corpus behind the demo: 18,988,131 websites, 189 TB compressed.
He then went through what âvector embeddingâ can mean (from word2vec in 2013 to token embeddings and model activations) before getting to the practical question: how do you calculate them?
The 22 models
The slide âThe 22 models I usedâ listed every model with its year, size, dimensions and licence:
- Images (99.2M photos, 17.8M screenshots):
siglip2-so400m-patch16-512(1152 dimensions),nomic-embed-vision-v1.5(768) andCLIP ViT-L/14(768). - Text (37.8M comments, 19.0M pages): from
Qwen3-Embedding-8B(7.6B parameters, 4096 dimensions) down toall-MiniLM-L6-v2andgranite-embedding-30m-english(384 dimensions), plus the E5, GTE, BGE, Jina, Nomic, Snowflake Arctic and EmbeddingGemma families, and a hashed bag of words with 8192 dimensions.
The footnote is the part Iâd underline: âAll 22 are open-weight â the closed APIs (Gemini Embedding, Nemotron-VL over OpenRouter) were trialled and dropped: per-token pricing does not survive 100 million rows.â

Three image models and nineteen text models, all open-weight.
Three ways to get embeddings
- Option 1: open models on a GPU. For the 99 million photos: SigLIP2, OpenCLIP ViT-L-14 and Nomic Embed Vision, each into its own table. One
g6.12xlarge(4Ă NVIDIA L4), spot, in the same region as the S3 bucket, with all three models loaded on every GPU so the S3 read and the JPEG decode are shared across them. Wall time: about a day. Cost: $50â200 for 300 million embeddings. For text, the 30M-parameter models took hours and the 8B ones took days. - Option 2: an API, from inside ClickHouse. The slide showed a named collection pointing at OpenRouter (which speaks the OpenAI API) and a
SELECT aiEmbed(review_text, 'google/gemini-embedding-2', map('credentials', 'openrouter')). TheaiEmbedfunction arrived in ClickHouse 26.6; it takes the model as a positional argument and works with any OpenAI-compatible endpoint. - Option 3: make them yourself. âYou do not always need a model.â A hashed bag of words, a TF-IDF vector or a vector of aggregated features are embeddings too. The bag-of-words map in the demo was built with a single
INSERT SELECTusingtokens,cityHash64,countEqualandL2Norm, stored asArray(BFloat16).

The cost of embedding 99 million photos with three open models on one spot GPU instance.
The Embeddings Explorer
Then came the live demo. The Embeddings Explorer (âProudly made with ClickHouse open-source databaseâ) lets you switch between three corpora (Photos, HackerNews, Web), the models, and linear, UMAP or 3D UMAP projections, and query the top-K most similar items. A linear projection of 99 million SigLIP2 photo embeddings, rotated with a Hadamard transform, came out as âa sphere, as promisedâ. Switching to a UMAP projection of the same photos (hue is a fourth UMAP component, brightness is density), and then to the same photos embedded with CLIP ViT-L/14, turned the sphere into something that looked like a nebula.

The same 99 million photos, embedded with CLIP ViT-L/14 and projected with UMAP in the Embeddings Explorer.
Storing embeddings efficiently
The most practical section of the talk was about storage. Most modern embedding models produce unit-normalised vectors, so L2 distance, cosine distance and dot product rank results the same way. Raw data should use a 16-bit type at most: âDo not use Float64 or Float32. ClickHouse provides BFloat16.â The example was Qwen3-Embedding-8B (4096 dimensions) on 37.8M Hacker News comments:
| What | Size |
|---|---|
| The whole table without embeddings | 12 GB |
| Embeddings in Float64 | 1.24 TB |
| Embeddings in Float32 | 620 GB |
| Embeddings in BFloat16 | 310 GB |
âIn most cases you will store further quantized data!â Quantization can go as low as 1â4 bits per dimension, and dimensionality reduction still gives good search results with 384 of the original 4096 dimensions. At 2 bits and 384 dimensions, the same comments take 3.6 GB.

From 1.24 TB to 310 GB just by choosing BFloat16, before any quantization.
The ClickHouse building blocks he showed for that:
randomHadamardTransform: a deterministic, norm-preserving random rotation. Applied before quantization, it spreads information evenly across coordinates and improves search quality; truncated, it acts as a JohnsonâLindenstrauss random projection. It shipped in ClickHouse 26.7.- Int8 quantization with
quantizeBFloat16ToInt8anddequantizeInt8ToBFloat16: half the storage of BFloat16, using a lookup table that assumes Gaussian-distributed coordinates. - The QBit data type: a bit-sliced layout where you choose at query time how many of the most significant bits to read (say, 10 of 16), and with strided storage how many leading dimensions to read, using functions such as
L2DistanceTransposed. Alexeyâs recall heatmaps showed the trade-off between bits, dimensions and Recall@100.
As a bonus, ClickHouse also supports vector similarity indexes (HNSW) for fast in-memory similarity search, âoften you donât need it, as QBit solves the problem perfectlyâ, plus ready-made quantization codecs such as RaBitQ and Turboquant.
My take: for fintech teams that need to join transactional data with similarity search (fraud pattern matching, anomaly detection, deduplication), the argument for doing both in one engine is now mostly about cost, and the cost argument is storage: pick BFloat16, rotate, quantize, and decide precision at query time.
The Venue: Adyenâs Amsterdam Office
The evening took place on a high floor of Adyenâs Amsterdam office, with the Muziekgebouw visible through the windows behind the stage. Adyen provided food and drinks, and the room was set up with round tables, two large screens and the yellow ClickHouse âThe leading database for AIâ banner.
Important note for visitors: Adyen requires all visitors to bring a valid photo ID (passport or ID card) to enter the building. You show it at reception and get a visitor sticker.
On AI in Fintech
What struck me most about the evening is that AI in fintech is moving from experimentation to production, and the rules of engagement have changed.
In the chatbot world, you can afford to be conversational and creative. In fintech, every agent decision has a value attached. A wrong fee match is, in Iftachâs words on the slide, a compliance risk, not a quality-of-analysis question.
This is why the âskills first, structure laterâ sequence matters. You ship the skill to learn what the workflow really is; then you move routing, guardrails and audit records into code, and prove with a golden baseline that nothing changed.
Why This Matters for Fintech Builders
The themes from this meetup echo across every fintech stack I work with:
- Determinism is a feature, not a limitation: the best AI systems know when to stop being creative and fall back to code.
- Observability canât be bolted on: agent decisions need traceable paths from input to output. Typed tools that return the SQL and rows make the audit trail a by-product.
- Vector + analytics = the new full stack: teams that can join traditional business intelligence with similarity search in one database avoid running a second system.
- Production is not a research paper: per-token API pricing that is fine for a prototype âdoes not survive 100 million rowsâ.
