Fast Model Writes the Code, Smart Model Fixes the Logic: Building Search on n8n and PostgreSQL
The author built a search over a catalog of 1,684 items for a Tilda page: the fast Particle-1 model wrote SQL and JavaScript in Cline, while the reasoning model GPT-6 Luna Pro was brought in at dead ends. There is no LLM at runtime, just a regular query. This is not a benchmark but a breakdown of a live case, where the main errors lay at the joints between nodes and in the data.
AI-processed from Habr AI; edited by Hamidun News
Plenty is written about top-tier models, but almost nothing about how to split roles between a fast model and a "thinking" one on a real task. The author of this breakdown took a working project and tested the approach in practice.
The Task and Why There Is No LLM at Runtime
The project needed a search over a catalog of handmade stone items. On a private Tilda page, a specialist selects areas of life (love, money, health, and so on) and picks a design: women's, men's, or unisex. In response, they get up to five cards from a PostgreSQL table with 1,684 records.
The author rejected the temptation to put a model that "understands the request" between the form and the database, for three reasons. The first is latency: a network call is unnecessary for searching 1,684 rows. The second is cost and variability: the search rules can be written explicitly. The third is the source of truth: SQL returns only what is in the catalog, whereas a model could add a plausible but invented property. So LLMs are used only during development.
The roles were as follows. Particle-1 in Cline was the "hands": it wrote SQL and code for n8n nodes, and fixed quotes and field names. GPT-6 Luna Pro was the "brain": it was called in when the problem was no longer syntax but diagnosis. The author kept launches, HTTP response checks, and product decisions for himself.
A caveat matters here: this is not an A/B test. The sessions differ in scope, so 0.49 USD versus 0.04 USD cannot be compared as the price of solving a single task. OpenRouter latency data is also only a reference point for a specific date.
Five Pitfalls in Order
1. The & operator. To count shared tags, the model used & for text[], which does not exist in PostgreSQL. The && operator only answers "is there an overlap" and does not count. The solution: && in WHERE to select candidates, and a subquery with unnest counts the matches.
2. Syntax error near undefined. The Code node output a field called sql_query, while the Postgres node read a different name. Meanwhile, the Code node was lit up green. Takeaway: check the actual OUTPUT of the previous node against the INPUT of the next, not the nice-looking expression in the parameters.
3. The array literal. Two levels of quotes are needed: double quotes inside for the elements, single quotes outside for the SQL string. The model lost the outer layer. The author failed to parameterize the array via $1, but honestly does not claim that n8n cannot do it. For a new production system, he would first insist on getting a parameterized query working.
4. Five rows in SQL, one card on the site. According to the documentation, Respond to Webhook executes once, on the first item. The All Incoming Items mode helps. Diagnosis was further confused by the fact that a broad unisex record with eight tags ended up on top, making it seem as if SQL always returned the same thing.
5. Women's design: one record out of 1,684. The filter is not broken; the data is skewed: almost everything landed in unisex. The author did not change the algorithm but fixed a product rule: a women's query allows female and unisex, and when scores tie, an exact gender match ranks higher. The model could not decide whether this was an import error.
The Hole the Models Did Not Notice
In the final review, the author asked not "why does it fail" but "what happens if the form is bypassed." Backslash and double quote were escaped, but not the single quote, and the literal was wrapped precisely in single quotes. Via curl, it was possible to break out of the string and alter the query. The password on the Tilda page protects only the HTML, not requests to n8n. An API key in client-side JS would not have helped either. The fix was made on the server: a whitelist of values for spheres and gender, plus correct escaping of both levels.
Takeaways
The split of "fast executor plus slow diagnostician" works if you yourself decide the moment to switch: an error in syntax or in system behavior. A green node status does not prove the pipeline is consistent. Ranking by cardinality(tags) does not prevent a broad record from winning. And an empty list of spheres silently disables the filter, so in a public API it is better to return 400. Security review remains human work: in this case, neither model flagged the injection.
- Nov 8, 2026Thinking Machines releases Inkling 2 Small: a 594B MoE that fine-tuned Qwen on its own for $426
- Nov 8, 2026YADRO Replaces Smartcat with Weblate, Dify and Qwen, Cutting Per-Word Cost Sixfold
- Nov 8, 2026REAP20 Speeds Up Local Qwen by 42% With No Accuracy Loss on DS1000
- Nov 8, 2026Inkling 2 Small Swore 316 Times, but the Profanity Barely Helped Predict Failures
Key Questions Answered
What are the key details on The Task and Why There Is No LLM at Runtime?
The project needed a search over a catalog of handmade stone items. On a private Tilda page, a specialist selects areas of life (love, money, health, and so on) and picks a design: women's, men's, or unisex. In response, they get up to five cards from a PostgreSQL table with 1,684 records. The author rejected the temptation to put a model that "understands the request" between the form and the database, for three reasons. The first is latency: a network call is unnecessary for searching 1,684 rows.
What are the key details on Five Pitfalls in Order?
1. The & operator. To count shared tags, the model used & for text[], which does not exist in PostgreSQL. The && operator only answers "is there an overlap" and does not count. The solution: && in WHERE to select candidates, and a subquery with unnest counts the matches. 2. Syntax error near undefined. The Code node output a field called sql_query, while the Postgres node read a different name. Meanwhile, the Code node was lit up green.
What are the key details on The Hole the Models Did Not Notice?
In the final review, the author asked not "why does it fail" but "what happens if the form is bypassed." Backslash and double quote were escaped, but not the single quote, and the literal was wrapped precisely in single quotes. Via curl, it was possible to break out of the string and alter the query. The password on the Tilda page protects only the HTML, not requests to n8n. An API key in client-side JS would not have helped either.
Test Frontier LLMs & Autonomous Agents in One Workspace
Run Claude Opus 5.5, GPT-6, Gemini 3.1, and DeepSeek side-by-side in Nomad AI (nomadnet.ai) — unified model routing, deep research, and multimodal workflows under one subscription.
The AI world, distilled — once a week
Seven stories that actually mattered, hand-picked. No noise, no reposts, no press releases.
Done! Check your inbox for a confirmation.