← Claude’s Mastery

AI AGENTS, MCP & RAG

Task 1
Understanding AI Agents

What is an AI Agent?

An agent is Claude with:

  • Memory - Remembers facts across conversations
  • Tools - Can call external functions (APIs, databases, etc.)
  • Planning - Can break complex tasks into steps
  • Autonomy - Executes multi-step workflows without human intervention

Agent Architecture:`

User Input

[Claude Agent]

├── Memory (SQLite/Vector DB)

├── Tools (Weather, Calculator, Search, etc.)

├── Planner (Breaks down tasks)

└── Executor (Runs steps)

Response


**Simple Agent Example:**

```python
class SimpleAgent:
    def __init__(self):
        self.client = anthropic.Anthropic()
        self.memory = {}
        self.tools = {
            "calculator": self.calculate,
            "weather": self.get_weather
        }

    def calculate(self, expression):
        return eval(expression)

    def get_weather(self, location):
        # Mock implementation
        return f"Sunny, 22°C in {location}"

    def run(self, user_input):
        # Check if user is giving new information to remember
        if "remember" in user_input.lower():
            # Extract and store in memory
            pass

        # Check if tool use is needed
        if "calculate" in user_input.lower():
            # Extract expression and use calculator
            pass

        # Default: just respond
        response = self.client.messages.create(
            model="claude-3-sonnet-20241022",
            messages=[{"role": "user", "content": user_input}]
        )

        return response.content[0].text
Task 2
MCP (Model Context Protocol)

What is MCP?

The Model Context Protocol (MCP) is a standard for integrating tools with AI models. It defines:

  • Tool schema - How tools are described to the model
  • Request/response format - How the model calls tools
  • Error handling - Standard error responses

MCP Tool Definition:

{
  "name": "get_weather",
  "description": "Get current weather for a location",
  "input_schema": {
    "type": "object",
    "properties": {
      "location": {
        "type": "string",
        "description": "City name or coordinates"
      },
      "unit": {
        "type": "string",
        "enum": ["celsius", "fahrenheit"]
      }
    },
    "required": ["location"]
  }
}

MCP Request (Claude calling a tool):

<tool_call>
{
  "tool": "get_weather",
  "parameters": {
    "location": "Tokyo",
    "unit": "celsius"
  }
}
</tool_call>

MCP Response (Tool returning to Claude):

<tool_result>
{
  "temperature": 22,
  "condition": "sunny",
  "humidity": 65,
  "wind_speed": 12
}
</tool_result>
Task 3
RAG (Retrieval Augmented Generation)

What is RAG?

RAG = Retrieval + Augmented + Generation

  1. Retrieval - Search for relevant documents from a knowledge base
  2. Augmented - Add those documents to Claude's context
  3. Generation - Claude answers based on the retrieved documents

When to Use RAG:

Scenario Use RAG?
Answering questions about your company's internal documents Yes
Chatting with a PDF or website Yes
General knowledge questions  No (Claude already knows)
Real-time data (stock prices, weather) No (use tools instead)

Simple RAG Architecture:

User Question: "What's our refund policy?"
         ↓
[Vector Database] ←── [Your Documents: 1000s of pages]
         ↓
Retrieve top 5 most relevant documents
         ↓
[Claude Prompt]:
"Answer based ONLY on these documents:
Document 1: ...
Document 2: ...
Document 3: ...

Question: What's our refund policy?

If the answer isn't in the documents, say 'I cannot find that information.'"
         ↓
Answer: "Our refund policy allows returns within 30 days of purchase..."

Complete RAG Implementation:

python

import chromadb
from sentence_transformers import SentenceTransformer
import anthropic

class SimpleRAG:
    def __init__(self):
        self.client = anthropic.Anthropic()
        self.chroma_client = chromadb.Client()
        self.collection = self.chroma_client.create_collection("my_docs")
        self.encoder = SentenceTransformer("all-MiniLM-L6-v2")

    def add_documents(self, documents):
        """Add documents to the knowledge base"""
        embeddings = self.encoder.encode(documents).tolist()
        self.collection.add(
            embeddings=embeddings,
            documents=documents,
            ids=[f"doc_{i}" for i in range(len(documents))]
        )

    def query(self, question, n_results=3):
        """Ask a question against the knowledge base"""
        # 1. Embed the question
        question_embedding = self.encoder.encode([question]).tolist()

        # 2. Retrieve relevant documents
        results = self.collection.query(
            query_embeddings=question_embedding,
            n_results=n_results
        )
        retrieved_docs = results['documents'][0]

        # 3. Build prompt with retrieved context
        prompt = f"""
        Answer the question based ONLY on the following documents.
        If the answer is not in the documents, say "I cannot find that information in the provided documents."

        DOCUMENTS:
        {'---'.join(retrieved_docs)}

        QUESTION: {question}

        ANSWER:
        """

        # 4. Get Claude's answer
        response = self.client.messages.create(
            model="claude-3-sonnet-20241022",
            max_tokens=500,
            temperature=0.2,
            messages=[{"role": "user", "content": prompt}]
        )

        return {
            "answer": response.content[0].text,
            "sources": retrieved_docs
        }

# Usage
rag = SimpleRAG()
rag.add_documents([
    "Our refund policy allows returns within 30 days of purchase.",
    "Products must be unused and in original packaging.",
    "Shipping costs are non-refundable."
])

result = rag.query("Can I return an item after 3 weeks?")
print(result["answer"])  # Yes, within 30 days...
print(result["sources"])