AIBites: AI Agent Prototype

tool use, agentic loop, file-reading agent, safety constraints

"The future of intelligence isn't artificial; it's collaborative."
- Perplexity.AI

1.0 - Introduction

AI Agents pdf   YouTube video An agent is a program that calls an LLM in a loop, giving the model access to tools (functions it can invoke), and continuing until the model decides it has finished. Agents let a developer go beyond what a browser chat bot offers: agent code running locally can read and write local files directly, without copying and pasting through a browser.
Fig 1. Agent Data Flow
Agent code replaces the platform chatbot UI with local code that sends prompts and receives results from a containerized LLM running in a data center. It uses messaging infrastructure from the platform Messages API. Fig 1 traces the round trip for a single prompt. The agent prepends a system prompt and any conversation history, then sends the combined context to the LLM container via the platform's HTTPS endpoint. The model generates a response - or a tool call requesting the agent to run a local function - and returns the result to the agent code. When the model issues a tool call the agent executes the requested function (e.g. reading a file), appends the result to the message history as a tool_result block, and calls the API again. The loop continues until the model signals end_turn.
Why agents instead of single calls?
  1. A single call cannot react to its own output. An agent can read a file, see what’s in it, and decide what to read next.
  2. Tool use turns the model into an orchestrator: it plans, delegates to tools, and synthesizes results - all without user intervention.
  3. Agents can retry failed steps, ask clarifying questions, and handle unexpected inputs gracefully.

2.0 - Agent Execution

Agents are applications that usually run from a terminal. The agent dev_agent.py, an example written in Python, is shown running in Fig 2. Click on the figure body to expand, click on the title to contract.
Fig 2. Agent Analysis of RustDirNav/src/lib.rs
The agent defines 7 user commands. Entering any other text sends it as a free-form prompt to the LLM. The execution in Fig 2 starts by providing a path to the project directory ./Test/RustDirNav. It then uses the /analyze command with a file path in that project to explore features and bugs in the Rust library. Fig 2 shows the terminal session after the agent starts in the ./Test/RustDirNav directory. The top of the output lists the 7 commands and confirms the working path. The user then runs /files to see which source files the agent found, followed by /analyze ./src/lib.rs. The agent reads the file, bundles it with a structured analysis prompt, and sends the combined message to the LLM. The model returns a markdown report covering purpose, code quality, potential improvements, identified bugs, and a recommended refactoring - all displayed inline in the terminal. The agent application code can be modified to fine-tune behavior, add new commands, and format output. Asking the claude.ai chatbot to make those changes works, but manual edits are often faster and more reliable.

3.0 - Defining a Tool

A tool is a JSON schema the agent passes to the API so the model knows which functions are available, what arguments they expect, and what they do. The model decides when to call a tool; the agent executes it and returns the result.
tools = [{
    "name": "read_file",
    "description": "Read a source file and return its contents as a string.",
    "input_schema": {
        "type": "object",
        "properties": {
            "path": {"type": "string", "description": "Relative path to the file"}
        },
        "required": ["path"]
    }
}]

4.0 - The Agentic Loop

The agentic loop calls the API repeatedly. Each iteration either receives a final answer (end_turn) or a tool call that the agent must execute before continuing. The full message history - including tool results - travels with every request so the model retains context across iterations.
import anthropic, pathlib

client = anthropic.Anthropic()
messages = [{"role": "user", "content": "Summarize the file main.py."}]

while True:
    resp = client.messages.create(
        model="claude-sonnet-4-6", max_tokens=2048,
        tools=tools, messages=messages
    )
    if resp.stop_reason == "end_turn":
        print(resp.content[0].text)
        break
    for block in resp.content:
        if block.type == "tool_use":
            text = pathlib.Path(block.input["path"]).read_text()
            messages += [
                {"role": "assistant", "content": resp.content},
                {"role": "user", "content": [{
                    "type": "tool_result",
                    "tool_use_id": block.id,
                    "content": text
                }]}
            ]

5.0 - Generating Agent Code

