by shareAI-lab
Bash is all you need - A nano Claude Code–like agent, built from 0 to 1
# Add to your Claude Code skills
git clone https://github.com/shareAI-lab/learn-claude-code THE AGENT PATTERN
=================
User --> messages[] --> LLM --> response
|
stop_reason == "tool_use"?
/ \
yes no
| |
execute tools return text
append results
loop back -----------------> messages[]
That's the minimal loop. Every AI coding agent needs this loop.
Production agents add policy, permissions, and lifecycle layers.
12 progressive sessions, from a simple loop to isolated autonomous execution. Each session adds one mechanism. Each mechanism has one motto.
s01 "Bash is all you need" — one tool + one loop = an agent
s02 "The loop didn't change" — adding tools means adding handlers, not rewriting the loop
s03 "Plan before you act" — visible plans improve task completion
s04 "Process isolation = context isolation" — fresh messages[] per subagent
s05 "Load on demand, not upfront" — inject knowledge via tool_result, not system prompt
s06 "Strategic forgetting" — forget old context to enable infinite sessions
s07 "State survives /compact" — file-based state outlives context compression
No comments yet. Be the first to share your thoughts!
s08 "Fire and forget" — non-blocking threads + notification queue
s09 "Append to send, drain to read" — async mailboxes for persistent teammates
s10 "Same request_id, two protocols" — one FSM pattern powers shutdown + plan approval
s11 "Poll, claim, work, repeat" — no coordinator needed, agents self-organize
s12 "Isolate by directory, coordinate by task ID" — task board + optional worktree lanes
def agent_loop(messages):
while True:
response = client.messages.create(
model=MODEL, system=SYSTEM,
messages=messages, tools=TOOLS,
)
messages.append({"role": "assistant",
"content": response.content})
if response.stop_reason != "tool_use":
return
results = []
for block in response.content:
if block.type == "tool_use":
output = TOOL_HANDLERS[block.name](**block.input)
results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": output,
})
messages.append({"role": "user", "content": results})
Ever...