Legal questions demand completeness, but standard RAG is built to return the closest matches, not every matching instance. A fixed RAG pipeline embeds the user's question, retrieves the most similar text passages from a search index, and asks the LLM to generate an answer from those passages. This approach works well for questions like "what does this contract say about termination?" but falls short for requests like "identify all documents related to X's fraudulent activity," which is exactly the kind of request litigators make.
Our initial release used this fixed pipeline/RAG approach, and we hit three hard limits:
Retrieval returns a ranked sample of the most similar passages. A relevance ranked sample can never establish completeness; "all" is simply not an operation the pipeline supports.
Every retrieved result must pass through the LLM's context window, which becomes impractical when the true answer spans hundreds or thousands of documents.
Many requests, such as "all emails between two custodians in a given quarter," do not need semantic search at all. They are metadata filters. A fixed pipeline runs an embedding search anyway and returns an approximation of something a traditional search could already do.
In the end, this approach limited the quality, completeness, and reliability of the answers we could give. It was a good initial release, but not a system a legal team could depend on.
A single pass pipeline also cannot recover from a wrong first guess. Legal questions are compositional: filter, then narrow, then evaluate. That requires orchestration, not a fixed sequence.
Figure 1: Simple RAG Chat
We built Agentic Chat as a custom harness around an LLM. Our harness exposes data and tools to the LLM, which then chooses the best path to respond to a user's request. For specific actions, the harness can invoke specialist agents, each with its own instructions for particular tools:
Retrieval Specialist: Builds metadata filters, keyword searches, and semantic searches. Its output is a composed query object, not documents. The query executes against the database and returns a link to the result set, keeping the documents themselves out of the context window. This result set also serves as the starting point for other techniques: by narrowing millions of documents down to a targeted subset first, it makes downstream approaches, such as per-document review, tractable.
Reviewer Assistant: Handles questions that RAG cannot answer: criteria that no filter can express and that require reading every document, such as "which of these discuss pricing disputes?" The agent converts the request into a prompt and initiates a parallelized, per-document, structured LLM evaluation. The results populate a results table that can be combined with additional filters or saved for further human review.
Result handles are the key mechanism. Document content can be kept out of the LLM's context window when it is not needed, and because handles persist across turns, the model can continue refining the filters. Consider an illustrative session on the public Electronic Discovery Reference Model (EDRM) Enron corpus, with counts shown for concreteness rather than as measured results: "find all emails from Ken Lay in 2001" returns a handle with 8,000 documents; "narrow to Q4" produces a new handle with 2,200; "which of those discuss revenue?" triggers the Reviewer Assistant and yields 140. Each step builds on the previous result handle. The user never restates prior criteria, and each handle is an exact, re-runnable query result. For the legal team, this means they can filter down, inspect the results, and broaden back out without losing their place. Same question, same data, same documents, every time. Defensible, not just plausible.
Figure 2: Agentic Chat Solution
Our design principle: the LLM decides what to do; deterministic systems carry it out. The LLM is invoked to interpret intent, select tools, compose filters, and generate a narrative answer. Nebula executes queries, performs joins and counts, stores results, and enforces permission scoping. In our view, this split is the single biggest driver of reliability, because it shifts the focus from "trust the model's answer" to "verify the model's query."
A precise way to state it: results are query complete, meaning every document matching the executed filter is returned, but not automatically intent complete, because the filter is the LLM's interpretation of the request. Decision transparency exists so users can close that gap themselves:
Any filters or searches the LLM constructs can be inspected, so users can verify exactly what was queried and replicate the results themselves, if desired.
The results of the queries are presented in the user interface as an interactive document table, allowing a user to inspect each intermediate result set, not just the final response.
Running the Reviewer Assistant on a set above the document count threshold requires explicit user confirmation before starting, keeping cost and time under the user's control.
The Reviewer Assistant uses structured output (classification, multi-label, extraction, or summary), so every evaluation returns filterable results with reasoning.
This is about trust through transparency. You are not asked to take the system's word for anything: you can see the exact filters that ran, check them against what you meant, and correct them if the interpretation missed. What comes back is never a black-box answer; it is a result you can inspect, verify, and stand behind.
One limitation to acknowledge is that fully understanding the user's intent is challenging because the LLM may not always interpret how a request aligns with the data’s actual vocabulary. For example, a user asking for "emails from Ken Lay" may expect matches for "Kenneth Lay," "Lay, Kenneth," or "kenneth.lay@enron.com," but the model can only filter on terms it infers from the request. We mitigate this by injecting the case summary, including known aliases and data conventions, into every request, and by surfacing the executed filter so users can review it. Showing the query is worth more than hiding the uncertainty.
Agentic Chat is not a bolt-on chatbot pointed at an export of your data and that distinction is critical, not cosmetic. Every guarantee described above, from query completeness to inspectable intermediate results, holds only because the agent and the review platform are one system. Nebula AI Case Explorer and Nebula are integrated views of the same platform, in both directions. That is an architecture, not a feature, and it cannot be reproduced by wiring a chat frontend onto a copy of the data:
Shared metadata. Document metadata and AI generated labels, such as key people, themes, key documents, and review status, are shared between Nebula and Nebula AI Case Explorer and are filterable by the agent. No sync pipeline is needed to copy data between the two.
Shared search architecture. The agent runs its queries against the same search index that powers Nebula, so results match what a reviewer sees in the review workflow. There is no separate index to build, refresh, or reconcile. Queries are also scoped to the document set selected for the AI Case Explorer project, not the full Nebula matter, so answers only ever draw from the documents the team put in scope.
Shared results. Result sets generated in Nebula AI Case Explorer are also shared with Nebula, so a document set surfaced through chat can become a working set in the review workflow rather than a screenshot in an email.
Security inheritance. Every agent session already carries the user's permission level and matter context. Tool state is isolated per session and per matter. We rejected external managed agent platforms because each additional system that persists data adds risk.
Context advantage. The case summary generated within the platform is included in every LLM call, ensuring the agent always has context on the specific matter.