[{"data":1,"prerenderedAt":1210},["ShallowReactive",2],{"guide-detail-hermes-agent-setup":3},{"id":4,"title":5,"body":6,"category":1196,"description":1197,"difficulty":1198,"extension":1199,"meta":1200,"navigation":116,"path":1201,"published":1202,"readTime":363,"seo":1203,"slug":1204,"stem":1205,"tags":1206,"updated":1202,"__hash__":1209},"guides\u002Fen\u002Fguides\u002Fhermes-agent-setup.md","Running a Hermes Agent Locally",{"type":7,"value":8,"toc":1185},"minimark",[9,14,18,21,42,45,49,68,71,124,127,181,183,187,203,206,231,234,251,253,257,260,665,668,685,687,691,694,895,897,901,904,921,1001,1003,1007,1010,1024,1091,1094,1096,1100,1143,1158,1160,1164,1181],[10,11,13],"h2",{"id":12},"what-is-hermes","What Is Hermes",[15,16,17],"p",{},"Hermes 3 (by Nous Research) is a fine-tune of Llama 3 trained specifically for function calling, structured outputs, and multi-turn agentic workflows. Unlike base Llama 3, Hermes follows a consistent tool-use format and rarely hallucinates tool names.",[15,19,20],{},"Key properties:",[22,23,24,28,36,39],"ul",{},[25,26,27],"li",{},"Supports OpenAI-compatible tool schemas (JSON schema format)",[25,29,30,31,35],{},"Deterministic ",[32,33,34],"code",{},"\u003Ctool_call>"," tag output — easy to parse",[25,37,38],{},"Runs entirely offline via Ollama",[25,40,41],{},"8B parameter variant fits in 8 GB VRAM \u002F 16 GB unified RAM",[43,44],"hr",{},[10,46,48],{"id":47},"prerequisites","Prerequisites",[22,50,51,62,65],{},[25,52,53,54,57,58,61],{},"Ollama installed and running (",[32,55,56],{},"ollama --version"," → ",[32,59,60],{},"0.3+",")",[25,63,64],{},"Python 3.11 or later",[25,66,67],{},"8 GB RAM minimum; 16 GB recommended for comfortable operation",[15,69,70],{},"Install Ollama if not present:",[72,73,78],"pre",{"className":74,"code":75,"language":76,"meta":77,"style":77},"language-bash shiki shiki-themes github-light github-dark","# macOS \u002F Linux\ncurl -fsSL https:\u002F\u002Follama.com\u002Finstall.sh | sh\n\n# Windows: download from https:\u002F\u002Follama.com\u002Fdownload\n","bash","",[32,79,80,89,111,118],{"__ignoreMap":77},[81,82,85],"span",{"class":83,"line":84},"line",1,[81,86,88],{"class":87},"sJ8bj","# macOS \u002F Linux\n",[81,90,92,96,100,104,108],{"class":83,"line":91},2,[81,93,95],{"class":94},"sScJk","curl",[81,97,99],{"class":98},"sj4cs"," -fsSL",[81,101,103],{"class":102},"sZZnC"," https:\u002F\u002Follama.com\u002Finstall.sh",[81,105,107],{"class":106},"szBVR"," |",[81,109,110],{"class":94}," sh\n",[81,112,114],{"class":83,"line":113},3,[81,115,117],{"emptyLinePlaceholder":116},true,"\n",[81,119,121],{"class":83,"line":120},4,[81,122,123],{"class":87},"# Windows: download from https:\u002F\u002Follama.com\u002Fdownload\n",[15,125,126],{},"Create a Python environment:",[72,128,130],{"className":74,"code":129,"language":76,"meta":77,"style":77},"python -m venv .venv\nsource .venv\u002Fbin\u002Factivate     # Linux\u002FmacOS\n# .venv\\Scripts\\activate      # Windows\n\npip install requests          # only stdlib + requests needed for the minimal agent\n",[32,131,132,146,157,162,166],{"__ignoreMap":77},[81,133,134,137,140,143],{"class":83,"line":84},[81,135,136],{"class":94},"python",[81,138,139],{"class":98}," -m",[81,141,142],{"class":102}," venv",[81,144,145],{"class":102}," .venv\n",[81,147,148,151,154],{"class":83,"line":91},[81,149,150],{"class":98},"source",[81,152,153],{"class":102}," .venv\u002Fbin\u002Factivate",[81,155,156],{"class":87},"     # Linux\u002FmacOS\n",[81,158,159],{"class":83,"line":113},[81,160,161],{"class":87},"# .venv\\Scripts\\activate      # Windows\n",[81,163,164],{"class":83,"line":120},[81,165,117],{"emptyLinePlaceholder":116},[81,167,169,172,175,178],{"class":83,"line":168},5,[81,170,171],{"class":94},"pip",[81,173,174],{"class":102}," install",[81,176,177],{"class":102}," requests",[81,179,180],{"class":87},"          # only stdlib + requests needed for the minimal agent\n",[43,182],{},[10,184,186],{"id":185},"pull-the-model","Pull the Model",[72,188,190],{"className":74,"code":189,"language":76,"meta":77,"style":77},"ollama pull hermes3:8b\n",[32,191,192],{"__ignoreMap":77},[81,193,194,197,200],{"class":83,"line":84},[81,195,196],{"class":94},"ollama",[81,198,199],{"class":102}," pull",[81,201,202],{"class":102}," hermes3:8b\n",[15,204,205],{},"Download size: ~5.1 GB (Q4_K_M quantization). After download, verify:",[72,207,209],{"className":74,"code":208,"language":76,"meta":77,"style":77},"ollama list | grep hermes\n# hermes3:8b    ...    5.1 GB\n",[32,210,211,226],{"__ignoreMap":77},[81,212,213,215,218,220,223],{"class":83,"line":84},[81,214,196],{"class":94},[81,216,217],{"class":102}," list",[81,219,107],{"class":106},[81,221,222],{"class":94}," grep",[81,224,225],{"class":102}," hermes\n",[81,227,228],{"class":83,"line":91},[81,229,230],{"class":87},"# hermes3:8b    ...    5.1 GB\n",[15,232,233],{},"For a smaller footprint on machines with 8 GB RAM:",[72,235,237],{"className":74,"code":236,"language":76,"meta":77,"style":77},"ollama pull hermes3:3b   # ~2.1 GB\n",[32,238,239],{"__ignoreMap":77},[81,240,241,243,245,248],{"class":83,"line":84},[81,242,196],{"class":94},[81,244,199],{"class":102},[81,246,247],{"class":102}," hermes3:3b",[81,249,250],{"class":87},"   # ~2.1 GB\n",[43,252],{},[10,254,256],{"id":255},"minimal-agent-script","Minimal Agent Script",[15,258,259],{},"The agent loop below handles tool dispatch manually. No LangChain required.",[72,261,264],{"className":262,"code":263,"language":136,"meta":77,"style":77},"language-python shiki shiki-themes github-light github-dark","# agent.py\nimport json\nimport re\nimport requests\n\nOLLAMA_URL = \"http:\u002F\u002Flocalhost:11434\u002Fapi\u002Fchat\"\nMODEL = \"hermes3:8b\"\n\nTOOLS = [\n    {\n        \"type\": \"function\",\n        \"function\": {\n            \"name\": \"get_weather\",\n            \"description\": \"Returns current weather for a city.\",\n            \"parameters\": {\n                \"type\": \"object\",\n                \"properties\": {\n                    \"city\": {\"type\": \"string\", \"description\": \"City name\"}\n                },\n                \"required\": [\"city\"]\n            }\n        }\n    }\n]\n\ndef get_weather(city: str) -> str:\n    # Replace with a real API call in production\n    return json.dumps({\"city\": city, \"temp_c\": 18, \"condition\": \"cloudy\"})\n\nTOOL_REGISTRY = {\"get_weather\": get_weather}\n\ndef chat(messages: list, tools: list) -> dict:\n    response = requests.post(OLLAMA_URL, json={\n        \"model\": MODEL,\n        \"messages\": messages,\n        \"tools\": tools,\n        \"stream\": False\n    })\n    response.raise_for_status()\n    return response.json()[\"message\"]\n\ndef run_agent(user_input: str):\n    messages = [\n        {\"role\": \"system\", \"content\": \"You are a helpful assistant with access to tools.\"},\n        {\"role\": \"user\",   \"content\": user_input}\n    ]\n\n    while True:\n        reply = chat(messages, TOOLS)\n        messages.append(reply)\n\n        if reply.get(\"tool_calls\"):\n            for call in reply[\"tool_calls\"]:\n                fn_name = call[\"function\"][\"name\"]\n                fn_args = call[\"function\"][\"arguments\"]\n                if isinstance(fn_args, str):\n                    fn_args = json.loads(fn_args)\n\n                result = TOOL_REGISTRY[fn_name](**fn_args)\n                messages.append({\n                    \"role\": \"tool\",\n                    \"content\": result\n                })\n        else:\n            print(reply[\"content\"])\n            break\n\nif __name__ == \"__main__\":\n    run_agent(\"What is the weather in Kyiv?\")\n",[32,265,266,271,276,281,286,290,296,302,307,313,319,325,331,337,343,349,355,361,367,373,379,385,391,397,403,408,414,420,426,431,437,442,448,454,460,466,472,478,484,490,496,501,507,513,519,525,531,536,542,548,554,559,565,571,577,583,589,595,600,606,612,618,624,630,636,642,648,653,659],{"__ignoreMap":77},[81,267,268],{"class":83,"line":84},[81,269,270],{},"# agent.py\n",[81,272,273],{"class":83,"line":91},[81,274,275],{},"import json\n",[81,277,278],{"class":83,"line":113},[81,279,280],{},"import re\n",[81,282,283],{"class":83,"line":120},[81,284,285],{},"import requests\n",[81,287,288],{"class":83,"line":168},[81,289,117],{"emptyLinePlaceholder":116},[81,291,293],{"class":83,"line":292},6,[81,294,295],{},"OLLAMA_URL = \"http:\u002F\u002Flocalhost:11434\u002Fapi\u002Fchat\"\n",[81,297,299],{"class":83,"line":298},7,[81,300,301],{},"MODEL = \"hermes3:8b\"\n",[81,303,305],{"class":83,"line":304},8,[81,306,117],{"emptyLinePlaceholder":116},[81,308,310],{"class":83,"line":309},9,[81,311,312],{},"TOOLS = [\n",[81,314,316],{"class":83,"line":315},10,[81,317,318],{},"    {\n",[81,320,322],{"class":83,"line":321},11,[81,323,324],{},"        \"type\": \"function\",\n",[81,326,328],{"class":83,"line":327},12,[81,329,330],{},"        \"function\": {\n",[81,332,334],{"class":83,"line":333},13,[81,335,336],{},"            \"name\": \"get_weather\",\n",[81,338,340],{"class":83,"line":339},14,[81,341,342],{},"            \"description\": \"Returns current weather for a city.\",\n",[81,344,346],{"class":83,"line":345},15,[81,347,348],{},"            \"parameters\": {\n",[81,350,352],{"class":83,"line":351},16,[81,353,354],{},"                \"type\": \"object\",\n",[81,356,358],{"class":83,"line":357},17,[81,359,360],{},"                \"properties\": {\n",[81,362,364],{"class":83,"line":363},18,[81,365,366],{},"                    \"city\": {\"type\": \"string\", \"description\": \"City name\"}\n",[81,368,370],{"class":83,"line":369},19,[81,371,372],{},"                },\n",[81,374,376],{"class":83,"line":375},20,[81,377,378],{},"                \"required\": [\"city\"]\n",[81,380,382],{"class":83,"line":381},21,[81,383,384],{},"            }\n",[81,386,388],{"class":83,"line":387},22,[81,389,390],{},"        }\n",[81,392,394],{"class":83,"line":393},23,[81,395,396],{},"    }\n",[81,398,400],{"class":83,"line":399},24,[81,401,402],{},"]\n",[81,404,406],{"class":83,"line":405},25,[81,407,117],{"emptyLinePlaceholder":116},[81,409,411],{"class":83,"line":410},26,[81,412,413],{},"def get_weather(city: str) -> str:\n",[81,415,417],{"class":83,"line":416},27,[81,418,419],{},"    # Replace with a real API call in production\n",[81,421,423],{"class":83,"line":422},28,[81,424,425],{},"    return json.dumps({\"city\": city, \"temp_c\": 18, \"condition\": \"cloudy\"})\n",[81,427,429],{"class":83,"line":428},29,[81,430,117],{"emptyLinePlaceholder":116},[81,432,434],{"class":83,"line":433},30,[81,435,436],{},"TOOL_REGISTRY = {\"get_weather\": get_weather}\n",[81,438,440],{"class":83,"line":439},31,[81,441,117],{"emptyLinePlaceholder":116},[81,443,445],{"class":83,"line":444},32,[81,446,447],{},"def chat(messages: list, tools: list) -> dict:\n",[81,449,451],{"class":83,"line":450},33,[81,452,453],{},"    response = requests.post(OLLAMA_URL, json={\n",[81,455,457],{"class":83,"line":456},34,[81,458,459],{},"        \"model\": MODEL,\n",[81,461,463],{"class":83,"line":462},35,[81,464,465],{},"        \"messages\": messages,\n",[81,467,469],{"class":83,"line":468},36,[81,470,471],{},"        \"tools\": tools,\n",[81,473,475],{"class":83,"line":474},37,[81,476,477],{},"        \"stream\": False\n",[81,479,481],{"class":83,"line":480},38,[81,482,483],{},"    })\n",[81,485,487],{"class":83,"line":486},39,[81,488,489],{},"    response.raise_for_status()\n",[81,491,493],{"class":83,"line":492},40,[81,494,495],{},"    return response.json()[\"message\"]\n",[81,497,499],{"class":83,"line":498},41,[81,500,117],{"emptyLinePlaceholder":116},[81,502,504],{"class":83,"line":503},42,[81,505,506],{},"def run_agent(user_input: str):\n",[81,508,510],{"class":83,"line":509},43,[81,511,512],{},"    messages = [\n",[81,514,516],{"class":83,"line":515},44,[81,517,518],{},"        {\"role\": \"system\", \"content\": \"You are a helpful assistant with access to tools.\"},\n",[81,520,522],{"class":83,"line":521},45,[81,523,524],{},"        {\"role\": \"user\",   \"content\": user_input}\n",[81,526,528],{"class":83,"line":527},46,[81,529,530],{},"    ]\n",[81,532,534],{"class":83,"line":533},47,[81,535,117],{"emptyLinePlaceholder":116},[81,537,539],{"class":83,"line":538},48,[81,540,541],{},"    while True:\n",[81,543,545],{"class":83,"line":544},49,[81,546,547],{},"        reply = chat(messages, TOOLS)\n",[81,549,551],{"class":83,"line":550},50,[81,552,553],{},"        messages.append(reply)\n",[81,555,557],{"class":83,"line":556},51,[81,558,117],{"emptyLinePlaceholder":116},[81,560,562],{"class":83,"line":561},52,[81,563,564],{},"        if reply.get(\"tool_calls\"):\n",[81,566,568],{"class":83,"line":567},53,[81,569,570],{},"            for call in reply[\"tool_calls\"]:\n",[81,572,574],{"class":83,"line":573},54,[81,575,576],{},"                fn_name = call[\"function\"][\"name\"]\n",[81,578,580],{"class":83,"line":579},55,[81,581,582],{},"                fn_args = call[\"function\"][\"arguments\"]\n",[81,584,586],{"class":83,"line":585},56,[81,587,588],{},"                if isinstance(fn_args, str):\n",[81,590,592],{"class":83,"line":591},57,[81,593,594],{},"                    fn_args = json.loads(fn_args)\n",[81,596,598],{"class":83,"line":597},58,[81,599,117],{"emptyLinePlaceholder":116},[81,601,603],{"class":83,"line":602},59,[81,604,605],{},"                result = TOOL_REGISTRY[fn_name](**fn_args)\n",[81,607,609],{"class":83,"line":608},60,[81,610,611],{},"                messages.append({\n",[81,613,615],{"class":83,"line":614},61,[81,616,617],{},"                    \"role\": \"tool\",\n",[81,619,621],{"class":83,"line":620},62,[81,622,623],{},"                    \"content\": result\n",[81,625,627],{"class":83,"line":626},63,[81,628,629],{},"                })\n",[81,631,633],{"class":83,"line":632},64,[81,634,635],{},"        else:\n",[81,637,639],{"class":83,"line":638},65,[81,640,641],{},"            print(reply[\"content\"])\n",[81,643,645],{"class":83,"line":644},66,[81,646,647],{},"            break\n",[81,649,651],{"class":83,"line":650},67,[81,652,117],{"emptyLinePlaceholder":116},[81,654,656],{"class":83,"line":655},68,[81,657,658],{},"if __name__ == \"__main__\":\n",[81,660,662],{"class":83,"line":661},69,[81,663,664],{},"    run_agent(\"What is the weather in Kyiv?\")\n",[15,666,667],{},"Run it:",[72,669,671],{"className":74,"code":670,"language":76,"meta":77,"style":77},"python agent.py\n# The weather in Kyiv is 18°C and cloudy.\n",[32,672,673,680],{"__ignoreMap":77},[81,674,675,677],{"class":83,"line":84},[81,676,136],{"class":94},[81,678,679],{"class":102}," agent.py\n",[81,681,682],{"class":83,"line":91},[81,683,684],{"class":87},"# The weather in Kyiv is 18°C and cloudy.\n",[43,686],{},[10,688,690],{"id":689},"tool-registration-pattern","Tool Registration Pattern",[15,692,693],{},"For more than a handful of tools, use a decorator to auto-register:",[72,695,697],{"className":262,"code":696,"language":136,"meta":77,"style":77},"import inspect\nfrom typing import get_type_hints\n\nTOOLS = []\nTOOL_REGISTRY = {}\n\ndef tool(fn):\n    \"\"\"Register a function as an agent tool.\"\"\"\n    hints = get_type_hints(fn)\n    properties = {}\n    for name, hint in hints.items():\n        if name == \"return\":\n            continue\n        properties[name] = {\n            \"type\": \"string\" if hint == str else \"number\" if hint in (int, float) else \"object\"\n        }\n\n    TOOLS.append({\n        \"type\": \"function\",\n        \"function\": {\n            \"name\": fn.__name__,\n            \"description\": (fn.__doc__ or \"\").strip(),\n            \"parameters\": {\n                \"type\": \"object\",\n                \"properties\": properties,\n                \"required\": list(properties.keys())\n            }\n        }\n    })\n    TOOL_REGISTRY[fn.__name__] = fn\n    return fn\n\n@tool\ndef search_web(query: str) -> str:\n    \"\"\"Search the web for current information.\"\"\"\n    return f\"Results for: {query}\"\n\n@tool\ndef read_file(path: str) -> str:\n    \"\"\"Read content of a local file.\"\"\"\n    with open(path) as f:\n        return f.read()\n",[32,698,699,704,709,713,718,723,727,732,737,742,747,752,757,762,767,772,776,780,785,789,793,798,803,807,811,816,821,825,829,833,838,843,847,852,857,862,867,871,875,880,885,890],{"__ignoreMap":77},[81,700,701],{"class":83,"line":84},[81,702,703],{},"import inspect\n",[81,705,706],{"class":83,"line":91},[81,707,708],{},"from typing import get_type_hints\n",[81,710,711],{"class":83,"line":113},[81,712,117],{"emptyLinePlaceholder":116},[81,714,715],{"class":83,"line":120},[81,716,717],{},"TOOLS = []\n",[81,719,720],{"class":83,"line":168},[81,721,722],{},"TOOL_REGISTRY = {}\n",[81,724,725],{"class":83,"line":292},[81,726,117],{"emptyLinePlaceholder":116},[81,728,729],{"class":83,"line":298},[81,730,731],{},"def tool(fn):\n",[81,733,734],{"class":83,"line":304},[81,735,736],{},"    \"\"\"Register a function as an agent tool.\"\"\"\n",[81,738,739],{"class":83,"line":309},[81,740,741],{},"    hints = get_type_hints(fn)\n",[81,743,744],{"class":83,"line":315},[81,745,746],{},"    properties = {}\n",[81,748,749],{"class":83,"line":321},[81,750,751],{},"    for name, hint in hints.items():\n",[81,753,754],{"class":83,"line":327},[81,755,756],{},"        if name == \"return\":\n",[81,758,759],{"class":83,"line":333},[81,760,761],{},"            continue\n",[81,763,764],{"class":83,"line":339},[81,765,766],{},"        properties[name] = {\n",[81,768,769],{"class":83,"line":345},[81,770,771],{},"            \"type\": \"string\" if hint == str else \"number\" if hint in (int, float) else \"object\"\n",[81,773,774],{"class":83,"line":351},[81,775,390],{},[81,777,778],{"class":83,"line":357},[81,779,117],{"emptyLinePlaceholder":116},[81,781,782],{"class":83,"line":363},[81,783,784],{},"    TOOLS.append({\n",[81,786,787],{"class":83,"line":369},[81,788,324],{},[81,790,791],{"class":83,"line":375},[81,792,330],{},[81,794,795],{"class":83,"line":381},[81,796,797],{},"            \"name\": fn.__name__,\n",[81,799,800],{"class":83,"line":387},[81,801,802],{},"            \"description\": (fn.__doc__ or \"\").strip(),\n",[81,804,805],{"class":83,"line":393},[81,806,348],{},[81,808,809],{"class":83,"line":399},[81,810,354],{},[81,812,813],{"class":83,"line":405},[81,814,815],{},"                \"properties\": properties,\n",[81,817,818],{"class":83,"line":410},[81,819,820],{},"                \"required\": list(properties.keys())\n",[81,822,823],{"class":83,"line":416},[81,824,384],{},[81,826,827],{"class":83,"line":422},[81,828,390],{},[81,830,831],{"class":83,"line":428},[81,832,483],{},[81,834,835],{"class":83,"line":433},[81,836,837],{},"    TOOL_REGISTRY[fn.__name__] = fn\n",[81,839,840],{"class":83,"line":439},[81,841,842],{},"    return fn\n",[81,844,845],{"class":83,"line":444},[81,846,117],{"emptyLinePlaceholder":116},[81,848,849],{"class":83,"line":450},[81,850,851],{},"@tool\n",[81,853,854],{"class":83,"line":456},[81,855,856],{},"def search_web(query: str) -> str:\n",[81,858,859],{"class":83,"line":462},[81,860,861],{},"    \"\"\"Search the web for current information.\"\"\"\n",[81,863,864],{"class":83,"line":468},[81,865,866],{},"    return f\"Results for: {query}\"\n",[81,868,869],{"class":83,"line":474},[81,870,117],{"emptyLinePlaceholder":116},[81,872,873],{"class":83,"line":480},[81,874,851],{},[81,876,877],{"class":83,"line":486},[81,878,879],{},"def read_file(path: str) -> str:\n",[81,881,882],{"class":83,"line":492},[81,883,884],{},"    \"\"\"Read content of a local file.\"\"\"\n",[81,886,887],{"class":83,"line":498},[81,888,889],{},"    with open(path) as f:\n",[81,891,892],{"class":83,"line":503},[81,893,894],{},"        return f.read()\n",[43,896],{},[10,898,900],{"id":899},"optional-langgraph-orchestration","Optional: LangGraph Orchestration",[15,902,903],{},"For complex multi-step workflows with conditional branching, LangGraph adds minimal overhead:",[72,905,907],{"className":74,"code":906,"language":76,"meta":77,"style":77},"pip install langgraph langchain-ollama\n",[32,908,909],{"__ignoreMap":77},[81,910,911,913,915,918],{"class":83,"line":84},[81,912,171],{"class":94},[81,914,174],{"class":102},[81,916,917],{"class":102}," langgraph",[81,919,920],{"class":102}," langchain-ollama\n",[72,922,924],{"className":262,"code":923,"language":136,"meta":77,"style":77},"from langchain_ollama import ChatOllama\nfrom langgraph.prebuilt import create_react_agent\n\nllm = ChatOllama(model=\"hermes3:8b\")\n\n# define tools as LangChain Tool objects\nfrom langchain_core.tools import tool as lc_tool\n\n@lc_tool\ndef get_weather(city: str) -> str:\n    \"\"\"Returns weather for a city.\"\"\"\n    return f\"18°C, cloudy in {city}\"\n\nagent = create_react_agent(llm, tools=[get_weather])\nresult = agent.invoke({\"messages\": [(\"user\", \"Weather in Berlin?\")]})\nprint(result[\"messages\"][-1].content)\n",[32,925,926,931,936,940,945,949,954,959,963,968,972,977,982,986,991,996],{"__ignoreMap":77},[81,927,928],{"class":83,"line":84},[81,929,930],{},"from langchain_ollama import ChatOllama\n",[81,932,933],{"class":83,"line":91},[81,934,935],{},"from langgraph.prebuilt import create_react_agent\n",[81,937,938],{"class":83,"line":113},[81,939,117],{"emptyLinePlaceholder":116},[81,941,942],{"class":83,"line":120},[81,943,944],{},"llm = ChatOllama(model=\"hermes3:8b\")\n",[81,946,947],{"class":83,"line":168},[81,948,117],{"emptyLinePlaceholder":116},[81,950,951],{"class":83,"line":292},[81,952,953],{},"# define tools as LangChain Tool objects\n",[81,955,956],{"class":83,"line":298},[81,957,958],{},"from langchain_core.tools import tool as lc_tool\n",[81,960,961],{"class":83,"line":304},[81,962,117],{"emptyLinePlaceholder":116},[81,964,965],{"class":83,"line":309},[81,966,967],{},"@lc_tool\n",[81,969,970],{"class":83,"line":315},[81,971,413],{},[81,973,974],{"class":83,"line":321},[81,975,976],{},"    \"\"\"Returns weather for a city.\"\"\"\n",[81,978,979],{"class":83,"line":327},[81,980,981],{},"    return f\"18°C, cloudy in {city}\"\n",[81,983,984],{"class":83,"line":333},[81,985,117],{"emptyLinePlaceholder":116},[81,987,988],{"class":83,"line":339},[81,989,990],{},"agent = create_react_agent(llm, tools=[get_weather])\n",[81,992,993],{"class":83,"line":345},[81,994,995],{},"result = agent.invoke({\"messages\": [(\"user\", \"Weather in Berlin?\")]})\n",[81,997,998],{"class":83,"line":351},[81,999,1000],{},"print(result[\"messages\"][-1].content)\n",[43,1002],{},[10,1004,1006],{"id":1005},"optional-chromadb-memory-backend","Optional: ChromaDB Memory Backend",[15,1008,1009],{},"Add persistent conversation memory in one install:",[72,1011,1013],{"className":74,"code":1012,"language":76,"meta":77,"style":77},"pip install chromadb\n",[32,1014,1015],{"__ignoreMap":77},[81,1016,1017,1019,1021],{"class":83,"line":84},[81,1018,171],{"class":94},[81,1020,174],{"class":102},[81,1022,1023],{"class":102}," chromadb\n",[72,1025,1027],{"className":262,"code":1026,"language":136,"meta":77,"style":77},"import chromadb\nfrom chromadb.utils import embedding_functions\n\nclient = chromadb.PersistentClient(path=\".agent_memory\")\nef = embedding_functions.DefaultEmbeddingFunction()\ncollection = client.get_or_create_collection(\"conversations\", embedding_function=ef)\n\ndef remember(text: str, doc_id: str):\n    collection.upsert(documents=[text], ids=[doc_id])\n\ndef recall(query: str, n: int = 3) -> list[str]:\n    results = collection.query(query_texts=[query], n_results=n)\n    return results[\"documents\"][0]\n",[32,1028,1029,1034,1039,1043,1048,1053,1058,1062,1067,1072,1076,1081,1086],{"__ignoreMap":77},[81,1030,1031],{"class":83,"line":84},[81,1032,1033],{},"import chromadb\n",[81,1035,1036],{"class":83,"line":91},[81,1037,1038],{},"from chromadb.utils import embedding_functions\n",[81,1040,1041],{"class":83,"line":113},[81,1042,117],{"emptyLinePlaceholder":116},[81,1044,1045],{"class":83,"line":120},[81,1046,1047],{},"client = chromadb.PersistentClient(path=\".agent_memory\")\n",[81,1049,1050],{"class":83,"line":168},[81,1051,1052],{},"ef = embedding_functions.DefaultEmbeddingFunction()\n",[81,1054,1055],{"class":83,"line":292},[81,1056,1057],{},"collection = client.get_or_create_collection(\"conversations\", embedding_function=ef)\n",[81,1059,1060],{"class":83,"line":298},[81,1061,117],{"emptyLinePlaceholder":116},[81,1063,1064],{"class":83,"line":304},[81,1065,1066],{},"def remember(text: str, doc_id: str):\n",[81,1068,1069],{"class":83,"line":309},[81,1070,1071],{},"    collection.upsert(documents=[text], ids=[doc_id])\n",[81,1073,1074],{"class":83,"line":315},[81,1075,117],{"emptyLinePlaceholder":116},[81,1077,1078],{"class":83,"line":321},[81,1079,1080],{},"def recall(query: str, n: int = 3) -> list[str]:\n",[81,1082,1083],{"class":83,"line":327},[81,1084,1085],{},"    results = collection.query(query_texts=[query], n_results=n)\n",[81,1087,1088],{"class":83,"line":333},[81,1089,1090],{},"    return results[\"documents\"][0]\n",[15,1092,1093],{},"Pass recalled context into the system message before each agent run.",[43,1095],{},[10,1097,1099],{"id":1098},"cost","Cost",[1101,1102,1103,1115],"table",{},[1104,1105,1106],"thead",{},[1107,1108,1109,1113],"tr",{},[1110,1111,1112],"th",{},"Option",[1110,1114,1099],{},[1116,1117,1118,1127,1135],"tbody",{},[1107,1119,1120,1124],{},[1121,1122,1123],"td",{},"hermes3:8b via Ollama",[1121,1125,1126],{},"$0 (local)",[1107,1128,1129,1132],{},[1121,1130,1131],{},"hermes3:8b via Groq",[1121,1133,1134],{},"Free tier: 14,400 req\u002Fday",[1107,1136,1137,1140],{},[1121,1138,1139],{},"hermes3:70b via Groq",[1121,1141,1142],{},"Free tier with rate limits",[15,1144,1145,1146,1149,1150,1153,1154,1157],{},"Groq API uses the same OpenAI-compatible endpoint — swap ",[32,1147,1148],{},"OLLAMA_URL"," for ",[32,1151,1152],{},"https:\u002F\u002Fapi.groq.com\u002Fopenai\u002Fv1\u002Fchat\u002Fcompletions"," and add an ",[32,1155,1156],{},"Authorization: Bearer \u003Ckey>"," header.",[43,1159],{},[10,1161,1163],{"id":1162},"see-also","See Also",[22,1165,1166,1174],{},[25,1167,1168,1173],{},[1169,1170,1172],"a",{"href":1171},"\u002Fen\u002Ftools","AI Agents tools directory"," — filter by AI Agents category",[25,1175,1176,1180],{},[1169,1177,1179],{"href":1178},"\u002Fen\u002Ftier-list\u002Ftext","Text model tier list"," — compare Hermes against GPT-4o, Claude, and others",[1182,1183,1184],"style",{},"html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":77,"searchDepth":91,"depth":113,"links":1186},[1187,1188,1189,1190,1191,1192,1193,1194,1195],{"id":12,"depth":91,"text":13},{"id":47,"depth":91,"text":48},{"id":185,"depth":91,"text":186},{"id":255,"depth":91,"text":256},{"id":689,"depth":91,"text":690},{"id":899,"depth":91,"text":900},{"id":1005,"depth":91,"text":1006},{"id":1098,"depth":91,"text":1099},{"id":1162,"depth":91,"text":1163},"ai-agents","Set up a function-calling Hermes agent with tool registration and optional memory backend in under 20 minutes.","intermediate","md",{},"\u002Fen\u002Fguides\u002Fhermes-agent-setup","2026-05-30",{"title":5,"description":1197},"hermes-agent-setup","en\u002Fguides\u002Fhermes-agent-setup",[1207,1196,196,1208,136],"hermes","function-calling","e1XmAE0eY6yYF7ODeSmKYNvgaatBNRKkQJq7aQBDE44",1781557609815]