Whole-Document Reasoning with Subagents and a Transparent Streaming Interface
Overview
Chunk retrieval is efficient because it sends only a small amount of evidence to the language model. It is also incomplete for tasks that depend on the full structure of a document. A summary, policy review, extraction of all requirements, or comparison of statements across distant sections may fail when the model sees only the top few chunks.
The main agent should not solve this by loading every complete document into its own context. The main context already contains the user conversation, system instructions, tool definitions, retrieved evidence, and prior tool results. A long manual can crowd out the information the agent needs to coordinate the task and answer clearly.
A subagent provides context isolation. The main agent identifies the correct document, creates a focused task, and delegates the full file to a separate model context. The subagent performs the analysis and returns a compact result. The main agent then integrates that result into the user-facing answer.
A complete document-analysis flow is:
- The user asks a broad question about a document or product.
- The main agent performs document search.
- Search returns a document identifier and supporting chunks.
- The main agent decides that chunk-level evidence is insufficient.
- It calls an analyze-document tool with the document identifier and a clear task.
- The subagent loads the complete parsed document.
- The subagent analyzes, summarizes, extracts, or reviews the file.
- The result returns to the main agent as a tool response.
- The main agent answers the user and preserves conversation continuity.
The subagent has a narrow responsibility. It does not need the complete tool set of the main agent. It needs access to the selected document and the instructions for the analysis. This reduces both context clutter and security exposure.
A product-manual example demonstrates the pattern. The user asks for a summary of a built-in oven and supplies a product code. The main agent uses hybrid search to identify the manual. It then calls the analysis subagent with the document identifier and a request to summarize the appliance. The subagent loads the complete manual and returns a structured summary. Follow-up questions such as whether the appliance can be used outside can use the same conversation history and, when necessary, run additional search.
The sequence matters. The main agent should not ask the subagent to load an arbitrary file name without first resolving it to a permitted document record. Search narrows the knowledge base. The database identifier gives the analysis tool an unambiguous and permission-checkable target.
Several implementation failures reveal the importance of this contract.
One failure passed the file name where the analysis tool expected a document identifier. The tool reported that the document was not found or not accessible. The file existed, but the lookup used the wrong field.
Another failure queried a table named public.document_chunks even though the actual schema used a different table name. PostgreSQL reported that the table could not be found in the schema cache. This was ordinary application-code drift, not a retrieval-model failure.
A database-client call also treated a no-content response as an exception. A query using a single-row helper received a 204-style empty result and failed instead of returning no record. The fix required handling an absent row explicitly.
These cases show why subagent debugging needs both model traces and application logs. The main-agent trace can show that analyze-document was called with an identifier and task. The subagent trace can show the model input and result. Server logs are still needed for database-client exceptions, table-name errors, permission failures, and event-stream bugs that occur between the two model calls.
The front end becomes significantly more complex when subagents are introduced. A normal chat can display one user message followed by one assistant stream. An agentic chat may need to display:
- Assistant text before a tool call.
- A tool-call start event.
- Tool arguments or a concise description.
- A running state.
- Tool completion.
- A tool result.
- Subagent start.
- Subagent reasoning-tag content when available.
- Subagent output.
- Additional main-agent reasoning.
- More tool calls.
- Final assistant text.
- Errors or cancellation.
These events arrive over time and must remain in chronological order. The renderer should not treat the final assistant message as one undifferentiated text block.
A practical event model assigns each event a type, identifier, parent relationship, sequence position, status, and content. Parent relationships are important for nested activity. An analyze-document tool call can contain subagent reasoning and output. The interface can group this activity in an expandable step while preserving its position in the conversation.
The exact event names can differ. The key is that the protocol distinguishes assistant text, reasoning segments, tool activity, subagent activity, errors, and completion instead of forcing the browser to infer structure from one text stream.
Reasoning-tag behavior varies by model. A Qwen 3 32-billion model emitted explicit think tags. A Qwen vision-language mixture-of-experts model did not use the same format. A cloud model produced another streaming pattern. The interface cannot assume that every provider begins with a reasoning block or returns identical tags.
When reasoning tags exist, they can be rendered as a separate expandable thought-process panel. When they do not exist, the assistant output should render normally. Multiple reasoning segments in one turn must create multiple panels in the correct positions. A later reasoning segment should not cause the first panel to jump below a tool result.
Several rendering bugs appeared during implementation:
- Tool calls appeared above earlier assistant text instead of below it.
- A tool call did not receive a completed state.
- Completed tool steps disappeared when the final answer arrived.
- Subagent output appeared both inside the subagent panel and again as main-agent text.
- A reasoning panel moved to the bottom after the subagent completed.
- Multiple think segments were merged or duplicated.
- The page jumped as streamed elements were reordered.
These were not cosmetic defects. They changed the user's understanding of what the agent did. A trustworthy interface should show the actual sequence: what the agent said, what it searched, what the subagent analyzed, and what answer followed.
Tool names and concise arguments should be visible. A generic label such as "one step completed" is less useful than "Search documents: built-in oven product code" or "Analyze document: summarize installation and safety requirements." The user does not need raw internal payloads, but enough transparency is needed to understand the evidence path.
Live events must also be persisted. An early interface displayed tool calls correctly during the active stream, but the information disappeared after refresh or when the user reopened an older thread. The events existed only in browser memory.
A structured JSONB field in the messages table can store the event history for each assistant turn. The saved record can include tool calls, results, subagent activity, and reasoning panels where appropriate. When the thread is reloaded, the browser reconstructs the same sequence.
The structured tool and subagent activity should be saved with the message so the same sequence can be reconstructed when the thread is opened again.
Conversation memory must remain compatible with tool events. The language model may need prior user and assistant text, but it does not necessarily need every rendering detail. The application can preserve a model-facing message history and a richer display history. Tool results that influence later questions should remain available to the model in an appropriate summarized or structured form.
Follow-up behavior proves whether memory works. After a full oven summary, the user asks, "Can this be used outside?" The agent should understand that "this" refers to the oven. It can use the prior document identity and run a focused search rather than start from nothing. Another follow-up asking whether it can be used in the United States may require document search and possibly external information, depending on what the manual contains.
Subagents and tool loops also interact. The main agent may perform search, call the subagent, receive the result, think again, and then answer. The application must count tool rounds correctly without treating every streamed fragment as a new round. The final-synthesis rule still applies if the sequence ends on a tool result.
The front end needs several supporting controls:
- A stop button that cancels a live stream and related work.
- A visible loading state.
- Stable scrolling during long tool sequences.
- A fixed user menu even when the thread list grows.
- Dynamic thread titles.
- Markdown rendering for final answers.
- Light and dark modes.
- Clear error messages.
- Expand and collapse behavior for steps.
Dark mode revealed a minor but representative asset issue. A logo designed for a light background did not display correctly on a dark surface. A separate dark-compatible asset was needed. Agentic features do not remove normal front-end responsibilities.
Subagent model choice can differ from main-agent model choice. A larger model may be used for full-document analysis while a faster model handles ordinary chat. A local model can analyze private documents without external transfer. The configuration should make these choices explicit rather than assuming one model is ideal for every role.
Practical subagent and interface rules:
- Search first and resolve the exact document identifier.
- Give the subagent a narrow task and only the required document.
- Keep the main context focused on coordination and final synthesis.
- Separate model traces from application logs.
- Use a typed chronological event protocol.
- Render subagent content only in its intended container.
- Support models with and without reasoning tags.
- Persist tool and subagent events for thread reload.
- Preserve document identity across follow-up questions.
- Use whole-document analysis only when chunk-level evidence is insufficient.