Model or dataset
developersdigest/llm-answer-engine avatar
developersdigest/llm-answer-engine

llm-answer-engine: A Perplexity-Style Answer Pipeline You Assemble From Four API Keys

Perplexity Inspired Answer Engine

5,036 stars775 forksTypeScriptMIT

At a glance

What is it?
developersdigest/llm-answer-engine is a Next.js reference implementation that chains Brave Search, Serper, Groq or Mixtral and OpenAI embeddings into a cited answer UI. It is a starting point, not a product: the interesting decisions live in app/config.tsx, and so do the constraints.
Who is it for?
Adopt it if you want a working reference for the retrieve, chunk, embed, rank, answer loop and you are comfortable holding four vendor keys (OpenAI, Groq, Brave, Serper). Do not adopt it as a drop-in Perplexity replacement for a public audience: rate limiting and semantic cache are off by default, the README documents no evaluation harness, and function calling is labelled beta.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 139 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

What Problem llm-answer-engine Actually Solves

Ask a language model a question about something recent and it either refuses or invents. The fix is retrieval: search the web first, feed the results into the prompt, and return citations alongside the prose. That loop is well understood but tedious to wire up, because it spans a search API, an HTML extractor, an embedding model, a vector comparison step, and a streaming chat endpoint. llm-answer-engine is a Next.js application that implements the whole chain so you can read the code instead of designing it. The README frames it as "an ideal starting point for developers interested in natural language processing and search technologies," and that word choice is accurate. It returns sources, answers, images, videos and follow-up questions from a single query. The intended user is a developer who wants to see how a Perplexity-shaped product is assembled, or who needs an internal question-answering tool where the sources matter more than the prose. It is not aimed at teams that want a hosted search product with an SLA.

The Retrieval Chain: Brave In, Cheerio Through, Mixtral Out

The architecture is a linear pipeline, and the README lists every component. Brave Search supplies the source pages and images. Serper supplies video and image results. Cheerio parses the fetched HTML so text can be extracted from it. Langchain.JS handles the text operations, specifically splitting and embeddings. OpenAI embeddings turn each chunk into a vector, and the app keeps the top matches according to numberOfSimilarityResults. Those chunks are then handed to the inference model, which by default is mixtral-8x7b-32768 served through Groq's OpenAI-compatible endpoint at https://api.groq.com/openai/v1. The Vercel AI SDK streams the generated text and chat UI. The result is a response with citations attached rather than a bare paragraph. Two details in the config reveal the shape of the data flow: numberOfPagesToScan defaults to 10, meaning ten pages are fetched and parsed per query, and textChunkSize of 800 with textChunkOverlap of 200 defines how each page is sliced before embedding. Those three numbers, not the model choice, determine most of your latency and your API bill.

Configuration Lives in One File, Which Is Both the Appeal and the Trap

Everything tunable sits in app/config.tsx: useOllamaInference, useOllamaEmbeddings, inferenceModel, inferenceAPIKey, embeddingsModel, textChunkSize, textChunkOverlap, numberOfSimilarityResults, numberOfPagesToScan, nonOllamaBaseURL, useFunctionCalling, useRateLimiting, useSemanticCache and usePortkey. That is a short list, and it is honest about what the project is. Because nonOllamaBaseURL points at Groq's OpenAI-compatible route, swapping providers is a matter of changing a base URL and a model string, assuming the replacement speaks the same protocol. The trap is that several of these flags default to false. useRateLimiting and useSemanticCache are both off, even though the README lists Upstash Redis rate limiting and Upstash semantic caching as optional technologies. A deployment that ignores those two keys will re-run the full ten-page retrieval for every identical query and will accept unlimited requests. The README does not say what happens to the Upstash configuration when the flags are false, and I cannot confirm it from the material, so treat enabling them as work you will have to verify yourself.

Getting It Running: Four Keys, Two Paths

