feat: Add Multi-Agent Self-Correcting Workflow sample using LangGraph#2980
feat: Add Multi-Agent Self-Correcting Workflow sample using LangGraph#2980geetaarora-google wants to merge 3 commits into
Conversation
There was a problem hiding this comment.
Nit: We generally try to use raw mermaid diagrams for flowcharts instead of images. They're more portable and use less storage. I've added a suggestion for putting this inline in the notebook.
| }, | ||
| "outputs": [], | ||
| "source": [ | ||
| "# Copyright 2024 Google LLC\n", |
There was a problem hiding this comment.
| "# Copyright 2024 Google LLC\n", | |
| "# Copyright 2026 Google LLC\n", |
| "id": "34aeaf2d" | ||
| }, | ||
| "source": [ | ||
| " Author(s) : [Geeta Arora](https://github.com/geetaarora-google) " |
There was a problem hiding this comment.
Please use the notebook structure from the notebook template. Put the author below the title and links
https://github.com/GoogleCloudPlatform/generative-ai/blob/main/notebook_template.ipynb
| "3. **Drafting:** The `Editor` agent receives the original document *and* the Ground Truth notes, rewriting the document strictly using the verified facts.\n", | ||
| "4. **Self-Correction:** The `Reviewer` acts as a harsh critic. If it spots a hallucination, it rejects the draft and **forces the workflow back to the Editor** until the draft is perfect.\n", | ||
| "\n", | ||
| "<img src=\"images/multi-agent_auto-correcting_flowchart.png\" width=\"200\" alt=\"Flowchart\">\n", |
There was a problem hiding this comment.
Use an in-line mermaid diagram instead of an embedded image
Example
flowchart LR
%% Define the shapes
Raw[Raw Document]
Extractor(Extractor Node)
Researcher(Researcher Node)
Editor(Editor Node)
Reviewer{Reviewer Node}
END((END))
%% Define the transitions and labels
Raw --> Extractor
Extractor --> Researcher
Researcher -->|Tool: query_internal_wiki| Editor
Editor --> Reviewer
Reviewer -->|Approved: False| Editor
Reviewer -->|Approved: True| END
| "Configure your Gemini API key. If you are running this in Colab, you can use the built-in secrets manager, or input it manually below." | ||
| ] | ||
| }, | ||
| { | ||
| "cell_type": "code", | ||
| "execution_count": null, | ||
| "metadata": { | ||
| "id": "3de45f39" | ||
| }, | ||
| "outputs": [], | ||
| "source": [ | ||
| "import os\n", | ||
| "import getpass\n", | ||
| "\n", | ||
| "if \"GOOGLE_API_KEY\" not in os.environ:\n", | ||
| " os.environ[\"GOOGLE_API_KEY\"] = getpass.getpass(\"Enter your Google Gemini API Key: \")" |
There was a problem hiding this comment.
This repository is specifically for Gemini on Agent Platform. Please change this to use the Enterprise version. See auth setup in the notebook template.
https://github.com/GoogleCloudPlatform/generative-ai/blob/main/notebook_template.ipynb
Also set these environment variables
export GOOGLE_GENAI_USE_ENTERPRISE=true
export GOOGLE_CLOUD_PROJECT='your-project-id'
export GOOGLE_CLOUD_LOCATION='global'| "from langchain_google_genai import ChatGoogleGenerativeAI\n", | ||
| "from langchain_core.tools import tool\n", | ||
| "\n", | ||
| "# Initialize Gemini 1.5 Flash (using latest to ensure highest compatibility)\n", |
There was a problem hiding this comment.
| "# Initialize Gemini 1.5 Flash (using latest to ensure highest compatibility)\n", | |
| "# Initialize Gemini 3.5 Flash\n", |
| "from langchain_core.tools import tool\n", | ||
| "\n", | ||
| "# Initialize Gemini 1.5 Flash (using latest to ensure highest compatibility)\n", | ||
| "llm = ChatGoogleGenerativeAI(model=\"gemini-flash-latest\", temperature=0)\n", |
There was a problem hiding this comment.
| "llm = ChatGoogleGenerativeAI(model=\"gemini-flash-latest\", temperature=0)\n", | |
| "llm = ChatGoogleGenerativeAI(model=\"gemini-3.5-flash\")\n", |
As far as I'm aware, latest doesn't work on Agent Platform. Updating to newest flash model.
| "def extractor_node(state: AgentState):\n", | ||
| " print(\"▶ [Extractor] Finding claims...\")\n", | ||
| " prompt = f\"Extract fact-checkable claims from this text. Output ONLY a valid JSON array of strings. Do not output any markdown formatting. Text: {state['original_document']}\"\n", | ||
| " response = llm.invoke([SystemMessage(content=\"You are the Extractor.\"), HumanMessage(content=prompt)])\n", | ||
| " content_str = _get_text(response).replace(\"```json\", \"\").replace(\"```\", \"\").strip()\n", | ||
| " try:\n", | ||
| " claims = json.loads(content_str)\n", | ||
| " if not isinstance(claims, list): claims = [str(claims)]\n", | ||
| " except:\n", | ||
| " claims = [content_str]\n", | ||
| " return {\"extracted_claims\": claims}\n", |
There was a problem hiding this comment.
It's a better practice to use structured output which enforces a JSON Schema.
Overview This PR introduces a new sample notebook demonstrating how to build a multi-agent, self-correcting workflow using langgraph, langchain-google-genai, and the Gemini Flash Latest model.
The fundamental problem with basic AI agents is that asking a single LLM to read a document, research the facts, rewrite the content, and review its own work often leads to hallucinations or skipped instructions. This sample solves that by breaking the workflow into strict, specialized personas that pass a shared state (TypedDict) between them.
Key Additions:
langgraph_multi-agent-rag-and-self-correction.ipynb: A comprehensive, step-by-step Jupyter notebook covering:
Specialized Agent Nodes: Defining strict personas (Researcher, Drafter, Editor, and Reviewer) to handle discrete tasks.
Deterministic Routing: Implementation of a reviewer_router that evaluates a boolean output from the Reviewer agent to determine if the workflow should proceed to the end or route back to the Drafter for self-correction.
State Management: Utilizing LangGraph's StateGraph and TypedDict to act as a shared whiteboard between agents.
Tool Binding: Initializing native search tools bound to Gemini Flash Latest.
multi-agent_auto-correcting_flowchart.png: An architectural diagram visualizing the LangGraph node routing and self-correction loop.
Changes/Fixes:
Motivation To provide developers with a robust, production-like pattern for chaining multiple Gemini calls into a cyclic, self-correcting graph rather than relying on a single zero-shot prompt.
Companion Medium Post: https://medium.com/@geetaarora_9514/if-youve-spent-any-time-building-with-llms-you-ve-likely-run-into-a-frustrating-wall-ask-a-39895adc8736