# Anthropic

Anthropic's Claude is a family of large language models developed by Anthropic and designed to revolutionize the way you interact with AI. Claude excels at a wide variety of tasks involving language, reasoning, analysis, coding, and more. The models are highly capable, easy to use, and can be customized to suit your needs.

In this notebook, we demonstrate how to use Anthropic Claude model for AgentChat in AG2.

## Features
- Function/tool calling
- Structured Outputs ([Notebook example](https://docs.ag2.ai/0.9.1/docs/use-cases/notebooks/notebooks/agentchat_structured_outputs))
- Token usage and cost correctly as per Anthropic's API costs (as of December 2024)
- [Extended thinking](https://docs.anthropic.com/en/docs/build-with-claude/extended-thinking?q=extended_thinking#pricing-and-token-usage-for-extended-thinking)

## Requirements
To use Anthropic Claude with AG2, first you need to install the `ag2[anthropic]` package.

To try out the function call feature of Claude model, you need to install `anthropic>=0.23.1`.
```bash
# If you need to install AG2 with Anthropic
pip install ag2[anthropic]
```

Tip

If you have been using `autogen` or `pyautogen`, all you need to do is upgrade it using:
```bash
pip install -U autogen[anthropic]
```
or
```bash
pip install -U pyautogen[anthropic]
``` 
as `pyautogen`, `autogen`, and `ag2` are aliases for the same PyPI package.

## Set the config for the Anthropic API
You can add any parameters that are needed for the custom model loading in the same configuration list.

It is important to add the `api_type` field and set it to a string that corresponds to the client type used: `anthropic`.

Example:
```json
[
    {
        "model": "claude-3-5-sonnet-20240620",
        "api_key": "your api key",
        "api_type": "anthropic"
    },
    {
        "model": "claude-3-7-sonnet-20250219",
        "api_key": "your api key",
        "api_type": "anthropic",
        "max_tokens": 8192, # override the default value of 4096, max tokens must be greater than thinking budget
        "timeout": 600, # for larger thinking budgets, increase the timeout OR enable streaming
        "thinking": {"type": "enabled", "budget_tokens": 2048}
    }
]
```

## Alternative
As an alternative to the `api_key` key and value in the config, you can set the environment variable `ANTHROPIC_API_KEY` to your Anthropic API key.

Linux/Mac:
```bash
export ANTHROPIC_API_KEY="your Anthropic API key here"
```

Windows:
```bash
set ANTHROPIC_API_KEY=your_anthropic_api_key_here
```

```python
import os
from typing_extensions import Annotated
import autogen

llm_config_claude = autogen.LLMConfig(
    model="claude-3-5-sonnet-20240620",
    api_key=os.getenv("ANTHROPIC_API_KEY"),
    api_type="anthropic",
)
```

## Alternative Anthropic VertexAI Client (GCP)
To use the Anthropic VertexAI client in AG2, you need to configure it for use with Google Cloud Platform (GCP). Ensure you have the necessary project credentials and install the required package.

Configuration
The following configuration example demonstrates how to set up Anthropic VertexAI:
```python
import os

llm_config_vertexai = LLMConfig(
    model="claude-3-5-sonnet-20240620-v1:0",
    gcp_project_id="your_project_id",
    gcp_region="us-west-2",  # Replace with your GCP region
    gcp_auth_token=None,  # Optional: If not passed, Google Default Authentication will be used
    api_type="anthropic",
)

with llm_config_vertexai:
    assistant = autogen.AssistantAgent("assistant")
```

### Two-agent Coding Example
Construct a simple conversation between a User proxy and a ConversableAgent based on Claude-3 model.
```python
with llm_config_claude:
    assistant = autogen.AssistantAgent("assistant")

user_proxy = autogen.UserProxyAgent(
    "user_proxy",
    human_input_mode="NEVER",
    code_execution_config={
        "work_dir": "coding",
        "use_docker": False,
    },
    is_termination_msg=lambda x: x.get("content", "") and x.get("content", "").rstrip().endswith("TERMINATE"),
    max_consecutive_auto_reply=1,
)

user_proxy.initiate_chat(
    assistant, message="Write a python program to print the first 10 numbers of the Fibonacci sequence."
)
```

```python
user_proxy (to assistant):

Write a python program to print the first 10 numbers of the Fibonacci sequence.

o--------------------------------------------------------------------------------

assistant (to user_proxy):

Certainly! I'll write a Python program to print the first 10 numbers of the Fibonacci sequence. Here's the code:

```python
# filename: fibonacci.py

def fibonacci(n):
    fib_sequence = [0, 1]

while len(fib_sequence) < n:
        next_number = fib_sequence[-1] + fib_sequence[-2]
        fib_sequence.append(next_number)

return fib_sequence

# Print the first 10 numbers of the Fibonacci sequence
n = 10
result = fibonacci(n)
print(f"The first {n} numbers of the Fibonacci sequence are:")
print(result)
```

This program does the following:
1. We define a function called `fibonacci` that takes an argument `n`, which is the number of Fibonacci numbers we want to generate.
2. We initialize the `fib_sequence` list with the first two numbers of the Fibonacci sequence: 0 and 1.
3. We use a while loop to generate subsequent numbers in the sequence by adding the last two numbers until we have `n` numbers in the sequence.
4. We return the complete Fibonacci sequence.
5. Outside the function, we set `n = 10` to get the first 10 numbers.
6. We call the `fibonacci` function with `n = 10` and store the result in the `result` variable.
7. Finally, we print the result.

Let's run this code and see the output. The code will be saved in a file named "fibonacci.py". You can execute it using Python.

o--------------------------------------------------------------------------------

## Tool Call Example with the Latest Anthropic API
Anthropic announced that tool use is supported in the Anthropic API. To use this feature, please install `anthropic>=0.23.1`.

### Register the function
```python
@user_proxy.register_for_execution()  # Decorator factory for registering a function to be executed by an agent
@assistant.register_for_llm(
    name="get_weather", description="Get the current weather in a given location."
)  # Decorator factory for registering a function to be used by an agent

def preprocess(location: Annotated[str, "The city and state, e.g. Toronto, ON."]) -> str:
    return "Absolutely cloudy and rainy"

user_proxy.initiate_chat(
    assistant,
    message="What's the weather in Toronto?",
)
```

```python
user_proxy (to assistant):

What's the weather in Toronto?

o--------------------------------------------------------------------------------

assistant (to user_proxy):

To get the weather in Toronto, we can use the available `get_weather` function. Let's call it to retrieve the current weather information for Toronto.
***** Suggested tool call (toolu_01KFiJWsMwTbcWerTHCgytuX): get_weather *****
Arguments:
{"location": "Toronto, ON"}
********************************************************************************

-------------

## Group Chat Example with both Claude and GPT Agents
### A group chat with GPT-4 as the judge
```python
from autogen import AssistantAgent, GroupChat, GroupChatManager, UserProxyAgent, LLMConfig

llm_config_gpt4 = autogen.LLMConfig(
    model="gpt-4",
    api_key=os.getenv("OPENAI_API_KEY"),
    api_type="openai",
)

with llm_config_gpt4:
    alice = AssistantAgent(
        "Openai_agent",
        system_message="You are from OpenAI. You make arguments to support your company's position.",
    )

dan = AssistantAgent(
        "Judge",
        system_message="You are a judge. You will evaluate the arguments and make a decision on which one is more convincing.",
    )

with llm_config_claude:
    bob = autogen.AssistantAgent(
        "Anthropic_agent",
        system_message="You are from Anthropic. You make arguments to support your company's position.",
    )

with llm_config_gpt35:
    charlie = AssistantAgent(
        "Research_Assistant",
        system_message="You are a helpful assistant to research the latest news and headlines.",
    )

code_interpreter = UserProxyAgent(
    "code-interpreter",
    human_input_mode="NEVER",
    code_execution_config={
        "work_dir": "coding",
        "use_docker": False,
    },
    default_auto_reply="",
    is_termination_msg=lambda x: x.get("content", "").find("TERMINATE") >= 0,
)

@code_interpreter.register_for_execution()  # Decorator factory for registering a function to be executed by an agent
@charlie.register_for_llm(
    name="get_headlines", description="Get the headline of a particular day."
)  # Decorator factory for registering a function to be used by an agent

def get_headlines(headline_date: Annotated[str, "Date in MMDDYY format, e.g., 06192024"]) -> str:
    mock_news = {
        "06202024": "OpenAI competitor Anthropic announces its most powerful AI yet.",
        "06192024": "OpenAI founder Sutskever sets up new AI company devoted to safe superintelligence.",
    }
    return mock_news.get(headline_date, "No news available for today.")

groupchat = GroupChat(
    agents=[alice, bob, charlie, dan, code_interpreter],
    messages=[],
    allow_repeat_speaker=False,
    max_round=10,
)

manager = GroupChatManager(
    groupchat=groupchat,
    llm_config=llm_config_gpt4,
)

user_proxy.initiate_chat(manager, message="Analyze the potential of OpenAI and Anthropic to revolutionize the field of AI based on today's headlines. Today is 06202024.")
```

```python
user_proxy (to chat_manager):

Analyze the potential of OpenAI and Anthropic to revolutionize the field of AI based on today's headlines. Today is 06202024.
```

---

### Thinking Mode
You can utilize Anthropic's thinking mode by setting it in the configuration.
```python
from autogen import ConversableAgent

# Here we configure the thinking mode and the token budget for thinking
llm_config = {
    "config_list": [
        {
            "model": "claude-3-7-sonnet-20250219",
            "api_type": "anthropic",
            "max_tokens": 8192,
            "timeout": 600,
            "thinking": {"type": "enabled", "budget_tokens": 2048},
        }
    ],
}

dagent = ConversableAgent(
    name="test",
    llm_config=llm_config,
)

# Create the run
response = agent.run(
    message="Please provide a comparison of JS and TS",
    user_input=False,
    max_turns=1,
)

# Process the run
response.process()

# Print out the final response (thinking tokens are not shown)
print(response.summary)
```
