Implementing Local Agentic Workflows: Leveraging Ollama Inference Servers and Pydantic AI for Tool-Calling Autonomy
The paradigm of Large Language Model (LLM) interaction is shifting from centralized, API-dependent cloud architectures toward localized, edge-based inference. This transition offers significant advantages in terms of data privacy, latency reduction, and the elimination of per-token operational costs. By utilizing tools like Ollama for model orchestration and Pydability AI for agentic logic, developers can construct sophisticated, autonomous agents capable of executing local system commands through tool-calling—all without an internet connection.
The Infrastructure: Local Inference via Ollama
The foundation of a local AI ecosystem is the inference engine. In this implementation, we utilize Ollama, a streamlined framework designed to manage and serve LLMs locally. Ollama functions as a localized inference server, exposing an API endpoint (typically on localhost:11434) that allows external Python applications to dispatch prompts and receive structured responses.
Hardware Constraints and Memory Management
When deploying local models, the primary bottleneck is not raw compute power, but rather available memory—specifically VRAM (Video RAM) for discrete GPUs or Unified Memory for Apple Silicon architectures.
The selection of a model must be strictly governed by your hardware's memory ceiling:
- Discrete GPU Architectures (e.g., NVIDIA RTX 4/5 series): Performance is dictated by the capacity of the dedicated VRAM. For instance, an NVIDIA RTX 4090 with 24GB of VRAM can comfortably host larger parameter models or higher-quantization versions of medium-sized models without falling back to much slower system RAM.
- Unified Memory Architectures (Apple Silicon): On macOS devices, the CPU and GPU share a single pool of memory. Modern Macs with configurations ranging from 16GB to 128GB of unified memory allow for the execution of significantly larger models than many consumer-grade Windows desktops, provided the model weights fit within the allocated RAM.
Model Selection Strategy: Gwen 3.5 and Parameter Scaling
To ensure high-speed inference (tokens per second), it is often optimal to utilize smaller parameter models. For this implementation, we focus on the Gwen 3.5 and Gwen 3 families. These models are categorized by their parameter counts, which directly correlate with both reasoning capability and memory footprint:
- Gwen 3.5 Series: Available in 0.8B, 2B, and 4B parameter variants.
- Gwen 3 Series: Includes highly optimized versions at 0.6B, 1.7B, and 4B parameters.
A smaller model (e.g., the 0.8B variant) will provide near-instantaneous response times but may struggle with complex logic or tool-calling accuracy. Conversely, a 4B parameter model offers more robust reasoning at the cost of increased latency and higher VRAM utilization. The deployment command ollama pull [model_name] handles the retrieval of these weights from the local registry.
Developing the Agentic Layer with Pydantic AI
While Ollama provides the "brain" (the inference engine), we require an orchestration layer to transform a simple chat interface into an Agent. An agent is characterized by its ability to interact with the external environment via Tools—Python functions that the model can invoke autonomously.
Environment Setup
The implementation relies on Python and the pydantic-ai library. This library is particularly powerful because it leverages Pydantic's robust type-checking capabilities to facilitate seamless tool-calling between the LLM and the local Python environment.
pip install pydantic-ai
# Or using uv for faster dependency management
uv pip install pydantic-ai
Connecting to the Inference Server
The first step in our agent.py script is establishing a connection to the Ollama provider. We point our client to the local inference server running on localhost:11able434. This allows us to treat the local model as if it were a remote API, while maintaining total data sovereignty.
from pydantic_ai import Agent, Model
from pydantic_ai.models.ollama import OllamaModel
# Defining the connection to the local inference server
model = OllamaModel(model_name='gwen3.5:4b', base_url='http://localhost:11434')
Implementing Tool-Calling via Function Injection
The core of agentic autonomy lies in "Tools." In Python, these are standard functions decorated or passed to the agent. The pydantic-ai framework utilizes type inference; it inspects the function signatures (arguments and return types) and automatically generates the JSON schema required by the LLM to understand how to call that tool.
In our implementation, we define several primitive tools:
- Temporal Tools:
get_current_time()to allow the agent to ground its responses in real-world time. - Computational Tools:
calculate_expression(expression: str)for executing precise arithmetic without LLM hallucination. - File I/O Tools:
save_note(content: str, filename: str)andread_note(filename: str). These allow the agent to persist state and interact with the local filesystem.
By providing these functions to the Agent object, we grant the model "hands" to manipulate the host system.
The Orchestration Loop and State Management
An agent must maintain context across a conversation. This is achieved through a Message History mechanism. In our implementation, we utilize a while loop that serves as the primary execution thread:
- User Input: Capture input via the standard terminal interface.
- Context Injection: The current user prompt is appended to a hidden history of all previous interactions (system prompts, tool calls, and model responses).
- Inference Request: The entire message history is sent to the Ollama server.
- Tool Execution & Feedback Loop: If the model decides to call a tool (e.g.,
save_note), the Python script executes the function locally and sends the result back to the model as a new message in the history. - Termination: The loop continues until an explicit exit command is received.
Conclusion: The Future of Local Autonomy
Building a local agent using Ollama and Pydantic AI demonstrates that high-performance, autonomous computing does not require massive cloud expenditures. By optimizing model selection based on VRAM/Unified Memory availability and leveraging the type-safe tool-calling capabilities of Pydantic AI, developers can create private, incredibly fast, and highly capable agents that reside entirely within their own infrastructure.