This page shows an example agent generated by the Claude.ai chatbot. It is written in Python and designed to support software development in common programming languages. Here are the prompts used with Claude Sonnet 4.5:
"generate a python agent that uses Anthropic API to support software development for code in a specified directory"
"modify to use Anthropic Key in environment variables (Win 11) if one is not supplied"
That prompt is unambiguous but allows a very broad range of possible responses. The results turned out to be surprisingly useful.
Using the Anthropic API requires a key linked to a credit card. The key setup allows spending limits to prevent surprises. This example used $0.07 to generate the agent and exercise it with several commands.

6.0 - Agent Code

The dropdown below displays all of the Python agent code. This defines a tool that handles local files and uses an Anthropic LLM to analyze directory structure and file contents.
Dev Agent Code The first 116 lines define functions that use the local file system and display output. Starting at line 118 the chat function builds a context, sends a prompt, and receives a reply via the Anthropic Messages API at line 152.
Figure 1. dev_agent.py

  1 """
  2 Software Development Agent using Anthropic API
  3 A sophisticated agent for analyzing, improving, and maintaining code in a specified directory.
  4 """
  5
  6 import anthropic
  7 import os
  8 import sys
  9 from pathlib import Path
 10 from typing import List, Dict, Optional
 11 import json
 12 import argparse
 13
 14 class SoftwareDevAgent:
 15     def __init__(self, api_key: str, directory: str, model: str = "claude-sonnet-4-20250514"):
 16         self.client = anthropic.Anthropic(api_key=api_key)
 17         self.directory = Path(directory).resolve()
 18         self.model = model
 19         self.conversation_history = []
 20
 21         if not self.directory.exists():
 22             raise ValueError(f"Directory does not exist: {self.directory}")
 23
 24     def get_file_tree(self, max_depth: int = 3) -> str:
 25         lines = [f"?? {self.directory.name}/"]
 26
 27         def add_tree(path: Path, prefix: str = "", depth: int = 0):
 28             if depth >= max_depth:
 29                 return
 30             try:
 31                 items = sorted(path.iterdir(), key=lambda x: (not x.is_dir(), x.name))
 32                 items = [item for item in items if not item.name.startswith('.')
 33                          and item.name not in ['__pycache__', 'node_modules', 'bin', 'obj']]
 34                 for i, item in enumerate(items):
 35                     is_last = i == len(items) - 1
 36                     connector = "?? " if is_last else "??? "
 37                     extension = "    " if is_last else "?   "
 38                     icon = "?? " if item.is_dir() else "?? "
 39                     lines.append(f"{prefix}{connector}{icon}{item.name}")
 40                     if item.is_dir():
 41                         add_tree(item, prefix + extension, depth + 1)
 42             except PermissionError:
 43                 pass
 44
 45         add_tree(self.directory)
 46         return "\n".join(lines)
 47
 48     def get_code_files(self) -> List[Path]:
 49         code_extensions = {'.py', '.js', '.jsx', '.ts', '.tsx', '.java', '.cpp',
 50                            '.c', '.h', '.hpp', '.cs', '.rs', '.go', '.rb', '.php'}
 51         files = []
 52         exclude_dirs = {'__pycache__', 'node_modules', 'bin', 'obj', '.git'}
 53         for path in self.directory.rglob('*'):
 54             if path.is_file() and path.suffix in code_extensions:
 55                 if not any(part in exclude_dirs for part in path.parts):
 56                     files.append(path)
 57         return files
 58
 59     def read_file(self, file_path: str) -> str:
 60         path = self.directory / file_path
 61         if not path.exists():
 62             return f"File not found: {file_path}"
 63         try:
 64             return path.read_text(encoding='utf-8')
 65         except Exception as e:
 66             return f"Error reading file: {e}"
 67
 68     def format_file_list(self) -> str:
 69         files = self.get_code_files()
 70         if not files:
 71             return "No code files found in directory."
 72         relative_files = [str(f.relative_to(self.directory)) for f in files]
 73         return f"Found {len(files)} code files:\n" + "\n".join(f"  - {f}" for f in relative_files)
 74
 75     def build_context(self) -> str:
 76         tree = self.get_file_tree()
 77         files = self.get_code_files()
 78         file_list = "\n".join(f"  - {f.relative_to(self.directory)}" for f in files[:20])
 79         return f"Project: {self.directory.name}\n\nDirectory Structure:\n{tree}\n\nCode Files:\n{file_list}"
 80
 81     def chat(self, user_message: str, include_context: bool = False) -> str:
 82         if include_context:
 83             context = self.build_context()
 84             full_message = f"Project context:\n{context}\n\nUser question: {user_message}"
 85         else:
 86             full_message = user_message
 87
 88         self.conversation_history.append({"role": "user", "content": full_message})
 89
 90         response = self.client.messages.create(
 91             model=self.model,
 92             max_tokens=4096,
 93             system="""You are an expert software development assistant. You help analyze code,
 94                 suggest improvements, identify bugs, and provide documentation. Be concise but thorough.
 95                 When analyzing code, focus on: correctness, performance, security, and maintainability.""",
 96             messages=self.conversation_history
 97         )
 98
 99         assistant_message = response.content[0].text
 100         self.conversation_history.append({"role": "assistant", "content": assistant_message})
 101         return assistant_message
 102
 103     def analyze_file(self, file_path: str) -> str:
 104         content = self.read_file(file_path)
 105         prompt = f"""Analyze this source file: {file_path}
 106             File contents:
 107             {content}
 108             Please provide:
 109             1. Purpose and functionality
 110             2. Code quality assessment
 111             3. Potential improvements
 112             4. Bugs and issues
 113             5. Documentation suggestions
 114             6. Recommended refactoring if needed"""
 115         return self.chat(prompt)
 116
 117     def suggest_improvements(self) -> str:
 118         context = self.build_context()
 119         prompt = f"""Based on this project:
 120             {context}
 121             Provide comprehensive improvement suggestions for:
 122             1. Project organization
 123             2. Code architecture
 124             3. Testing strategy
 125             4. Documentation strategy
 126             5. Development workflow"""
 127         return self.chat(prompt)
 128
 129     def generate_readme(self) -> str:
 130         context = self.build_context()
 131         prompt = f"Generate a comprehensive README.md for:\n{context}"
 128         return self.chat(prompt)
 129
 130     def interactive_mode(self):
 131         print("\n?? Software Development Agent")
 132         print(f"?? Working Directory: {self.directory}\n")
 133         print("Commands:")
 134         print("  /analyze [file] - Analyze a specific file")
 135         print("  /improve - Get improvement suggestions")
 136         print("  /readme - Generate README")
 137         print("  /tree - Show directory tree")
 138         print("  /files - List code files")
 139         print("  /clear - Clear conversation history")
 140         print("  /quit - Exit\n")
 141         print("Or just ask me anything about your code!\n")
 142
 143         while True:
 144             try:
 145                 user_input = input("You: ").strip()
 146                 if not user_input:
 147                     continue
 148                 if user_input.lower() == '/quit':
 149                     print("\nGoodbye!")
 150                     break
 151                 elif user_input.lower() == '/clear':
 152                     self.conversation_history = []
 153                     print("Conversation history cleared.")
 154                 elif user_input.lower() == '/tree':
 155                     print(self.get_file_tree())
 156                 elif user_input.lower() == '/files':
 157                     print(self.format_file_list())
 158                 elif user_input.lower() == '/improve':
 159                     print("\n?? Generating suggestions...\n")
 160                     print(self.suggest_improvements())
 161                 elif user_input.lower() == '/readme':
 162                     print("\n?? Generating README...\n")
 163                     print(self.generate_readme())
 164                 elif user_input.lower().startswith('/analyze'):
 165                     parts = user_input.split(maxsplit=1)
 166                     if len(parts) > 1:
 167                         file_path = parts[1]
 168                         print(f"\n?? Analyzing...\n")
 169                         print(self.analyze_file(file_path))
 170                     else:
 171                         print("Usage: /analyze <file_path>")
 172                 else:
 173                     include_ctx = len(self.conversation_history) == 0
 174                     print("\nAgent: " + self.chat(user_input, include_context=include_ctx) + "\n")
 175             except KeyboardInterrupt:
 176                 print("\n\nInterrupted. Type /quit to exit.")
 177             except Exception as e:
 178                 print(f"Error: {e}")
 179
 180 def main():
 181     parser = argparse.ArgumentParser(description='Software Development Agent using Anthropic API')
 182     parser.add_argument('directory', nargs='?', default='.', help='Project directory path')
 183     parser.add_argument('--api-key', help='Anthropic API key (or set ANTHROPIC_API_KEY env var)')
 184     parser.add_argument('--model', default='claude-sonnet-4-20250514', help='Claude model to use')
 185     parser.add_argument('--analyze', help='Analyze a specific file and exit')
 186     parser.add_argument('--improve', action='store_true', help='Get improvement suggestions and exit')
 187     parser.add_argument('--readme', action='store_true', help='Generate README and exit')
 188     args = parser.parse_args()
 189
 190     api_key = args.api_key or os.environ.get("ANTHROPIC_API_KEY")
 191     if not api_key:
 192         print("\n? Error: Anthropic API key is required")
 193         print("Set ANTHROPIC_API_KEY or pass --api-key")
 194         sys.exit(1)
 195
 196     try:
 197         agent = SoftwareDevAgent(api_key, args.directory, args.model)
 198     except ValueError as e:
 199         print(f"Error: {e}")
 200         sys.exit(1)
 201
 202     if args.analyze:
 203         print(agent.analyze_file(args.analyze))
 204     elif args.improve:
 205         print(agent.suggest_improvements())
 206     elif args.readme:
 207         print(agent.generate_readme())
 208     else:
 209         agent.interactive_mode()
 210
 211 if __name__ == "__main__":
 212     main()

6.1 - Initializing the Agent

When started the agent accepts a path to a project directory and emits a list of available commands. Entering free-form text sends that as a prompt to the LLM.
Initialize Agent Figure 2. Starting dev_agent.py

  1 C:\github\JimFawcett\NewSite\Code\AI\DemoAgent-Claude2
  2 > python dev_agent.py ./Test/RustDirNav
  3
  4 ?? Software Development Agent
  5 ?? Working Directory: C:\github\JimFawcett\NewSite\Code\AI\DemoAgent-Claude2\Test\RustDirNav
  6
  7 Commands:
  8   /analyze [file] - Analyze a specific file
  9   /improve - Get improvement suggestions
 10   /readme - Generate README
 11   /tree - Show directory tree
 12   /files - List code files
 13   /clear - Clear conversation history
 14   /quit - Exit
 15
 16 Or just ask me anything about your code!
 17
        

6.2 - File Tree

The /tree command displays the directory subtree rooted at the specified project path. That helps to properly configure an /analyze command.
Local File Tree Figure 3. Local file tree

 17 You: /files
 18
 19 Found 4 code files:
 20   - examples\test1.rs
 21   - src\lib.rs
 22   - test_dir\test_file.rs
 23   - test_dir\test_sub1_dir\test_file1.rs

 24 You: /tree
 25
 26 ?? RustDirNav/
 27 ├── ?? Pictures
 28 │   ├── ?? RustDirNav.jpg
 29 │   └── ?? RustDirNavOutput.JPG
 30 ├── ?? examples
 31 │   ├── ?? test1.rs
 32 │   └── ?? test11.rs.html
 33 ├── ?? src
 34 │   ├── ?? lib.rs
 35 │   └── ?? lib1.rs.html
 36 ├── ?? test_dir
 37 │   ├── ?? test_sub1_dir
 38 │   │   ├── ?? test_file1.rs
 39 │   │   └── ?? test_file2.exe
 40 │   ├── ?? test_sub2_dir
 41 │   │   └── ?? test_file3.txt
 42 │   └── ?? test_file.rs
 43 ├── ?? Cargo.lock
 44 ├── ?? Cargo.toml
 45 └── ?? README.md
        

