<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: armando salles</title>
    <description>The latest articles on DEV Community by armando salles (@armando_salles_3371ba0851).</description>
    <link>https://dev.to/armando_salles_3371ba0851</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3939823%2F55f00460-d623-427c-8a0e-74a7d19cefff.jpg</url>
      <title>DEV Community: armando salles</title>
      <link>https://dev.to/armando_salles_3371ba0851</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/armando_salles_3371ba0851"/>
    <language>en</language>
    <item>
      <title>Building a Multi-Agent Clinical Research System with LangGraph, DeepSeek and Tavily</title>
      <dc:creator>armando salles</dc:creator>
      <pubDate>Tue, 19 May 2026 08:54:43 +0000</pubDate>
      <link>https://dev.to/armando_salles_3371ba0851/building-a-multi-agent-clinical-research-system-with-langgraph-deepseek-and-tavily-5eem</link>
      <guid>https://dev.to/armando_salles_3371ba0851/building-a-multi-agent-clinical-research-system-with-langgraph-deepseek-and-tavily-5eem</guid>
      <description>&lt;h1&gt;
  
  
  Building a Multi-Agent Clinical Research System with LangGraph, DeepSeek and Tavily
&lt;/h1&gt;

&lt;p&gt;Imagine asking a complex medical question and having a network of AI agents research the web, critique the quality of their own findings, and only write the final report after you personally approve the evidence. That is exactly what I built.&lt;/p&gt;

&lt;p&gt;In this article I'll walk through the architecture, the key decisions, and the code that makes it work.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Clinicians, researchers, and health operators spend hours reviewing scientific literature before making decisions. The question was: can a multi-agent AI system do this reliably, with quality control built in?&lt;/p&gt;

&lt;h2&gt;
  
  
  The Architecture
&lt;/h2&gt;

&lt;p&gt;The system runs a LangGraph StateGraph with 4 specialized agents:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Orchestrator&lt;/strong&gt; — initializes state and coordinates the flow&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Researcher&lt;/strong&gt; — searches the web via Tavily and PubMed (up to 3 rounds)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Critic&lt;/strong&gt; — evaluates data quality and loops back if insufficient&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Writer&lt;/strong&gt; — generates the final structured clinical report&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why LangGraph over CrewAI?
&lt;/h2&gt;

&lt;p&gt;LangGraph gives explicit control over graph edges, state transitions, and interrupt points. In a clinical context, predictability matters more than convenience. CrewAI abstracts too much — LangGraph lets you see exactly what runs, when, and why.&lt;/p&gt;

&lt;h2&gt;
  
  
  The State
&lt;/h2&gt;

&lt;p&gt;The most important design decision in the state is the &lt;code&gt;operator.add&lt;/code&gt; annotation on &lt;code&gt;research_data&lt;/code&gt;. LangGraph overwrites state fields by default. Without this, each research round would erase the previous one. The annotation tells LangGraph to append instead — building cumulative context across revision cycles.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;TypedDict&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Dict&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Annotated&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;operator&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AgentState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TypedDict&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;research_data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Annotated&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Dict&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;]],&lt;/span&gt; &lt;span class="n"&gt;operator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;critic_feedback&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;revision_count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;
    &lt;span class="n"&gt;final_report&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;is_sufficient&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  The Critic Agent — The Key Design Decision
&lt;/h2&gt;

&lt;p&gt;The Critic is what separates this system from a simple RAG pipeline. It receives the research data and asks: Is the evidence recent enough? Are there contradictions between sources? Is the population studied the right one?&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;critic_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;AgentState&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;You are a Medical Critic. 
    Evaluate if this research is sufficient for the query.
    Query: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;query&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;
    Research Data: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;research_data&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;
    Respond ONLY with valid JSON:
    {{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;is_sufficient&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;: true, &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;feedback&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;your feedback&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;}}&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

    &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;llm_deepseek&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nc"&gt;HumanMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;)])&lt;/span&gt;
    &lt;span class="n"&gt;parsed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;is_sufficient&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;parsed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;is_sufficient&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;critic_feedback&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;parsed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;feedback&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;If the Critic returns &lt;code&gt;is_sufficient: false&lt;/code&gt;, the graph sends the Researcher back for another round — up to 3 times maximum to prevent infinite loops.&lt;/p&gt;
&lt;h2&gt;
  
  
  Human-in-the-Loop
&lt;/h2&gt;

&lt;p&gt;This is the most critical safety feature. Before the Writer generates the final report, the graph pauses and presents the collected evidence to the user.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;clinical_app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;workflow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;checkpointer&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nc"&gt;MemorySaver&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="n"&gt;interrupt_before&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;writer&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;clinical_app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;aget_state&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;ans&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Approve research and generate report? (y/n): &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;ans&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;y&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;clinical_app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;astream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;writer&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;report&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;writer&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;final_report&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;When the user types &lt;code&gt;y&lt;/code&gt;, the graph resumes from the checkpoint using &lt;code&gt;MemorySaver&lt;/code&gt; — no data is lost between the pause and the resume.&lt;/p&gt;
&lt;h2&gt;
  
  
  Real Test Query
