PRODUCT // OTACONSKEEP SEARCH FREE
Productfree

Products · Private search · Free

I built an AI answer box into my search engine

A private search page that still shows the results, and writes a short answer that has to name which of those results it used. The model never sees the open web. It sees five snippets.

Designed by Antonio G. Garcia · This page has the method and the measurements. It does not include hostnames, keys, or a VPN status URL.

01 // The problem

Why a results page is not an answer

Ordinary search makes you open tabs until one of them says the thing you needed. A local model with no search answers immediately, from whatever it already memorized, and there is nothing to check.

Search alone

Ten links, no sentence

The useful page is often result two or four. Ambiguous words also drag in pages that share a verb and nothing else. You can see them. You still have to read them.

Offline model alone

Fast, and uncited

Ask about this week and the model answers from memory. If that memory is old, it will name the wrong person and miss the incident. There is no source chip to click.

The box in the middle: SearXNG still fetches. Ollama only reads the top five titles, links, and snippets already on the page. Every sentence has to point at one of those numbers, or the box is supposed to say the results do not answer.

02 // Architecture

Browser, search, five results, local model

Browser→ SearXNG→ Top 5 results→ Ollama→ Cited answer
Diagram: the question stays in the browser, SearXNG fetches, Ollama only sees five results, and the answer cites them.
The question stays on this box. SearXNG fetches. The model only sees five results.

On this Keep the results page is branded Otaconskeep: dark simple theme, the wordmark in place of the stock SearXNG logo, and a card titled Keep AI answer. The card’s chip shows the model name and the seconds from results landing to the last token.

03 // The prompt

Five snippets. A cite-or-admit rule.

The five rules sent to Ollama: trimmed question, top five title URL and snippet, two to four sentences with citations, only those numbers, and admit when the results do not answer.
That list is the whole prompt. The open web is not attached.
  1. The question, trimmed to 300 characters.
  2. The top 5 results: title, URL, and the snippet already on the page.
  3. Write 2 to 4 sentences, under 90 words. After each one, cite the result number, like [2].
  4. Use only those numbers. No extra sources. No URL dump.
  5. If those results do not answer it, say so.

The browser posts that package to /ok/ai on the same origin. The plugin streams tokens back as NDJSON. Cross-site requests are rejected. If Ollama is down, the card says the local model is not reachable. It does not fall over to a cloud model.

04 // Side by side

The same question, with and without search

Question: what did the British prime minister say about Iran this week? Same model both times, gpt-oss:20b, thinking set low.

Offline Ollama answer in 0.9 seconds naming Rishi Sunak and a nuclear deal, with no citation and no mention of RAF Fairford.
No results. 0.9 seconds. It named Rishi Sunak and a nuclear-deal line. It never mentioned RAF Fairford. There is nothing to check.
Otaconskeep search results with a Keep AI answer that cites The Hill and The Independent, and leaves the unrelated medical pages uncited.
With the top five results. 2.2 seconds. The card cites The Hill and The Independent. It does not cite the medical pages the word “did” also returned.
Two columns comparing the uncited memory answer with the cited search answer for the same question.
Check the claim against the sources it named, not against the other results on the page.

The word “did” pulled in unrelated medical and product pages. They sat in the five. The answer did not use them. The cited headlines are the ones that actually discuss the incident. That is the difference search integration is supposed to make: a sentence you can click back to, and a refusal to treat every hit as support.

05 // A practical search

A real Ollama error, tied to a source

The second search was how to fix ollama llama runner process has terminated. This is the kind of question a results page usually answers with a video, a blog, and two GitHub issues, and leaves you to merge them.

Keep AI answer for the llama runner terminated error, citing a YouTube fix and a write-up, with the timer at 3.1 seconds.
3.1 seconds. The fix is tied to sources on the page, including the YouTube walkthrough and the localaimaster write-up.

06 // Performance

This take, on this machine

Timing card: gpt-oss 20B on an RTX 3090, 13.7 of 24 GB in use, model resident 12.9 GB, with waits of 0.9, 2.2, 3.1, and 1.2 seconds.
Not a benchmark. The 3090 was already holding the model.
RunWaitWhat the card did
No search results0.9sAnswered from memory. No citation.
Prime minister, with results2.2sCited The Hill and The Independent.
Ollama crash, with results3.1sCited the pages that describe the fix.
Serial number the results do not have1.2sSaid the results do not contain it.

