Skip to content

Instantly share code, notes, and snippets.

@josefrichter
Created July 12, 2026 10:34
Show Gist options
  • Select an option

  • Save josefrichter/fa402e6dc70669e2b377e734d89e6aff to your computer and use it in GitHub Desktop.

Select an option

Save josefrichter/fa402e6dc70669e2b377e734d89e6aff to your computer and use it in GitHub Desktop.
Self-authoring agent skills on the BEAM (LFE): compile an LLM snippet to a module, hot-load it, and every agent can call it. Companion to josefrichter.design/blog/skills-are-modules
(defmodule crowd-demo
(export (run 0) (install-skill 1) (bot-loop 1)))
;; ---------------------------------------------------------------------------
;; A bot is a process. It waits for work, calls whatever skill it's asked to,
;; and reports the result back. It has NO built-in knowledge of any skill.
;; ---------------------------------------------------------------------------
(defun bot-loop (name)
(receive
(`#(call ,from ,mod ,fun ,args)
(let ((result (try
(tuple 'ok (apply mod fun args))
(catch
(`#(,_class ,reason ,_stack)
(tuple 'undefined reason))))))
(! from (tuple name result)))
(bot-loop name))
('stop 'ok)))
(defun spawn-bot (name)
(spawn 'crowd-demo 'bot-loop (list name)))
;; Ask a bot to run a skill, wait for its reply, return it.
(defun ask (pid name mod fun args)
(! pid `#(call ,(self) ,mod ,fun ,args))
(receive
(`#(,name ,result) result)
(after 2000 #(error timeout))))
;; ---------------------------------------------------------------------------
;; Installing a skill: the "model" handed back source text. We read it into
;; forms (code is data), compile those forms to a real BEAM module, and
;; hot-load it into the running node. From now on EVERY process can call it.
;; ---------------------------------------------------------------------------
(defun install-skill (source)
(let* ((`#(ok ,forms) (lfe_io:read_string source))
(`#(ok (#(ok ,mod ,bin))) (lfe_comp:forms forms '())))
(code:load_binary mod "nofile" bin)
mod))
;; ---------------------------------------------------------------------------
;; The demo.
;; ---------------------------------------------------------------------------
(defun run ()
;; Two independent bots. Alice will "learn" a skill; Bob never touches it.
(let ((alice (spawn-bot 'alice))
(bob (spawn-bot 'bob)))
(io:format "1. Before anyone learns anything~n" '())
(io:format " bob asked to run web-search:query -> ~p~n~n"
(list (ask bob 'bob 'web-search 'query (list "beam vs node"))))
;; The source a model would have written, as plain text.
(let ((skill-source
"(defmodule web-search
(export (query 1)))
(defun query (q)
(++ \"results for: \" q))"))
(io:format "2. Alice installs the skill the model wrote~n" '())
(let ((mod (install-skill skill-source)))
(io:format " hot-loaded module: ~p~n~n" (list mod)))
(io:format "3. Alice runs it (she authored it)~n" '())
(io:format " alice -> ~p~n~n"
(list (ask alice 'alice 'web-search 'query (list "beam vs node"))))
(io:format "4. Bob runs the SAME skill - never installed it, never restarted~n" '())
(io:format " bob -> ~p~n~n"
(list (ask bob 'bob 'web-search 'query (list "beam vs node"))))
(! alice 'stop)
(! bob 'stop)
'ok)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment