# LangGraph Bird Classification Agent - Complete Guide **A beginner-friendly guide to setting up and using the bird classification agent system.** --- ## Table of Contents > **🚀 First time here?** Start with [Installation](#installation) → [Configuration](#configuration) → [CLI Commands](#cli-commands) > **🐦 Want interactive chat?** Jump to [eBird Server Setup](#ebird-server-setup) 1. [What is This?](#what-is-this) 2. [Prerequisites](#prerequisites) 3. [Installation](#installation) 4. [Configuration](#configuration) 5. [Usage Guide](#usage-guide) 6. [eBird Server Setup](#ebird-server-setup) ⭐ **Important for interactive mode** 7. [CLI Commands](#cli-commands) 8. [Programmatic Usage](#programmatic-usage) 9. [Advanced Configuration](#advanced-configuration) 10. [Troubleshooting](#troubleshooting) 11. [Testing](#testing) 12. [Examples](#examples) --- ## What is This? This is an intelligent AI agent that can: - **Identify birds** from images (via URLs or uploads) - **Answer questions** about bird species - **Find bird sightings** near locations (when connected to eBird server) - **Recommend birding hotspots** - **Hold conversations** with memory of previous messages **Technology Stack:** - **LangGraph:** Agent framework - **LangChain:** LLM integration - **MCP (Model Context Protocol):** Tool integration - **Modal:** GPU-powered bird classifier - **OpenAI GPT:** Agent reasoning --- ## Prerequisites ### Required 1. **Python 3.11+** ```bash python --version # Should be 3.11 or higher ``` 2. **Virtual Environment** (recommended) ```bash python -m venv .venv-hackathon source .venv-hackathon/bin/activate # Mac/Linux # or .venv-hackathon\Scripts\activate # Windows ``` 3. **API Keys:** - **OpenAI API Key** (for GPT models) - Get from: https://platform.openai.com/api-keys - **Modal Bird Classifier URL** (from Phase 1 deployment) - **Bird Classifier API Key** (from Modal secrets) ### Optional (for multi-server setup) 4. **eBird API Key** (for bird data) - Get from: https://ebird.org/api/keygen 5. **eBird MCP Server** running locally or deployed --- ## Installation ### Step 1: Navigate to Directory ```bash cd /Users/jacobbinder/Desktop/hackathon/hackathon_draft ``` ### Step 2: Activate Virtual Environment ```bash source ../.venv-hackathon/bin/activate ``` ### Step 3: Install Dependencies ```bash # Install all required packages pip install -r langgraph_agent/requirements.txt ``` **What gets installed:** - `langchain` - LLM framework - `langchain-openai` - OpenAI integration - `langgraph` - Agent framework - `langchain-mcp-adapters` - MCP protocol support - `fastmcp` - MCP client/server - `python-dotenv` - Environment variable management ### Step 4: Verify Installation ```bash python -c "from langgraph_agent import AgentFactory; print('✅ Installation successful!')" ``` If you see `✅ Installation successful!`, you're ready to proceed! --- ## Configuration ### Step 1: Understand the Configuration File The agent uses `langgraph_agent/config.py` to manage all settings. It reads from environment variables in your `.env` file. ### Step 2: Create/Update .env File Navigate to the project root: ```bash cd /Users/jacobbinder/Desktop/hackathon/hackathon_draft ``` Edit `.env` file (create if it doesn't exist): ```bash nano .env # or use your favorite editor ``` ### Step 3: Add Required Variables **Minimal Configuration (Classifier Only):** ```bash # OpenAI API Key (Required) OPENAI_API_KEY=sk-proj-your-openai-api-key-here # Modal Bird Classifier (Required) MODAL_MCP_URL=https://yourname--bird-classifier-mcp-web.modal.run/mcp BIRD_CLASSIFIER_API_KEY=your-modal-api-key-here # Agent Settings (Optional - uses defaults if not set) LLM_MODEL=gpt-4o-mini LLM_TEMPERATURE=0 ``` **Full Configuration (With eBird Server):** ```bash # OpenAI API Key OPENAI_API_KEY=sk-proj-your-openai-api-key-here # Modal Bird Classifier MODAL_MCP_URL=https://yourname--bird-classifier-mcp-web.modal.run/mcp BIRD_CLASSIFIER_API_KEY=your-modal-api-key-here # eBird MCP Server EBIRD_MCP_URL=http://localhost:8000/mcp EBIRD_USE_STDIO=false MCP_API_KEY=your-ebird-mcp-key # Optional, for production # eBird API (if running eBird server) EBIRD_API_KEY=your-ebird-api-key # Agent Settings LLM_MODEL=gpt-4o-mini LLM_TEMPERATURE=0 AGENT_MAX_ITERATIONS=10 AGENT_TIMEOUT=120 ``` ### Step 4: Save and Verify Configuration Save the file and verify it loads correctly: ```bash python -c "from langgraph_agent import AgentConfig; AgentConfig.validate(); AgentConfig.print_config()" ``` **Expected Output:** ``` ====================================================================== Agent Configuration ====================================================================== Modal URL: https://yourname--bird-classifier-mcp-web.modal.run/mcp Modal API Key: your-modal-api-key... eBird URL: http://localhost:8000/mcp eBird Stdio: False LLM Model: gpt-4o-mini Temperature: 0.0 ====================================================================== ``` --- ## Usage Guide ### Understanding Agent Types The system provides **two types of agents**: > **IMPORTANT FOR BEGINNERS:** The classifier agent (type 1) works immediately after installation. The multi-server agent (type 2) requires the eBird server to be running first. See [eBird Server Setup](#ebird-server-setup) below. #### 1. Classifier Agent (Simple) - **Purpose:** Identify birds from images - **Tools:** 2 (classify_from_url, classify_from_base64) - **Best for:** Quick bird identification - **MCP Servers:** Modal classifier only #### 2. Multi-Server Agent (Advanced) - **Purpose:** Full bird identification + data exploration - **Tools:** 9 (2 from Modal + 7 from eBird) - **Best for:** Conversational bird exploration - **MCP Servers:** Modal classifier + eBird data --- ### Visual Guide: Which Agent Type Do I Use? ``` ┌─────────────────────────────────────────────────────────────────┐ │ CLASSIFIER AGENT (Simple) │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ What you need: │ │ ✅ Modal MCP URL (from Phase 1) │ │ ✅ Modal API Key │ │ ✅ OpenAI API Key │ │ ❌ eBird server (NOT needed) │ │ │ │ What it can do: │ │ ✅ Identify birds from image URLs │ │ ✅ Identify birds from base64 images │ │ ❌ Find bird sightings near locations │ │ ❌ Get eBird hotspot information │ │ │ │ How to use: │ │ python -m langgraph_agent demo │ │ python langgraph_agent/test_agent.py │ │ │ └─────────────────────────────────────────────────────────────────┘ ┌─────────────────────────────────────────────────────────────────┐ │ MULTI-SERVER AGENT (Advanced) │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ What you need: │ │ ✅ Modal MCP URL │ │ ✅ Modal API Key │ │ ✅ OpenAI API Key │ │ ✅ eBird API Key │ │ ✅ eBird MCP server running (see setup guide below) │ │ │ │ What it can do: │ │ ✅ Everything from Classifier Agent + │ │ ✅ Find recent bird sightings near any location │ │ ✅ Discover birding hotspots │ │ ✅ Get notable sightings │ │ ✅ Search for specific species │ │ ✅ Conversational memory │ │ │ │ How to use: │ │ 1. Start eBird server: python ebird_tools.py --http --port 8000│ │ 2. python -m langgraph_agent interactive │ │ 3. python langgraph_agent/test_agent.py multi │ │ │ └─────────────────────────────────────────────────────────────────┘ ``` --- ## eBird Server Setup ### When Do You Need the eBird Server? **You DON'T need eBird server for:** - ✅ `python -m langgraph_agent demo` (classifier only) - ✅ `python langgraph_agent/test_agent.py` (basic classifier tests) - ✅ Creating classifier agents in your own code **You DO need eBird server for:** - ❌ `python -m langgraph_agent interactive` (multi-server chat) - ❌ `python langgraph_agent/test_agent.py multi` (multi-server tests) - ❌ Creating multi-server agents in your own code - ❌ Gradio app (`app.py`) --- ### Two Ways to Run eBird Server #### **Option 1: stdio (Recommended for Local Development)** ⭐ **Advantages:** - ✅ No manual server management - ✅ Agent auto-starts/stops server - ✅ One terminal window only - ✅ Simpler for beginners **Setup:** 1. **Add to .env:** ```bash EBIRD_USE_STDIO=true EBIRD_API_KEY=your-ebird-api-key-here ``` 2. **That's it!** Just run your agent: ```bash python -m langgraph_agent interactive # eBird server starts automatically! ``` --- #### **Option 2: HTTP (For Production/Manual Control)** **Advantages:** - ✅ Better for production deployment - ✅ One server serves multiple agents - ✅ More control over server lifecycle **Setup:** 1. **Configure .env:** ```bash EBIRD_USE_STDIO=false EBIRD_MCP_URL=http://localhost:8000/mcp EBIRD_API_KEY=your-ebird-api-key-here ``` 2. **Terminal 1 - Start eBird Server:** ```bash cd /Users/jacobbinder/Desktop/hackathon/hackathon_draft source ../.venv-hackathon/bin/activate python ebird_tools.py --http --port 8000 ``` 3. **Verify server (new terminal):** ```bash curl http://localhost:8000/health # Should return: {"status": "ok"} ``` 4. **Terminal 2 - Run Agent:** ```bash cd /Users/jacobbinder/Desktop/hackathon/hackathon_draft source ../.venv-hackathon/bin/activate python -m langgraph_agent interactive ``` --- ### ✅ MCP_API_KEY Authentication Verification YES, `app.py` is properly configured to use the eBird MCP API key. Here's the authentication flow: **Authentication Chain:** - `.env:11` - Defines `MCP_API_KEY=test-api-key` - `config.py:21` - Loads it as `AgentConfig.MCP_API_KEY` - `mcp_clients.py:63-71` - Uses it for eBird HTTP authentication: ```python # HTTP transport (server running separately) ebird_headers = {} if AgentConfig.MCP_API_KEY: ebird_headers["Authorization"] = f"Bearer {AgentConfig.MCP_API_KEY}" servers_config["ebird"] = { "transport": "streamable_http", "url": AgentConfig.EBIRD_MCP_URL, "headers": ebird_headers if ebird_headers else None } ``` - `app.py:18` - Calls `AgentFactory.create_streaming_agent()` → which calls `MCPClientManager.create_multi_server_client()` → which includes the authenticated eBird connection **Current setup (from .env):** - `EBIRD_USE_STDIO=false` - Using HTTP mode - `MCP_API_KEY=test-api-key` - Auth key for eBird server - Authentication header: `Authorization: Bearer test-api-key` --- ### Troubleshooting eBird Server #### Problem: "Connection refused" or "All connection attempts failed" **Cause:** eBird server is not running **Solution:** 1. Check if server terminal is still running 2. Restart the server: `python ebird_tools.py --http --port 8000` 3. Verify with: `curl http://localhost:8000/health` #### Problem: "Address already in use" when starting server **Cause:** Port 8000 is already taken **Solution 1:** Stop the existing process ```bash # Find process using port 8000 lsof -ti:8000 # Kill it kill -9 $(lsof -ti:8000) # Start server again python ebird_tools.py --http --port 8000 ``` **Solution 2:** Use a different port ```bash # Start on different port python ebird_tools.py --http --port 8001 # Update .env EBIRD_MCP_URL=http://localhost:8001/mcp ``` #### Problem: "EBIRD_API_KEY not set" **Cause:** Missing eBird API key in .env **Solution:** 1. Get API key from: https://ebird.org/api/keygen 2. Add to `.env` file: ```bash EBIRD_API_KEY=your-key-here ``` 3. Restart the eBird server --- ### Quick Reference: Server vs No Server | Command | Needs eBird Server? | What It Does | |---------|-------------------|--------------| | `python -m langgraph_agent demo` | ❌ No | Test classifier with single image | | `python -m langgraph_agent demo [url]` | ❌ No | Test classifier with custom image | | `python -m langgraph_agent interactive` | ✅ Yes | Chat with full agent (classifier + eBird) | | `python langgraph_agent/test_agent.py` | ❌ No | Run classifier tests (2 images) | | `python langgraph_agent/test_agent.py multi` | ✅ Yes | Run multi-server tests (requires eBird) | --- ## CLI Commands ### Running the CLI The agent package can be run as a Python module from the project root: ```bash cd /Users/jacobbinder/Desktop/hackathon/hackathon_draft python -m langgraph_agent [command] [options] ``` --- ### Command 1: Demo Mode (Default) **Purpose:** Quick test with a single image classification **Usage:** ```bash # Use default test image python -m langgraph_agent demo # Or specify your own image URL python -m langgraph_agent demo "https://example.com/bird.jpg" ``` **What happens:** 1. Loads configuration from `.env` 2. Prints config summary 3. Creates classifier agent 4. Classifies the bird image 5. Prints results **Example Output:** ``` ====================================================================== Agent Configuration ====================================================================== Modal URL: https://jakeworkoutharder-dev--bird-classifier... Modal API Key: b1363a05f1ef1a8c... LLM Model: gpt-4o-mini Temperature: 0.0 ====================================================================== [STATUS]: Connecting to Modal MCP server... [STATUS]: Loading MCP tools... [LOADED]: 2 tools - ['classify_from_base64', 'classify_from_url'] [STATUS]: Creating LangGraph agent... [SUCCESS]: Agent ready! ====================================================================== Testing bird classification... [IMAGE URL]: https://images.unsplash.com/photo-1445820200644... [AGENT RESPONSE]: The bird in the image is a **Grandala** with a confidence score of **99.9%**! What a beautiful bird! [DEMO COMPLETE!] ``` --- ### Command 2: Interactive Mode > **⚠️ IMPORTANT:** This command requires the eBird server to be running first! See [eBird Server Setup](#ebird-server-setup) for step-by-step instructions. **Purpose:** Chat with the agent in real-time **Usage:** ```bash python -m langgraph_agent interactive ``` **What happens:** 1. Creates multi-server agent with memory 2. Opens interactive chat 3. Maintains conversation history 4. Type queries, get responses 5. Quit with 'exit' or 'quit' **Example Session:** ``` ====================================================================== Bird Classification Agent - Interactive Mode ====================================================================== Commands: - Type 'quit' or 'exit' to end session - Paste image URLs to classify birds - Ask about bird locations, sightings, hotspots ====================================================================== [STATUS]: Connecting to Modal and eBird MCP servers... [STATUS]: Loading MCP tools... [LOADED]: 9 tools - ['classify_from_base64', 'classify_from_url', 'search_species', 'get_recent_sightings_nearby', ...] [STATUS]: Creating multi-server LangGraph agent... [SUCCESS]: Agent ready with all tools! You: What bird is this? https://example.com/cardinal.jpg Agent: This is a **Northern Cardinal** with 98.7% confidence! These beautiful red birds are common across North America and known for their bright plumage and distinctive crest. You: Where can I see them near Boston? Agent: Northern Cardinals have been spotted recently near Boston! Here are some locations: - Mount Auburn Cemetery (15 sightings this week) - Arnold Arboretum (12 sightings) - Fresh Pond Reservation (8 sightings) You: quit Goodbye! Happy birding! ``` **Key Features:** - 🧠 **Remembers conversation** - References previous messages - 🔧 **Auto-selects tools** - Agent decides which tools to use - 💬 **Natural language** - Talk like you would to a person --- ## Programmatic Usage ### Import the Package From any Python file in your project: ```python import asyncio from langgraph_agent import AgentFactory, AgentConfig ``` --- ### Example 1: Simple Bird Classification ```python import asyncio from langgraph_agent import AgentFactory async def classify_bird(): # Create classifier agent agent = await AgentFactory.create_classifier_agent() # Classify a bird result = await agent.ainvoke({ "messages": [{ "role": "user", "content": "What bird is this? https://example.com/bird.jpg" }] }) # Print response print(result["messages"][-1].content) # Run asyncio.run(classify_bird()) ``` --- ### Example 2: Conversational Agent with Memory ```python import asyncio from langgraph_agent import AgentFactory async def conversation(): # Create agent with memory agent = await AgentFactory.create_classifier_agent(with_memory=True) # Thread ID for conversation tracking config = {"configurable": {"thread_id": "user_123"}} # Turn 1: Classify bird result1 = await agent.ainvoke({ "messages": [{ "role": "user", "content": "Identify this: https://example.com/cardinal.jpg" }] }, config) print("Turn 1:", result1["messages"][-1].content) # Turn 2: Ask follow-up (agent remembers the bird!) result2 = await agent.ainvoke({ "messages": [{ "role": "user", "content": "What color is this bird?" }] }, config) print("Turn 2:", result2["messages"][-1].content) asyncio.run(conversation()) ``` **Output:** ``` Turn 1: This is a Northern Cardinal with 98.7% confidence! Turn 2: The Northern Cardinal is bright red, which we identified in the previous image. Males are vibrant red while females are brown with red highlights. ``` --- ### Example 3: Custom Configuration ```python import asyncio from langgraph_agent import AgentFactory async def custom_agent(): # Create agent with custom settings agent = await AgentFactory.create_classifier_agent( model_name="gpt-4o", # Use more powerful model temperature=0.3, # Add creativity with_memory=True # Enable conversation memory ) # Use the agent... result = await agent.ainvoke({ "messages": [{ "role": "user", "content": "Classify and tell me a fun fact about this bird: URL" }] }) print(result["messages"][-1].content) asyncio.run(custom_agent()) ``` --- ### Example 4: Multi-Server Agent (Classifier + eBird) ```python import asyncio from langgraph_agent import AgentFactory async def multi_server_agent(): # Create agent with both MCP servers agent = await AgentFactory.create_multi_server_agent( with_memory=True ) config = {"configurable": {"thread_id": "session_1"}} # Agent can now use 9 tools across 2 servers! result = await agent.ainvoke({ "messages": [{ "role": "user", "content": "What bird is this? Where can I see it near NYC? https://example.com/bird.jpg" }] }, config) print(result["messages"][-1].content) asyncio.run(multi_server_agent()) ``` **What the agent does:** 1. Uses `classify_from_url` to identify the bird 2. Uses `search_species` to get species code 3. Uses `get_recent_sightings_nearby` to find sightings near NYC 4. Formats response with all information --- ### Example 5: Check Configuration ```python from langgraph_agent import AgentConfig # Print current configuration AgentConfig.print_config() # Access specific values print(f"Using model: {AgentConfig.DEFAULT_MODEL}") print(f"Modal URL: {AgentConfig.MODAL_MCP_URL}") # Validate configuration try: AgentConfig.validate() print("✅ Configuration is valid!") except ValueError as e: print(f"❌ Configuration error: {e}") ``` --- ## Advanced Configuration ### Changing the LLM Model Edit `.env` file: ```bash # Use GPT-4o (more powerful, slower, more expensive) LLM_MODEL=gpt-4o # Use GPT-4o-mini (faster, cheaper, default) LLM_MODEL=gpt-4o-mini # Use GPT-3.5 (cheapest, fastest, less capable) LLM_MODEL=gpt-3.5-turbo ``` **Or override in code:** ```python agent = await AgentFactory.create_classifier_agent( model_name="gpt-4o" # Override default ) ``` --- ### Adjusting Temperature **Temperature controls creativity:** - `0.0` = Deterministic, factual (recommended for classification) - `0.5` = Balanced - `1.0` = Creative, varied responses In `.env`: ```bash LLM_TEMPERATURE=0.3 ``` Or in code: ```python agent = await AgentFactory.create_classifier_agent( temperature=0.3 ) ``` --- ### Configuring eBird Server Transport **Option 1: HTTP Transport (default)** ```bash EBIRD_USE_STDIO=false EBIRD_MCP_URL=http://localhost:8000/mcp ``` Start eBird server separately: ```bash python ebird_tools.py --http --port 8000 ``` **Option 2: Stdio Transport** ```bash EBIRD_USE_STDIO=true ``` Agent will automatically start eBird server as subprocess. --- ## Troubleshooting ### Issue 1: "ModuleNotFoundError: No module named 'langgraph_agent'" **Cause:** Package not in Python path **Solution:** ```bash # Make sure you're in the correct directory cd /Users/jacobbinder/Desktop/hackathon/hackathon_draft # Verify package exists ls langgraph_agent/ # Try import again python -c "from langgraph_agent import AgentFactory" ``` --- ### Issue 2: "ValueError: MODAL_MCP_URL not set in .env" **Cause:** Missing or incorrect environment variables **Solution:** ```bash # Check .env file exists ls -la .env # Verify contents cat .env | grep MODAL_MCP_URL # Make sure it's set correctly (no quotes, no trailing slash) MODAL_MCP_URL=https://your-url-here/mcp ``` --- ### Issue 3: "401 Unauthorized" when calling Modal **Cause:** Incorrect API key **Solution:** ```bash # Verify API key in .env matches Modal secret cat .env | grep BIRD_CLASSIFIER_API_KEY # Get correct key from Modal modal secret list # Update .env with correct key ``` --- ### Issue 4: Agent is slow (30+ seconds per request) **Cause:** Using expensive model or large conversation history **Solution 1: Use faster model** ```bash # In .env LLM_MODEL=gpt-4o-mini # Instead of gpt-4o ``` **Solution 2: Limit conversation history** ```python from langchain_core.messages.utils import trim_messages # Trim to last 10 messages before invoking messages = trim_messages(state["messages"], max_tokens=2000) ``` --- ### Issue 5: "Too many tools loaded" or incorrect tool count **Cause:** Wrong server configuration **Expected tool counts:** - Classifier only: **2 tools** - Multi-server: **9 tools** (2 + 7) **Solution:** ```bash # Check which agent type you're creating # For classifier only: agent = await AgentFactory.create_classifier_agent() # For multi-server: agent = await AgentFactory.create_multi_server_agent() ``` --- ## Testing ### Component Testing (Individual Parts) Before testing agents, verify each component works individually. #### Test Modal Classifier (Step 1) **Verify Modal deployment:** ```bash modal app list ``` **Test with curl:** ```bash curl -X POST \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -H "X-API-Key: YOUR_API_KEY" \ -d '{ "jsonrpc": "2.0", "id": 1, "method": "initialize", "params": { "protocolVersion": "2024-11-05", "capabilities": {}, "clientInfo": { "name": "test", "version": "1.0" } } }' \ https://yourname--bird-classifier-mcp-web.modal.run/mcp ``` ✅ **Success:** Modal responds with JSON result --- ### Agent Testing (Combined System) #### Test 1: Basic Classifier Agent (No eBird Server Needed) This test works immediately after installation - no eBird server required! ```bash cd /Users/jacobbinder/Desktop/hackathon/hackathon_draft # Activate virtual environment source ../.venv-hackathon/bin/activate # Test basic classifier agent (2 bird images) python langgraph_agent/test_agent.py ``` **Expected Output:** ``` ====================================================================== Test Suite: Basic Classifier Agent ====================================================================== [STATUS]: Connecting to Modal MCP server... [STATUS]: Loading MCP tools... [LOADED]: 2 tools - ['classify_from_base64', 'classify_from_url'] [STATUS]: Creating LangGraph agent... [SUCCESS]: Agent ready! [TEST 1/2] ====================================================================== [RESULT]: The bird in the image is a **Jandaya Parakeet**! I have a high confidence score of **99.84%** in this identification. [TEST 2/2] ====================================================================== [RESULT]: The bird in the image is identified as a **Grandala** with a confidence score of **99.9%**! What a beautiful bird! [ALL TESTS COMPLETE!] ``` --- #### Test 2: Multi-Server Agent (Requires eBird Server) This test requires the eBird server to be running first! **Step-by-Step:** 1. **Terminal 1 - Start eBird Server:** ```bash cd /Users/jacobbinder/Desktop/hackathon/hackathon_draft source ../.venv-hackathon/bin/activate # Start eBird server (keep this running) python ebird_tools.py --http --port 8000 ``` 2. **Terminal 2 - Run Multi-Server Test:** ```bash cd /Users/jacobbinder/Desktop/hackathon/hackathon_draft source ../.venv-hackathon/bin/activate # Run multi-server test python langgraph_agent/test_agent.py multi ``` **Expected Output:** ``` ====================================================================== Test Suite: Multi-Server Agent ====================================================================== [STATUS]: Connecting to Modal and eBird servers... [STATUS]: Loading MCP tools... [LOADED]: 9 tools available - classify_from_base64 - classify_from_url - search_species - get_recent_sightings_nearby - get_notable_sightings_nearby - get_recent_checklists_nearby - get_regional_statistics - list_hotspots_nearby - get_checklist_details [TEST 1]: Classify bird from URL ====================================================================== [RESULT]: The bird in the image is a **Jandaya Parakeet** with 99.84% confidence! [TEST 2]: Follow-up question (tests memory) ====================================================================== [RESULT]: You can see Jandaya Parakeets near Boston (42.36, -71.06): - Arnold Arboretum (3 sightings this month) - Mount Auburn Cemetery (2 sightings) Note: These are exotic birds, not native to the area. [ALL TESTS COMPLETE!] ``` **What This Tests:** - ✅ Multi-server connection (Modal + eBird) - ✅ Tool integration (9 tools from both servers) - ✅ Conversation memory (follow-up question) - ✅ Cross-server reasoning (classify → location lookup) --- ## Examples ### Complete Example: Bird Identification App ```python """ Simple bird identification CLI app """ import asyncio from langgraph_agent import AgentFactory async def main(): print("🐦 Bird Identification App") print("=" * 50) # Create agent print("\n[1/3] Initializing agent...") agent = await AgentFactory.create_classifier_agent() # Get image URL from user print("\n[2/3] Waiting for input...") image_url = input("Enter bird image URL: ").strip() if not image_url: print("❌ No URL provided") return # Classify print("\n[3/3] Classifying...") result = await agent.ainvoke({ "messages": [{ "role": "user", "content": f"Identify this bird: {image_url}" }] }) # Display result print("\n" + "=" * 50) print("RESULT:") print("=" * 50) print(result["messages"][-1].content) if __name__ == "__main__": asyncio.run(main()) ``` **Run it:** ```bash python my_bird_app.py ``` --- ## Quick Reference ### Import Patterns ```python # Import everything from langgraph_agent import ( AgentFactory, AgentConfig, create_bird_agent, create_multi_agent, MCPClientManager, get_prompt_for_agent_type ) # Or import as needed from langgraph_agent import AgentFactory ``` ### Create Agent (Simple) ```python # Minimal agent = await AgentFactory.create_classifier_agent() # With memory agent = await AgentFactory.create_classifier_agent(with_memory=True) # Custom model agent = await AgentFactory.create_classifier_agent( model_name="gpt-4o", temperature=0.3 ) ``` ### Create Agent (Multi-Server) ```python # Default (with memory) agent = await AgentFactory.create_multi_server_agent() # Custom settings agent = await AgentFactory.create_multi_server_agent( model_name="gpt-4o", temperature=0.5, with_memory=True ) ``` ### Invoke Agent ```python # Single turn result = await agent.ainvoke({ "messages": [{"role": "user", "content": "Your message"}] }) # With memory (multi-turn) config = {"configurable": {"thread_id": "session_1"}} result = await agent.ainvoke({ "messages": [{"role": "user", "content": "Your message"}] }, config) ``` --- ## Summary ✅ **Installation:** Install dependencies, set up `.env` ✅ **Configuration:** Edit `.env` with API keys and URLs ✅ **Usage:** CLI commands or Python imports ✅ **CLI:** `demo` for testing (no eBird), `interactive` for chat (needs eBird) ✅ **Programmatic:** Import `AgentFactory`, create agents, invoke ✅ **Testing:** Run `test_agent.py` to verify setup **Ready to build?** Start with these commands (no eBird server needed): ```bash # Test the classifier python -m langgraph_agent demo # Run basic tests python langgraph_agent/test_agent.py ``` **Want multi-server features?** See [eBird Server Setup](#ebird-server-setup) above. **Questions?** Check the [HuggingFace Deployment Guide](../../project_docs/implementation/hf_deploy_planning.md) or [Phase 3 Documentation](../../project_docs/implementation/phase_3.md). Happy birding! 🐦