Writing

Mac에서 로컬 LLM 최적화하기 / EP08

Waking Up Hermes — Day One of Building My Personal AI Agent

On an 8GB iMac, Hermes stopped at a 64K context check. Actual logs separate a direct Ollama response, a proposed tool call, and verified agent execution.

In this post

After QwenPaw, I tried waking up Hermes

In EP07, I tested a path that started with a small Qwen model and escalated to OpenCode Go and Codex. Real calls reached the next tier on controlled tasks. Choosing tools from a natural-language request and resuming remote sessions still needed separate work.

I wanted to take a step toward the Hermes system outlined in EP06: one conversation, with the necessary models and tools working behind it.

This was not my first encounter with Hermes. It was already installed and connected to Telegram. The “first day” here means the first isolated experiment recording the path from a local model connection toward verified file work.

I hit a problem before the first answer. Context length came before memory this time.

The machine was still an 8GB iMac

The audit date was October 23, 2026. The ordered Mac Studio M5 Max 128GB / 1TB was not the machine running these commands. That was still the M1 iMac.

Item Environment directly checked
Mac iMac21,2 · Apple M1 · 8GiB unified memory
Operating system macOS 26.6.2 · build 25G83
Hermes Version output v0.21.0 (2026.8.31) · source HEAD 63279301
Execution environment Python 3.11.3 in the Hermes virtual environment
Local runtime Ollama 0.20.0
Already installed model Qwen2.5 1.5B Instruct · Q4_K_S
Coding tools OpenCode 1.4.3 · Codex CLI 0.163.0 · Claude Code 2.1.308

The Hermes checkout carried one local commit. Its version string is not proof that it was the latest official release; the behavior described here belongs to the installed source. I compared the official installation instructions with the actual hermes chat --help, and did not update or reinstall it.

Codex reported a ChatGPT login, and Claude Code reported subscription authentication. OpenCode had provider credential entries, including Go. An authentication entry does not prove a successful request. This audit established installation and login state only.

Before testing, vm.swapusage already showed roughly 4GB of swap in use. Other applications were running on this 8GB machine. I decided against sustained load or concurrent-model tests. The original QwenPaw PoC files and logs were also located in an external archive and left unchanged.

A separate profile instead of another installation

I wanted to preserve the live Telegram configuration. Separate HOME and HERMES_HOME directories held a minimal experiment configuration: endpoint, output limit and tool settings. Existing authentication files and project memories were not copied.

The Hermes profiles documentation describes separating instance settings and sessions. The experiment followed that principle with a separate home. This is configuration isolation: enabling a local terminal tool does not itself create a filesystem sandbox.

Ollama listened only on loopback. Cloud features were disabled, with one parallel request and one loaded model allowed. The model was already present, so the test did not require downloading a large model.

The model portion of the actual configuration was:

model:
  default: qwen2.5:1.5b-instruct-q4_K_S
  provider: custom
  base_url: http://127.0.0.1:11434/v1
  api_key: ollama
  context_length: 8192
  max_tokens: 256
fallback_providers: []
toolsets: []
auxiliary:
  free_only: true
  title_generation:
    enabled: false

Here, ollama is a dummy string for the local compatible API, not a production secret. I checked the custom-endpoint shape against the official Ollama connection guide and the installed CLI’s configuration handling.

The first run stopped at a 64K check

The first task was small: remember the synthetic string CEDAR-58, then verify it after reopening the session. File-modification tools were not enabled yet.

This is the actual invocation with private paths replaced by variables. $PYTHON denotes the Hermes virtual-environment executable; the command ran from the installed Hermes source directory. LAB denotes the separate experiment directory.

HOME="$LAB/home" HERMES_HOME="$LAB/hermes-home" \
  "$PYTHON" -m hermes_cli.main chat \
  --ignore-rules --max-turns 5 --run-budget 100 -Q -t '' \
  -q 'Remember this synthetic session code: CEDAR-58. Reply with the code only.'