Model: gpt-oss:20b. GPU: NVIDIA GeForce RTX 3090, 24 GB. During the take, about 13.7 GB was in use and the resident model was about 12.9 GB. The chip on the card is results-landing to the last token. Search itself returned in about a second, which is the separate “response time” line on the results page.

Another model tag can sit on the same Ollama host. The answer box uses the model named in OK_AI_MODEL. Confirm the running tag with ollama ps before you quote a number.

07 // One limitation

Poor results, and a box that should admit it

Query: what is the serial number of this RTX 3090. The hits are generic how-tos and forum threads about finding a GPU serial. None of them are this machine.

The answer box says the search results do not provide the serial number for that specific RTX 3090. Timer reads 1.2 seconds.
1.2 seconds. The pages are generic how-tos. The box says they do not have this GPU’s serial.

That refusal is the behavior you want. A nearby how-to is not a serial number. The same rule covers a dead Ollama: the card shows “The local model is not reachable right now.” It does not invent an answer while the model is down.

What still fails: if the top five snippets are wrong, the citation will point at a wrong page with confidence. Citing a bad source is better than hiding it, and it is still a bad answer. Read the page the number links to.

08 // Privacy

Local inference is not the same as a private query

The model call stays on your machine. The search call does not. SearXNG asks the engines you enabled, so those providers still see the query and the exit IP of whatever path you gave them.

Generate a new SearXNG secret with openssl rand -hex 32. Keep it in your env file or your local settings, not in a screenshot and not in a commit.

09 // Tutorial

Build the Otaconskeep answer box

You need Docker, a running Ollama, and a model that already fits on your GPU. This Keep used gpt-oss:20b. Use another tag if that one does not fit. The card will print whatever OK_AI_MODEL is set to.

1. Pull a model you can actually hold

ollama pull gpt-oss:20b ollama ps

ollama ps should show that tag resident on the GPU before you time a search. A silent router in front of Ollama can swap models. Talk to the Ollama you think you are talking to.

2. Start SearXNG with the plugin mounted

Put docker-compose.yml, otacon_ai.py, and ok_ai_card.html in one directory. Copy settings.example.yml to searxng/settings.yml and replace both secret placeholders. Inside the container, 127.0.0.1 is the container, so OK_AI_OLLAMA has to be an address the container can route to the host. On a typical Linux Docker bridge that is http://172.17.0.1:11434. Change it if your host listens elsewhere.

openssl rand -hex 32 # paste that value into SEARXNG_SECRET and server.secret_key docker compose up -d

3. Turn the plugin on in settings

On current SearXNG, a plugins: map replaces the default plugin map. It does not merge. The example file lists the stock plugins this Keep keeps, plus searx.plugins.otacon_ai.SXNGPlugin. An old enabled_plugins: list does nothing on this image.

brand.public_instances is a string. An empty string hides the public-instance list. The boolean false fails to load.

The locks in preferences.lock stop a cookie from turning safe search, autocomplete, the image proxy, POST, or the query-in-title flag back off.

4. Include the card in the results template

Mount ok_ai_card.html at searx/templates/simple/ok_ai_card.html, which the example compose file already does. In the theme base.html, inside the results area, add:

{% include 'simple/ok_ai_card.html' %}

SearXNG caches templates. Restart the container after a template or settings change. The card reads the top result articles already in the page, posts {q, results} to /ok/ai, and turns [2] into a button that links to result 2. Hovering a citation outlines that result.

The results logo text in this Keep is the word Otaconskeep, set in the search template, with general.instance_name set to the same name. The homepage clock, lock line, and photo headlines are a separate template on the same instance. They use the same dark theme. They are not required for the answer card to run.

5. Prove it with three searches

  1. Ask one current-events question with Ollama alone, then the same question in search. The second answer should cite pages that are actually about it.
  2. Ask how to fix a real error you have hit, and click the citation.
  3. Ask for a fact the results cannot contain, such as the serial number of the GPU in front of you. The card should say the results do not have it.

Read the chip. That number is the wait you felt, on the model that was loaded.

10 // Files

What you can copy

Left off this page on purpose: the real secret, the host address, and the URL of the VPN status check. Copy the pattern. Generate your own secret. Point Ollama at your own host.

Close

What the build taught

A local model is quick and unaccountable. A search page is accountable and slow to read. The useful object is the card that can only talk about the five results in front of you, shows how many seconds that took, and is willing to say the pages do not contain the answer.

Next for this Keep is a tighter homepage, and a habit of opening the cited page before trusting the sentence. The box is a reader. It is not a second source.

Antonio G. Garcia · Otaconskeep · October 13, 2026