ke_search_ai 

Classification

ke_search_ai

Version
Language

en

Copyright

2026

Author

ke_search_ai Dev Team

License

This document is published under the Open Content License

Rendered

Fri, 31 Jul 2026 09:25:59 +0000

The extension ke_search_ai extends the popular TYPO3 search extension ke_search with AI capabilities. It uses RAG (Retrieval-Augmented Generation) to provide users with a concise, AI-generated answer to their search query, placed directly above the traditional search results.

Table of Contents 

Overview 

  • AI-generated search results based on RAG (Retrieval-Augmented Generation).
  • Sources list providing transparency for generated answers.
  • No external vector database required (embeddings are stored in the TYPO3 database).
  • Optimized performance through AJAX loading and multi-level caching.
  • Flexible AI provider support (Mistral AI, OpenAI, and other OpenAI-compatible APIs).
  • Privacy-aware: Only uses content from the search index that the user is allowed to see.

ke_search_ai uses a RAG pipeline (Retrieval-Augmented Generation) to show a short AI-generated answer above the normal search result list. It also shows the sources list on which the answer is based.

The normal search result list is shown below and untouched by this feature.

The AI-generated answer is based only on index entries that would appear in a standard search without a search phrase (same restrictions as the result list: starting points, time restrictions, fe_group, filters, language). The retrieval never runs over the full index. If the empty search cannot be executed or returns no results, no AI answer is shown (this avoids exposing group- or time-restricted content). The search service of ke_search is used to determine the allowed index entries (see Installation and setup).

An AI provider is required to create the embeddings and the answer.

An external vector database is not needed, the embeddings are stored in the TYPO3 database. While this reduces external dependencies, it may lead to performance issues with large indexes. This is addressed by loading the AI overview with AJAX to make sure the search result page is displayed as fast as possible.

Workflow 

  1. Data preparation: Index entries from tx_kesearch_index are converted into vectors (embeddings) via an embedding API and stored in the table tx_kesearchai_embeddings. This is done by the console command ke_search_ai:embeddingindex (manually or via Scheduler).
  2. Retrieval: When a user searches, the search term is also converted into a vector. A similarity search (cosine similarity) finds the most relevant stored chunks. The corresponding full text is loaded from the index and passed as context to the LLM.
  3. Generation: An LLM receives the search query and the retrieved excerpts and generates a short answer that is displayed above the result list. Default provider: Mistral AI (OpenAI-compatible API). See Mistral API.

Frontend 

Fluid: The variable resultListAdditionalRawContent is prepended with <div class="kesearch-ai-answer">…</div>, so the answer appears above the result list when the default template is used.

Performance note 

This version stores embeddings in a MySQL table and runs the similarity search in PHP. For very large indexes (e.g. > 10,000 entries), consider using --pid or --limit and plan indexing accordingly. A future extension could support an external vector database.

Installation and setup 

Requirements 

  • TYPO3 version 13 or higher.
  • ke_search with a populated search index (tx_kesearch_index).
  • Embedding index: The console command ke_search_ai:embeddingindex must be run (manually or via Scheduler) so that embeddings are stored in tx_kesearchai_embeddings. See the section Building the embedding index below.
  • LLM API: An API key and endpoint for a chat/completions API (e.g. Mistral, OpenAI, or any OpenAI-compatible provider). Configure URL, key and model in Extension Manager under AI-generated results (RAG)LLM.
  • Embedding API: An API key and endpoint for an embeddings API (same or different provider). Configure under AI-generated results (RAG)Embeddings.

The feature has been tested with Mistral AI (default configuration) but works with other OpenAI-compatible AI providers (e.g. OpenAI, Azure OpenAI, local models). Use the same API URL pattern and model names as required by your provider.

Installation and first steps 

  1. Install the extension via composer

    You can either install it directly from a repository:

    composer require tpwd/ke_search_ai
    Copied!

    Or if you received the extension as a ZIP file, place it in a folder named packages in your project root, add the path repository to your composer.json and then require it:

    {
        "repositories": [
            {
                "type": "path",
                "url": "packages/*"
            }
        ]
    }
    Copied!
    composer require tpwd/ke_search_ai
    Copied!
  2. Update the database schema

    vendor/bin/typo3 database:updateschema
    Copied!
  3. Configure the extension

    Activate "Enable AI-generated results (RAG)", configure the LLM and Embedding API in the Extension Manager. See Configuration.

  4. Create the embedding index

    Run the console command to create the embeddings for your search index:

    vendor/bin/typo3 ke_search_ai:embeddingindex
    Copied!

Building the embedding index 

Before the feature can show answers, the embedding index must be built:

vendor/bin/typo3 ke_search_ai:embeddingindex
Copied!

Options:

  • --pid=123 Only process index entries from this storage PID.
  • --limit=500 Do at most 500 API calls per run. Default: 500.
  • --update Only process new or changed entries (by content hash).
  • --verbose See the process in detail.

Embedding index status 

To print a summary table (index size, embedding coverage, configured embedding API URL, and the last embedding update time from tx_kesearchai_embeddings.tstamp):

vendor/bin/typo3 ke_search_ai:embeddingindex status
Copied!

Optional: --pid=123 limits index size, coverage, and last-update to entries from that storage PID (same semantics as when building the index).

Run the command after the normal ke_search indexer, or schedule it in the TYPO3 Scheduler (e.g. daily after ke_search:indexing).

Configuration 

In the Extension Manager (ke_search_ai), open the category AI-generated results (RAG):