6.3 - Analysis Source File

The next section shows the agent's file analysis of a Rust library that implements directory navigation. Here is the source code for that library file.
RustDirNav/src/lib.rs Code Figure 4. Rust Directory Navigation Library
  1 /////////////////////////////////////////////////////////////
  2 // rust_dir_nav::lib.rs                                     //
  3 // Jim Fawcett, https://JimFawcett.github.io, 12 Apr 2020   //
  4 /////////////////////////////////////////////////////////////
  5 /*
  6    DirNav<App> is a directory navigator that uses the generic
  7    parameter App to define how files and directories are handled.
  8    - displays only paths that have file targets by default
  9    - hide(false) will show all directories traversed
 10    - recurses directory tree at specified root by default
 11    - recurse(false) examines only specified path.
 12 */
 13 use std::fs::{self, DirEntry};
 14 use std::io;
 15 use std::io::{Error, ErrorKind};
 16 use std::path::{Path, PathBuf};
 17
 18 pub trait DirEvent {
 19     fn do_dir(&mut self, d: &str);
 20     fn do_file(&mut self, f: &str);
 21 }
 22
 23 pub struct DirNav<App: DirEvent + Default> {
 24     pub pats: Vec<String>,
 25     pub app: App,
 26     pub num_files: usize,
 27     pub num_dirs: usize,
 28     pub recurse: bool,
 29     pub hide: bool,
 30 }
 31
 32 impl<App: DirEvent + Default> DirNav<App> {
 33     pub fn new() -> Self {
 34         DirNav {
 35             pats: Vec::new(),
 36             app: App::default(),
 37             num_files: 0,
 38             num_dirs: 0,
 39             recurse: true,
 40             hide: true,
 41         }
 42     }
 43
 44     pub fn add_pat<S: Into<String>>(&mut self, patt: S) -> &mut Self {
 45         self.pats.push(patt.into());
 46         self
 47     }
 48
 49     pub fn in_patterns(&self, entry: &DirEntry) -> bool {
 50         let filename = entry.file_name().into_string().unwrap_or_default();
 51         let ext = filename.split('.').last().unwrap_or_default();
 52         self.pats.iter().any(|p| p == ext)
 53     }
 54
 55     pub fn visit(&mut self, dir: &Path) -> io::Result<()> {
 56         if !dir.is_dir() {
 57             return Err(Error::new(ErrorKind::InvalidInput, "not a directory"));
 58         }
 59         self.num_dirs += 1;
 60         let mut files: Vec<PathBuf> = Vec::new();
 61         let mut dirs: Vec<PathBuf> = Vec::new();
 62
 63         for entry in fs::read_dir(dir)? {
 64             let entry = entry?;
 65             if entry.path().is_dir() {
 66                 dirs.push(entry.path());
 67             } else if self.in_patterns(&entry) | self.pats.is_empty() {
 68                 files.push(entry.path());
 69             }
 70         }
 71
 72         if !files.is_empty() || !self.hide {
 73             self.app.do_dir(&dir.display().to_string());
 74         }
 75
 76         for f in files {
 77             self.num_files += 1;
 78             self.app.do_file(&f.display().to_string());
 79         }
 80
 81         if self.recurse {
 82             for d in dirs {
 83                 self.visit(&d)?;
 84             }
 85         }
 86         Ok(())
 87     }
 88 }

