LangGraph agents need access to live web data to answer current questions, verify facts, and ground their responses. Adding a search tool to a LangGraph graph gives the agent the ability to query Google, Reddit, YouTube, and other platforms on demand. This tutorial shows how to define a Scavio search tool, register it as a LangGraph tool node, and wire it into your agent graph. The agent will be able to call the search tool during execution and receive structured JSON results that it can reason over.
Prerequisites
- Python 3.10+ installed
- langgraph and langchain-core packages installed
- A Scavio API key from scavio.dev
- Basic understanding of LangGraph state graphs
Walkthrough
Step 1: Define the search tool function
Create a tool function that wraps the Scavio API and returns structured results.
import os, requests
from langchain_core.tools import tool
API_KEY = os.environ["SCAVIO_API_KEY"]
@tool
def web_search(query: str) -> str:
"""Search the web for current information."""
resp = requests.post("https://api.scavio.dev/api/v1/search",
headers={"x-api-key": API_KEY},
json={"platform": "google", "query": query})
results = resp.json().get("organic_results", [])[:5]
return "\n".join(f"- {r['title']}: {r.get('snippet', '')}" for r in results)Step 2: Create the agent state and graph
Set up the LangGraph state graph with the search tool bound to the agent node.
from langgraph.graph import StateGraph, MessagesState
from langgraph.prebuilt import ToolNode
from langchain_openai import ChatOpenAI
tools = [web_search]
model = ChatOpenAI(model="gpt-4o-mini").bind_tools(tools)
def agent(state: MessagesState):
return {"messages": [model.invoke(state["messages"])]}
tool_node = ToolNode(tools)Step 3: Wire the graph
Connect agent and tool nodes with conditional routing based on tool calls.
from langgraph.graph import END
def should_continue(state: MessagesState):
last = state["messages"][-1]
return "tools" if last.tool_calls else END
graph = StateGraph(MessagesState)
graph.add_node("agent", agent)
graph.add_node("tools", tool_node)
graph.set_entry_point("agent")
graph.add_conditional_edges("agent", should_continue)
graph.add_edge("tools", "agent")
app = graph.compile()Step 4: Run the agent with a search query
Invoke the agent with a question that requires live web data.
from langchain_core.messages import HumanMessage
result = app.invoke({
"messages": [HumanMessage(content="What are the top CRM tools for startups in 2026?")]
})
print(result["messages"][-1].content)Python Example
import os, requests
from langchain_core.tools import tool
@tool
def web_search(query: str) -> str:
"""Search the web for current information."""
resp = requests.post("https://api.scavio.dev/api/v1/search",
headers={"x-api-key": os.environ["SCAVIO_API_KEY"]},
json={"platform": "google", "query": query})
results = resp.json().get("organic_results", [])[:5]
return "\n".join(f"- {r['title']}: {r.get('snippet', '')}" for r in results)
print(web_search.invoke("best CRM 2026"))JavaScript Example
const H = {"x-api-key": process.env.SCAVIO_API_KEY, "Content-Type": "application/json"};
async function webSearch(query) {
const r = await fetch("https://api.scavio.dev/api/v1/search", {
method: "POST", headers: H,
body: JSON.stringify({platform: "google", query})
});
const results = (await r.json()).organic_results || [];
return results.slice(0,5).map(r => r.title + ": " + (r.snippet||"")).join("\n");
}
console.log(await webSearch("best CRM 2026"));Expected Output
A LangGraph agent that can call a web search tool during execution, receiving structured search results and using them to answer questions with current data.