🪟 Windows TippsThe Gemini desktop app is now available for Windows(11.09.2026 um 17:06 Uhr)
🪟 Windows TippsHeader and Footer not showing in Excel(14.09.2026 um 22:43 Uhr)
🕵️ SicherheitslückenBurn Out, Or Fade Away(14.09.2026 um 14:25 Uhr)
🪟 Windows TippsKB5129194 Windows 11 26H1 Out of Band Update - Deskmodder.de(14.09.2026 um 19:25 Uhr)
🪟 Windows TippsThe Gemini desktop app is now available for Windows(11.09.2026 um 17:06 Uhr)
🪟 Windows TippsHeader and Footer not showing in Excel(14.09.2026 um 22:43 Uhr)
🕵️ SicherheitslückenBurn Out, Or Fade Away(14.09.2026 um 14:25 Uhr)
🪟 Windows TippsKB5129194 Windows 11 26H1 Out of Band Update - Deskmodder.de(14.09.2026 um 19:25 Uhr)

🔧 Programmierung 🕛 vor 4 Monaten 14 Min Lesezeit
0

I Built an AI That Argues With Itself About Anything

↗ Quelle (dev.to)
🗣️ Stimme:
📑 Inhaltsübersicht

This is a submission for the

Demo Video:



Open in any modern browser (Chrome 113+ for local mode; any modern browser for cloud mode). The Settings panel has a radio toggle to pick local or cloud. Try one of the suggestion buttons (Tesla in 2026, AI bubble?, Buy a house?) or type your own opinionated question.






Code



Repo: . The key lives only in your browser's localStorage; it is never embedded in the public code, never transmitted to anyone except Google. Inference takes 20 to 40 seconds per query. The privacy story shifts: queries go through Google.



You pick. The Settings panel has a radio toggle and a key input. The header tells you which mode is active.






The eight engineering problems



Naming the problems is the actual point of this post because most of them are reusable knowledge for anyone trying to ship browser-LLM apps.






1. The page was not cross-origin isolated



GitHub Pages does not let you set custom HTTP headers. Without two specific headers (Cross-Origin-Opener-Policy: same-origin and Cross-Origin-Embedder-Policy: credentialless), the browser will not enable SharedArrayBuffer. The ONNX runtime needs SharedArrayBuffer to run on WebGPU. Without it, every model load failed with raw numeric errors that pointed into the WebAssembly heap (literal numbers like 11514632).



Fix: ship a service worker (adapted from coi-serviceworker, MIT) that intercepts every response and adds the missing headers. First load registers the worker and reloads. After that, the page is cross-origin isolated and SharedArrayBuffer becomes available.






2. WebGPU compile froze the tab for a minute



The first time the ONNX runtime loads a model on WebGPU, it has to compile shaders for every operation in the network. For Gemma 4 E2B that takes anywhere from thirty seconds to over a minute. Done on the main thread, the page becomes unresponsive.



Fix: put the entire model life cycle in a Web Worker. The page sees a thin proxy that exposes model.load(onProgress) and model.chat(messages, opts). The proxy talks to the worker over postMessage. Heavy work happens off the main thread; the page stays interactive.






3. The worker flooded the main thread anyway



After moving the model into the worker, the page froze again for a different reason. Transformers.js fires a progress callback for every chunk of the download. With a 1.5 GB file, that is hundreds of events per second. Each one became a postMessage to the main thread. The main thread message queue saturated.



Fix: throttle progress messages to one every 100 milliseconds. Always send state changes immediately (started, finished, ready) but coalesce the actual progress percentages.






4. Wikipedia search returned nothing for verbose questions



Pressure-testing the live site exposed a fundamental issue. Even simple queries like "What is photosynthesis?" were producing answers like "research notes are empty." Two of three workers were giving up.



