The core logic here is that the environment (Docker, a sandbox, etc.) should be your security boundary, not the code harness itself. By avoiding a system prompt, you also save precious context window tokens, which modern high-reasoning models handle just fine without.
Here is the complete implementation for a lightweight AI workflow:
import json,sys;from subprocess import getoutput as sh;from urllib.request import Request as R,urlopen
url=sys.argv[1];h=[];b=dict(model="gpt-5.6",input=h,tools=[dict(type="custom",name="sh")])
while p:=input("> "):
h+=[dict(role="user",content=p)];H={"Content-Type":"application/json"}
while True:
o=(r:=json.load(urlopen(R(url,json.dumps(b).encode(),H))))["output"]
h+=o;c=[i for i in o if i["type"]=="custom_tool_call"];z=r["usage"]["total_tokens"]/10500
if not c:print(o[-1]["content"][0]["text"],f'\n[{z:06.3f}%]');break
h+=[dict(type="custom_tool_call_output",call_id=i["call_id"],output=sh(i["input"])) for i in c]
Why this works as a practical tutorial for agents #
If you want to deploy this from scratch, here is the breakdown of the logic:
- Zero Dependencies: It uses
urllib
and subprocess
from the stdlib. This means zero supply chain risk and near-instant startup time.
- The Tool Loop: The
while True
loop is the "brain." It checks if the model's output contains a custom_tool_call
. If it does, it executes the shell command (sh
) and feeds the result back into the history (h
).
- Open-Ended Control: By giving the agent access to
sh
, you've essentially given it the keys to the environment. It can read files, list directories, or run scripts.
- Context Tracking: The
z
variable calculates the percentage of the context window used, which is critical for long-running sessions.
To run this, you just need an OpenAI-compatible inference endpoint. You can pass the URL as a command-line argument: python agent.py http://your-api-endpoint
.
This is a great starting point for anyone wanting a deep dive into how LLM agents actually function without the abstraction layers of LangChain or AutoGPT.
Next AI Voiceover Workflow: Scaling Solo Content →