Skip to contents

{artclaude} provides an R interface to Anthropic’s Claude API with full support for extended thinking, tool use, computer control, vision, and advanced beta features. Built on {ellmer} with Artalytics conventions.

Environment Variables

Variable Required Default
ART_CLAUDE_KEY Yes -
ART_CLAUDE_MODEL No claude-opus-4-5-20251101
ART_CLAUDE_MAX_TOKENS No 8192
ART_CLAUDE_TIMEOUT No 120
ART_CLAUDE_BASE_URL No https://api.anthropic.com/v1
Sys.setenv(ART_CLAUDE_KEY = "sk-ant-api03-...")

Quick Start

# Install from GitHub
pak::pkg_install("artalytics/artclaude")

# Set API key
Sys.setenv(ART_CLAUDE_KEY = "sk-ant-api03-...")

# Basic chat
chat <- claude_new()
chat$chat("Explain Impressionism in 2 sentences.")

See the function reference for complete API documentation.

Examples

Basic Text

chat <- claude_new()
chat$chat("Explain Impressionism in 2 sentences.")

# With system prompt
chat <- claude_new(sys_prompt = "You are an art historian. Be concise.")
chat$chat("What is Baroque?")

# With temperature
chat <- claude_new(temp = 0.9)
chat$chat("Write a haiku about art.")

Multi-turn Conversation

chat <- claude_new(sys_prompt = "You are an art expert.")
chat$chat("What is Baroque art?")
chat$chat("How does it differ from Renaissance?")
chat$chat("Name 3 Baroque painters.")

Image Input

chat <- claude_new()

# Local file
chat$chat(ellmer::content_image_file("artwork.png"), "Describe this artwork.")

# URL
chat$chat(ellmer::content_image_url("https://example.com/painting.jpg"), "What style?")

# Multiple images
chat$chat(
  ellmer::content_image_file("painting1.png"),
  ellmer::content_image_file("painting2.png"),
  "Compare these two artworks."
)

PDF Input

chat <- claude_new()
chat$chat(ellmer::content_pdf_file("catalog.pdf"), "Summarize this.")

Structured Output

schema <- ellmer::type_object(
  style = ellmer::type_string("Art movement"),
  period = ellmer::type_string("Time period"),
  artists = ellmer::type_array(ellmer::type_string(), "Notable artists")
)

chat <- claude_new(temp = 0)
result <- chat$chat_structured("Describe Impressionism", type = schema)

Streaming

chat <- claude_new()
stream <- chat$stream("Tell me a story about an artist.")
coro::loop(for (chunk in stream) cat(chunk))

Beta Features

# 1M context window (Sonnet only)
chat <- claude_new(
  ml = "claude-sonnet-4-5-20250929",
  beta = "context-1m-2025-08-07"
)

Prompt Caching

chat <- claude_new(cache = "5m")   # 5 minutes (default)
chat <- claude_new(cache = "1h")   # 1 hour
chat <- claude_new(cache = "none") # disabled

Extended Thinking

Enable Claude to reason step-by-step before responding. Best with Opus 4.5.

# With token budget (min 1024)
chat <- claude_new(think_tokens = 16000)
chat$chat("Prove there are infinitely many prime numbers.")

# With effort level
chat <- claude_new(think_effort = "high")
chat$chat("Design a caching architecture for a high-traffic API.")

# Interleaved thinking (for tool use)
chat <- claude_new(think_tokens = 20000, interleaved = TRUE)

Token budget guidelines: - 1024-4000: Quick reasoning - 4000-16000: Moderate complexity - 16000-32000: Complex multi-step - 32000+: Very complex problems

Effort Control (Opus 4.5 Only)

Control token consumption while maintaining quality. Only available for Opus 4.5.

# Medium effort: 76% fewer tokens, matches Sonnet 4.5 quality
chat <- claude_new(effort = "medium")
chat$chat("Explain quantum computing")

# Low effort for simple tasks
chat <- claude_new(effort = "low")
chat$chat("What is 2+2?")