The bug was upstream. The model-driven planner was generating verbose sub-questions like "What is the fundamental definition of photosynthesis and its core chemical processes?" Wikipedia's classic search API does title-prefix matching, and that string is not the prefix of any Wikipedia article title.



Fix in three parts. Switch to Wikipedia's full-text search API. Strip filler words from the search query before sending it (a list of about 60 question-shape filler words). Add a relevance gate: if no result title contains a meaningful word from the query, treat it as zero results and cascade to a different source.






5. The planner was spending 30 seconds on something a regex could do



The original planner used the model itself to extract the topic and generate three search queries. It took about 30 seconds on Gemma 4. Then I noticed the model was just echoing the user's full question into the template. It was not actually doing extraction. It was a slow templating engine.



Fix: replace the planner's model call with a small JavaScript function. Strip leading question words and trailing punctuation. Strip "X better than Y" comparisons to keep just X. Cap at 3 words. Done in milliseconds. The planner card still appears in the swarm visualization; it just shows the topic immediately rather than streaming through 30 seconds of model generation.






6. Wikipedia gave facts but no opinions



For opinion questions ("Is remote work better than in-office work?"), Wikipedia gave the encyclopedic article on remote work, which is descriptive, not opinionated. Workers correctly noticed they could not construct a real critique from descriptive material and refused.



Fix: search multiple sources in parallel. For every worker query, fetch Wikipedia AND Hacker News comments at the same time. Wikipedia provides encyclopedic grounding. HN comments provide actual user opinions and lived experience, with paragraphs of real takes that no encyclopedia has. Workers see both and decide what to anchor on. The "0 servers contacted" line in the footer lost its third significant digit but the architecture finally produces grounded opinion content.






7. Cloud mode was the next thing the project needed



Local Gemma 4 E2B at 3 to 5 minutes per query is real and unavoidable on consumer GPUs. The architecture only worked at "single user with patience" volume. Adding a cloud option mattered because it lets the same architecture run at 30 seconds per query on bigger Gemma 4 variants.



The challenge was doing it without compromising the privacy story for users who care about it. Solution: BYOK. The Settings panel has a key input that writes only to localStorage. The public code contains no key (verified with git grep for AIza patterns before every push). The cloud path makes one fetch per agent call directly to generativelanguage.googleapis.com from the user's browser. We never see the key, never proxy the requests, never log anything.



The cloud adapter has a 60-second per-call timeout (we observed one worker hang indefinitely while the other two completed) and a two-stage resilience strategy. First, each model gets up to three attempts with 1s/2s exponential backoff if the API returns a 5xx, a 429, an empty body, or a timeout. Google's "Internal error encountered" on Gemma 4 is almost always transient and clears within one retry. Second, if a model still fails after retries, we fall through to the other Gemma 4 variant in the chain (E4B and 31B Dense). Hard errors like 404 (model not on your key) skip straight to the next variant; auth and bad-request errors bail immediately.






8. Gemma 4 dumps its thinking into the response



Even with thinkingConfig.thinkingBudget=0 (which the API rejects for Gemma 4 with a 400, by the way), Gemma 4 on the Gemini API outputs its internal reasoning verbatim: drafts, refinement passes, "Word count check" notes, before the actual final answer. The user's first cloud query produced about 600 words of thinking-out-loud before the clean structured answer.



Fix: client-side stripping. The synthesizer's output always starts with ## Where they agreed. Find the LAST occurrence of that heading, trim everything before it. Strip leading "Final Polish:" / "Refined version:" labels. The model's thinking goes in the bin; the user sees only the polished output.






What I want to be honest about



A few things people might assume from the demo that are not actually true.



Local mode is sequential, not parallel. WebGPU LLM inference is single-stream per session. The three perspective agents take turns on one GPU. The visualization makes it look concurrent. Logically it is, physically it is not. Cloud mode actually fires three parallel Gemini calls but the synthesizer still waits for all three.