&lt;/h2&gt;

&lt;p&gt;I ran the system with this query:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Latest evidence on semaglutide for obesity treatment in CKD patients?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The Critic agent referenced the 2024 FLOW trial in its evaluation — the AI didn't just search, it questioned the quality and specificity of what it found. The final report is available in the repository as &lt;code&gt;clinical_report.md&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Terminal Output
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;🎯 Orchestrator: Iniciando pipeline...
🔬 Researcher: Rodada 1 de pesquisa...
   🔧 Usando ferramenta: tavily_search
   🔧 Usando ferramenta: pubmed_mock_search
🧐 Critic: Avaliando qualidade dos dados...
   ✅ Suficiente: True
--- Executing: __interrupt__ ---

Aprovar pesquisa e gerar relatório? (y/n): y
✍️  Writer: Gerando relatório clínico...
✅ Relatório gerado: clinical_report.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;LangGraph&lt;/strong&gt; — stateful multi-agent orchestration&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LangChain&lt;/strong&gt; — LLM abstractions and tool calling&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DeepSeek&lt;/strong&gt; — cost-efficient OpenAI-compatible LLM&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tavily&lt;/strong&gt; — AI-optimized real web search&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pydantic&lt;/strong&gt; — structured outputs&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Python 3.14&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Full Repository
&lt;/h2&gt;

&lt;p&gt;Complete code, architecture decisions, and the AI-generated clinical report example:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/Armandogith" rel="noopener noreferrer"&gt;
        Armandogith
      &lt;/a&gt; / &lt;a href="https://github.com/Armandogith/langgraph-research-orchestrator" rel="noopener noreferrer"&gt;
        langgraph-research-orchestrator
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;🧬 LangGraph Clinical Research Orchestrator&lt;/h1&gt;
&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;Multi-Agent AI system for clinical evidence surveillance.&lt;br&gt;
Built with LangGraph, DeepSeek and Tavily.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;How it works&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;You ask a complex medical question. A network of AI agents researches, critiques
and only writes the report when the data quality is approved — by both the Critic
agent and a human reviewer.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Agent Flow&lt;/h2&gt;

&lt;/div&gt;

  &lt;div class="js-render-enrichment-target"&gt;
    &lt;div class="render-plaintext-hidden"&gt;
      &lt;pre&gt;graph TD
    A([START]) --&amp;gt; B[🎯 Orchestrator]
    B --&amp;gt; C[🔬 Researcher\nTavily + PubMed]
    C --&amp;gt; D[🧐 Critic\nEvaluates quality]
    D --&amp;gt;|Not sufficient| C
    D --&amp;gt;|Approved| E{👤 Human Review\nHITL}
    E --&amp;gt;|y| F[✍️ Writer\nMarkdown Report]
    F --&amp;gt; G([END])
&lt;/pre&gt;
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;span class="js-render-enrichment-loader d-flex flex-justify-center flex-items-center width-full"&gt;
    &lt;span&gt;
  
    
    
    &lt;span class="sr-only"&gt;Loading&lt;/span&gt;
&lt;/span&gt;
  &lt;/span&gt;


&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Agents&lt;/h2&gt;

&lt;/div&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Agent&lt;/th&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Orchestrator&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Initializes state and coordinates the flow&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Researcher&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Searches web via Tavily + PubMed mock&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Critic&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Evaluates data quality — loops back if insufficient&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Writer&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Generates final structured clinical report&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Key Technical Decisions&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;LangGraph over CrewAI&lt;/strong&gt; — explicit control over edges, state and interrupts&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;operator.add&lt;/code&gt; on &lt;code&gt;research_data&lt;/code&gt;&lt;/strong&gt; — append-only accumulation across revisions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;interrupt_before=["writer"]&lt;/code&gt;&lt;/strong&gt; — human…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/Armandogith/langgraph-research-orchestrator" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Real PubMed API integration (replace mock)&lt;/li&gt;
&lt;li&gt;FastAPI endpoint to serve queries via HTTP&lt;/li&gt;
&lt;li&gt;Weekly monitoring mode with alerts on new studies&lt;/li&gt;
&lt;li&gt;Multi-condition support — configurable per user&lt;/li&gt;
&lt;li&gt;Output variants — technical for doctors, simplified for patients&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;If you're building with LangGraph or multi-agent systems, I'd love to connect. Drop a comment below or find me on &lt;a href="https://www.linkedin.com/in/armando-oliveira" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>landgraph</category>
      <category>python</category>
      <category>agents</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
