C.W.K.
Stream
Lesson 03 of 05 · published

Common Production Tools: Files, Web, Code

~38 min · files, web, sandbox, code-execution

Level 0Observer
0 XP0/40 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete

Agents need boring hands

The glamorous part is model choice. The useful part is a toolbelt that reads files, searches the web, fetches URLs, writes drafts, runs tests, and reports failures without destroying the workspace. Most agent products are differentiated by tool quality more than by slogans.

Separate read, write, and execute

Do not give one vague file_tool the power to list, read, write, delete, and shell out. Split tools by blast radius. Read tools can be broad. Write tools should be scoped. Execute tools need sandboxing, timeout, output caps, and approval.

Tool results should point, not dump

A search tool should return ids, titles, URLs, snippets, and confidence. It should not dump an entire webpage. A file search should return paths and match ranges. The next tool can fetch the full content when the model has earned it.

Code

File tools with scoped writes·python
from pathlib import Path

WORKSPACE = Path("/workspace").resolve()

def resolve_safe(path: str) -> Path:
    target = (WORKSPACE / path).resolve()
    if not str(target).startswith(str(WORKSPACE)):
        raise PermissionError("Path escapes workspace")
    return target

def read_file(path: str, max_chars: int = 12000) -> dict:
    target = resolve_safe(path)
    return {"path": str(target), "content": target.read_text()[:max_chars]}

def write_draft(path: str, content: str) -> dict:
    target = resolve_safe(path)
    if not str(target).endswith(".md"):
        raise PermissionError("write_draft only writes markdown")
    target.parent.mkdir(parents=True, exist_ok=True)
    target.write_text(content)
    return {"path": str(target), "chars": len(content), "changed_state": True}
Web tools with result envelopes·python
def web_search(query: str, max_results: int = 5) -> dict:
    raw = search_provider(query, max_results=max_results)
    return {
        "query": query,
        "results": [
            {
                "id": f"r{i}",
                "title": item["title"],
                "url": item["url"],
                "snippet": item["snippet"][:240],
            }
            for i, item in enumerate(raw[:max_results])
        ],
        "next_action": "Use fetch_url(url) for the most relevant official source.",
    }
Code execution needs a real sandbox·python
import subprocess, tempfile, textwrap

def run_python_sandboxed(code: str, timeout: int = 10) -> dict:
    with tempfile.NamedTemporaryFile("w", suffix=".py", delete=False) as f:
        f.write(textwrap.dedent(code))
        filename = f.name
    result = subprocess.run(
        ["python", filename],
        text=True,
        capture_output=True,
        timeout=timeout,
    )
    return {
        "exit_code": result.returncode,
        "stdout": result.stdout[-4000:],
        "stderr": result.stderr[-4000:],
    }

External links

Exercise

Design a three-tool file system API for an agent: one read tool, one scoped write tool, and one approval-required destructive tool.
Hint
Different blast radius means different tool. Don't hide it behind one mega-tool.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.