6.4 - Analysis Results

The agent's analysis of RustDirNav/src/lib.rs covers purpose, code quality, potential improvements, bugs, documentation, and a recommended refactoring.
Analyze Code File The analysis covers: purpose and functionality, code quality assessment, potential improvements, bugs and issues, documentation suggestions, and recommended refactoring. Figure 5. dev_agent.py analyze ./src/lib.rs
 46 You: /analyze ./src/lib.rs
 47
 48 ?? Analyzing...
 49
 50 Agent: ## Analysis of `rust_dir_nav::lib.rs`
 51
 52 ### 1. Purpose and Functionality
 53
 54 This library provides a generic directory navigation system (`DirNav<App>`) that traverses
 55 filesystem directories and processes files based on configurable patterns (file extensions).
 56
 57 Key features:
 58 - **Generic Design**: Uses a trait (`DirEvent`) to allow custom file/directory handling
 59 - **Pattern Matching**: Filters files by extensions
 60 - **Configurable Traversal**: Options for recursive traversal and hiding empty directories
 61 - **Cross-platform**: Handles Windows/Linux path separator differences
 62
 63 ### 2. Code Quality Assessment
 64
 65 **Strengths:**
 66 - Good use of generics and traits for extensibility
 67 - Comprehensive test coverage with proper setup
 68 - Clear separation of concerns
 69 - Proper error handling with `io::Result`
 70
 71 **Areas for Improvement:**
 72 - Some inconsistent naming conventions
 73 - Mixed coding styles
 74 - Platform-specific code that could be better abstracted
 75
 76 ### 3. Potential Improvements
 77
 78 #### A. Consistent Naming
 79
 80 ```rust
 81 pub trait DirectoryEventHandler {  // More descriptive than DirEvent
 82     fn handle_directory(&mut self, path: &str);
 83     fn handle_file(&mut self, path: &str);
 84 }
 85 ```
 86
 87 #### B. Improved Error Handling
 88
 89 ```rust
 90 use thiserror::Error;
 91
 92 #[derive(Error, Debug)]
 93 pub enum DirNavError {
 94     #[error("Path is not a directory: {path}")]
 95     NotADirectory { path: String },
 96     #[error("IO error: {0}")]
 97     Io(#[from] std::io::Error),
 98 }
 99 ```
 100
 101 #### C. Simplified Pattern Matching
 102
 103 ```rust
 104 fn matches_pattern(&self, entry: &DirEntry) -> bool {
 105     if self.patterns.is_empty() { return true; }
 106     entry.path()
 107         .extension()
 108         .and_then(|ext| ext.to_str())
 109         .map(|ext| self.patterns.iter().any(|pat| pat == ext))
 110         .unwrap_or(false)
 111 }
 112 ```
 113
 114 ### 4. Bugs and Issues
 115
 116 #### Critical: Logical vs. Bitwise OR at line 67
 117
 118 ```rust
 119 // BUG: | evaluates both sides regardless of left result
 120 if self.in_patterns(&entry) | self.pats.is_empty() {
 121 // CORRECT:
 122 if self.in_patterns(&entry) || self.pats.is_empty() {
 123 ```
 124
 125 #### Design: Mutable Reference Return
 126 `get_app()` returns a mutable reference, breaking encapsulation.
 127
 128 ### 5. Documentation Suggestions
 129
 130 Add module-level doc comments explaining the generic parameter contract and usage examples.
 131
 132 ### 6. Recommended Refactoring
 133
 134 The core logic can be made more idiomatic by separating configuration from traversal state,
 135 using a builder pattern for construction, and passing `&Path` instead of `&str` to event
 136 handler methods.
