a neighborhood LLM. Good.
However after the primary few chats, you is perhaps questioning: what else can I do with it?
Nicely, how about making the native LLM agentic with some instrument use?
On this publish, we’ll discover how you can flip a neighborhood LLM right into a tool-using agent. Particularly, we’ll use
- Gemma 4 mannequin (edge-friendly variants) as our native LLM
- Ollama for serving the native LLM
- OpenAI Brokers SDK for the agent runtime
- Tavily net search MCP as one instance of the exterior instrument
We’ll construct a mini deep analysis agent that may search the net, collect the proof, and synthesize a solution with citations, given a person query.
By the top of the publish, you’d have a working native deep analysis agent and a reusable implementation sample for turning a neighborhood mannequin into a neighborhood AI agent.

If you’re enthusiastic about a neighborhood coding-agent setup, I beforehand lined Gemma 4 + OpenCode. On this publish, we concentrate on the extra normal sample of connecting a neighborhood mannequin to an agent runtime and exterior instruments.
1. Set Up the Native Agent Stack
We have to put together 4 items earlier than we write the code: Ollama, Gemma 4 (particularly the Gemma 4 E4B mannequin), OpenAI Brokers SDK, and Tavily MCP.
First, let’s set up Ollama.
On Home windows, you possibly can obtain the installer from the official Ollama web site:
https://ollama.com/obtain
Or use winget in PowerShell:
winget set up Ollama.Ollama
On Linux, Ollama might be put in with:
"curl -fsSL https://ollama.com/set up.sh | sh"
After set up, please examine:
ollama --version
On Home windows, keep in mind to launch Ollama from the Begin menu. As soon as it’s operating, the native API endpoint is out there.
Subsequent, we pull the native mannequin. Right here, we use Gemma 4 E4B variant:
ollama pull gemma4:e4b
Gemma 4 has a number of variants. The E4B mannequin is an efficient match for our goal, as it’s designed with edge/native agentic workflows in thoughts. My machine has an NVIDIA RTX 2000 Ada Laptop computer GPU with about 8 GB VRAM. In case your machine is extra constrained, you possibly can attempt the lighter E2B variant:
ollama pull gemma4:e2b
Subsequent, we want the agent runtime library. For that, we use OpenAI Brokers SDK:
pip set up openai-agents
You’d additionally want the OpenAI-compatible shopper:
pip set up openai
One thing to notice right here: later, we’ll level the shopper to Ollama’s native endpoint, so this doesn’t imply we’re sending mannequin calls to OpenAI.
Lastly, we want a Tavily MCP endpoint. In case you haven’t used it earlier than, Tavily is a search API designed for LLM functions. On this publish, we use its MCP server so the agent can search the net.
You’d must first create a Tavily account and get an API key. On the Tavily platform, you possibly can straight generate a MCP hyperlink with the next form:
https://mcp.tavily.com/mcp/?tavilyApiKey=
Now we’re prepared.
Utilizing Tavily right here just isn’t a sponsored selection; it’s used right here as one handy MCP instrument, the identical sample can work with different MCP-compatible instruments as effectively.
In actual fact, the entire stack right here just isn’t the one choice. As a substitute of utilizing Ollama, you might serve the native mannequin with LM Studio or llama.cpp. As a substitute of Gemma 4 fashions, you can even attempt with different fashions from, e.g., Qwen household. For agent framework, we even have choices from Google or Anthropic. You would additionally join totally different MCP instruments as a substitute of Tavily. I take advantage of this mixture just because I’m accustomed to that stack. However the vital takeaway on this case research is the overall native agentic sample.
2. Configure the Native Analysis Agent
With OpenAI Brokers SDK, that is the ultimate Agent object we have to compose:
from brokers import Agent
agent = Agent(
title="Native Analysis Agent",
directions=RESEARCH_AGENT_INSTRUCTIONS,
mannequin=mannequin,
mcp_servers=[tavily_server],
mcp_config={"include_server_in_tool_names": True},
)
Let’s unpack every half.
2.1 The Mannequin
First, the mannequin.
from openai import AsyncOpenAI
from brokers import OpenAIChatCompletionsModel
MODEL_NAME = "gemma4:e4b"
OLLAMA_BASE_URL = "http://localhost:11434/v1"
shopper = AsyncOpenAI(
api_key="ollama",
base_url=OLLAMA_BASE_URL,
)
mannequin = OpenAIChatCompletionsModel(
mannequin=MODEL_NAME,
openai_client=shopper,
)
We begin by making a shopper that factors at Ollama’s native OpenAI-compatible endpoint.
Then, we use OpenAIChatCompletionsModel to wrap the Gemma mannequin right into a mannequin object. This permits the Brokers SDK to make use of that mannequin contained in the agent loop.
Be aware that the api_key="ollama" worth is only a placeholder. Ollama doesn’t really want an actual OpenAI API key. We use it as a result of the shopper expects this subject.
2.2 The Instruction
Subsequent, we outline the instruction for the agent with the specified analysis conduct:
from datetime import datetime
CURRENT_DATE = datetime.now().strftime("%B %d, %Y")
# Be aware that this instruction is iterated with AI
RESEARCH_AGENT_INSTRUCTIONS = f"""
[Role]
You're a concise analysis assistant.
[Task]
Reply the person's query by turning it right into a small net analysis activity.
Use the present date when decoding time-sensitive questions: {CURRENT_DATE}.
[Research behavior]
Begin with one focused search question.
For suggestion or comparability questions, full this analysis loop earlier than answering:
first determine the primary choices, then seek for comparability context, then synthesize a suggestion.
Use follow-up searches when the primary outcomes are inadequate, conflicting, or solely cowl a part of the query.
Choose related and credible sources, and observe which supply helps every vital declare.
Earlier than answering, examine whether or not the gathered proof is sufficient to help the conclusion.
[Expected output]
Give a direct reply first, then briefly clarify the proof behind it.
Embrace supply hyperlinks for key factual claims.
[Rules]
Don't depend on reminiscence for details that will have modified.
Don't invent lacking particulars.
Hold the reply concise.
""".strip()
2.3 The Instruments
Now we equip the agent with the net search instrument. On this case, we use the Tavily search engine by MCP:
from brokers import Agent, Runner
from brokers.mcp import MCPServerStreamableHttp
TAVILY_MCP_URL = "YOUR_TAVILY_MCP_URL"
async with MCPServerStreamableHttp(
title="tavily",
params={"url": TAVILY_MCP_URL},
) as tavily_server:
instruments = await tavily_server.list_tools()
print("Out there Tavily instruments:")
for instrument in instruments:
description = (instrument.description or "").exchange("n", " ")
print(f"- {instrument.title}: {description[:120]}")
agent = Agent(
title="Native Analysis Agent",
directions=RESEARCH_AGENT_INSTRUCTIONS,
mannequin=mannequin,
mcp_servers=[tavily_server],
mcp_config={"include_server_in_tool_names": True},
)
outcome = await Runner.run(agent, RESEARCH_QUESTION, max_turns=MAX_TURNS)
This code block does three issues:
- It opens a connection to Tavily’s MCP server with
async with MCPServerStreamableHttp(...) as tavily_server:As soon as related, Tavily would expose its obtainable instruments to the Brokers SDK. - We create the Agent object contained in the MCP context. Be aware that we’ve got
mcp_servers=[tavily_server], which attaches Tavily’s MCP instruments to the agent. - We lastly run the agent with
outcome = await Runner.run(agent, RESEARCH_QUESTION, max_turns=MAX_TURNS). The context supervisor issues right here as a result of the MCP connection is barely energetic contained in theasync withblock.
mcp_config={"include_server_in_tool_names": True}is principally for readability within the hint. With out it, the instrument title will solely seem astavily_search. With it, the instrument title will present asmcp_tavily__tavily_search. This makes it clearer that the instrument name got here by the Tavily MCP server.
3. Run a Analysis Query
Now that the agent is configured, let’s check it with one concrete query:
“Which June 23, 2026 World Cup match had the most important group-stage stakes, and why?”
To examine what occurred, I print a compact hint:
def compact(worth: object, restrict: int = 220) -> str:
textual content = str(worth).exchange("n", " ")
return textual content if len(textual content) <= restrict else textual content[:limit] + "..."
for step, merchandise in enumerate(outcome.new_items, begin=1):
raw_item = getattr(merchandise, "raw_item", None)
raw_type = getattr(raw_item, "kind", "")
raw_name = getattr(raw_item, "title", "")
raw_output = getattr(raw_item, "output", "")
print(
f"{step:02d} | {kind(merchandise).__name__} | "
f"{raw_type or raw_name} | {compact(raw_output or raw_item)}"
)
In my run, the hint regarded like this:
01 | ToolCallItem | function_call | ResponseFunctionToolCall(arguments='{"question":"World Cup 2026 group stage matches June 23, 2026 stakes"}', title='mcp_tavily__tavily_search', ...)
02 | ToolCallOutputItem | | {'call_id': ..., 'output': ...}
03 | MessageOutputItem | message | ResponseOutputMessage(... ultimate reply ...)
This permits us to see the agentic conduct straight. On this run, the native Gemma mannequin determined to name the Tavily search instrument, the Brokers SDK executed that instrument name, and handed the outcomes again to the mannequin. Then, the mannequin produced the ultimate reply.
To see the ultimate response, we will print:
print(outcome.final_output)
That is what the agent produced:
The match with the most important group-stage stakes on June 23, 2026, was Colombia vs. DR Congo.
Why:
In accordance with FIFA reporting, this particular match was highlighted as a crucial second the place Colombia superior into the knockout part of the match.
The article notes that Daniel Munoz scored the primary objective for Colombia throughout this Group Ok fixture, which straight contributed to their development within the competitors.
Proof
- FIFA: An article titled "Colombia v Congo DR Group Ok FIFA World Cup 2026" particularly studies on a key second from this match, stating that Munoz's objective helped fireplace Colombia into the knockout part.
Supply: https://digitalhub.fifa.com/remodel/450614d3-72d7-4c1f-85ff-ea0fbee6f28d/Colombia-v-Congo-DR-Group-Ok-FIFA-World-Cup-2026?focuspoint=0.51
- Yahoo Sports activities: Confirms the fixture and outcome for that date: Colombia defeated DR Congo.
Supply: https://sports activities.yahoo.com/soccer/article/2026-world-cup-results-standings-and-schedule-live-scores-group-stage-updates-and-how-to-watch-050724193.html
Discover that the agent solely made one search spherical on this run, because the search outcomes already contained sufficient proof for the mannequin to reply. For extra complicated questions, a number of rounds of search and reasoning can be mandatory, and our present framework naturally helps that.
4. Wrapping Up
A neighborhood LLM doesn’t have to remain as a chat mannequin.
On this publish, we deployed a Gemma 4 E4B mannequin domestically by Ollama, then we put the mannequin inside an agent runtime supplied by OpenAI Brokers SDK, and we gave the agent an internet search instrument in order that it may well discover data on-line to reply customers’ questions.
From right here, you possibly can simply lengthen this sample with stronger analysis directions or construct a extra specific planning-reflection workflow, if you wish to hold working within the course of deep analysis, or you possibly can join the agent to extra MCP instruments for a lot of different use circumstances.
Glad constructing!
Reference
Ollama: https://ollama.com/
Gemma mannequin household: https://ai.google.dev/gemma
OpenAI Brokers SDK: https://openai.github.io/openai-agents-python/
Brokers SDK MCP docs: https://openai.github.io/openai-agents-python/mcp/
Tavily MCP docs: https://docs.tavily.com/documentation/mcp















