DEV Community

Kasi Yaswanth
Kasi Yaswanth

Posted on

LangGraph API Failure

We've all been there - you've built an agentic AI system using LangGraph and MCP, and it's been humming along just fine, until one day, a third-party API that one of your MCP Tool primitives relies on suddenly changes its response format. Your agent, which was previously adapting beautifully to user input, is now stuck in an infinite loop, unable to recover from the unexpected API response. This is exactly what happened to us recently, and in this post, we'll dive into the postmortem analysis of the failure, and explore strategies for implementing robustness against similar failures in the future.

The specific issue we encountered was with an MCP Tool primitive that used the Google Maps API to get the current traffic conditions. The primitive was designed to adapt to changes in traffic conditions by adjusting the recommended route accordingly. However, when the Google Maps API suddenly changed its response format, our primitive was unable to parse the response, and our LangGraph agent was unable to adapt to the new format. The agent kept trying to execute the primitive, but the primitive kept failing, causing the agent to loop indefinitely.

To understand why this happened, let's take a look at the code for the MCP Tool primitive:

import json
from mcp import Tool

class TrafficConditions(Tool):
    def __init__(self, api_key):
        self.api_key = api_key

    def execute(self, context):
        url = f"https://maps.googleapis.com/maps/api/traffic/json?key={self.api_key}"
        response = requests.get(url)
        data = json.loads(response.content)
        traffic_conditions = data["traffic"]["conditions"]
        context["traffic_conditions"] = traffic_conditions
        return context
Enter fullscreen mode Exit fullscreen mode

The issue here is that the primitive assumes a specific response format from the Google Maps API, and when that format changes, the primitive fails. To make the primitive more robust, we can add some error handling to handle unexpected response formats. We can also use the LangGraph add_conditional_edges method to specify alternative edges to take when the primitive fails.

Here's an updated version of the primitive that includes error handling and alternative edges:

import json
from mcp import Tool
from langgraph import StateGraph

class TrafficConditions(Tool):
    def __init__(self, api_key):
        self.api_key = api_key

    def execute(self, context):
        try:
            url = f"https://maps.googleapis.com/maps/api/traffic/json?key={self.api_key}"
            response = requests.get(url)
            data = json.loads(response.content)
            traffic_conditions = data["traffic"]["conditions"]
            context["traffic_conditions"] = traffic_conditions
            return context
        except KeyError:
            # handle unexpected response format
            context["error"] = "Unexpected response format from Google Maps API"
            return context

# create a LangGraph state graph
graph = StateGraph()

# add a node for the TrafficConditions primitive
node = graph.add_node("TrafficConditions", TrafficConditions(api_key="YOUR_API_KEY"))

# add a conditional edge to handle the case where the primitive fails
graph.add_conditional_edges(node, [
    ("error", "Unexpected response format from Google Maps API", "ErrorHandlingNode")
])
Enter fullscreen mode Exit fullscreen mode

In this updated version, we've added a try-except block to handle the case where the Google Maps API returns an unexpected response format. We've also added a conditional edge to specify an alternative edge to take when the primitive fails. This allows the LangGraph agent to adapt to the failure and take a different path.

One practical gotcha to watch out for when implementing robustness against API changes is to make sure to test your primitives and agents thoroughly after making changes. It's easy to introduce new bugs or unexpected behavior when adding error handling or alternative edges, so make sure to test your system thoroughly to ensure that it's working as expected.

As we continue to build and deploy agentic AI systems, we'll encounter more and more complex challenges and failures. Tomorrow, we'll explore another critical aspect of building robust agentic AI systems, and dive deeper into the complexities of designing and implementing adaptive agents that can thrive in a rapidly changing world.

Top comments (0)