# High effort (equivalent to default)
chat <- claude_new(effort = "high")
chat$chat("Analyze this complex problem...")

Effort levels: - "low": Minimal token usage, best for simple queries - "medium": Balanced quality/cost (76% token reduction vs default) - "high": Maximum quality (same as omitting effort parameter)

API Reference: https://platform.claude.com/docs/en/build-with-claude/effort

Files API

Upload files once and reference them across multiple conversations.

# Upload a file
file <- claude_file_upload("report.pdf")
file$id          # "file_abc123..."
file$filename    # "report.pdf"
file$size_bytes  # 1048576

# Use in multiple conversations
chat1 <- claude_new()
chat1$chat(claude_file_content(file$id), "Summarize this report")

chat2 <- claude_new()
chat2$chat(claude_file_content(file$id), "Extract key metrics")

# With title and context
chat$chat(
  claude_file_content(file$id,
    title = "Q4 Report",
    context = "Financial results for Q4 2024"
  ),
  "What were the revenue trends?"
)

# List uploaded files
files <- claude_file_list()
sapply(files, function(f) f$filename)

# Get file metadata
metadata <- claude_file_get(file$id)

# Download file content
content <- claude_file_download(file$id)

# Clean up
claude_file_delete(file$id)

Supported file types: - PDFs (application/pdf) - Images (image/jpeg, image/png, image/gif, image/webp) - Plain text (text/plain)

Limits: - Max file size: 500 MB - Total storage: 100 GB per organization

API Reference: https://platform.claude.com/docs/en/build-with-claude/files

Tool Use

Enable Claude to call functions, search the web, and execute code.

# Custom tool
weather_tool <- claude_tool(
  fn = function(city) paste("Weather in", city, ": Sunny"),
  name = "get_weather",
  desc = "Get weather for a city",
  city = ellmer::type_string("City name")
)
chat <- claude_new(tools = list(weather_tool))
chat$chat("What's the weather in Paris?")

# Web search (requires Anthropic Console setup)
chat <- claude_new(tools = list(claude_web_search()))
chat$chat("Latest AI news")

# Web fetch - read specific URLs
chat <- claude_new(tools = list(claude_web_fetch()))
chat$chat("Read https://cran.r-project.org/web/packages/ellmer/index.html and summarize")

# Code execution
chat <- claude_new(
  tools = list(claude_code_exec()),
  beta = beta_headers$BETA_CODE_EXEC_BASH
)
chat$chat("Calculate first 20 Fibonacci numbers")

# Token-efficient tool responses (reduces tokens by up to 70%)
chat <- claude_new(
  tools = list(claude_web_search()),
  token_efficient = TRUE
)
chat$chat("Search for R package best practices")

See vignette("custom-tools"), vignette("web-search"), and vignette("code-execution") for comprehensive tool use documentation.

Long-Running Agents

Enable Claude to persist information across sessions using the memory tool.

# Create memory-enabled agent
memory_dir <- tempfile("claude_memory_")
chat <- claude_new(
  tools = list(claude_memory(memory_dir)),
  beta = beta_headers$BETA_CONTEXT_MGMT
)

# First session - store information
chat$chat("Remember that my favorite color is blue")
chat$chat("Also remember I'm working on project Alpha")

# New session - memory persists
chat2 <- claude_new(
  tools = list(claude_memory(memory_dir)),
  beta = beta_headers$BETA_CONTEXT_MGMT
)
chat2$chat("What is my favorite color?")
# Returns "blue" from memory

chat2$chat("What project am I working on?")
# Returns "project Alpha" from memory

Memory tool capabilities: - Create, read, update, delete memory files - Persists between sessions - Enables long-running agents with knowledge continuity - Requires beta header BETA_CONTEXT_MGMT

API Reference: https://docs.claude.com/en/docs/agents-and-tools/tool-use/memory-tool

Context Editing

Automatically clear stale tool results to prevent context exhaustion in long sessions.