If I wanted to strengthen this library for production use I would implement some, but not all, of the suggestions. Some add complexity without much added value.

6.5 - Suggested Improvements

The /improve command asks the agent to review the full project structure and suggest improvements covering: Almost all suggestions include detailed code examples.
Suggested Improvements Figure 6. dev_agent.py suggested improvements
400 You: /improve
401
402 ?? Generating suggestions...
403
404 Agent: ## Comprehensive Project Improvement Suggestions
405
406 ### 1. Project Organization
407
408 Recommended structure:
409 ```
410 rust_dir_nav/
411 ├── src/
412 │   ├── lib.rs          # Public API and re-exports
413 │   ├── navigator.rs    # Core DirNav implementation
414 │   ├── traits.rs       # DirEvent and other traits
415 │   ├── error.rs        # Error types
416 │   └── builder.rs      # Builder pattern
417 ├── examples/
418 │   ├── basic_usage.rs
419 │   └── custom_handler.rs
420 ├── tests/
421 │   └── integration_tests.rs
422 └── benches/
423     └── navigation_bench.rs
424 ```
425
426 ### 2. Code Architecture
427
428 Separate configuration from traversal state with a builder:
429
430 ```rust
431 impl<App: DirEvent + Default> DirNav<App> {
432     pub fn builder() -> DirNavBuilder<App> {
433         DirNavBuilder::new()
434     }
435
436     pub fn navigate(&mut self, root: &Path) -> Result<&NavigationStats> {
437         self.visit_directory(root)?;
438         Ok(&self.stats)
439     }
440 }
441 ```
442
443 ### 3. Testing Strategy
444
445 ```rust
446 #[tokio::test]
447 async fn test_basic_navigation() {
448     let temp_dir = common::create_test_structure();
449     let mut nav = DirectoryNavigator::new(FileCollector::new())
450         .with_extensions(&["rs", "toml"])
451         .recursive(true);
452     let stats = nav.navigate(temp_dir.path()).await.unwrap();
453     assert_eq!(stats.files_processed, 3);
454 }
455 ```
456
457 ### 4. Documentation Strategy
458
459 Add module-level documentation with runnable examples in `//!` doc comments.
460 Use `cargo doc --open` to verify rendered output.
461
462 ### 5. Development Workflow
463
464 Add a CI pipeline (`.github/workflows/ci.yml`) that runs `cargo test`, `cargo clippy`,
465 and `cargo fmt --check` on stable, beta, and nightly toolchains.
The suggestions include a re-implementation of lib.rs. The suggested code has some interesting features but expands the line count by about 50 percent. I would not use it as-is, but would examine it carefully and adopt ideas selectively to keep the codebase close to its original size.