AI-generated results configuration in Extension Manager
  • Enable AI-generated results: Turn the feature on.
  • LLM: API URL (default: https://api.mistral.ai/v1/chat/completions), API key, model (default: mistral-small-latest), answer language (e.g. de), max response tokens.
  • Embeddings: Embedding API URL (default: https://api.mistral.ai/v1/embeddings), API key, model (default: mistral-embed).
  • Retrieval: Top K (number of chunks, e.g. 5–10), minimum similarity score (0–1, default 0.4; 0 = no filtering; typical 0.4–0.6 to exclude irrelevant hits), max characters per chunk.
  • Cache: Cache lifetime in seconds for the AI answer per search term (0 = no cache).
  • Logging: Log level (default: WARNING). See Debugging.

API keys can be configured in the Extension Settings (Extension Manager → ke_search_ai). For deployment, you may use env:VARIABLE_NAME as the value (e.g. env:MISTRAL_API_KEY) to read from the environment.

Modifying the system prompt (event) 

To change the system prompt sent to the LLM (e.g. to add rules or a different tone), listen to the PSR-14 event Tpwd\KeSearchAi\AiGeneratedResults\Event\ModifyAiGeneratedSystemPromptEvent.

Security: Do not inject user-controlled or unfiltered input into the system prompt. Use only static or sanitized text so the prompt remains trusted. See Security.

Register a listener in your extension's Configuration/Services.yaml:

YourVendor\YourExtension\EventListener\ModifyAiSystemPrompt:
  tags:
    - name: event.listener
      identifier: 'yourExtensionModifyAiSystemPrompt'
      event: Tpwd\KeSearchAi\AiGeneratedResults\Event\ModifyAiGeneratedSystemPromptEvent
Copied!

Example listener:

public function __invoke(ModifyAiGeneratedSystemPromptEvent $event): void
{
    $event->setSystemPrompt(
        $event->getSystemPrompt() . ' Only use a maximum of two sentences.'
    );
}
Copied!

The event provides getSystemPrompt() / setSystemPrompt() and getLanguage() (ISO 639-1).

Examples 

AI Overview 

Search with a term to see the AI-generated answer above the result list.

Search with a term

Caching 

The extension uses two TYPO3 caches to reduce API calls and improve response time:

  1. AI-generated answer (cache identifier: kesearchai_results)

    The final text returned by the LLM is cached per search. Each cache entry is identified by a key derived from the search term, the Top K setting, the minimum similarity score setting, and the answer language (e.g. from the current site language). When a user searches with the same term and language and the entry is still valid, the answer is taken from the cache and no embedding or LLM request is made.

    Lifetime is set with Cache in the Extension Manager (aiCacheLifetime, in seconds; default 2592000 = 30 days). Set to 0 to disable this cache.

  2. Query and index embeddings (cache identifier: kesearchai_embeddings)

    The same cache is used in two places:

    • At search time: When generating an answer, the search term is converted into a vector via the embedding API. That query vector is cached per search term (and per embedding API URL and model). If the same search term is used again before the cache entry expires, the embedding API is not called and the stored vector is reused for the similarity search.
    • When building the embedding index: The console command ke_search_ai:embeddingindex also uses this cache. For each index entry, the chunk text (title, abstract, content) is hashed and the resulting embedding is stored in the cache. When you run the command again (e.g. with --update), entries whose source text has not changed get their embedding from the cache instead of calling the embedding API. Duplicate or similar content across index entries also benefits from cache hits. The command’s --limit option counts only API calls; cache hits do not count toward the limit.

    Lifetime is configured with Embedding cache lifetime (aiEmbeddingCacheLifetime, default 2592000 seconds = 30 days). This reduces embedding API cost both for repeated search terms and when (re)building the embedding index.

Security 

RAG context and prompt injection

The retrieved index content (title, abstract, content) is passed as context to the LLM. Only index trusted content. If the index contains manipulated or untrusted text (e.g. instructions like “Ignore previous instructions…”), the model may follow them and alter the answer. Treat indexed content as part of the trusted prompt; avoid indexing user-generated or unmoderated content if you cannot accept this risk.

System prompt event

When using ModifyAiGeneratedSystemPromptEvent, do not inject user-controlled or unfiltered input into the system prompt. The system prompt should remain under your control; listeners must only add static or sanitized instructions so that the prompt stays trusted.

Cost Control 

  • Caching: Set Caching (e.g. aiCacheLifetime = 2592000 = 30 days) to avoid repeated API calls for the same search term.
  • Retrieval: aiTopK and aiMaxCharsPerChunk limit the context size and thus input tokens. aiMaxTokensResponse limits the answer length.
  • Embeddings: One embedding call per search; at index time, one call per index entry. Use affordable embedding models (e.g. Mistral mistral-embed).

Debugging 

When the ke_search_ai extension log level is set to DEBUG (Extension Manager → ke_search_ai →
Log level), the extension logs detailed information to help analyze the RAG pipeline:
- Retrieval: The search term and the similarity scores of the top-k results (including UID and
title of the indexed records) are logged to help analyze why certain records were chosen as context.
- LLM API: Request (URL, model, max_tokens, system and user prompt; long text is truncated)
and response (answer content, truncated if long). If the API returns token usage (e.g. Mistral, OpenAI), prompt_tokens, completion_tokens and total_tokens are logged to help estimate costs.
- Embedding API: Request (URL, model, input length and a short preview of the text) and
response (number of dimensions). If the API returns token usage, prompt_tokens and total_tokens are logged.

Log entries are written to the file var/log/ke_search_ai.log. API keys are never logged.

By default, the log level is set to WARNING, meaning only errors and warnings are recorded.

Changelog 

Version 1.0.0 (upcoming) 

  • [!!!] This version introduces AI based search to ke_search.
  • [FEATURE] Add AI-generated results above search list with RAG pipeline and AJAX, see Overview