mirror of
https://github.com/shareAI-lab/analysis_claude_code.git
synced 2026-02-04 05:06:39 +08:00
3.8 KiB
3.8 KiB
v0: Bash is All You Need
The ultimate simplification: ~50 lines, 1 tool, full agent capability.
After building v1, v2, and v3, a question emerges: what is the essence of an agent?
v0 answers this by going backwards—stripping away everything until only the core remains.
The Core Insight
Unix philosophy: everything is a file, everything can be piped. Bash is the gateway to this world:
| You need | Bash command |
|---|---|
| Read files | cat, head, grep |
| Write files | echo '...' > file |
| Search | find, grep, rg |
| Execute | python, npm, make |
| Subagent | python v0_bash_agent.py "task" |
The last line is the key insight: calling itself via bash implements subagents. No Task tool, no Agent Registry—just recursion.
The Complete Code
#!/usr/bin/env python
from anthropic import Anthropic
import subprocess, sys, os
client = Anthropic(api_key="your-key", base_url="...")
TOOL = [{
"name": "bash",
"description": """Execute shell command. Patterns:
- Read: cat/grep/find/ls
- Write: echo '...' > file
- Subagent: python v0_bash_agent.py 'task description'""",
"input_schema": {"type": "object", "properties": {"command": {"type": "string"}}, "required": ["command"]}
}]
SYSTEM = f"CLI agent at {os.getcwd()}. Use bash. Spawn subagent for complex tasks."
def chat(prompt, history=[]):
history.append({"role": "user", "content": prompt})
while True:
r = client.messages.create(model="...", system=SYSTEM, messages=history, tools=TOOL, max_tokens=8000)
history.append({"role": "assistant", "content": r.content})
if r.stop_reason != "tool_use":
return "".join(b.text for b in r.content if hasattr(b, "text"))
results = []
for b in r.content:
if b.type == "tool_use":
out = subprocess.run(b.input["command"], shell=True, capture_output=True, text=True, timeout=300)
results.append({"type": "tool_result", "tool_use_id": b.id, "content": out.stdout + out.stderr})
history.append({"role": "user", "content": results})
if __name__ == "__main__":
if len(sys.argv) > 1:
print(chat(sys.argv[1])) # Subagent mode
else:
h = []
while (q := input(">> ")) not in ("q", ""):
print(chat(q, h))
That's the entire agent. ~50 lines.
How Subagents Work
Main Agent
└─ bash: python v0_bash_agent.py "analyze architecture"
└─ Subagent (isolated process, fresh history)
├─ bash: find . -name "*.py"
├─ bash: cat src/main.py
└─ Returns summary via stdout
Process isolation = Context isolation
- Child process has its own
history=[] - Parent captures stdout as tool result
- Recursive calls enable unlimited nesting
What v0 Sacrifices
| Feature | v0 | v3 |
|---|---|---|
| Agent types | None | explore/code/plan |
| Tool filtering | None | Whitelists |
| Progress display | Plain stdout | Inline updates |
| Code complexity | ~50 lines | ~450 lines |
What v0 Proves
Complex capabilities emerge from simple rules:
- One tool is enough — Bash is the gateway to everything
- Recursion = hierarchy — Self-calls implement subagents
- Process = isolation — OS provides context separation
- Prompt = constraint — Instructions shape behavior
The core pattern never changes:
while True:
response = model(messages, tools)
if response.stop_reason != "tool_use":
return response.text
results = execute(response.tool_calls)
messages.append(results)
Everything else—todos, subagents, permissions—is refinement around this loop.
Bash is All You Need.