Agents Architecture¶
DeepCritical uses Pydantic AI agents for all AI-powered operations. All agents follow a consistent pattern and use structured output types.
Agent Pattern¶
All agents use the Pydantic AI Agent class with the following structure:
- System Prompt: Module-level constant with date injection
- Agent Class:
__init__(model: Any | None = None) - Main Method: Async method (e.g.,
async def evaluate(),async def write_report()) - Factory Function:
def create_agent_name(model: Any | None = None) -> AgentName
Model Initialization¶
Agents use get_model() from src/agent_factory/judges.py if no model is provided. This supports:
- OpenAI models
- Anthropic models
- HuggingFace Inference API models
The model selection is based on the configured LLM_PROVIDER in settings.
Error Handling¶
Agents return fallback values on failure rather than raising exceptions:
KnowledgeGapOutput(research_complete=False, outstanding_gaps=[...])- Empty strings for text outputs
- Default structured outputs
All errors are logged with context using structlog.
Input Validation¶
All agents validate inputs:
- Check that queries/inputs are not empty
- Truncate very long inputs with warnings
- Handle None values gracefully
Output Types¶
Agents use structured output types from src/utils/models.py:
KnowledgeGapOutput: Research completeness evaluationAgentSelectionPlan: Tool selection planReportDraft: Long-form report structureParsedQuery: Query parsing and mode detection
For text output (writer agents), agents return str directly.
Agent Types¶
Knowledge Gap Agent¶
File: src/agents/knowledge_gap.py
Purpose: Evaluates research state and identifies knowledge gaps.
Output: KnowledgeGapOutput with: - research_complete: Boolean indicating if research is complete - outstanding_gaps: List of remaining knowledge gaps
Methods: - async def evaluate(query, background_context, conversation_history, iteration, time_elapsed_minutes, max_time_minutes) -> KnowledgeGapOutput
Tool Selector Agent¶
File: src/agents/tool_selector.py
Purpose: Selects appropriate tools for addressing knowledge gaps.
Output: AgentSelectionPlan with list of AgentTask objects.
Available Agents: - WebSearchAgent: General web search for fresh information - SiteCrawlerAgent: Research specific entities/companies - RAGAgent: Semantic search within collected evidence
Writer Agent¶
File: src/agents/writer.py
Purpose: Generates final reports from research findings.
Output: Markdown string with numbered citations.
Methods: - async def write_report(query, findings, output_length, output_instructions) -> str
Features: - Validates inputs - Truncates very long findings (max 50000 chars) with warning - Retry logic for transient failures (3 retries) - Citation validation before returning
Long Writer Agent¶
File: src/agents/long_writer.py
Purpose: Long-form report generation with section-by-section writing.
Input/Output: Uses ReportDraft models.
Methods: - async def write_next_section(query, draft, section_title, section_content) -> LongWriterOutput - async def write_report(query, report_title, report_draft) -> str
Features: - Writes sections iteratively - Aggregates references across sections - Reformats section headings and references - Deduplicates and renumbers references
Proofreader Agent¶
File: src/agents/proofreader.py
Purpose: Proofreads and polishes report drafts.
Input: ReportDraft Output: Polished markdown string
Methods: - async def proofread(query, report_title, report_draft) -> str
Features: - Removes duplicate content across sections - Adds executive summary if multiple sections - Preserves all references and citations - Improves flow and readability
Thinking Agent¶
File: src/agents/thinking.py
Purpose: Generates observations from conversation history.
Output: Observation string
Methods: - async def generate_observations(query, background_context, conversation_history) -> str
Input Parser Agent¶
File: src/agents/input_parser.py
Purpose: Parses and improves user queries, detects research mode.
Output: ParsedQuery with: - original_query: Original query string - improved_query: Refined query string - research_mode: "iterative" or "deep" - key_entities: List of key entities - research_questions: List of research questions
Factory Functions¶
All agents have factory functions in src/agent_factory/agents.py:
def create_knowledge_gap_agent(model: Any | None = None) -> KnowledgeGapAgent
def create_tool_selector_agent(model: Any | None = None) -> ToolSelectorAgent
def create_writer_agent(model: Any | None = None) -> WriterAgent
# ... etc
Factory functions: - Use get_model() if no model provided - Raise ConfigurationError if creation fails - Log agent creation
See Also¶
- Orchestrators - How agents are orchestrated
- API Reference - Agents - API documentation
- Contributing - Code Style - Development guidelines