Cloud mode is private to Google, not to me. Your queries go to Google's servers. Your key goes from your browser directly to Google. I never see either. But this is different from the local mode promise of "nothing leaves your tab." Both are valid trade-offs; you pick.



Niche cross-domain queries return weak findings. When the public sources do not have an opinion to mine, the agents lean on training knowledge alone. They are honest about which claims have evidence versus widely-held belief.



The 3 GB local-mode download is real. No way around it for first-time local visitors. We gate the download behind an explicit click and persist via the browser cache so reload is free. Cloud mode is the alternative for visitors who do not want to commit.



Factual lookup queries do not benefit from this architecture. If you ask "What is photosynthesis?" the skeptic does not really argue against photosynthesis. Three perspective agents on a factual lookup just produce three slightly different summaries of the same article. AgentMesh shines on questions with actual disagreement.






What I would build next



If I keep working on this past the challenge, four things in priority order.



Native Gemma 4 tool calling. The model has a structured tool-call format built into its chat template. Right now I use a deterministic dispatch (Wikipedia + HN comments in parallel). Switching to the native format would make tool selection cleaner and add another concrete reason the project specifically uses Gemma 4.



Multimodal, properly. Gemma 4 E2B is multimodal. The code paths for image input exist in model.worker.js but I rolled them back because per-component dtype configuration on diverse Chrome drivers needed more debugging than the challenge time-box allowed. Drop an image into the prompt. The skeptic argues against what is in it. The advocate argues for. The pragmatist describes how it gets used.



More than three perspectives. A historical agent (how did this work in the past?). A futurist agent (where is this going?). A user-of-the-thing agent. The architecture trivially extends.



More sources. Reddit JSON, Brave Search (would need a second BYOK key), Stack Exchange. Each broadens the grounding for opinionated queries.



I am not committing to any of these yet. What I do next depends on what happens with this post. If a hospital CTO emails me about clinical literature review with locally-bound data, I will go faster on something like a persistent OPFS notebook. If five engineers fork the repo, I will go faster on multimodal and tool-calling. If neither, this stays a portfolio piece I am happy with.






Thanks



To Google DeepMind for releasing Gemma 4 with weights small enough to actually fit in a browser tab AND making the bigger variants available on AI Studio for free, so the same project can run at two scales. To Hugging Face for Transformers.js, especially the 4.2.0 release that finally worked end to end. To gzuidhof for the coi-serviceworker library, which solved the cross-origin isolation problem in about five minutes once I knew it existed. To nico-martin for publishing the gemma4-browser-extension code, which was my reference for which library version actually loads this model. To everyone who keeps the open browser-ML stack moving forward.



The code is MIT. Fork it. Rip out the parts you want. If you build something better with it, I would love to see what.

Vollständiger Original-Bericht
Ausführliche Details, Code-Beispiele & Hersteller-Stellungnahme auf dev.to.
↗ Original-Artikel auf dev.to lesen
Wie bewertest du diesen Beitrag?
1 Klick Feedback
Teilen mit Netzwerk & Team:

Community-Analysen & Experten-Meinungen 0

Verfasse deine eigene Analyse, teile Workarounds oder diskutiere diesen Vorfall im Blog.
Noch keine Community-Analyse verfasst. Markiere einen Textabschnitt oder klicke oben auf Eigene Analyse verfassen“!
Community Pulse: Relevanz-Einschätzung
1 Klick Experten-Votum
🔴 Akute Relevanz 0%
🟡 In Evaluierung 0%
🟢 Keine Auswirkung 0%
Spannende Innovation 0%
Verwandte Story-Cluster & Quellen (Vektor-KI)
Port 8095 Engine
1 Quelle
The Gemini desktop app is now available for Windows
1 Quelle
Header and Footer not showing in Excel
1 Quelle
Burn Out, Or Fade Away
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten I Built an AI That Argues With Itself About Anything

Thematisch verwandte Begriffe: Built, That, Argues, With · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...