# Enable context editing for tool-heavy workflows
chat <- claude_new(
  tools = list(claude_web_search()),
  context_edit = claude_context_edit(
    trigger_tokens = 30000L,  # Clear when context reaches 30k tokens
    keep_tool_uses = 5L,      # Keep 5 most recent tool uses
    clear_at_least = 2000L    # Clear at least 2k tokens per edit
  ),
  beta = beta_headers$BETA_CONTEXT_MGMT
)

# Can run 100+ searches without hitting limits
for (i in 1:100) {
  chat$chat(paste("Search for topic", i))
}

# Exclude specific tools from clearing (e.g., memory)
chat <- claude_new(
  tools = list(claude_memory(tempdir()), claude_web_search()),
  context_edit = claude_context_edit(exclude_tools = c("memory")),
  beta = beta_headers$BETA_CONTEXT_MGMT
)

Context editing benefits: - 84% token reduction in 100-turn sessions - Enables workflows that would otherwise fail from context limits - Preserves conversation flow while removing stale results

API Reference: https://anthropic.com/news/context-management

Agent Skills

Load pre-built or custom skills for specialized tasks like document processing.

# Use pre-built PowerPoint skill
chat <- claude_new(
  skills = list(claude_skill("pptx")),
  tools = list(claude_code_exec()),
  beta = c(beta_headers$BETA_SKILLS, beta_headers$BETA_CODE_EXEC_BASH)
)
chat$chat("Create a presentation about R package development")

# Load skill from local directory
skill_dir <- tempfile("skill_")
fs::dir_create(skill_dir)
writeLines(c(
  "---",
  "name: greeting",
  "description: Greet users professionally",
  "---",
  "",
  "Always greet users with 'Welcome to Artalytics!'"
), fs::path(skill_dir, "SKILL.md"))

chat <- claude_new(
  skills = list(claude_skill_local(skill_dir)),
  tools = list(claude_code_exec()),
  beta = c(beta_headers$BETA_SKILLS, beta_headers$BETA_CODE_EXEC_BASH)
)
chat$chat("Please greet me")

# Upload skill for persistent use
result <- claude_skill_upload(skill_dir)
chat <- claude_new(
  skills = list(claude_skill(result$skill_id)),
  tools = list(claude_code_exec()),
  beta = c(beta_headers$BETA_SKILLS, beta_headers$BETA_CODE_EXEC_BASH)
)

# List available skills
claude_skill_list(type = "all")
claude_skill_list(type = "prebuilt")  # pptx, xlsx, docx, pdf

Pre-built skills: - "pptx": Create/modify PowerPoint presentations - "xlsx": Create/modify Excel spreadsheets - "docx": Create/modify Word documents - "pdf": Extract/process PDF content

API Reference: https://platform.claude.com/docs/en/build-with-claude/skills-guide

Computer Use

Enable Claude to control your computer through screenshots, mouse, and keyboard.

# Screenshot function (platform-specific)
take_screenshot <- function() {
  path <- tempfile(fileext = ".png")
  # macOS: system2("screencapture", c("-x", path))
  # Linux: system2("scrot", path)
  # Windows: Use PowerShell or screenshot package
  path
}

# Action function using pyautogui via reticulate
execute_action <- function(action) {
  pyautogui <- reticulate::import("pyautogui")
  switch(action$action,
    "left_click" = pyautogui$click(action$coordinate[1], action$coordinate[2]),
    "type" = pyautogui$write(action$text),
    "key" = pyautogui$press(action$text)
    # ... other actions
  )
}

# Run computer use
result <- claude_computer(
  prompt = "Open Notepad and type 'Hello, World!'",
  screenshot_fn = take_screenshot,
  action_fn = execute_action,
  display_size = c(1920L, 1080L),
  max_iter = 20L
)

Available Actions: - screenshot, mouse_move, left_click, right_click, double_click - type, key, scroll_up, scroll_down

Warning: Computer use is experimental and gives Claude direct system control. Always use isolation (VM/container), limit network access, and never expose credentials.

See vignette("computer-use") for comprehensive documentation and safety guidelines.


Proprietary - Do Not Distribute