How the Ollama LLM Provider Works in Hiring Agent: Implementation Guide
The Ollama LLM provider wraps the local Ollama server via the ollama Python package, sanitizing parameters and enforcing a 32,768-token context window to enable fully offline inference without API keys.
The interviewstreet/hiring-agent repository abstracts language model interactions through a provider pattern. The OllamaProvider class serves as the default fallback implementation when no external GEMINI_API_KEY is configured, allowing the application to run against a locally hosted Ollama server using the standardized interface defined in models.py.
Architecture and Provider Selection
The application decouples LLM selection from business logic using a factory function that instantiates the appropriate provider at runtime.
Runtime Provider Selection Logic
The get_llm_provider function in llm_utils.py determines which implementation to use based on environment variables. If GEMINI_API_KEY is present, it returns a GeminiProvider instance; otherwise, it instantiates OllamaProvider. This design allows seamless switching between cloud and local inference without modifying downstream consumers.
# Inside llm_utils.py
from models import OllamaProvider, GeminiProvider
import os
def get_llm_provider():
# Prefer Gemini if a key is present; otherwise use Ollama
api_key = os.getenv("GEMINI_API_KEY")
if api_key:
return GeminiProvider(api_key)
else:
return OllamaProvider()
The OllamaProvider Class
Defined at models.py#L71-L105, this class implements the provider contract. Its __init__ method imports the ollama library and stores it as self.client, while the chat method normalizes requests and handles communication with the local Ollama HTTP server.
How OllamaProvider.chat Works Internally
The chat method executes a four-stage pipeline to prepare and dispatch requests to localhost:11434.
-
Client Initialization – The constructor imports the
ollamapackage and assigns it toself.client, establishing the connection to the local server. -
Option Sanitization – The method copies the input
optionsdictionary and performs two critical sanitization steps:- Removes any
streamkey, as Ollama's HTTP API does not accept this parameter at the top level - Forces
num_ctxto 32768 to ensure a large, consistent context window across all models
- Removes any
-
Parameter Assembly – It constructs a
chat_paramsdictionary containing:model: The Ollama model name (e.g.,llama2,mistral)messages: The conversation history as a list of{"role": "...", "content": "..."}dictionariesoptions: The sanitized configuration dictionary- Optional keys like
streamandformatpassed via**kwargs
-
Request Dispatch – The method calls
self.client.chat(**chat_params), which performs an HTTP POST to the Ollama server. The raw JSON response is returned directly, maintaining compatibility with the response format expected by other providers.
Implementation Examples
Direct Provider Usage
When working outside the standard evaluator flow, you can instantiate OllamaProvider directly to send chat requests to your local server:
from models import OllamaProvider
# Initialise provider (no API key required)
ollama = OllamaProvider()
# Example conversation
messages = [
{"role": "system", "content": "You are a helpful interview coach."},
{"role": "user", "content": "Give me feedback on my resume summary."},
]
# Optional generation options
options = {"temperature": 0.7, "top_p": 0.9}
# Perform the chat request
response = ollama.chat(
model="llama2", # any model available to your local Ollama server
messages=messages,
options=options,
stream=False, # optional: disable streaming
)
print(response["message"]["content"])
Integration in the Evaluation Pipeline
Higher-level modules like evaluator.py consume the provider through the factory function, remaining agnostic to the underlying implementation:
# evaluator.py (simplified)
def evaluate_resume(resume_text):
provider = get_llm_provider()
prompt = build_prompt(resume_text) # uses Jinja templates
response = provider.chat(
model="llama2",
messages=[{"role": "user", "content": prompt}],
options={"temperature": 0.0},
)
return response["message"]["content"]
Key Source Files
models.py– Contains theOllamaProviderclass implementation and theGeminiProvidercounterpart (source)llm_utils.py– Houses theget_llm_providerfactory function for runtime selection logic (source)evaluator.py– Example consumer that obtains LLM feedback for resume evaluation (source)prompt.py– Assembles Jinja-templated messages passed to the provider'schatmethod (source)
Summary
- The
OllamaProviderclass inmodels.pyenables local LLM inference by wrapping the officialollamaPython package. - Option sanitization automatically removes unsupported
streamparameters and enforces a 32,768-token context window via thenum_ctxsetting. - The
get_llm_providerfunction inllm_utils.pyselectsOllamaProviderautomatically when noGEMINI_API_KEYenvironment variable is present. - Downstream modules remain provider-agnostic, receiving standardized response dictionaries that match the shape of Gemini API responses.
- All communication occurs via HTTP POST to the local Ollama server (typically
localhost:11434/api/chat).
Frequently Asked Questions
What is the default LLM provider in Hiring Agent?
When the GEMINI_API_KEY environment variable is unset, the application defaults to OllamaProvider according to the logic in llm_utils.py. This fallback mechanism ensures the hiring agent can operate entirely offline using locally hosted models without requiring cloud API credentials.
How does the Ollama provider handle streaming responses?
The provider explicitly removes any stream key from the options dictionary during the sanitization phase before dispatching to Ollama's HTTP API. While the underlying ollama Python package supports streaming, the Hiring Agent implementation strips this parameter to maintain compatibility with the synchronous response format expected by the evaluator and other consumers.
What context window size does the Ollama provider use?
According to the source code in models.py, the provider forces a num_ctx value of 32768 tokens during the option sanitization step. This hardcoded default ensures consistent, large context windows across all models regardless of their individual default configurations, supporting evaluation of lengthy resume content.
Can I use OllamaProvider with any local model?
Yes, the model parameter passed to chat() accepts any model name available to your local Ollama server, including llama2, mistral, codellama, or custom fine-tuned models. The provider passes this string directly to the Ollama HTTP API endpoint without validation, allowing immediate access to any model currently pulled in your local Ollama registry.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →