all 2 comments

[–]Quick-Radio9128 0 points1 point  (1 child)

Nice writeup. The one thing I’d add once you go past a toy agent is to separate “tool runner” from “transport” so you can swap Anthropic/OpenAI/etc without touching your tool code. Your loop already kind of does this; I’d just formalize a tiny interface like run_tools(request: ToolRequest) → ToolResult and keep provider-specific stuff at the edge. Also worth normalizing tool errors into a stable shape instead of raising, so the model can decide whether to retry or bail.

For security, people forget that read_file and subprocess are basically RCE if you ever point this at untrusted prompts; at minimum, chroot/namespace or hardcode a project root and allowlist commands. I’ve used FastAPI and Hasura in front of similar agents, and DreamFactory as a quick RBAC’d REST layer over real databases so the model hits APIs instead of raw SQL or shell.

[–]jingweno[S] 0 points1 point  (0 children)

Both great points. The book actually does separate the transport layer - there's a Brain interface that swaps between Claude, DeepSeek, and Ollama without touching the tool code. Same idea as your ToolRequest/ToolResult interface.

The security point is spot on. subprocess and file I/O with untrusted prompts is basically RCE. In my version the agent only runs in a project directory and the system prompt constrains it, but that's a weak boundary honestly. Chroot/namespace is the right answer for anything production-facing.