1) Macros really helped. Harnesses are really not that complicated logically. They have a bunch of fundamental concepts like the model, tools, and loops. These can be expressed as native extensions of the language with macros. This helps because you can express them much simpler, and don't have to bloat your repo by trying to support every provider, tool call, or model.
2) The SBCL REPL is a very native place for a coding agent to live. I am not a fan of the TUIs that products like Codex or Claude Code have -- they're a little too restrictive. But the SBCL REPL is fun and interactive. It means I can do things like context management more programmatically and can inspect things in the program and in my conversation history clearly.
3) This kind of continues my macro point. But if adding support for a new model, new tool call, or new coding loop takes 20-30 lines and is already abstracted, it's very easy to have an LLM modify the harness to your purpose. There's an example where I created a custom Apprentice loop (more detail in README), but it lets you do more experimentation having the simple macros defined.
Also lots of folks today are talking about Recursive Self Intelligence and evolving intelligence, and I could see a world where in this project, you can create and define a tool call that edits the Lisp code itself to create a more effective harness! This is a unique Lisp capability due to the image-based nature of the REPL, but not something I have attempted so far.
My second project in Common Lisp. Wanted to see if I could replace my Claude Code subscription with Emacs + CL.
Lots of configurability and easy to define new models and tools! Let me know what you think -- it's my first time using macros in a non-trivial way.
Super interesting project!
Reminds me the good old days when I learn emacs lisp.
My question is, why lisp here? What is the unique advantage of using common lisp over other langs for coding harness scenario?
1) Macros really helped. Harnesses are really not that complicated logically. They have a bunch of fundamental concepts like the model, tools, and loops. These can be expressed as native extensions of the language with macros. This helps because you can express them much simpler, and don't have to bloat your repo by trying to support every provider, tool call, or model.
2) The SBCL REPL is a very native place for a coding agent to live. I am not a fan of the TUIs that products like Codex or Claude Code have -- they're a little too restrictive. But the SBCL REPL is fun and interactive. It means I can do things like context management more programmatically and can inspect things in the program and in my conversation history clearly.
3) This kind of continues my macro point. But if adding support for a new model, new tool call, or new coding loop takes 20-30 lines and is already abstracted, it's very easy to have an LLM modify the harness to your purpose. There's an example where I created a custom Apprentice loop (more detail in README), but it lets you do more experimentation having the simple macros defined.
Also lots of folks today are talking about Recursive Self Intelligence and evolving intelligence, and I could see a world where in this project, you can create and define a tool call that edits the Lisp code itself to create a more effective harness! This is a unique Lisp capability due to the image-based nature of the REPL, but not something I have attempted so far.