Skip to main content

use_anthropic_tools/
use_anthropic_tools.rs

1use anyhow::{anyhow, Result};
2use schemars::JsonSchema;
3use serde::Deserialize;
4use serde::Serialize;
5use std::ffi::OsStr;
6use std::path::Path;
7
8use allms::{
9    files::{AnthropicFile, LLMFiles},
10    llm::{
11        tools::{
12            AnthropicCodeExecutionConfig, AnthropicFileSearchConfig, AnthropicWebSearchConfig,
13            LLMTools,
14        },
15        AnthropicModels,
16    },
17    Completions,
18};
19
20// Example 1: Web search
21#[derive(Deserialize, Serialize, JsonSchema, Debug, Clone)]
22struct AINewsArticles {
23    pub articles: Vec<AINewsArticle>,
24}
25
26#[derive(Deserialize, Serialize, JsonSchema, Debug, Clone)]
27struct AINewsArticle {
28    pub title: String,
29    pub url: String,
30    pub description: String,
31}
32
33// Example 2: Code interpreter example
34#[derive(Deserialize, Serialize, Debug, Clone, JsonSchema)]
35pub struct CodeInterpreterResponse {
36    pub problem: String,
37    pub code: String,
38    pub solution: String,
39}
40
41// Example 3: File search
42#[derive(Deserialize, Serialize, Debug, Clone, JsonSchema)]
43pub struct ConcertInfo {
44    dates: Vec<String>,
45    band: String,
46    genre: String,
47    venue: String,
48    city: String,
49    country: String,
50    ticket_price: String,
51}
52
53const BANDS_GENRES: &[(&str, &str)] = &[
54    ("Metallica", "Metal"),
55    ("The Beatles", "Rock"),
56    ("Daft Punk", "Electronic"),
57    ("Miles Davis", "Jazz"),
58    ("Johnny Cash", "Country"),
59];
60
61#[tokio::main]
62async fn main() -> Result<()> {
63    env_logger::init();
64
65    let anthropic_api_key: String =
66        std::env::var("ANTHROPIC_API_KEY").expect("ANTHROPIC_API_KEY not set");
67
68    // Example 1: Web search example
69    let web_search_tool = LLMTools::AnthropicWebSearch(AnthropicWebSearchConfig::new());
70    let anthropic_responses = Completions::new(
71        AnthropicModels::ClaudeOpus4_7,
72        &anthropic_api_key,
73        None,
74        None,
75    )
76    .add_tool(web_search_tool);
77
78    match anthropic_responses
79        .get_answer::<AINewsArticles>("Find up to 5 most recent news items about Artificial Intelligence, Generative AI, and Large Language Models. 
80        For each news item, provide the title, url, and a short description.")
81        .await
82    {
83        Ok(response) => println!("AI news articles:\n{:#?}", response),
84        Err(e) => eprintln!("Error: {:?}", e),
85    }
86
87    // Example 2: Code interpreter example
88
89    let code_interpreter_tool =
90        LLMTools::AnthropicCodeExecution(AnthropicCodeExecutionConfig::new());
91    let anthropic_responses = Completions::new(
92        AnthropicModels::ClaudeOpus4_7,
93        &anthropic_api_key,
94        None,
95        None,
96    )
97    .add_tool(code_interpreter_tool);
98
99    match anthropic_responses
100        .get_answer::<CodeInterpreterResponse>(
101            "Calculate the mean and standard deviation of [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]",
102        )
103        .await
104    {
105        Ok(response) => println!("Code interpreter response:\n{:#?}", response),
106        Err(e) => eprintln!("Error: {:?}", e),
107    }
108
109    // Example 3: File search example
110
111    // Read the concert file and upload it to Anthropic
112    let path = Path::new("metallica.pdf");
113    let bytes = std::fs::read(path)?;
114    let file_name = path
115        .file_name()
116        .and_then(OsStr::to_str)
117        .map(|s| s.to_string())
118        .ok_or_else(|| anyhow!("Failed to extract file name"))?;
119
120    let anthropic_file = AnthropicFile::new(None, &anthropic_api_key)
121        .upload(&file_name, bytes)
122        .await?;
123
124    // Extract concert information using Anthropic API with file search tool
125    let file_search_tool = LLMTools::AnthropicFileSearch(AnthropicFileSearchConfig::new(
126        anthropic_file.id.clone().unwrap_or_default(),
127    ));
128
129    let anthropic_responses = Completions::new(
130        AnthropicModels::ClaudeSonnet4_6,
131        &anthropic_api_key,
132        None,
133        None,
134    )
135    .set_context("bands_genres", &BANDS_GENRES)?
136    .add_tool(file_search_tool);
137
138    match anthropic_responses
139        .get_answer::<ConcertInfo>("Extract the information requested in the response type from the attached concert information.
140            The response should include the genre of the music the 'band' represents.
141            The mapping of bands to genres was provided in 'bands_genres' list.")
142        .await
143    {
144        Ok(response) => println!("Concert Info:\n{:#?}", response),
145        Err(e) => eprintln!("Error: {:?}", e),
146    }
147
148    // Cleanup
149    anthropic_file.delete().await?;
150
151    Ok(())
152}