You need API keys from OpenAI, Groq, Brave Search and Serper before anything works. The non-Docker path is git clone https://github.com/developersdigest/llm-answer-engine.git, then cd llm-answer-engine, then npm install or bun install. Create a .env file in the project root containing OPENAI_API_KEY, GROQ_API_KEY, BRAVE_SEARCH_API_KEY and SERPER_API, then npm run dev or bun run dev. The Docker path skips the .env file: you edit docker-compose.yml directly to add the keys, then run docker compose up -d for Compose v2 or docker-compose up -d for v1. There is also a Vercel deploy button. Its environment description contains a genuinely useful warning: if you are using Groq instead of OpenAI, enter a random string in the OpenAI key field so the build does not error. That tells you the OpenAI key is validated at build time even when inference runs on Groq, which is a rough edge worth knowing before you spend an afternoon on a failed deploy.

Function Calling Is Beta, and the Default Model String Is the First Thing to Check

The README labels function calling as beta and lists what is supported: Maps and Locations through the Serper Locations API, Shopping through the Serper Shopping API, TradingView stock data via a free widget, and Spotify via a free API. The section ends by inviting issues or pull requests for anything else, which is a reasonable signal that coverage is narrow. The larger limitation is the default inferenceModel value of mixtral-8x7b-32768. Groq has retired models before, and a hosted model identifier is not a stable interface. If that string stops resolving, the application fails at the inference step regardless of how well the retrieval half works, and the README gives no fallback or health check. There is also no evaluation harness described anywhere in the material, so you have no documented way to measure whether changing textChunkSize from 800 to 1200 improves answer quality. You would be tuning by eye. And because retrieval depends on Brave and Serper simultaneously, a quota or billing problem at either provider degrades the product in a way that looks like a model failure to the end user.

Where It Fits Against a Framework Like LangChain Templates

The obvious alternative is to build the same pipeline on a retrieval framework such as LlamaIndex or a LangChain retrieval template, or to use a hosted answer API and skip the assembly. The difference is control over the middle of the pipeline. llm-answer-engine exposes the chunk size, the overlap, the number of similarity results and the number of pages scanned as top-level constants in one file, which makes the retrieval behaviour inspectable in a way that a framework abstraction hides. A framework gives you more loaders, more vector store integrations and a broader set of retrievers, but you inherit its abstractions and its upgrade cadence. This repository gives you roughly a dozen settings and a linear code path you can read end to end in an afternoon. The trade is that you also inherit the maintenance: no plugin ecosystem, no retriever zoo, and no upstream fixing your provider breakage. If your requirement is a specific, narrow answer engine with citations and you want to own the code, the flat config file wins. If you need many document types and vector stores, the framework will save you weeks.

Licence, Upgrades and What Running It Costs You

The project is MIT licensed, which permits commercial use, modification and redistribution provided the copyright notice and permission notice are retained. That is a permissive starting point for a product, but the licence covers this repository only. The API keys you supply are governed by separate agreements with OpenAI, Groq, Brave and Serper, and those terms, not MIT, determine what you may do with the retrieved content and the generated answers. I am not giving legal advice; read each provider's terms before shipping. On maintenance, the repository was pushed on 2026-04-29 and is not archived, but no releases were retrieved, so there is no tagged version to pin and no changelog to read before upgrading. You would track the main branch. The recurring cost is per query and stacks across providers: one Brave search, one Serper call for media, embedding calls over roughly ten pages split into 800-character chunks, and one inference call. Reducing numberOfPagesToScan is the single most effective lever on that bill, and it is a one-line edit in app/config.tsx.

Editorial conclusion

Adopt it if you want a working reference for the retrieve, chunk, embed, rank, answer loop and you are comfortable holding four vendor keys (OpenAI, Groq, Brave, Serper). Do not adopt it as a drop-in Perplexity replacement for a public audience: rate limiting and semantic cache are off by default, the README documents no evaluation harness, and function calling is labelled beta. Before committing, verify current Groq model availability against the inferenceModel string in app/config.tsx and confirm the Serper and Brave quotas your traffic will consume.

Official sources

  1. developersdigest/llm-answer-engine on GitHub
  2. Issues
  3. License: MIT
  4. Project website
  5. README
Community notes

Community notes