Skip to content
3 min read · 652 words

Data Flow

Two pipelines carry most of the system's complexity. This page shows exactly what data enters, transforms, and persists at every stage of each.

Pipeline 1 — Multi-agent email workflow

POST /agents/{id}/workflows/email · handler in routers/agents.py · agents in services/multi_agent_email_service.py

Rendering diagram…

What is persisted, stage by stage

StageWorkflowStepToolCallOther rows
Analysis Agentanalysis_agent (input: email, output: analysis JSON)multi_agent_analysis_agent with model/tokens/cost estimates
Task Agenttask_agentmulti_agent_task_agent (no cost — no LLM call)one Task per action item
Reply Agentreply_agentmulti_agent_reply_agent with cost estimates
Reviewer Agentreviewer_agentmulti_agent_reviewer_agent with cost estimates
FinalizeWorkflowRun.status/quality_score/final_output updated
On any exceptionworkflow_error step (status failed)multi_agent_email_workflow failed callWorkflowRun.status='failed', error stored; HTTP 500

Cost estimates come from estimate_openai_cost() in monitoring_service.py — a character-based approximation, not billing data (Cost Monitoring).

The full step-by-step narrative, including every prompt, is in Email Workflow.

Pipeline 2 — Corrective RAG

Two phases: ingestion (upload time) and query (ask time).

Ingestion — POST /agents/{id}/documents/upload

Rendering diagram…

SQLite keeps the authoritative record (documents + chunks + vector IDs); Chroma holds the embeddings for search. Details: Ingestion.

Query — POST /agents/{id}/documents/ask

The question runs through a compiled LangGraph StateGraph (Corrective RAG):

Rendering diagram…

One ToolCall named langgraph_corrective_rag records the question, the answer, the sources, and the evaluator verdict.

A plain RAG chain answers no matter how weak retrieval was. Here a dedicated evaluator LLM call (temperature 0) sits between retrieval and generation and routes to a refusal when the context does not actually contain the answer — trading one extra LLM call for a large reduction in hallucinated answers. See Evaluation.

Simple flows (for completeness)

  • Chat — see Request Lifecycle: 2 Message rows + 1 AgentRun per exchange.
  • Email analyze (single-agent) — same Analysis Agent + optional task creation, logged as 1–2 ToolCalls, no WorkflowRun. Compare with the multi-agent version in Email Workflow.
  • Document search — raw vector search without generation: POST .../documents/search returns scored chunks directly (Retrieval).
  • Dashboard — pure read: aggregates tasks, tool calls, and workflow runs in Python (Observability).