A Wrocław renovation company wanted to know what AI assistants tell buyers looking for a contractor. This AI visibility audit asked three of them 10 buyer questions in 4 languages and measured 120 answers. The company was mentioned in 4 of the 96 answers where its name was not in the question.
Everything below comes from one measured run — models, prompts, and the code that ran them are named exactly, so the audit can be repeated and the numbers checked.
Buyers increasingly ask an AI assistant (ChatGPT, Claude, Gemini) who to hire instead of scanning the top-10 Google results.
The question is not whether you rank but whether you are on the shortlist it returns — and if not, who is.
The measurement is a Python script, run from the command line, that reads a prompt library, sends prompts in bulk to one model, and writes each answer back into that model's own column — three runs, one per model, produce the 120 answers.
| Dimension | Values | Count |
|---|---|---|
| Questions | 2 branded (does the assistant know this company?) + 8 unbranded (buyer looking for any contractor: best firm, price per m², shortlist with contacts, developer-state finishing, remote owner, language of service, how to choose, timeline) | 10 |
| Languages | Polish (primary market), Ukrainian, Russian, English | 4 |
| Models | gpt-5.5, claude-sonnet-5, gemini-3.7-flash — each with its own live web search enabled | 3 |
| Answers | 10 × 4 × 3 — of which 96 are unbranded, the headline denominator | 120 |
Each provider exposes web search differently, so "with search on" means three different things.
# Anthropic — Messages API, server-side search tool client.messages.stream( model="claude-sonnet-5", max_tokens=16000, system=SYSTEM_PROMPT, tools=[{"type": "web_search_20260209", "name": "web_search", "max_uses": 5}], messages=[{"role": "user", "content": prompt}]) # OpenAI — Responses API, `instructions` carries the system prompt client.responses.stream( model="gpt-5.5", input=prompt, instructions=SYSTEM_PROMPT, tools=[{"type": "web_search"}]) # Google — google-genai, Search grounding client.models.generate_content_stream( model="gemini-3.7-flash", contents=prompt, config=types.GenerateContentConfig( system_instruction=SYSTEM_PROMPT, tools=[types.Tool(google_search=types.GoogleSearch())]))
In the 96 answers where the question did not contain the company name, Ravenna Pro appeared 4 times. All four came from a single model. The other 92 answers handed the buyer a list of competitors.
| Unbranded question | PL | UK | RU | EN |
|---|---|---|---|---|
| Best turnkey renovation company | ||||
| Cost per m² for a 60 m² flat | ||||
| Five vetted contractors with contacts | ||||
| Developer-state finishing, named estates | ||||
| Owner lives abroad, remote management | ||||
| Service in Ukrainian | ||||
| How to choose a contractor | ||||
| How long a renovation takes |
The domain was cited 17 times across 120 answers — but 13 of those sit on the two branded questions, where the model was handed the name and went looking. On six of the eight unbranded questions it was cited zero times.
Every branded answer places the business in Wrocław — but two thirds of them simultaneously pull a Warsaw registered address and a PKD classification of "architecture / design services" out of the company registries. A quarter drift toward the Italian city of Ravenna, concentrated in Russian and English. The registry record is, in effect, arguing with the marketing site, and the model reports both.
When a model builds a list of contractors it leans on marketplaces and ranking pages, not on company sites. Oferteo and Fixly are the two most-cited domains in the entire corpus. Ravenna Pro has no profile on either, so it cannot enter the list those pages feed — regardless of the quality of its work.
Not "competitors" in the abstract — the firms models actually name when asked for advice, and the specific claims they repeat about each.
| Firm | What the models repeat about them | Source |
|---|---|---|
| RUKOS | trading since 2014, "design through handover" model, 5/5 from 45 reviews | own site + Oferteo |
| PPUH ART-RAD | 5.0/5 from 12 reviews, 20+ years, itemised quote, schedule, warranty, VAT invoice | Oferteo |
| MAXYSBUD | full scope including developer handover inspection, 2-year warranty, named estates | own site |
| NEO REMONT | 2 M PLN contractor liability insurance, post-completion service | third-party ranking |
| SIGNUM Interiors | prices from 1390 PLN/m², worked on Olimpia Port, Browary Wrocławskie, Port Popowice | own site |
Visibility in one says very little about visibility in another — which is the practical argument for measuring more than one.
| Model | Avg length | Sources / answer | Own-site citations | Unbranded wins |
|---|---|---|---|---|
| gpt-5.5 | 3 828 | 4.3 | 12 / 40 | 4 |
| claude-sonnet-5 | 2 987 | 1.9 | 4 / 40 | 0 |
| gemini-3.7-flash | 2 416 | 1.4 | 1 / 40 | 0 |
gpt-5.5 searched hardest — 4.3 distinct domains per answer against Gemini's 1.4 — and that alone explains all four unbranded mentions. The company's visibility currently rests on one model happening to dig deeper, which is luck rather than position.
gemini-3.7-flash is the alarming one. One citation in forty, zero unbranded mentions. It runs on live Google Search, so it is the closest available proxy for what Google's own stack knows — and by that proxy the company is close to absent from the ecosystem where most of its buyers decide. It is a proxy, not the AI Overview itself; that surface has no API.
| Language | Own-site citations | Brand mentions | Reading |
|---|---|---|---|
| Polish | 5 | 7 / 30 | home market, densest competition, the only language where models quote prices at all |
| Ukrainian | 4 | 7 / 30 | weakest competition — the existing /uk/ version is a real, underused edge |
| Russian | 5 | 8 / 30 | most mentions and most Italy confusion; no /ru/ version exists |
| English | 3 | 6 / 30 | longest answers, most sources consulted, fewest citations of this site |
The single clearest causal finding in the run came from the Ukrainian-language question. Both of its hits happened because a /uk/ version of the site exists; the model opened it, confirmed the page was genuinely in Ukrainian, ranked the company first, and — uniquely in all 120 answers — reproduced the phone number.
Ordered so that nothing gets attributed to the wrong company before the rest is worth doing.
LocalBusiness JSON-LD with exact NAP and sameAs; make the Wrocław address the primary one everywhere a machine reads it; put the phone in extractable markup. The Warsaw contamination and the 4% phone-recall rate are the same defect.