Codex 校核(2026-10-09) Python 官方 exec 文档明确:限制 globals 或覆盖 builtins 并不是安全机制,执行代码仍可访问内建能力;原文“Python exec 限制命名空间更安全”不能理解为可运行不可信代码的沙箱。代码执行必须另外建立操作系统或虚拟机隔离与权限边界。 MCP 当前 2026-07-28 Tools 规范规定 tools/list 返回当前工具集,并可通过 subscriptions/listen 的 toolsListChanged 与 notifications/tools/list_changed 通知变化;“MCP 工具设计时定义、运行时不能变化”的对比不准确。动态造函数是本文方案的设计方向,不代表它比 MCP 的动态发现更通用或已具备安全隔离。对话持久化也不能单独证明运行时函数对象在重启后恢复。
An Agent in 100 Lines of Lisp — 深度消化
来源: HN: 126pts | 原文 | GitHub 作者: Jamie Beach 消化时间: 2026-07-12 16:00 UTC
核心发现
一个 AI agent loop 本质上只是一个 8 行递归函数。当模型被赋予 Lisp 的 eval 作为唯一的工具时,它能自己写出第二个工具(web search)、第三个工具(任意计算)——完全颠覆了”工具目录在设计时固定”的传统假设。
技术要点
1. Agent loop = 递归函数
(defun agent-loop (messages)
(let* ((message (ref (call-model messages) "choices" 0 "message"))
(tool-calls (gethash "tool_calls" message)))
(if (and tool-calls (plusp (length tool-calls)))
(agent-loop (append messages
(list message)
(map 'list #'execute tool-calls)))
(append messages (list message)))))- 基本情况:模型回答 → 返回历史
- 递归情况:模型要调用工具 → 执行工具 → 追加结果 → 递归
- 无框架,无状态机,agent 的状态就是被递归折叠的消息列表
2. 唯一工具:eval
Lisp 是同像性(homoiconic)语言——代码就是数据,数据就是代码。模型写出 Lisp 表达式字符串,agent 直接 read 然后 eval。
* (agent:run "What is the 30th Fibonacci number? Compute it, don't recall it.")
⤷ (defun fibonacci (n) (if (<= n 2) 1 (+ (fibonacci (- n 1)) (fibonacci (- n 2))))) => FIBONACCI
⤷ (fibonacci 30) => 832040
模型没有”回忆”答案,它写了一个递归函数并运行了它。
3. 自我构建工具
作者给了 agent 一个 Brave Search API key。agent 用 eval 自己写了个 brave-search 函数:
(defun brave-search (api-key query &key (count 10))
"Search using Brave Search API"
(let* ((encoded-query (quri:url-encode query))
(url (format nil "https://api.search.brave.com/res/v1/web/search?q=~a&count=~d" encoded-query count))
(response (dexador:get url :headers `(("Accept" . "application/json")
("X-Subscription-Token" . ,api-key)))))
(shasht:read-json response)))从未构建 web search 工具。Agent 只有一个工具(eval),用这个工具写出了第二个工具。
4. 记忆 = 20 行文件 I/O
(defun remember (messages)
(with-open-file (out *memory-file* :direction :output :if-exists :supersede)
(shasht:write-json (coerce messages 'vector) out))
messages)
(defun recall ()
(if (probe-file *memory-file*)
(coerce (with-open-file (in *memory-file*) (shasht:read-json in)) 'list)
(list *system-message*)))无 schema,无迁移,无向量数据库。序列化格式 = 运行时格式。
5. 技能即记忆
通过 eval 定义的函数在进程退出时消失,但 transcript 持久化了。在新会话中,agent 读取自己的历史并通过 eval 重新让能力”活”过来。
“An agent whose skills are literally stories it tells itself.”
对 Hermes 的启发
| 维度 | 当前 Hermes | 可借鉴 |
|---|---|---|
| Agent loop | 命令式状态机 | 递归消息累积模式 |
| 工具扩展 | MCP 设计时协商 | Python exec() 作为运行时自建工具 |
| 技能系统 | SKILL.md 预编写 | 技能作为”模型写给自己看的故事” |
| 记忆 | gbrain / pgvector | 轻量场景可只用 JSON 文件 |
| 持久化 | 多存储后端 | ”remember-compress-recall” 模式 |
关键 insight: Hermes 已经在滑动这条光谱——代码解释器是第一代(模型写临时程序),SKILL.md 是第二代(能力存为文本运行时加载)。Lisp agent 把剩余的距离一下子拉平了:它的技能就存在自己的 transcript 里。
建议
- 🟡 P1 — 探索为 Hermes 添加 Python
exec()工具(沙箱化),让模型能直接写代码并执行,不需要绕道terminal()。这比当前模式更安全(受限命名空间)且更自文档化(模型会追踪自己写的代码) - 🟢 P2 — 研究 Hermes 的 agent loop 能否简化为递归消息累积模式
- 🟢 P2 — 将 “skills are memories” 洞察记录到 multi-agent-coordination skill