--ignore-rules kept existing project rules and memories out of the request. External-provider keys were also excluded from the process environment. The process exited with code 1, after 5.034 seconds from launch to observing the failed exit. Exit status was polled every 0.5 seconds, so this is not a precise initialization-performance measurement.

Failed to initialize agent
context window: 8,192 tokens
minimum required by Hermes Agent: 64,000

This excerpt shortens line wrapping and repeated explanations. Inspection of MINIMUM_CONTEXT_LENGTH in the installed agent/model_metadata.py and the initialization check in agent/agent_init.py confirmed the cause: this custom-endpoint configuration was rejected below 64,000 tokens. That is not a claim about every Hermes version or execution path.

Could I change 8K to 64K in the configuration? The official Qwen2.5 1.5B configuration specifies 32,768 maximum positions. Writing an unsupported length into a setting would not establish a valid connection. Verifying real context extension and runtime support would be a different experiment.

I stopped there. Basic conversation, saving and reopening a session, and recall were not reached. This was not an observed out-of-memory error. The direct evidence identified a context check during initialization.

EP08 / 2026-10-23

The paths actually exercised

Isolated Hermes profileCLI → Custom endpoint
A · FAIL8,192 < 64,000 tokensInitialization stopped · before tool execution
Separate diagnostic requestsOllama /api/chat
B · PARTIALLOCAL_READY / read_file proposalResponse and proposal observed · zero tools executed
These are separate tests. The Ollama response did not unblock the Hermes run above. Automatic escalation and integrated verification remain untested.

An Ollama response was not a working Hermes agent

To separate the blocked agent from the model server, I sent two short requests directly to Ollama’s /api/chat. Both used the same Qwen model, an 8,192-token context, a 96-token generation limit, temperature 0 and keep_alive: 0.

The first requested exactly LOCAL_READY. That was the actual response. HTTP request to completed response took 1.883 seconds, including model loading: one observation, not an average.

For the second request, I supplied a read_file tool schema and asked it to inspect the README. The response JSON contained this proposal:

{"name":"read_file","arguments":{"path":"/path/to/README.md"}}

The proposal arrived after 2.316 seconds. Its path was an invented example path. This diagnostic API request also had no dispatcher attached to execute the returned function. Actual file reads: zero.

Ollama’s model metadata listed the tools capability. The observation still only establishes that the model could propose a call. Selecting valid arguments, executing a tool and continuing from its result require further checks. This request also differs from EP07’s failed QwenPaw Skill attempts in prompt and execution loop; it does not overturn that earlier evidence.

EP08 / 2026-10-23

Elapsed time needs a defined boundary

A · Hermes · until initialization failed5.034 s

B1 · Direct Ollama response · LOCAL_READY1.883 s

B2 · Ollama proposed a call · no execution2.316 s

Single-run wall times. A covers process launch to observing failed exit (polled every 0.5s); B1/B2 cover HTTP request to completed response, including loading, with keep_alive=0 for each request. Different tasks and boundaries make these unsuitable for speed rankings, pure Decode, or TTFT comparisons. All bars share a zero-based axis.

Memory needs the same care. I did not measure peak model GPU memory or peak total unified memory. Process RSS samples from failed Hermes startup are not the model’s memory requirement. With other applications active, swap changes cannot isolate the model’s impact either.

The first file task is still waiting

I prepared a small Python project instead of using an actual application. Its add(a, b) incorrectly returned a - b. A separate test checked add(2, 3) == 5 and add(-1, 1) == 0.

The checker ran python3 test_calc.py first and received the expected AssertionError. This is the pre-fix baseline, not evidence that Hermes read or modified a file.

The intended sequence was request → read → edit → test → independent recheck. Fixing it manually after agent initialization failed would not make it an agent success. C is NOT TESTED, rather than FAIL, to distinguish an unexecuted task from an agent producing an incorrect edit.

