Why Enkaidu?#

Inspiration#

It all started when I read the article “How to Build an Agent” by Thorsten Ball1 where he shows that an agentic coding assistant is at its heart no more than a loop with inference and tool calling.

I was already running local models on my Macbook using ollama and playing with building out AI-driven workflows in Ruby. When I implemented the core loop in Ruby using the ruby_llm gem and tried it with recent models, I was amazed how well tool-calling worked. While my earlier experiments with tool calling had been disappointing, clearly the models had improved substantially.

Circumstance#

A number of things were happening around the same time.

  1. Many more local models with tool-calling and “reasoning” were becoming freely available.
  2. MCP (model context protocol) was becoming prevalent and I wanted to understand how that protocol worked.
  3. I was not happy with the libraries for working with LLMs, and I wanted to use them in ways that were not easy to reconcile with their goals.

Furthermore#

Several years ago I discovered Crystal2 and since then it has been my go-to for native application development. Crystal gave me all the pleasure of Ruby-like syntax with all the performance and pleasure I felt with C.

Using Crystal also meant I could build a native CLI app, one that could run without depending on a runtine system.

Beginning#

At its simplest, Enkaidu is a user input + AI inference loop. Here’s what a very early prototype looked like,

  • with a loop that
    • queried the user for prompt,
    • repeatedly sent the prompt to the LLM,
      • executed tool calls to aquire a prompt
      • until none remained,
    • and returned to the user to go again
  print "QUERY > "
  while prompt = gets do
    while resp = llm_ask(prompt) do
      break unless resp.tool_call?

      puts "CALL: #{resp}"
      prompt = tool_call(resp)
    end
    puts resp
    print "\nQUERY > "
  end

While the loop belies the underying complexity of “asking an LLM” and “calling a tool”, it is still surprising how much of an “agent assisstant” is this entire loop.

Today#

Enkaidu has evolved into a more full-fledged “agentic assistant”, and in addition to working with local LLMs and integrating with MCP servers it also supports

  • many built-in tools and toolsets3,
  • forked sessions (a la branching) 4,
  • custom prompts5,
  • slash commands6, and
  • macros to package up slash commands and prompts7.

However, its purpose remains the same: understand how LLMs work and see through to the underlying activity of the agentic loop as a single query turns into a series of actions driven by a collaboration between the user and the AI.

Freedom#

As the commercial (and quite amazing) coding assistants became more and more entrenched in the use of commercial LLMs, Enkaidu started to become more interesting as a way to work with LLMs that we could select and mix and match.

If you want to be able to guarantee where your inference happens, or control who can see your work, or just want to see all the inner workings of how your prompts are being handled, try Enkaidu.