Hermes is NousResearch's open-source model family trained specifically for function calling and agentic workflows. This guide covers running Hermes locally, defining tools in JSON Schema, and building a basic tool-calling loop.
NousResearch Hermes models are fine-tuned on top of Llama and Mistral base models specifically for function calling, structured JSON output, and agentic reasoning. They follow the function-calling format precisely and are less likely to hallucinate tool names or arguments compared to general-purpose models.
Hermes 3 (based on Llama 3.1 70B) supports parallel tool calling, meaning it can request multiple tool executions in a single response turn — critical for efficient agent loops. It also supports the 'thought' field in tool call responses for chain-of-thought reasoning before function execution.
Pull the Hermes 3 8B model: `ollama pull hermes3:8b`. For better function-calling accuracy, use the larger 70B: `ollama pull hermes3:70b` (requires 40+ GB unified memory or VRAM).
Hermes supports the same OpenAI-compatible chat completion format that Ollama exposes at `/v1/chat/completions`. This means any OpenAI SDK client can drive it without code changes.
Tools are defined as JSON Schema objects passed in the `tools` field of the chat completion request. Each tool has a name, description, and parameters schema. The description is critical — write it as you would write a docstring for a senior developer. The model uses it to decide when to call the function.
Example tool definition in Python: pass a `tools` list to the SDK with entries like `{"type": "function", "function": {"name": "get_weather", "description": "Get the current weather for a city", "parameters": {"type": "object", "properties": {"city": {"type": "string"}}, "required": ["city"]}}}`.
The basic agentic loop has four steps: (1) send the user's message plus available tools to the model; (2) check if the response contains a `tool_calls` field; (3) execute each tool call with your actual implementation and collect results; (4) send the tool results back to the model as messages with role 'tool' and re-request a final response.
Repeat until the model returns a response with no tool calls — this is the final answer. Use a maximum iteration count (e.g. 10) as a safety limit to prevent infinite loops if the model gets stuck.
Define two tools: `search_web(query: str) -> str` and `get_page_content(url: str) -> str`. In your implementation, `search_web` calls a search API (DuckDuckGo, SerpAPI) and returns a JSON list of results. `get_page_content` fetches a URL and returns the cleaned text.
Prompt the model: 'Find the current price of Bitcoin and summarise the most recent news about it.' Hermes will call `search_web`, receive results, call `get_page_content` on relevant URLs, then synthesise a final answer. This three-turn exchange takes around 3–5 seconds with the 8B model locally.
For tasks where you want structured JSON output without function calling, Hermes supports the `response_format: {type: 'json_object'}` option. Pair this with a system prompt that specifies the exact JSON schema you want. Hermes reliably produces valid JSON that matches the described schema.
This is useful for data extraction, classification, and parsing tasks where you need machine-readable output. Example: 'Extract all person names, company names, and dates from this text and return them as JSON with arrays for each entity type.'
ReAct (Reason + Act) is the foundational pattern for LLM agents. This guide builds a working ReAct agent from scratch using the OpenAI API and function calling, with a web search and calculator tool.
Read guideLangGraph is LangChain's framework for building stateful, multi-agent workflows as directed graphs. This guide covers graph basics, state management, and building a practical multi-agent pipeline.
Read guide