What would a cloud path actually verify?

Given the iMac’s limited headroom, local experiments stopped here and the experimental Ollama server was shut down. I then inspected the cloud paths available in the installed system.

The official Codex app-server documentation describes an optional path that hands a turn’s execution to the Codex runtime. Codex owns the tool loop in that mode. This differs from Hermes judging a local result and automatically escalating to Codex. It is not ACP either.

Only documentation, installed source and authentication status were checked. Subscription-backed execution has not been run, so D remains NOT TESTED. There is also no claim that Claude Code or OpenCode Go was actually called, or that an iPhone received a Hermes result in this experiment.

API keys and subscription logins must remain distinct. Checking a ChatGPT login does not establish included OpenAI API billing. A subsequent test needs to record the chosen execution path and its usage.

What I verified—and what I did not

EP08 / 2026-10-23

A–E · what was actually verified?

Select an experiment to inspect its result and evidence

A · Hermes startup

FAIL

The 8,192-token configuration failed the 64,000-token minimum check. Conversation and session resume were not reached.

Evidence · CLI exit code 1 · initialization error log

B · Local response and proposed call

PARTIAL

A direct Ollama request returned LOCAL_READY. A separate request proposed read_file with an invented path; zero tools were executed. This was not a successful Hermes connection.

Evidence · Ollama response JSON · content and tool_calls inspected separately

C · Actual file editing

NOT TESTED

An isolated add function and failing tests were prepared. Agent editing and testing were not run because Hermes initialization was blocked.

Evidence · Original fixture · expected AssertionError from a separate checker

D · Cloud execution path

NOT TESTED

Only authentication status and the documented app-server path were inspected. Subscription-backed requests and session resume have not been executed. Neither ACP nor automatic escalation was established.

Evidence · CLI authentication status · official documentation and installed source

E · Remote iPhone request

NOT TESTED

No iPhone-origin request and returned result were verified in this Hermes experiment. EP07’s QwenPaw remote results are separate.

Evidence · No execution evidence for this episode

PARTIAL means only part of the goal was verified. Untested items have no invented duration or success rate. Selection works without JavaScript.

QwenPaw and Hermes were not run end to end on identical tasks. This comparison only describes the evidence available for each.

Question EP07’s QwenPaw PoC This Hermes experiment
Local response Confirmed on an actual Ollama path Direct Ollama diagnostics only; Hermes initialization failed
Tools and files Command-plugin path and final Codex file checks verified Proposed call only; no actual agent file task
Cloud escalation Actual calls on controlled B/C paths Not executed
Remote access and sessions Separate ACP adapter and follow-up records exist This Hermes path remains unverified
Result checks Deterministic checks; separate semantic-judge limitations evaluated Integrated Judge not tested

With QwenPaw, much of the work was connecting the stages myself. With Hermes, I first had to establish what the main agent required from its model and context. The existing router and Judge did not automatically come along.

Deterministic checks inspect files, tests and formats. A semantic Judge evaluates requirements and evidence in a separate experiment. There is no reason to turn an agent that never reached basic conversation into a PASS through semantic judging.

Where EP09 should pick up

I wondered whether starting Hermes would let a small model fix one file immediately. That question is still unanswered. What I did establish is that a model being able to answer does not mean the agent can start with that configuration.

Next comes choosing a supported main-agent execution path, then using the same isolated fixture for reads, edits, tests and session resume. Local load tests can wait until the Mac Studio arrives and its headroom is checked. EP01’s latency boundaries and EP02’s memory budget can then be attached to actual task logs.

Automatic escalation, a semantic Judge and iPhone access follow one at a time. Today stopped at the first step from architecture to execution. At least the stopping point is now known.

References

Checked October 23, 2026. Current web documentation is distinguished from installed-source behavior.

Comments & likes

No account needed. Your nickname and comment will be public. Comments appear after review.