Combine search and formatting into the single function your chatbot will actually call on every user question.
1One Clean Interface Over Two Steps
Composing small, already-tested functions into a single entry point is standard engineering practice, and RAG pipelines are no exception. Everything downstream of this point only needs to know 'give retrieve() a query vector, get back context text' — it doesn't need to know or care that two separate steps are happening underneath.
2What This Function Enables
With retrieve() in place, your chatbot has everything it needs to answer questions grounded in real data: embed the incoming question (Module 1), retrieve and format the relevant context (this function), then hand both to the LLM with a strict grounding instruction. That's the entire RAG chain, and Module 3 builds exactly that last piece.
3Step-by-Step Breakdown
Combining Search and Formatting. You now have two working pieces: similarity_search() finds relevant chunk ids, and format_context() turns ids into labeled text. This lesson wires them into a single retrieve() function — the one call your chatbot will actually make on every user question.
Build the Combined retrieve() Function. Finish retrieve(): call similarity_search() with the query vector and top_k, then pass its result straight into format_context() and return that. Two lines, using functions you've already built and tested.
Why is it useful to wrap similarity_search() and format_context() into one retrieve() function, instead of always calling both separately?
- →It gives the rest of your chatbot one clean interface — pass in a query vector, get back a ready-to-inject context string — hiding the two-step implementation detail.
- →It makes the underlying similarity search mathematically faster.
Module 2 Complete. retrieve() is done: query vector in, labeled context string out. Module 3 is where this masterclass pays off — wiring retrieve() into a real, grounded LLM call that finally answers the Nexora PTO question correctly.
Level Up 🚀
Advanced cheat sheets, SEO tricks, and interview prep for this topic.
Browser Support
Fully supported.
Fully supported.
Fully supported.
Fully supported.
Accessibility (A11y)
1Keep Internal Function Composition Invisible to the UI Layer
The retrieve()/search()/format() split is an internal implementation detail — the UI layer consuming it should only ever depend on the stable retrieve() interface, so internal refactors don't ripple into UI code.
const context = await retrieve(queryVector);SEO Implications
- 1
Target 'RAG pipeline function' as a distinct search
Developers search for the composition pattern once they already understand embeddings and retrieval individually.
Best Practices
Compose Small, Tested Functions Rather Than One Monolithic One
Building similarity_search() and format_context() separately, then composing them, means each piece can be tested and debugged independently — a bug in formatting doesn't require re-deriving the search logic to isolate.
Frequent Bugs
Inlining search and formatting logic directly into the LLM call site, making the retrieval logic untestable in isolation.
Keep retrieval as its own composed function with a clear input (query vector) and output (context string), independent of how it's eventually used in a prompt.
Real-World Examples
Chatbot Request Handler
A production chatbot's request handler calls exactly one function — retrieve(query_vector) — without needing to know it's internally doing a vector search followed by text formatting.
context = retrieve(embed(user_question))