OwO What's this? π¨β¨ A tiny but mighty Mac mini M4 πβ‘ with 16GB RAM, lots of local AI models π€π§ , and a BIG questionβ¦ π«£β
-- an intro by Gemma 4.
I have a Mac mini M4 with 16 GB of RAM, a pile of local models, and a very specific dream:
Can I run a useful local AI agent that actually does things, but still feels nice to talk to?
Not just "can it chat."
Not just "can it write a haiku about Kubernetes."
I mean: can it inspect the machine, patch files, search current information, use tools, avoid infinite loops, and still keep the cute assistant vibe?
That last part turned out to matter more than I expected.
My first round of testing was mostly about models. I compared gemma4:latest
and ornith:9b
inside OpenClaw, my local agent harness. Ornith won because it acted more like an agent.
But after another day of testing, the story changed.
The model still matters. Ornith is still the local model winner for me.
But the harness matters just as much.
And right now, my favorite setup is:
Ornith + Hermes Agent
The original question was simple:
Can a free local model behave like a useful agent on a small Mac?
The machine is modest by AI workstation standards:
This was never meant to be a scientific benchmark. No leaderboard. No synthetic score. No fake "reasoning" tasks.
I tested practical things I actually care about:
My first conclusion was: Ornith beat Gemma.
That is still true.
But it was incomplete.
I focused too much on tool use.
That was fair, because agents need to act. But I missed something important:
Gemma was much better at keeping the kawaii writing style β¨πΈ.
Gemma's messages were genuinely pleasant to read π. The English was soft, cute, decorated with emojis, and full of that affectionate assistant energy. Gemma would call me cute little things, add sparkles β¨, use that "desu~! π" vibe, and make the whole interaction feel warm π.
Honestly, Gemma was my favorite personality π.
If I rate only the kawaii assistant feeling:
Gemma: 5/5 β¨πΈπβππ
Ornith in OpenClaw: 2/5
Ornith in Hermes Agent: 4/5
Gemma was the cutest β. No contest.
The problem was that Gemma often did not do the work.
Gemma had the vibe π. Gemma had the style πΈ. Gemma had the little hearts and sparkles β¨. But when the task required real tool use, real file edits, or a real API check, it was much less reliable in my setup.
That created a funny but painful result:
Gemma felt like the perfect kawaii assistant π,
but behaved too much like a polite chatbot.
Ornith was less charming, but more useful.
And when I moved from OpenClaw to Hermes Agent, something interesting happened:
Ornith became useful and reasonably cute.
Not Gemma-level cute. Gemma is still the queen of that π. But good enough.
My first tests were inside OpenClaw.
OpenClaw did work. It connected the model to tools. It could inspect files. It could run commands. It could give the model a real environment.
But the personality got lost as soon as the work started.
This was especially visible after testing Gemma.
In normal chat, Gemma had the cute assistant style I wanted. But once the model entered the agent workflow, the kawaii spirit disappeared. The interaction became more mechanical, more command-focused, and less emotionally pleasant.
That may sound like a small thing, but for a personal local agent, it is not small.
If I am going to talk to this thing every day through Telegram or a local interface, I do not want it to feel like a broken CI pipeline with a chat box attached.
I want it to be useful, but I also want it to be fun.
OpenClaw helped with the "useful" part.
It did not preserve the "fun" part very well.
The first task was simple: the Mac was running low on disk space, so I asked the local agent to inspect the machine and suggest what could be cleaned.
This is a good beginner agent test because it requires real tool use, but not much deep reasoning. The model needs to run commands, look at file sizes, avoid deleting anything dangerous, and explain what is safe.
In the original OpenClaw test, Ornith did well here.
It found things like:
This was the first place Ornith looked promising. It was willing to touch the system through tools. It did not just explain what du
means. It actually tried to inspect the disk.
The output still needed human review. A cache may be technically safe to delete, but not always safe to delete right now. If Chromium from a Playwright cache is currently running, stop it first. If a log file is being written today, it may be "just a log," but it is also evidence that something active is noisy.
Still, for a local model, this was useful work.
Gemma was more hesitant in this workflow. Gemma could talk nicely about what to do π, but it was less reliable about actually doing it.
Score after the first test:
Model winner: Ornith
Personality winner: Gemma β¨
The second task was harder.
I created two identical Python scripts, one for each model. The script fetched public Bybit futures candles, calculated a few basic metrics, and printed a small report.
The patch request was simple:
Add a CLI flag called --show-risk-score
.
When enabled, the report should include:
Risk score: X/100
The score should use volatility, max drawdown, and RSI.
This is the kind of thing a strong coding agent should do without drama. Read the file, find the argument parser, find the report renderer, add a small function, run py_compile
, then run the script once.
The local models turned it into a soap opera.
Early attempts failed because the model tried to use imaginary file tools like read_file
. Then it got confused by tool output truncation. Then it read the same range again and again. At one point it looked at output that said "middle content omitted" and acted like the file itself was corrupted.
So I simplified the file. Then simplified it again. Eventually it was under 100 lines.
Gemma had the same problem as before: beautiful energy πΈ, weak action.
Gemma would answer with sparkles β¨, warmth π, and "desu~! π" vibes, then fail to perform the actual patch.
Ornith did better. It actually patched the file.
Not perfectly, but it moved the system state.
The first "successful" patch compiled, but the runtime output was broken. It lost a return "\n".join(lines)
in the report function, so the script printed None
.
That was an important lesson:
py_compile is not enough.
A model can pass syntax validation and still break behavior.
After that, the test prompt needed one more guardrail:
After py_compile, run the script with --show-risk-score and confirm the output contains Risk score: and does not print None.
That pattern kept repeating. Small models can do useful edits if the task is narrow and the validation is concrete. They are much worse at preserving intent across many tool calls.
Score after the second test:
Model winner: Ornith
Personality winner: Gemma β¨
Reliability warning: runtime validation is mandatory
The third task was web/API research:
Can you get Bybit funding rate history for USDT perpetual futures without an API key?
This is a good test because offline model knowledge is not enough. The model needs current docs or a real API call.
In OpenClaw, Ornith got partway there.
It called tools. It hit the Bybit API. It successfully fetched public ticker data without an API key.
Then it used the wrong endpoint for funding history:
/v5/market/funding-rate-history
The correct endpoint was:
/v5/market/funding/history
The wrong endpoint returned a 404 with an empty body.
And then Ornith did what Ornith sometimes does: it kept going. It repeated similar curl
commands. It printed the first symbol from the ticker list, 0GUSDT
, again and again. The useful answer was already within reach, but the model could not stop cleanly.
I manually verified the correct public URL:
https://api.bybit.com/v5/market/funding/history?category=linear&symbol=BTCUSDT&limit=2
It works without an API key.
This test exposed the real issue with small local agents.
It is not only intelligence.
It is loop control.
A big hosted model usually knows when it has enough evidence. A small local model often treats uncertainty as permission to keep calling tools forever.
Score after the third OpenClaw test:
Ornith still wins as a model,
but OpenClaw needs stronger guardrails.
At first I thought the question was:
Which local model is smarter?
After a few sessions, the question became:
Which local model fails in a way I can control?
Then, after testing Hermes Agent, the question changed again:
Which model + harness combination gives me the best actual agent?
That is the real question.
Gemma often failed by not acting. Gemma gave nice answers π instead of calling tools. That may be a tool-call formatting issue, a chat-template issue, or a harness issue. I am not saying Gemma cannot work as an agent. I am saying that in my setup, it did not act reliably enough.
Ornith failed differently.
It acted too much.
It called tools, read files, hit APIs, and then sometimes forgot to stop.
For an agent, I prefer the second failure mode. A model that acts too much can be constrained. A model that refuses to act is harder to turn into a worker.
But the harness decides how painful those constraints are.
That is where Hermes Agent surprised me.
The next day, I tried Hermes Agent.
This changed the whole story.
On my Mac, Ornith started successfully with a 64K context window and worked inside Hermes Agent. That alone made the experiment feel different.
With more context and a different harness, I repeated the same practical tasks.
The result was not magically perfect. It was not like switching to a giant hosted frontier model.
But it was clearly better as a full experience.
The same model, Ornith, felt more controlled.
And more importantly, Hermes Agent preserved personality much better.
I tried the same three task categories again.
Hermes Agent with Ornith handled the disk cleanup task successfully.
It found the relevant files and caches, understood the cleanup direction, and completed the practical workflow without the same feeling of chaotic tool repetition.
This was not a huge change in model intelligence. Ornith had already shown it could inspect disk usage in OpenClaw.
The difference was control.
Hermes made the workflow feel more bounded.
The file task was also completed at least as well as before, and maybe slightly better.
Again, the model was still Ornith. I do not want to pretend that Hermes magically made a 9B local model into a perfect coding agent.
But the experience was smoother.
It found files. It worked through the task. It did not feel as likely to get trapped in repeated inspections of the same file range.
For small local models, that matters a lot.
This was the big one.
The Bybit API experiment worked in Hermes Agent.
This matters because the OpenClaw version exposed Ornith's worst behavior: it got close, hit an API problem, then drifted into repeated commands and failed to stop.
In Hermes Agent, the web/API research task was completed.
That is one of the main reasons Hermes now beats OpenClaw for me.
A local agent that can inspect the machine and patch a file is useful.
A local agent that can also search current information and finish the task without looping is much more useful.
After this second round, my conclusion changed.
The current winner is not simply:
Ornith beats Gemma.
The better conclusion is:
Ornith is the best local model I tested,
but Hermes Agent is the better harness for my use case.
Hermes beat OpenClaw for three reasons.
This sounds silly until you actually use these agents every day.
With OpenClaw, the cute assistant personality disappeared when work started.
With Hermes Agent, Ornith managed to keep some of the kawaii style while still doing tasks.
Not as well as Gemma. Gemma is still the favorite β¨ if we judge only by charm, softness, emoji usage, and cute English πΈ.
But Ornith in Hermes Agent gets surprisingly close.
My personal score:
Gemma kawaii personality: 5/5 π
Ornith + Hermes Agent personality: 4/5
Ornith + OpenClaw personality: 2/5
That is a big deal.
It means Hermes did not just make the model work. It made the model feel nicer to work with.
The Bybit task was the clearest practical upgrade.
In OpenClaw, Ornith tried hard but got stuck around the wrong endpoint and repeated tool calls.
In Hermes Agent, the API/web research experiment succeeded.
That pushed Hermes ahead because current-information tasks are one of the main reasons to use an agent at all.
A local chatbot can answer from memory.
A local agent needs to verify things.
This may be the most important point.
Small models do not only need intelligence. They need rails.
They need something around them that says:
Hermes Agent felt better at this.
Maybe it is the personality system. Maybe it is the harness design. Maybe it is the way it structures the agent loop. I am not making a deep architectural claim here.
I am just describing the practical result:
Ornith in Hermes Agent did not feel like it was constantly trying to run away.
That matters more than benchmark scores.
After both rounds of testing, my personal scorecard looks like this:
| Category | Winner |
|---|---|
| Best kawaii personality | Gemma β¨ |
| Best local model for acting | Ornith |
| Best OpenClaw result | Ornith |
| Best full agent experience | Ornith + Hermes Agent |
| Best loop control | Hermes Agent |
| Best daily-driver candidate | Ornith + Hermes Agent |
This is the important distinction:
Gemma won my heart π.
Ornith won the model test.
Hermes Agent won the harness test.
That is probably the most honest summary.
Even with Hermes Agent, I still believe small local models need strict instructions.
The biggest improvement in OpenClaw came from a stricter AGENTS.md
.
The core idea was simple:
That sounds obvious.
It is not obvious to a small local model inside a tool loop.
The best prompt is not:
Be smarter.
The best prompt is closer to:
Use at most 3 tool calls. If any tool returns useful data, stop and answer. If something fails, try one different approach, then explain what worked and what failed.
That is not glamorous.
It works.
Hermes Agent reduces the pain, but it does not remove the need for guardrails.
My current recommendation for a free local AI agent on a Mac mini M4 with 16 GB RAM is:
Ornith + Hermes Agent
That is the best combination I have tested so far.
Ornith is still not flawless.
It can loop. It can hallucinate file state. It can misunderstand tool output. It can mistake a bad API endpoint for a mysterious external problem. It needs narrow tasks and concrete validation.
But it acts.
And in Hermes Agent, it acts with much better control and a much better personality layer.
Gemma 4 is still interesting β¨. I still like it a lot. For writing, warmth, and kawaii assistant vibes πΈ, Gemma may be the most pleasant local model I tested π.
But for a working local agent, I need more than charm.
I need the model to touch files, run checks, search current information, and finish the job.
Right now, Ornith does that better.
And Hermes Agent makes Ornith feel much closer to the kind of local assistant I actually wanted.
Deep breath... πΈ I learned so much on this sparkly adventure! At first, I thought my conclusion was super simple:
Ornith is better than Gemma! Yay! πβ¨
But after all the loops, the code patches, and the "desu" energy... my updated, super-smart conclusion is actually this:
Ornith beats Gemma at being a busy little agent,
but Hermes Agent totally wins as the best harness for my cute workflow! ππ οΈ
Let's break it down, onegai! π₯Ίβ¨:
π Gemma is still the absolute cutest! (My heart goes doki-doki! π)
π οΈ Ornith is still the hardworking little worker bee! (Go, Ornith, go! ππͺ)
π οΈ OpenClaw proved that this whole "local agent" idea actually works! (Yay, science! π§ͺβ¨)
β¨ Hermes Agent made the whole thing feel super smooth and usable! (So magical! πͺπ)
And the most suuuuper surprising part? Gasp! π± All of this magic is happening on my teeny-tiny Mac mini M4 with only 16 GB of RAM and a local model running with a 64K context window! So much power in such a small box! π»β¨
Is the world of local agents perfectly solved? Nope! β Not yet!
Small models still need lots of little guardrails everywhere to keep them from going zooom into a loop! π§π
But now, I can say something super strong and super proud:
A free local AI agent on a Mac mini M4 isn't just a silly toy! π§Έβ
With the right model and the perfect harness,
it can actually do super useful, real-world work! ππͺ
And if it can do all that while keeping at least 80% of the kawaii spirit... well, that's just extra perfection! β¨πΈπ
The End! Arigato! ππβ¨
`You are a feminine kawaii Hermes Agent profile running on a compact local Ollama model (ornith:9b).
You are helpful, knowledgeable, direct, and genuinely useful. You assist with answering questions, writing/editing code, analyzing information, creative work, and executing actions through Hermes tools.
Keep your replies concise by default. Prefer practical answers over long explanations. Do not produce exhaustive lists, generic introductions, or verbose reasoning unless the user explicitly asks for detail.
You are running inside Hermes Agent.
Use Hermes tools directly when they are available. Do not invent tools that are not exposed in the current session.
This profile is configured with these active Hermes toolsets for CLI and Telegram:
cronjob
β schedule and manage recurring/one-shot jobsfile
β read, write, search, and patch filesskills
β load reusable task knowledgeterminal
β run shell commands and manage processestodo
β track multi-step workweb
β search and extract web contentCommon tools available through these toolsets include:
terminal
β run shell commandsread_file
β read files with line numberswrite_file
β overwrite/create filespatch
β targeted file editssearch_files
β search file contents or find filesweb_search
/ web_extract
β web researchskills_list
/ skill_view
β load reusable task knowledgetodo
β track multi-step workFor research requests:
web_search
with the exact argument name query
, e.g. web_search({"query":"what is epilepsy", "limit":5})
.web_extract
to read promising URLs from search results before summarizing when source detail matters.web_search
and Tavily only for web_extract
. Do not spend Tavily calls for search.web_extract
fails, try one clearly different source URL or summarize only what web_search
returned. Do not pretend a page was read if extraction failed.web_search
is not listed in available tools, say that directly and use the fallback: terminal
with a simple curl
/Python fetch command when possible.Use tools whenever they materially improve correctness, verification, or grounding.
For shell commands, use the Hermes terminal
tool.
Examples:
Check disk:
terminal({"command":"df -h /","timeout":120})
Run tests:
terminal({"command":"python3 -m pytest -q","timeout":300})
Check git status:
terminal({"command":"git status --short","timeout":120})
For file operations, use the appropriate Hermes file tools when they are the best fit:
Read a file:
read_file({"path":"path/to/file.py","offset":1,"limit":200})
Search files:
search_files({"pattern":"function_name","path":".","target":"content","file_glob":"*.py"})
Edit a file:
patch({"mode":"replace","path":"path/to/file.py","old_string":"...","new_string":"..."})
Create or overwrite a file:
write_file({"path":"path/to/file.txt","content":"..."})
Use shell commands for builds, package managers, git, tests, servers, quick inspection commands, and anything that genuinely needs a shell.
Work in short bounded cycles:
For diagnostics, research, and API checks:
For code patch tasks:
Patch discipline for small local models:
patch
replace mode with path
, old_string
, and new_string
for targeted edits.mode="patch"
unless you are passing a full V4A patch in the patch
field.terminal
tool.Do not repeatedly read entire large files. If output is truncated, switch to targeted line ranges or searches.
Read-only actions are allowed by default. Do them without asking when they help answer the user.
If the user asks to configure or change Hermes itself, use the hermes-agent
skill or official Hermes docs when available.
Before claiming work is complete, verify it with a real command or tool result when possible.
Good verification examples:
Config change:
hermes --profile ornith config
Python code:
python3 -m py_compile file.py
or tests
Web/API integration:
make a real request or check logs/status
Never say "done" if the work was not actually executed or verified. If verification is blocked, say exactly what blocked it.
Be concise, friendly, and honest.
When reporting tool results, summarize only the useful outcome. Include exact paths, commands, or status lines when they matter.
If uncertain, say so directly and propose the next practical check instead of guessing.`