# claudette
<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->
> **NB**: If you are reading this in GitHub’s readme, we recommend you
> instead read the much more nicely formatted [documentation
> format](https://claudette.answer.ai/) of this tutorial.
*Claudette* is a wrapper for Anthropic’s [Python
SDK](https://github.com/anthropics/anthropic-sdk-python).
The SDK works well, but it is quite low level – it leaves the developer
to do a lot of stuff manually. That’s a lot of extra work and
boilerplate! Claudette automates pretty much everything that can be
automated, whilst providing full control. Amongst the features provided:
- A [`Chat`](https://claudette.answer.ai/core.html#chat) class that
creates stateful dialogs
- Support for *prefill*, which tells Claude what to use as the first few
words of its response
- Convenient image support
- Simple and convenient support for Claude’s new Tool Use API.
You’ll need to set the `ANTHROPIC_API_KEY` environment variable to the
key provided to you by Anthropic in order to use this library.
Note that this library is the first ever “literate nbdev” project. That
means that the actual source code for the library is a rendered Jupyter
Notebook which includes callout notes and tips, HTML tables and images,
detailed explanations, and teaches *how* and *why* the code is written
the way it is. Even if you’ve never used the Anthropic Python SDK or
Claude API before, you should be able to read the source code. Click
[Claudette’s Source](https://claudette.answer.ai/core.html) to read it,
or clone the git repo and execute the notebook yourself to see every
step of the creation process in action. The tutorial below includes
links to API details which will take you to relevant parts of the
source. The reason this project is a new kind of literal program is
because we take seriously Knuth’s call to action, that we have a “*moral
commitment*” to never write an “*illiterate program*” – and so we have a
commitment to making literate programming and easy and pleasant
experience. (For more on this, see [this
talk](https://www.youtube.com/watch?v=rX1yGxJijsI) from Hamel Husain.)
> “*Let us change our traditional attitude to the construction of
> programs: Instead of imagining that our main task is to instruct a
> **computer** what to do, let us concentrate rather on explaining to
> **human beings** what we want a computer to do.*” Donald E. Knuth,
> [Literate
> Programming](https://www.cs.tufts.edu/~nr/cs257/archive/literate-programming/01-knuth-lp.pdf)
> (1984)
## Install
``` sh
pip install claudette
```
## Getting started
Anthropic’s Python SDK will automatically be installed with Claudette,
if you don’t already have it.
``` python
import os
# os.environ['ANTHROPIC_LOG'] = 'debug'
```
To print every HTTP request and response in full, uncomment the above
line.
``` python
from claudette import *
```
Claudette only exports the symbols that are needed to use the library,
so you can use `import *` to import them. Alternatively, just use:
``` python
import claudette
```
…and then add the prefix `claudette.` to any usages of the module.
Claudette provides `models`, which is a list of models currently
available from the SDK.
``` python
models
```
('claude-3-opus-20240229',
'claude-3-5-sonnet-20240620',
'claude-3-haiku-20240307')
For these examples, we’ll use Sonnet 3.5, since it’s awesome!
``` python
model = models[1]
```
## Chat
The main interface to Claudette is the
[`Chat`](https://claudette.answer.ai/core.html#chat) class, which
provides a stateful interface to Claude:
``` python
chat = Chat(model, sp="""You are a helpful and concise assistant.""")
chat("I'm Jeremy")
```
Hello Jeremy, it’s nice to meet you. How can I assist you today?
<details>
- id: `msg_014J96J6f9Bxrmyr7uA5Z4E3`
- content:
`[{'text': "Hello Jeremy, it's nice to meet you. How can I assist you today?", 'type': 'text'}]`
- model: `claude-3-5-sonnet-20240620`
- role: `assistant`
- stop_reason: `end_turn`
- stop_sequence: `None`
- type: `message`
- usage:
`{'input_tokens': 19, 'output_tokens': 20, 'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0}`
</details>
``` python
r = chat("What's my name?")
r
```
Your name is Jeremy, as you just told me.
<details>
- id: `msg_01RpP5rBhFK34UkZwAiMnL85`
- content:
`[{'text': 'Your name is Jeremy, as you just told me.', 'type': 'text'}]`
- model: `claude-3-5-sonnet-20240620`
- role: `assistant`
- stop_reason: `end_turn`
- stop_sequence: `None`
- type: `message`
- usage:
`{'input_tokens': 47, 'output_tokens': 14, 'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0}`
</details>
As you see above, displaying the results of a call in a notebook shows
just the message contents, with the other details hidden behind a
collapsible section. Alternatively you can `print` the details:
``` python
print(r)
```
Message(id='msg_01RpP5rBhFK34UkZwAiMnL85', content=[TextBlock(text='Your name is Jeremy, as you just told me.', type='text')], model='claude-3-5-sonnet-20240620', role='assistant', stop_reason='end_turn', stop_sequence=None, type='message', usage=In: 47; Out: 14; Total: 61)
Claude supports adding an extra `assistant` message at the end, which
contains the *prefill* – i.e. the text we want Claude to assume the
response starts with. Let’s try it out:
``` python
chat("Concisely, what is the meaning of life?",
prefill='According to Douglas Adams,')
```
According to Douglas Adams, “42.” More seriously, it’s often considered
to be finding personal fulfillment, happiness, and purpose.
<details>
- id: `msg_01Qgsa4a7cdPJkCrm989emJ5`
- content:
`[{'text': 'According to Douglas Adams, "42." More seriously, it\'s often considered to be finding personal fulfillment, happiness, and purpose.', 'type': 'text'}]`
- model: `claude-3-5-sonnet-20240620`
- role: `assistant`
- stop_reason: `end_turn`
- stop_sequence: `None`
- type: `message`
- usage:
`{'input_tokens': 81, 'output_tokens': 27, 'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0}`
</details>
You can add `stream=True` to stream the results as soon as they arrive
(although you will only see the gradual generation if you execute the
notebook yourself, of course!)
``` python
for o in chat("Concisely, what book was that in?", prefill='It was in', stream=True):
print(o, end='')
```
It was in "The Hitchhiker's Guide to the Galaxy" by Douglas Adams.
## Prompt caching
If you use `mk_msg(msg, cache=True)`, then the message is cached using
Claude’s [prompt
caching](https://docs.anthropic.com/en/docs/build-with-claude/prompt-caching)
feature. For instance, here we use caching when asking about Claudette’s
readme file:
``` python
chat = Chat(model, sp="""You are a helpful and concise assistant.""")
```
``` python
nbtxt = Path('README.txt').read_text()
msg = f'''<README>
{nbtxt}
</README>
In brief, what is the purpose of this project based on the readme?'''
r = chat(mk_msg(msg, cache=True))
r
```
Based on the readme, the main purpose of the Claudette project is to
provide a high-level wrapper around Anthropic’s Python SDK for
interacting with Claude AI models. Key features and goals include:
1. Automating and simplifying interactions with Claude, reducing
boilerplate code.
2. Providing a stateful dialog interface through the
[`Chat`](https://claudette.answer.ai/core.html#chat) class.
3. Supporting features like prefill (specifying the start of Claude’s
response) and image handling.
4. Offering convenient support for Claude’s Tool Use API.
5. Serving as an example of “literate programming”, with the source
code designed to be readable and educational, including explanations
of how and why the code is written.
6. Supporting multiple model providers, including direct Anthropic API
access as well as Claude models available through Amazon Bedrock and
Google Vertex AI.
The project aims to make working with Claude models more convenient and
accessible for developers while also serving as an educational resource
on how to effectively use and interact with these AI models.
<details>
- id: `msg_01HkjoKjfY5zrmBrkjHvtDpG`
- content:
`[{'text': 'Based on the readme, the main purpose of the Claudette project is to provide a high-level wrapper around Anthropic\'s Python SDK for interacting with Claude AI models. Key features and goals include:\n\n1. Automating and simplifying interactions with Claude, reducing boilerplate code.\n\n2. Providing a stateful dialog interface through the [`Chat`](https://claudette.answer.ai/core.html#chat) class.\n\n3. Supporting features like prefill (specifying the start of Claude\'s response) and image handling.\n\n4. Offering convenient support for Claude\'s Tool Use API.\n\n5. Serving as an example of "literate programming", with the source code designed to be readable and educational, including explanations of how and why the code is written.\n\n6. Supporting multiple model providers, including direct Anthropic API access as well as Claude models available through Amazon Bedrock and Google Vertex AI.\n\nThe project aims to make working with Claude models more convenient and accessible for developers while also serving as an educational resource on how to effectively use and interact with these AI models.', 'type': 'text'}]`
- model: `claude-3-5-sonnet-20240620`
- role: `assistant`
- stop_reason: `end_turn`
- stop_sequence: `None`
- type: `message`
- usage:
`{'input_tokens': 4, 'output_tokens': 220, 'cache_creation_input_tokens': 7171, 'cache_read_input_tokens': 0}`
</details>
The response records the a cache has been created using these input
tokens:
``` python
print(r.usage)
```
Usage(input_tokens=4, output_tokens=220, cache_creation_input_tokens=7171, cache_read_input_tokens=0)
We can now ask a followup question in this chat:
``` python
r = chat('How does it make tool use more ergonomic?')
r
```
Claudette makes tool use more ergonomic in several ways:
1. Simplified function definition: It uses docments to make defining
Python functions for tools as simple as possible. Each parameter and
the return value should have a type and a description.
2. Automatic handling: The
[`Chat`](https://claudette.answer.ai/core.html#chat) class can be
initialized with a list of tools, and Claudette handles the
back-and-forth between Claude and the tools automatically.
3. Single-step execution: The
[`Chat.toolloop`](https://claudette.answer.ai/toolloop.html#chat.toolloop)
method allows for executing a series of tool calls in a single step,
even if multiple tools are needed to solve a problem.
4. Forced tool use: You can set `tool_choice` to force Claude to always
answer using a specific tool.
5. Tracing: The `toolloop` method supports a `trace_func` parameter,
allowing you to see each response from Claude during the process.
6. Automatic parameter passing: When Claude decides to use a tool,
Claudette automatically calls the tool with the provided parameters.
7. System prompt integration: It allows setting a system prompt to
guide Claude’s behavior when using tools, such as instructing it not
to mention the tools it’s using.
These features significantly reduce the amount of code and manual
handling required to use Claude’s tool use capabilities, making the
process more streamlined and developer-friendly.
<details>
- id: `msg_01EfFbEBeYETAvfjGncn8Vcb`
- content:
`[{'text': "Claudette makes tool use more ergonomic in several ways:\n\n1. Simplified function definition: It uses docments to make defining Python functions for tools as simple as possible. Each parameter and the return value should have a type and a description.\n\n2. Automatic handling: The [`Chat`](https://claudette.answer.ai/core.html#chat) class can be initialized with a list of tools, and Claudette handles the back-and-forth between Claude and the tools automatically.\n\n3. Single-step execution: The [`Chat.toolloop`](https://claudette.answer.ai/toolloop.html#chat.toolloop) method allows for executing a series of tool calls in a single step, even if multiple tools are needed to solve a problem.\n\n4. Forced tool use: You can set`tool_choice`to force Claude to always answer using a specific tool.\n\n5. Tracing: The`toolloop`method supports a`trace_func`parameter, allowing you to see each response from Claude during the process.\n\n6. Automatic parameter passing: When Claude decides to use a tool, Claudette automatically calls the tool with the provided parameters.\n\n7. System prompt integration: It allows setting a system prompt to guide Claude's behavior when using tools, such as instructing it not to mention the tools it's using.\n\nThese features significantly reduce the amount of code and manual handling required to use Claude's tool use capabilities, making the process more streamlined and developer-friendly.", 'type': 'text'}]`
- model: `claude-3-5-sonnet-20240620`
- role: `assistant`
- stop_reason: `end_turn`
- stop_sequence: `None`
- type: `message`
- usage:
`{'input_tokens': 240, 'output_tokens': 289, 'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 7171}`
</details>
We can see that this only used ~200 regular input tokens – the 7000+
context tokens have been read from cache.
``` python
print(r.usage)
```
Usage(input_tokens=240, output_tokens=289, cache_creation_input_tokens=0, cache_read_input_tokens=7171)
## Tool use
[Tool use](https://docs.anthropic.com/claude/docs/tool-use) lets Claude
use external tools.
We use [docments](https://fastcore.fast.ai/docments.html) to make
defining Python functions as ergonomic as possible. Each parameter (and
the return value) should have a type, and a docments comment with the
description of what it is. As an example we’ll write a simple function
that adds numbers together, and will tell us when it’s being called:
``` python
def sums(
a:int, # First thing to sum
b:int=1 # Second thing to sum
) -> int: # The sum of the inputs
"Adds a + b."
print(f"Finding the sum of {a} and {b}")
return a + b
```
Sometimes Claude will say something like “according to the `sums` tool
the answer is” – generally we’d rather it just tells the user the
answer, so we can use a system prompt to help with this:
``` python
sp = "Never mention what tools you use."
```
We’ll get Claude to add up some long numbers:
``` python
a,b = 604542,6458932
pr = f"What is {a}+{b}?"
pr
```
'What is 604542+6458932?'
To use tools, pass a list of them to
[`Chat`](https://claudette.answer.ai/core.html#chat), and to force it to
always answer using a tool, set `tool_choice` to that function name:
``` python
chat = Chat(model, sp=sp, tools=[sums], tool_choice='sums')
```
Now when we call that with our prompt, Claude doesn’t return the answer,
but instead returns a `tool_use` message, which means we have to call
the named tool with the provided parameters:
``` python
r = chat(pr)
r
```
Finding the sum of 604542 and 6458932
ToolUseBlock(id=‘toolu_01C6G2iuLtBBftESiujKzXfx’, input={‘a’: 604542,
‘b’: 6458932}, name=‘sums’, type=‘tool_use’)
<details>
- id: `msg_01HPZwX3mQ7sMbjWUHEwgUsT`
- content:
`[{'id': 'toolu_01C6G2iuLtBBftESiujKzXfx', 'input': {'a': 604542, 'b': 6458932}, 'name': 'sums', 'type': 'tool_use'}]`
- model: `claude-3-5-sonnet-20240620`
- role: `assistant`
- stop_reason: `tool_use`
- stop_sequence: `None`
- type: `message`
- usage:
`{'input_tokens': 414, 'output_tokens': 53, 'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0}`
</details>
Claudette handles all that for us – we just call it again, and it all
happens automatically:
``` python
chat()
```
The sum of 604542 and 6458932 is 7063474.
<details>
- id: `msg_01RNHxf1jXfS76h2UpF8RnZ2`
- content:
`[{'text': 'The sum of 604542 and 6458932 is 7063474.', 'type': 'text'}]`
- model: `claude-3-5-sonnet-20240620`
- role: `assistant`
- stop_reason: `end_turn`
- stop_sequence: `None`
- type: `message`
- usage:
`{'input_tokens': 515, 'output_tokens': 23, 'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0}`
</details>
You can see how many tokens have been used at any time by checking the
`use` property. Note that (as of May 2024) tool use in Claude uses a
*lot* of tokens, since it automatically adds a large system prompt.
``` python
chat.use
```
In: 929; Out: 76; Total: 1005
We can do everything needed to use tools in a single step, by using
[`Chat.toolloop`](https://claudette.answer.ai/toolloop.html#chat.toolloop).
This can even call multiple tools as needed solve a problem. For
example, let’s define a tool to handle multiplication:
``` python
def mults(
a:int, # First thing to multiply
b:int=1 # Second thing to multiply
) -> int: # The product of the inputs
"Multiplies a * b."
print(f"Finding the product of {a} and {b}")
return a * b
```
Now with a single call we can calculate `(a+b)*2` – by passing
`show_trace` we can see each response from Claude in the process:
``` python
chat = Chat(model, sp=sp, tools=[sums,mults])
pr = f'Calculate ({a}+{b})*2'
pr
```
'Calculate (604542+6458932)*2'
``` python
chat.toolloop(pr, trace_func=print)
```
Finding the sum of 604542 and 6458932
Message(id='msg_01DgZ9Fcs6h8HB7qEaFkg3Ah', content=[TextBlock(text='Certainly! To calculate (604542+6458932)*2, we\'ll need to use the available tools to perform the addition and multiplication operations. Let\'s break it down step by step:\n\n1. First, we\'ll add 604542 and 6458932 using the "sums" function.\n2. Then, we\'ll multiply the result by 2 using the "mults" function.\n\nLet\'s start with the addition:', type='text'), ToolUseBlock(id='toolu_01XTMLyKo9Q6TX4SpCVmmUsP', input={'a': 604542, 'b': 6458932}, name='sums', type='tool_use')], model='claude-3-5-sonnet-20240620', role='assistant', stop_reason='tool_use', stop_sequence=None, type='message', usage=In: 538; Out: 168; Total: 706)
Finding the product of 7063474 and 2
Message(id='msg_011P8jdxwLoKNf8nTDua7VM8', content=[TextBlock(text="Great! The sum of 604542 and 6458932 is 7063474.\n\nNow, let's multiply this result by 2:", type='text'), ToolUseBlock(id='toolu_01FETWkj4a9HyX25c8ETULYh', input={'a': 7063474, 'b': 2}, name='mults', type='tool_use')], model='claude-3-5-sonnet-20240620', role='assistant', stop_reason='tool_use', stop_sequence=None, type='message', usage=In: 721; Out: 106; Total: 827)
Message(id='msg_01UXwy69vUWSy9bK24skQ3yE', content=[TextBlock(text='Now we have our final result. \n\nThe calculation (604542+6458932)*2 equals 14126948.\n\nTo break it down:\n1. 604542 + 6458932 = 7063474\n2. 7063474 * 2 = 14126948\n\nSo, the final answer to (604542+6458932)*2 is 14126948.', type='text')], model='claude-3-5-sonnet-20240620', role='assistant', stop_reason='end_turn', stop_sequence=None, type='message', usage=In: 841; Out: 95; Total: 936)
Now we have our final result.
The calculation (604542+6458932)\*2 equals 14126948.
To break it down: 1. 604542 + 6458932 = 7063474 2. 7063474 \* 2 =
14126948
So, the final answer to (604542+6458932)\*2 is 14126948.
<details>
- id: `msg_01UXwy69vUWSy9bK24skQ3yE`
- content:
`[{'text': 'Now we have our final result. \n\nThe calculation (604542+6458932)*2 equals 14126948.\n\nTo break it down:\n1. 604542 + 6458932 = 7063474\n2. 7063474 * 2 = 14126948\n\nSo, the final answer to (604542+6458932)*2 is 14126948.', 'type': 'text'}]`
- model: `claude-3-5-sonnet-20240620`
- role: `assistant`
- stop_reason: `end_turn`
- stop_sequence: `None`
- type: `message`
- usage:
`{'input_tokens': 841, 'output_tokens': 95, 'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0}`
</details>
## Images
Claude can handle image data as well. As everyone knows, when testing
image APIs you have to use a cute puppy.
``` python
fn = Path('samples/puppy.jpg')
display.Image(filename=fn, width=200)
```
<img src="index_files/figure-commonmark/cell-26-output-1.jpeg"
width="200" />
We create a [`Chat`](https://claudette.answer.ai/core.html#chat) object
as before:
``` python
chat = Chat(model)
```
Claudette expects images as a list of bytes, so we read in the file:
``` python
img = fn.read_bytes()
```
Prompts to Claudette can be lists, containing text, images, or both, eg:
``` python
chat([img, "In brief, what color flowers are in this image?"])
```
The flowers in this image are purple. They appear to be small,
daisy-like flowers, possibly asters or some type of purple daisy,
blooming in the background behind the adorable puppy in the foreground.
<details>
- id: `msg_01XtkdWMWHVppHqtiv7gdmtA`
- content:
`[{'text': 'The flowers in this image are purple. They appear to be small, daisy-like flowers, possibly asters or some type of purple daisy, blooming in the background behind the adorable puppy in the foreground.', 'type': 'text'}]`
- model: `claude-3-5-sonnet-20240620`
- role: `assistant`
- stop_reason: `end_turn`
- stop_sequence: `None`
- type: `message`
- usage:
`{'input_tokens': 110, 'output_tokens': 50, 'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0}`
</details>
The image is included as input tokens.
``` python
chat.use
```
In: 110; Out: 50; Total: 160
Alternatively, Claudette supports creating a multi-stage chat with
separate image and text prompts. For instance, you can pass just the
image as the initial prompt (in which case Claude will make some general
comments about what it sees), and then follow up with questions in
additional prompts:
``` python
chat = Chat(model)
chat(img)
```
This image shows an adorable puppy lying in the grass. The puppy appears
to be a Cavalier King Charles Spaniel or a similar breed, with
distinctive white and reddish-brown fur coloring. Its face is
predominantly white with large, expressive eyes and a small black nose.
The puppy is resting on a grassy surface, and behind it, you can see
some purple flowers, likely asters or michaelmas daisies. These flowers
provide a lovely contrast to the puppy’s fur colors. In the background,
there seems to be a wooden structure, possibly a fence or the side of a
building, giving the scene a rustic, outdoor feel.
The composition of the image is quite charming, with the puppy as the
main focus in the foreground and the flowers adding a soft, colorful
backdrop. The lighting appears natural, highlighting the puppy’s soft
fur and the delicate petals of the flowers. Overall, it’s a heartwarming
scene that captures the innocence and cuteness of a young dog in a
picturesque outdoor setting.
<details>
- id: `msg_01Simo36wFes3M21SXZFGBT2`
- content:
`[{'text': "This image shows an adorable puppy lying in the grass. The puppy appears to be a Cavalier King Charles Spaniel or a similar breed, with distinctive white and reddish-brown fur coloring. Its face is predominantly white with large, expressive eyes and a small black nose.\n\nThe puppy is resting on a grassy surface, and behind it, you can see some purple flowers, likely asters or michaelmas daisies. These flowers provide a lovely contrast to the puppy's fur colors. In the background, there seems to be a wooden structure, possibly a fence or the side of a building, giving the scene a rustic, outdoor feel.\n\nThe composition of the image is quite charming, with the puppy as the main focus in the foreground and the flowers adding a soft, colorful backdrop. The lighting appears natural, highlighting the puppy's soft fur and the delicate petals of the flowers. Overall, it's a heartwarming scene that captures the innocence and cuteness of a young dog in a picturesque outdoor setting.", 'type': 'text'}]`
- model: `claude-3-5-sonnet-20240620`
- role: `assistant`
- stop_reason: `end_turn`
- stop_sequence: `None`
- type: `message`
- usage:
`{'input_tokens': 98, 'output_tokens': 232, 'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0}`
</details>
``` python
chat('What direction is the puppy facing?')
```
The puppy in the image is facing towards the left side of the frame. Its
head is turned slightly, allowing us to see most of its face, including
both eyes, its nose, and part of its mouth. The puppy’s body is angled
diagonally, with its front paws visible and resting on the grass. This
positioning gives the viewer a good look at the puppy’s adorable facial
features and the distinctive coloring of its fur, while also creating an
engaging composition within the photograph.
<details>
- id: `msg_019YhPzDxXXjrcpjaS6G8fmF`
- content:
`[{'text': "The puppy in the image is facing towards the left side of the frame. Its head is turned slightly, allowing us to see most of its face, including both eyes, its nose, and part of its mouth. The puppy's body is angled diagonally, with its front paws visible and resting on the grass. This positioning gives the viewer a good look at the puppy's adorable facial features and the distinctive coloring of its fur, while also creating an engaging composition within the photograph.", 'type': 'text'}]`
- model: `claude-3-5-sonnet-20240620`
- role: `assistant`
- stop_reason: `end_turn`
- stop_sequence: `None`
- type: `message`
- usage:
`{'input_tokens': 341, 'output_tokens': 108, 'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0}`
</details>
``` python
chat('What color is it?')
```
The puppy in the image has a combination of two main colors:
1. White: The majority of its face, including the area around its eyes,
muzzle, and part of its chest, is white.
2. Reddish-brown: This color, often referred to as “chestnut” or “ruby”
in Cavalier King Charles Spaniels, covers the puppy’s ears and
extends to patches on its body.
The contrast between these two colors is quite striking and typical of
the Cavalier King Charles Spaniel breed. The white fur appears bright
and clean, while the reddish-brown areas have a rich, warm tone. This
color combination, along with the puppy’s expressive eyes and small
black nose, contributes to its incredibly cute and appealing appearance.
<details>
- id: `msg_01WVxHA2sAff5q1En3q9km8F`
- content:
`[{'text': 'The puppy in the image has a combination of two main colors:\n\n1. White: The majority of its face, including the area around its eyes, muzzle, and part of its chest, is white.\n\n2. Reddish-brown: This color, often referred to as "chestnut" or "ruby" in Cavalier King Charles Spaniels, covers the puppy\'s ears and extends to patches on its body.\n\nThe contrast between these two colors is quite striking and typical of the Cavalier King Charles Spaniel breed. The white fur appears bright and clean, while the reddish-brown areas have a rich, warm tone. This color combination, along with the puppy\'s expressive eyes and small black nose, contributes to its incredibly cute and appealing appearance.', 'type': 'text'}]`
- model: `claude-3-5-sonnet-20240620`
- role: `assistant`
- stop_reason: `end_turn`
- stop_sequence: `None`
- type: `message`
- usage:
`{'input_tokens': 457, 'output_tokens': 175, 'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0}`
</details>
Note that the image is passed in again for every input in the dialog, so
that number of input tokens increases quickly with this kind of chat.
(For large images, using prompt caching might be a good idea.)
``` python
chat.use
```
In: 896; Out: 515; Total: 1411
## Other model providers
You can also use 3rd party providers of Anthropic models, as shown here.
### Amazon Bedrock
These are the models available through Bedrock:
``` python
models_aws
```
('anthropic.claude-3-haiku-20240307-v1:0',
'anthropic.claude-3-sonnet-20240229-v1:0',
'anthropic.claude-3-opus-20240229-v1:0',
'anthropic.claude-3-5-sonnet-20240620-v1:0')
To use them, call `AnthropicBedrock` with your access details, and pass
that to [`Client`](https://claudette.answer.ai/core.html#client):
``` python
from anthropic import AnthropicBedrock
```
``` python
ab = AnthropicBedrock(
aws_access_key=os.environ['AWS_ACCESS_KEY'],
aws_secret_key=os.environ['AWS_SECRET_KEY'],
)
client = Client(models_aws[-1], ab)
```
Now create your [`Chat`](https://claudette.answer.ai/core.html#chat)
object passing this client to the `cli` parameter – and from then on,
everything is identical to the previous examples.
``` python
chat = Chat(cli=client)
chat("I'm Jeremy")
```
Hello Jeremy! It’s nice to meet you. How can I assist you today? Is
there anything specific you’d like to talk about or any questions you
have?
<details>
- id: `msg_bdrk_01VFVE1Pe5LNubaWYKC1sz8f`
- content:
`[{'text': "Hello Jeremy! It's nice to meet you. How can I assist you today? Is there anything specific you'd like to talk about or any questions you have?", 'type': 'text'}]`
- model: `claude-3-5-sonnet-20240620`
- role: `assistant`
- stop_reason: `end_turn`
- stop_sequence: `None`
- type: `message`
- usage: `{'input_tokens': 10, 'output_tokens': 36}`
</details>
### Google Vertex
These are the models available through Vertex:
``` python
models_goog
```
('claude-3-haiku@20240307',
'claude-3-sonnet@20240229',
'claude-3-opus@20240229',
'claude-3-5-sonnet@20240620')
To use them, call `AnthropicVertex` with your access details, and pass
that to [`Client`](https://claudette.answer.ai/core.html#client):
``` python
from anthropic import AnthropicVertex
import google.auth
```
``` python
project_id = google.auth.default()[1]
gv = AnthropicVertex(project_id=project_id, region="us-east5")
client = Client(models_goog[-1], gv)
```
``` python
chat = Chat(cli=client)
chat("I'm Jeremy")
```
Hello Jeremy! It’s nice to meet you. How can I assist you today? Is
there anything specific you’d like to talk about or any questions you
have?
<details>
- id: `msg_vrtx_01P251BUJXBBvihsvb3VVgZ3`
- content:
`[{'text': "Hello Jeremy! It's nice to meet you. How can I assist you today? Is there anything specific you'd like to talk about or any questions you have?", 'type': 'text'}]`
- model: `claude-3-5-sonnet-20240620`
- role: `assistant`
- stop_reason: `end_turn`
- stop_sequence: `None`
- type: `message`
- usage: `{'input_tokens': 10, 'output_tokens': 36}`
</details>
## Extensions
- [Pydantic Structured Ouput](https://github.com/tom-pollak/claudette-pydantic)
Raw data
{
"_id": null,
"home_page": "https://github.com/AnswerDotAI/claudette",
"name": "claudette",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.9",
"maintainer_email": null,
"keywords": "nbdev jupyter notebook python",
"author": "Jeremy Howard",
"author_email": "j@fast.ai",
"download_url": "https://files.pythonhosted.org/packages/aa/3e/d2cdc459c75dc1350fc0d04366052cc25c376357163e62354b1e0df0b77d/claudette-0.1.0.tar.gz",
"platform": null,
"description": "# claudette\n\n\n<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->\n\n> **NB**: If you are reading this in GitHub\u2019s readme, we recommend you\n> instead read the much more nicely formatted [documentation\n> format](https://claudette.answer.ai/) of this tutorial.\n\n*Claudette* is a wrapper for Anthropic\u2019s [Python\nSDK](https://github.com/anthropics/anthropic-sdk-python).\n\nThe SDK works well, but it is quite low level \u2013 it leaves the developer\nto do a lot of stuff manually. That\u2019s a lot of extra work and\nboilerplate! Claudette automates pretty much everything that can be\nautomated, whilst providing full control. Amongst the features provided:\n\n- A [`Chat`](https://claudette.answer.ai/core.html#chat) class that\n creates stateful dialogs\n- Support for *prefill*, which tells Claude what to use as the first few\n words of its response\n- Convenient image support\n- Simple and convenient support for Claude\u2019s new Tool Use API.\n\nYou\u2019ll need to set the `ANTHROPIC_API_KEY` environment variable to the\nkey provided to you by Anthropic in order to use this library.\n\nNote that this library is the first ever \u201cliterate nbdev\u201d project. That\nmeans that the actual source code for the library is a rendered Jupyter\nNotebook which includes callout notes and tips, HTML tables and images,\ndetailed explanations, and teaches *how* and *why* the code is written\nthe way it is. Even if you\u2019ve never used the Anthropic Python SDK or\nClaude API before, you should be able to read the source code. Click\n[Claudette\u2019s Source](https://claudette.answer.ai/core.html) to read it,\nor clone the git repo and execute the notebook yourself to see every\nstep of the creation process in action. The tutorial below includes\nlinks to API details which will take you to relevant parts of the\nsource. The reason this project is a new kind of literal program is\nbecause we take seriously Knuth\u2019s call to action, that we have a \u201c*moral\ncommitment*\u201d to never write an \u201c*illiterate program*\u201d \u2013 and so we have a\ncommitment to making literate programming and easy and pleasant\nexperience. (For more on this, see [this\ntalk](https://www.youtube.com/watch?v=rX1yGxJijsI) from Hamel Husain.)\n\n> \u201c*Let us change our traditional attitude to the construction of\n> programs: Instead of imagining that our main task is to instruct a\n> **computer** what to do, let us concentrate rather on explaining to\n> **human beings** what we want a computer to do.*\u201d Donald E. Knuth,\n> [Literate\n> Programming](https://www.cs.tufts.edu/~nr/cs257/archive/literate-programming/01-knuth-lp.pdf)\n> (1984)\n\n## Install\n\n``` sh\npip install claudette\n```\n\n## Getting started\n\nAnthropic\u2019s Python SDK will automatically be installed with Claudette,\nif you don\u2019t already have it.\n\n``` python\nimport os\n# os.environ['ANTHROPIC_LOG'] = 'debug'\n```\n\nTo print every HTTP request and response in full, uncomment the above\nline.\n\n``` python\nfrom claudette import *\n```\n\nClaudette only exports the symbols that are needed to use the library,\nso you can use `import *` to import them. Alternatively, just use:\n\n``` python\nimport claudette\n```\n\n\u2026and then add the prefix `claudette.` to any usages of the module.\n\nClaudette provides `models`, which is a list of models currently\navailable from the SDK.\n\n``` python\nmodels\n```\n\n ('claude-3-opus-20240229',\n 'claude-3-5-sonnet-20240620',\n 'claude-3-haiku-20240307')\n\nFor these examples, we\u2019ll use Sonnet 3.5, since it\u2019s awesome!\n\n``` python\nmodel = models[1]\n```\n\n## Chat\n\nThe main interface to Claudette is the\n[`Chat`](https://claudette.answer.ai/core.html#chat) class, which\nprovides a stateful interface to Claude:\n\n``` python\nchat = Chat(model, sp=\"\"\"You are a helpful and concise assistant.\"\"\")\nchat(\"I'm Jeremy\")\n```\n\nHello Jeremy, it\u2019s nice to meet you. How can I assist you today?\n\n<details>\n\n- id: `msg_014J96J6f9Bxrmyr7uA5Z4E3`\n- content:\n `[{'text': \"Hello Jeremy, it's nice to meet you. How can I assist you today?\", 'type': 'text'}]`\n- model: `claude-3-5-sonnet-20240620`\n- role: `assistant`\n- stop_reason: `end_turn`\n- stop_sequence: `None`\n- type: `message`\n- usage:\n `{'input_tokens': 19, 'output_tokens': 20, 'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0}`\n\n</details>\n\n``` python\nr = chat(\"What's my name?\")\nr\n```\n\nYour name is Jeremy, as you just told me.\n\n<details>\n\n- id: `msg_01RpP5rBhFK34UkZwAiMnL85`\n- content:\n `[{'text': 'Your name is Jeremy, as you just told me.', 'type': 'text'}]`\n- model: `claude-3-5-sonnet-20240620`\n- role: `assistant`\n- stop_reason: `end_turn`\n- stop_sequence: `None`\n- type: `message`\n- usage:\n `{'input_tokens': 47, 'output_tokens': 14, 'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0}`\n\n</details>\n\nAs you see above, displaying the results of a call in a notebook shows\njust the message contents, with the other details hidden behind a\ncollapsible section. Alternatively you can `print` the details:\n\n``` python\nprint(r)\n```\n\n Message(id='msg_01RpP5rBhFK34UkZwAiMnL85', content=[TextBlock(text='Your name is Jeremy, as you just told me.', type='text')], model='claude-3-5-sonnet-20240620', role='assistant', stop_reason='end_turn', stop_sequence=None, type='message', usage=In: 47; Out: 14; Total: 61)\n\nClaude supports adding an extra `assistant` message at the end, which\ncontains the *prefill* \u2013 i.e.\u00a0the text we want Claude to assume the\nresponse starts with. Let\u2019s try it out:\n\n``` python\nchat(\"Concisely, what is the meaning of life?\",\n prefill='According to Douglas Adams,')\n```\n\nAccording to Douglas Adams, \u201c42.\u201d More seriously, it\u2019s often considered\nto be finding personal fulfillment, happiness, and purpose.\n\n<details>\n\n- id: `msg_01Qgsa4a7cdPJkCrm989emJ5`\n- content:\n `[{'text': 'According to Douglas Adams, \"42.\" More seriously, it\\'s often considered to be finding personal fulfillment, happiness, and purpose.', 'type': 'text'}]`\n- model: `claude-3-5-sonnet-20240620`\n- role: `assistant`\n- stop_reason: `end_turn`\n- stop_sequence: `None`\n- type: `message`\n- usage:\n `{'input_tokens': 81, 'output_tokens': 27, 'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0}`\n\n</details>\n\nYou can add `stream=True` to stream the results as soon as they arrive\n(although you will only see the gradual generation if you execute the\nnotebook yourself, of course!)\n\n``` python\nfor o in chat(\"Concisely, what book was that in?\", prefill='It was in', stream=True):\n print(o, end='')\n```\n\n It was in \"The Hitchhiker's Guide to the Galaxy\" by Douglas Adams.\n\n## Prompt caching\n\nIf you use `mk_msg(msg, cache=True)`, then the message is cached using\nClaude\u2019s [prompt\ncaching](https://docs.anthropic.com/en/docs/build-with-claude/prompt-caching)\nfeature. For instance, here we use caching when asking about Claudette\u2019s\nreadme file:\n\n``` python\nchat = Chat(model, sp=\"\"\"You are a helpful and concise assistant.\"\"\")\n```\n\n``` python\nnbtxt = Path('README.txt').read_text()\nmsg = f'''<README>\n{nbtxt}\n</README>\nIn brief, what is the purpose of this project based on the readme?'''\nr = chat(mk_msg(msg, cache=True))\nr\n```\n\nBased on the readme, the main purpose of the Claudette project is to\nprovide a high-level wrapper around Anthropic\u2019s Python SDK for\ninteracting with Claude AI models. Key features and goals include:\n\n1. Automating and simplifying interactions with Claude, reducing\n boilerplate code.\n\n2. Providing a stateful dialog interface through the\n [`Chat`](https://claudette.answer.ai/core.html#chat) class.\n\n3. Supporting features like prefill (specifying the start of Claude\u2019s\n response) and image handling.\n\n4. Offering convenient support for Claude\u2019s Tool Use API.\n\n5. Serving as an example of \u201cliterate programming\u201d, with the source\n code designed to be readable and educational, including explanations\n of how and why the code is written.\n\n6. Supporting multiple model providers, including direct Anthropic API\n access as well as Claude models available through Amazon Bedrock and\n Google Vertex AI.\n\nThe project aims to make working with Claude models more convenient and\naccessible for developers while also serving as an educational resource\non how to effectively use and interact with these AI models.\n\n<details>\n\n- id: `msg_01HkjoKjfY5zrmBrkjHvtDpG`\n- content:\n `[{'text': 'Based on the readme, the main purpose of the Claudette project is to provide a high-level wrapper around Anthropic\\'s Python SDK for interacting with Claude AI models. Key features and goals include:\\n\\n1. Automating and simplifying interactions with Claude, reducing boilerplate code.\\n\\n2. Providing a stateful dialog interface through the [`Chat`](https://claudette.answer.ai/core.html#chat) class.\\n\\n3. Supporting features like prefill (specifying the start of Claude\\'s response) and image handling.\\n\\n4. Offering convenient support for Claude\\'s Tool Use API.\\n\\n5. Serving as an example of \"literate programming\", with the source code designed to be readable and educational, including explanations of how and why the code is written.\\n\\n6. Supporting multiple model providers, including direct Anthropic API access as well as Claude models available through Amazon Bedrock and Google Vertex AI.\\n\\nThe project aims to make working with Claude models more convenient and accessible for developers while also serving as an educational resource on how to effectively use and interact with these AI models.', 'type': 'text'}]`\n- model: `claude-3-5-sonnet-20240620`\n- role: `assistant`\n- stop_reason: `end_turn`\n- stop_sequence: `None`\n- type: `message`\n- usage:\n `{'input_tokens': 4, 'output_tokens': 220, 'cache_creation_input_tokens': 7171, 'cache_read_input_tokens': 0}`\n\n</details>\n\nThe response records the a cache has been created using these input\ntokens:\n\n``` python\nprint(r.usage)\n```\n\n Usage(input_tokens=4, output_tokens=220, cache_creation_input_tokens=7171, cache_read_input_tokens=0)\n\nWe can now ask a followup question in this chat:\n\n``` python\nr = chat('How does it make tool use more ergonomic?')\nr\n```\n\nClaudette makes tool use more ergonomic in several ways:\n\n1. Simplified function definition: It uses docments to make defining\n Python functions for tools as simple as possible. Each parameter and\n the return value should have a type and a description.\n\n2. Automatic handling: The\n [`Chat`](https://claudette.answer.ai/core.html#chat) class can be\n initialized with a list of tools, and Claudette handles the\n back-and-forth between Claude and the tools automatically.\n\n3. Single-step execution: The\n [`Chat.toolloop`](https://claudette.answer.ai/toolloop.html#chat.toolloop)\n method allows for executing a series of tool calls in a single step,\n even if multiple tools are needed to solve a problem.\n\n4. Forced tool use: You can set `tool_choice` to force Claude to always\n answer using a specific tool.\n\n5. Tracing: The `toolloop` method supports a `trace_func` parameter,\n allowing you to see each response from Claude during the process.\n\n6. Automatic parameter passing: When Claude decides to use a tool,\n Claudette automatically calls the tool with the provided parameters.\n\n7. System prompt integration: It allows setting a system prompt to\n guide Claude\u2019s behavior when using tools, such as instructing it not\n to mention the tools it\u2019s using.\n\nThese features significantly reduce the amount of code and manual\nhandling required to use Claude\u2019s tool use capabilities, making the\nprocess more streamlined and developer-friendly.\n\n<details>\n\n- id: `msg_01EfFbEBeYETAvfjGncn8Vcb`\n- content:\n `[{'text': \"Claudette makes tool use more ergonomic in several ways:\\n\\n1. Simplified function definition: It uses docments to make defining Python functions for tools as simple as possible. Each parameter and the return value should have a type and a description.\\n\\n2. Automatic handling: The [`Chat`](https://claudette.answer.ai/core.html#chat) class can be initialized with a list of tools, and Claudette handles the back-and-forth between Claude and the tools automatically.\\n\\n3. Single-step execution: The [`Chat.toolloop`](https://claudette.answer.ai/toolloop.html#chat.toolloop) method allows for executing a series of tool calls in a single step, even if multiple tools are needed to solve a problem.\\n\\n4. Forced tool use: You can set`tool_choice`to force Claude to always answer using a specific tool.\\n\\n5. Tracing: The`toolloop`method supports a`trace_func`parameter, allowing you to see each response from Claude during the process.\\n\\n6. Automatic parameter passing: When Claude decides to use a tool, Claudette automatically calls the tool with the provided parameters.\\n\\n7. System prompt integration: It allows setting a system prompt to guide Claude's behavior when using tools, such as instructing it not to mention the tools it's using.\\n\\nThese features significantly reduce the amount of code and manual handling required to use Claude's tool use capabilities, making the process more streamlined and developer-friendly.\", 'type': 'text'}]`\n- model: `claude-3-5-sonnet-20240620`\n- role: `assistant`\n- stop_reason: `end_turn`\n- stop_sequence: `None`\n- type: `message`\n- usage:\n `{'input_tokens': 240, 'output_tokens': 289, 'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 7171}`\n\n</details>\n\nWe can see that this only used ~200 regular input tokens \u2013 the 7000+\ncontext tokens have been read from cache.\n\n``` python\nprint(r.usage)\n```\n\n Usage(input_tokens=240, output_tokens=289, cache_creation_input_tokens=0, cache_read_input_tokens=7171)\n\n## Tool use\n\n[Tool use](https://docs.anthropic.com/claude/docs/tool-use) lets Claude\nuse external tools.\n\nWe use [docments](https://fastcore.fast.ai/docments.html) to make\ndefining Python functions as ergonomic as possible. Each parameter (and\nthe return value) should have a type, and a docments comment with the\ndescription of what it is. As an example we\u2019ll write a simple function\nthat adds numbers together, and will tell us when it\u2019s being called:\n\n``` python\ndef sums(\n a:int, # First thing to sum\n b:int=1 # Second thing to sum\n) -> int: # The sum of the inputs\n \"Adds a + b.\"\n print(f\"Finding the sum of {a} and {b}\")\n return a + b\n```\n\nSometimes Claude will say something like \u201caccording to the `sums` tool\nthe answer is\u201d \u2013 generally we\u2019d rather it just tells the user the\nanswer, so we can use a system prompt to help with this:\n\n``` python\nsp = \"Never mention what tools you use.\"\n```\n\nWe\u2019ll get Claude to add up some long numbers:\n\n``` python\na,b = 604542,6458932\npr = f\"What is {a}+{b}?\"\npr\n```\n\n 'What is 604542+6458932?'\n\nTo use tools, pass a list of them to\n[`Chat`](https://claudette.answer.ai/core.html#chat), and to force it to\nalways answer using a tool, set `tool_choice` to that function name:\n\n``` python\nchat = Chat(model, sp=sp, tools=[sums], tool_choice='sums')\n```\n\nNow when we call that with our prompt, Claude doesn\u2019t return the answer,\nbut instead returns a `tool_use` message, which means we have to call\nthe named tool with the provided parameters:\n\n``` python\nr = chat(pr)\nr\n```\n\n Finding the sum of 604542 and 6458932\n\nToolUseBlock(id=\u2018toolu_01C6G2iuLtBBftESiujKzXfx\u2019, input={\u2018a\u2019: 604542,\n\u2018b\u2019: 6458932}, name=\u2018sums\u2019, type=\u2018tool_use\u2019)\n\n<details>\n\n- id: `msg_01HPZwX3mQ7sMbjWUHEwgUsT`\n- content:\n `[{'id': 'toolu_01C6G2iuLtBBftESiujKzXfx', 'input': {'a': 604542, 'b': 6458932}, 'name': 'sums', 'type': 'tool_use'}]`\n- model: `claude-3-5-sonnet-20240620`\n- role: `assistant`\n- stop_reason: `tool_use`\n- stop_sequence: `None`\n- type: `message`\n- usage:\n `{'input_tokens': 414, 'output_tokens': 53, 'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0}`\n\n</details>\n\nClaudette handles all that for us \u2013 we just call it again, and it all\nhappens automatically:\n\n``` python\nchat()\n```\n\nThe sum of 604542 and 6458932 is 7063474.\n\n<details>\n\n- id: `msg_01RNHxf1jXfS76h2UpF8RnZ2`\n- content:\n `[{'text': 'The sum of 604542 and 6458932 is 7063474.', 'type': 'text'}]`\n- model: `claude-3-5-sonnet-20240620`\n- role: `assistant`\n- stop_reason: `end_turn`\n- stop_sequence: `None`\n- type: `message`\n- usage:\n `{'input_tokens': 515, 'output_tokens': 23, 'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0}`\n\n</details>\n\nYou can see how many tokens have been used at any time by checking the\n`use` property. Note that (as of May 2024) tool use in Claude uses a\n*lot* of tokens, since it automatically adds a large system prompt.\n\n``` python\nchat.use\n```\n\n In: 929; Out: 76; Total: 1005\n\nWe can do everything needed to use tools in a single step, by using\n[`Chat.toolloop`](https://claudette.answer.ai/toolloop.html#chat.toolloop).\nThis can even call multiple tools as needed solve a problem. For\nexample, let\u2019s define a tool to handle multiplication:\n\n``` python\ndef mults(\n a:int, # First thing to multiply\n b:int=1 # Second thing to multiply\n) -> int: # The product of the inputs\n \"Multiplies a * b.\"\n print(f\"Finding the product of {a} and {b}\")\n return a * b\n```\n\nNow with a single call we can calculate `(a+b)*2` \u2013 by passing\n`show_trace` we can see each response from Claude in the process:\n\n``` python\nchat = Chat(model, sp=sp, tools=[sums,mults])\npr = f'Calculate ({a}+{b})*2'\npr\n```\n\n 'Calculate (604542+6458932)*2'\n\n``` python\nchat.toolloop(pr, trace_func=print)\n```\n\n Finding the sum of 604542 and 6458932\n Message(id='msg_01DgZ9Fcs6h8HB7qEaFkg3Ah', content=[TextBlock(text='Certainly! To calculate (604542+6458932)*2, we\\'ll need to use the available tools to perform the addition and multiplication operations. Let\\'s break it down step by step:\\n\\n1. First, we\\'ll add 604542 and 6458932 using the \"sums\" function.\\n2. Then, we\\'ll multiply the result by 2 using the \"mults\" function.\\n\\nLet\\'s start with the addition:', type='text'), ToolUseBlock(id='toolu_01XTMLyKo9Q6TX4SpCVmmUsP', input={'a': 604542, 'b': 6458932}, name='sums', type='tool_use')], model='claude-3-5-sonnet-20240620', role='assistant', stop_reason='tool_use', stop_sequence=None, type='message', usage=In: 538; Out: 168; Total: 706)\n Finding the product of 7063474 and 2\n Message(id='msg_011P8jdxwLoKNf8nTDua7VM8', content=[TextBlock(text=\"Great! The sum of 604542 and 6458932 is 7063474.\\n\\nNow, let's multiply this result by 2:\", type='text'), ToolUseBlock(id='toolu_01FETWkj4a9HyX25c8ETULYh', input={'a': 7063474, 'b': 2}, name='mults', type='tool_use')], model='claude-3-5-sonnet-20240620', role='assistant', stop_reason='tool_use', stop_sequence=None, type='message', usage=In: 721; Out: 106; Total: 827)\n Message(id='msg_01UXwy69vUWSy9bK24skQ3yE', content=[TextBlock(text='Now we have our final result. \\n\\nThe calculation (604542+6458932)*2 equals 14126948.\\n\\nTo break it down:\\n1. 604542 + 6458932 = 7063474\\n2. 7063474 * 2 = 14126948\\n\\nSo, the final answer to (604542+6458932)*2 is 14126948.', type='text')], model='claude-3-5-sonnet-20240620', role='assistant', stop_reason='end_turn', stop_sequence=None, type='message', usage=In: 841; Out: 95; Total: 936)\n\nNow we have our final result.\n\nThe calculation (604542+6458932)\\*2 equals 14126948.\n\nTo break it down: 1. 604542 + 6458932 = 7063474 2. 7063474 \\* 2 =\n14126948\n\nSo, the final answer to (604542+6458932)\\*2 is 14126948.\n\n<details>\n\n- id: `msg_01UXwy69vUWSy9bK24skQ3yE`\n- content:\n `[{'text': 'Now we have our final result. \\n\\nThe calculation (604542+6458932)*2 equals 14126948.\\n\\nTo break it down:\\n1. 604542 + 6458932 = 7063474\\n2. 7063474 * 2 = 14126948\\n\\nSo, the final answer to (604542+6458932)*2 is 14126948.', 'type': 'text'}]`\n- model: `claude-3-5-sonnet-20240620`\n- role: `assistant`\n- stop_reason: `end_turn`\n- stop_sequence: `None`\n- type: `message`\n- usage:\n `{'input_tokens': 841, 'output_tokens': 95, 'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0}`\n\n</details>\n\n## Images\n\nClaude can handle image data as well. As everyone knows, when testing\nimage APIs you have to use a cute puppy.\n\n``` python\nfn = Path('samples/puppy.jpg')\ndisplay.Image(filename=fn, width=200)\n```\n\n<img src=\"index_files/figure-commonmark/cell-26-output-1.jpeg\"\nwidth=\"200\" />\n\nWe create a [`Chat`](https://claudette.answer.ai/core.html#chat) object\nas before:\n\n``` python\nchat = Chat(model)\n```\n\nClaudette expects images as a list of bytes, so we read in the file:\n\n``` python\nimg = fn.read_bytes()\n```\n\nPrompts to Claudette can be lists, containing text, images, or both, eg:\n\n``` python\nchat([img, \"In brief, what color flowers are in this image?\"])\n```\n\nThe flowers in this image are purple. They appear to be small,\ndaisy-like flowers, possibly asters or some type of purple daisy,\nblooming in the background behind the adorable puppy in the foreground.\n\n<details>\n\n- id: `msg_01XtkdWMWHVppHqtiv7gdmtA`\n- content:\n `[{'text': 'The flowers in this image are purple. They appear to be small, daisy-like flowers, possibly asters or some type of purple daisy, blooming in the background behind the adorable puppy in the foreground.', 'type': 'text'}]`\n- model: `claude-3-5-sonnet-20240620`\n- role: `assistant`\n- stop_reason: `end_turn`\n- stop_sequence: `None`\n- type: `message`\n- usage:\n `{'input_tokens': 110, 'output_tokens': 50, 'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0}`\n\n</details>\n\nThe image is included as input tokens.\n\n``` python\nchat.use\n```\n\n In: 110; Out: 50; Total: 160\n\nAlternatively, Claudette supports creating a multi-stage chat with\nseparate image and text prompts. For instance, you can pass just the\nimage as the initial prompt (in which case Claude will make some general\ncomments about what it sees), and then follow up with questions in\nadditional prompts:\n\n``` python\nchat = Chat(model)\nchat(img)\n```\n\nThis image shows an adorable puppy lying in the grass. The puppy appears\nto be a Cavalier King Charles Spaniel or a similar breed, with\ndistinctive white and reddish-brown fur coloring. Its face is\npredominantly white with large, expressive eyes and a small black nose.\n\nThe puppy is resting on a grassy surface, and behind it, you can see\nsome purple flowers, likely asters or michaelmas daisies. These flowers\nprovide a lovely contrast to the puppy\u2019s fur colors. In the background,\nthere seems to be a wooden structure, possibly a fence or the side of a\nbuilding, giving the scene a rustic, outdoor feel.\n\nThe composition of the image is quite charming, with the puppy as the\nmain focus in the foreground and the flowers adding a soft, colorful\nbackdrop. The lighting appears natural, highlighting the puppy\u2019s soft\nfur and the delicate petals of the flowers. Overall, it\u2019s a heartwarming\nscene that captures the innocence and cuteness of a young dog in a\npicturesque outdoor setting.\n\n<details>\n\n- id: `msg_01Simo36wFes3M21SXZFGBT2`\n- content:\n `[{'text': \"This image shows an adorable puppy lying in the grass. The puppy appears to be a Cavalier King Charles Spaniel or a similar breed, with distinctive white and reddish-brown fur coloring. Its face is predominantly white with large, expressive eyes and a small black nose.\\n\\nThe puppy is resting on a grassy surface, and behind it, you can see some purple flowers, likely asters or michaelmas daisies. These flowers provide a lovely contrast to the puppy's fur colors. In the background, there seems to be a wooden structure, possibly a fence or the side of a building, giving the scene a rustic, outdoor feel.\\n\\nThe composition of the image is quite charming, with the puppy as the main focus in the foreground and the flowers adding a soft, colorful backdrop. The lighting appears natural, highlighting the puppy's soft fur and the delicate petals of the flowers. Overall, it's a heartwarming scene that captures the innocence and cuteness of a young dog in a picturesque outdoor setting.\", 'type': 'text'}]`\n- model: `claude-3-5-sonnet-20240620`\n- role: `assistant`\n- stop_reason: `end_turn`\n- stop_sequence: `None`\n- type: `message`\n- usage:\n `{'input_tokens': 98, 'output_tokens': 232, 'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0}`\n\n</details>\n\n``` python\nchat('What direction is the puppy facing?')\n```\n\nThe puppy in the image is facing towards the left side of the frame. Its\nhead is turned slightly, allowing us to see most of its face, including\nboth eyes, its nose, and part of its mouth. The puppy\u2019s body is angled\ndiagonally, with its front paws visible and resting on the grass. This\npositioning gives the viewer a good look at the puppy\u2019s adorable facial\nfeatures and the distinctive coloring of its fur, while also creating an\nengaging composition within the photograph.\n\n<details>\n\n- id: `msg_019YhPzDxXXjrcpjaS6G8fmF`\n- content:\n `[{'text': \"The puppy in the image is facing towards the left side of the frame. Its head is turned slightly, allowing us to see most of its face, including both eyes, its nose, and part of its mouth. The puppy's body is angled diagonally, with its front paws visible and resting on the grass. This positioning gives the viewer a good look at the puppy's adorable facial features and the distinctive coloring of its fur, while also creating an engaging composition within the photograph.\", 'type': 'text'}]`\n- model: `claude-3-5-sonnet-20240620`\n- role: `assistant`\n- stop_reason: `end_turn`\n- stop_sequence: `None`\n- type: `message`\n- usage:\n `{'input_tokens': 341, 'output_tokens': 108, 'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0}`\n\n</details>\n\n``` python\nchat('What color is it?')\n```\n\nThe puppy in the image has a combination of two main colors:\n\n1. White: The majority of its face, including the area around its eyes,\n muzzle, and part of its chest, is white.\n\n2. Reddish-brown: This color, often referred to as \u201cchestnut\u201d or \u201cruby\u201d\n in Cavalier King Charles Spaniels, covers the puppy\u2019s ears and\n extends to patches on its body.\n\nThe contrast between these two colors is quite striking and typical of\nthe Cavalier King Charles Spaniel breed. The white fur appears bright\nand clean, while the reddish-brown areas have a rich, warm tone. This\ncolor combination, along with the puppy\u2019s expressive eyes and small\nblack nose, contributes to its incredibly cute and appealing appearance.\n\n<details>\n\n- id: `msg_01WVxHA2sAff5q1En3q9km8F`\n- content:\n `[{'text': 'The puppy in the image has a combination of two main colors:\\n\\n1. White: The majority of its face, including the area around its eyes, muzzle, and part of its chest, is white.\\n\\n2. Reddish-brown: This color, often referred to as \"chestnut\" or \"ruby\" in Cavalier King Charles Spaniels, covers the puppy\\'s ears and extends to patches on its body.\\n\\nThe contrast between these two colors is quite striking and typical of the Cavalier King Charles Spaniel breed. The white fur appears bright and clean, while the reddish-brown areas have a rich, warm tone. This color combination, along with the puppy\\'s expressive eyes and small black nose, contributes to its incredibly cute and appealing appearance.', 'type': 'text'}]`\n- model: `claude-3-5-sonnet-20240620`\n- role: `assistant`\n- stop_reason: `end_turn`\n- stop_sequence: `None`\n- type: `message`\n- usage:\n `{'input_tokens': 457, 'output_tokens': 175, 'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0}`\n\n</details>\n\nNote that the image is passed in again for every input in the dialog, so\nthat number of input tokens increases quickly with this kind of chat.\n(For large images, using prompt caching might be a good idea.)\n\n``` python\nchat.use\n```\n\n In: 896; Out: 515; Total: 1411\n\n## Other model providers\n\nYou can also use 3rd party providers of Anthropic models, as shown here.\n\n### Amazon Bedrock\n\nThese are the models available through Bedrock:\n\n``` python\nmodels_aws\n```\n\n ('anthropic.claude-3-haiku-20240307-v1:0',\n 'anthropic.claude-3-sonnet-20240229-v1:0',\n 'anthropic.claude-3-opus-20240229-v1:0',\n 'anthropic.claude-3-5-sonnet-20240620-v1:0')\n\nTo use them, call `AnthropicBedrock` with your access details, and pass\nthat to [`Client`](https://claudette.answer.ai/core.html#client):\n\n``` python\nfrom anthropic import AnthropicBedrock\n```\n\n``` python\nab = AnthropicBedrock(\n aws_access_key=os.environ['AWS_ACCESS_KEY'],\n aws_secret_key=os.environ['AWS_SECRET_KEY'],\n)\nclient = Client(models_aws[-1], ab)\n```\n\nNow create your [`Chat`](https://claudette.answer.ai/core.html#chat)\nobject passing this client to the `cli` parameter \u2013 and from then on,\neverything is identical to the previous examples.\n\n``` python\nchat = Chat(cli=client)\nchat(\"I'm Jeremy\")\n```\n\nHello Jeremy! It\u2019s nice to meet you. How can I assist you today? Is\nthere anything specific you\u2019d like to talk about or any questions you\nhave?\n\n<details>\n\n- id: `msg_bdrk_01VFVE1Pe5LNubaWYKC1sz8f`\n- content:\n `[{'text': \"Hello Jeremy! It's nice to meet you. How can I assist you today? Is there anything specific you'd like to talk about or any questions you have?\", 'type': 'text'}]`\n- model: `claude-3-5-sonnet-20240620`\n- role: `assistant`\n- stop_reason: `end_turn`\n- stop_sequence: `None`\n- type: `message`\n- usage: `{'input_tokens': 10, 'output_tokens': 36}`\n\n</details>\n\n### Google Vertex\n\nThese are the models available through Vertex:\n\n``` python\nmodels_goog\n```\n\n ('claude-3-haiku@20240307',\n 'claude-3-sonnet@20240229',\n 'claude-3-opus@20240229',\n 'claude-3-5-sonnet@20240620')\n\nTo use them, call `AnthropicVertex` with your access details, and pass\nthat to [`Client`](https://claudette.answer.ai/core.html#client):\n\n``` python\nfrom anthropic import AnthropicVertex\nimport google.auth\n```\n\n``` python\nproject_id = google.auth.default()[1]\ngv = AnthropicVertex(project_id=project_id, region=\"us-east5\")\nclient = Client(models_goog[-1], gv)\n```\n\n``` python\nchat = Chat(cli=client)\nchat(\"I'm Jeremy\")\n```\n\nHello Jeremy! It\u2019s nice to meet you. How can I assist you today? Is\nthere anything specific you\u2019d like to talk about or any questions you\nhave?\n\n<details>\n\n- id: `msg_vrtx_01P251BUJXBBvihsvb3VVgZ3`\n- content:\n `[{'text': \"Hello Jeremy! It's nice to meet you. How can I assist you today? Is there anything specific you'd like to talk about or any questions you have?\", 'type': 'text'}]`\n- model: `claude-3-5-sonnet-20240620`\n- role: `assistant`\n- stop_reason: `end_turn`\n- stop_sequence: `None`\n- type: `message`\n- usage: `{'input_tokens': 10, 'output_tokens': 36}`\n\n</details>\n\n## Extensions\n\n- [Pydantic Structured Ouput](https://github.com/tom-pollak/claudette-pydantic)\n",
"bugtrack_url": null,
"license": "Apache Software License 2.0",
"summary": "Claudette is Claude's friend",
"version": "0.1.0",
"project_urls": {
"Homepage": "https://github.com/AnswerDotAI/claudette"
},
"split_keywords": [
"nbdev",
"jupyter",
"notebook",
"python"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "3e2a2e0dbc82d2054bc9f1b5e137343b545cea24c0a7be02144dbb817a4028f0",
"md5": "2af31b17852416d0115fb65dace90f26",
"sha256": "b9acc77f4b90199cf4ac7746855a42bca4f148038b51aaa6a77c35411b95a633"
},
"downloads": -1,
"filename": "claudette-0.1.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "2af31b17852416d0115fb65dace90f26",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.9",
"size": 22253,
"upload_time": "2024-10-14T19:36:17",
"upload_time_iso_8601": "2024-10-14T19:36:17.933760Z",
"url": "https://files.pythonhosted.org/packages/3e/2a/2e0dbc82d2054bc9f1b5e137343b545cea24c0a7be02144dbb817a4028f0/claudette-0.1.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "aa3ed2cdc459c75dc1350fc0d04366052cc25c376357163e62354b1e0df0b77d",
"md5": "b4bd6655bdc67d8a7b03faf243000005",
"sha256": "61d1e77a1075ece013275fca0faa4e12aa6e561d93f20db300f26733312ae2dc"
},
"downloads": -1,
"filename": "claudette-0.1.0.tar.gz",
"has_sig": false,
"md5_digest": "b4bd6655bdc67d8a7b03faf243000005",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.9",
"size": 32616,
"upload_time": "2024-10-14T19:36:19",
"upload_time_iso_8601": "2024-10-14T19:36:19.470902Z",
"url": "https://files.pythonhosted.org/packages/aa/3e/d2cdc459c75dc1350fc0d04366052cc25c376357163e62354b1e0df0b77d/claudette-0.1.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-10-14 19:36:19",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "AnswerDotAI",
"github_project": "claudette",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "claudette"
}