7.0 - Usage Reference

All of the prior dropdown contents were generated by the dev_agent.py agent. This section contains a usage guide generated by the claude.ai chatbot when it created the agent.
Agent Usage Guide
This usage guide was created by claude.ai as part of agent creation.

Software Development Agent - Usage Guide

Installation

1. Install dependencies:

pip install -r requirements.txt

2. Set your API key:

On Windows (PowerShell):

# For current session only
$env:ANTHROPIC_API_KEY="your-api-key-here"

# For permanent (all future sessions)
[System.Environment]::SetEnvironmentVariable('ANTHROPIC_API_KEY','your-api-key-here','User')

On Linux/Mac:

export ANTHROPIC_API_KEY='your-api-key-here'
# To make permanent:
echo 'export ANTHROPIC_API_KEY="your-api-key-here"' >> ~/.bashrc

Interactive Commands

  • /analyze <file> - Analyze a specific file in detail
  • /improve - Get suggestions for improving the codebase
  • /readme - Generate a comprehensive README
  • /tree - Display the directory structure
  • /files - List all code files found
  • /clear - Clear conversation history
  • /quit - Exit the agent

Example Conversations

Code Review

You: Can you review the error handling in my Python files?

Agent: [Analyzes error handling patterns across the codebase]

Debugging Help

You: I'm getting a NullPointerException in UserService.java

Agent: [Examines the file and suggests fixes]

Architecture Questions

You: Should I split my main.py file into multiple modules?

Agent: [Provides architectural advice based on the code structure]

Features

  • Codebase Analysis - Understand project structure and organization
  • File-Specific Review - Deep dive into individual files
  • Improvement Suggestions - Get actionable recommendations
  • Bug Detection - Identify potential issues
  • Documentation Generation - Create READMEs and docstrings
  • Conversational Context - Maintains history for follow-up questions
  • Multi-Language Support - Python, JS, TS, Java, C++, C#, Rust, Go, Ruby, PHP

Tips for Best Results

  1. Be Specific - Ask targeted questions about particular files or issues
  2. Provide Context - Mention what you're trying to achieve
  3. Iterate - Use follow-up questions to drill deeper
  4. Review Suggestions - The agent provides recommendations; you decide
  5. Keep History - Don't /clear too often; context helps

Security Note

  • The agent reads files from your local directory
  • Code is sent to Anthropic's API for analysis
  • Avoid using on projects with credentials stored in code

Example Workflow

  1. Start the agent in your project directory
  2. Use /tree to understand the structure
  3. Use /files to see what code files were detected
  4. Ask general questions about architecture or design
  5. Use /analyze for specific files that need attention
  6. Use /improve to get a roadmap of improvements
  7. Implement changes and ask follow-up questions
  8. Use /readme when ready to document the project

8.0 - Safety Constraints

An unconstrained agent can do more than intended. Useful guards: The dev_agent.py above keeps all file access inside the project directory specified at startup, and only reads files - it never writes. Adding write capability should be treated as a significant trust boundary and protected accordingly.

9.0 - Takeaways

Generally, the agent model works well. This example provides: My take on using LLM-based AI for software development is consistent with conventional wisdom: I like to think of AI support in terms of the agile programming model:

10.0 - References

Resource Description
Tool Use Docs Anthropic’s guide to defining and using tools with the Claude API.
Messages API Anthropic Messages API reference - the transport used by all agents.
AIBites: Agent AI Full agent demos with extended code-viewer dropdowns and execution screenshots.
AIBites: Agentic AI Multi-agent orchestration and agentic frameworks.
AI Agents pdf Slide deck covering agent architecture, tool use, and safety.