diff --git a/README.md b/README.md index 7f8650eb..d0cea84f 100644 --- a/README.md +++ b/README.md @@ -56,14 +56,11 @@ _Pst. hey, you, give us a star if you like it!_ ## Table of Contents -- [The Problems with Agent Tools](#the-problems-with-agent-tools) -- [Without Arcade vs. With Arcade](#without-arcade-vs-with-arcade) -- [Why Build Tools with Arcade?](#why-build-tools-with-arcade) -- [Quickstart: Call your first tool](#quickstart-call-your-first-tool) -- [Building Your Own Tools](#building-your-own-tools) +- [Quickstart: Install and call a tool](#quickstart-install-and-call-a-tool) +- [Build LLM Tools with Arcade SDK](#build-llm-tools-with-arcade-sdk) - [Tool SDK Installation](#tool-sdk-installation) - - [Creating a New Tool](#creating-a-new-tool) - - [Sharing Your Toolkit](#sharing-your-toolkit) + - [Creating a new Toolkit](#creating-a-new-toolkit) + - [Deploy your tools to call with LLMs](#deploy-your-tools-to-call-with-llms) - [Calling your tools](#calling-your-tools) - [LLM API](#llm-api) - [Tools API](#tools-api) @@ -72,162 +69,7 @@ _Pst. hey, you, give us a star if you like it!_ - [Client Libraries](#client-libraries) - [Support and Community](#support-and-community) -## The Problems with Agent Tools - -**The Auth Problem** -Most agent tools lack multi-user authorization capabilities. They typically rely on hardcoded API keys or environment variables, making it impossible to securely access user-specific data or integrate with services requiring user authentication and/or authorization. - -**The Execution Problem** -Tool execution typically happens on the same resources as the agent, limiting scalability and preventing the use of specialized compute resources (serverless, on-premise, etc.). - -**The Tool Definition Problem** -Maintaining tool definitions separately from code is difficult, especially when tools must work across multiple agent applications and LLMs with different formats. - -Arcade solves these challenges with standardized tool definition and execution, a robust multi-user auth system, and flexible integration APIs. - -## Without Arcade vs. With Arcade - -
| Without Arcade | -With Arcade | -
|---|---|
| - -```python -# Building a Gmail tool without Arcade -import os -from google.oauth2.credentials import Credentials -from googleapiclient.discovery import build - -def get_credentials(): - # Get credentials from environment variables - secret = os.environ["GMAIL_CREDENTIALS"] - # Always same token same user - # Usually we dangerously elevated privileges - token = os.environ["GMAIL_TOKEN"] - return secret, token - -# Define the tool in code, then update -# definition for each LLM -def list_emails(max_results=10): - - # Get credentials here? pass it in? - secret, token = get_credentials() - # Cache the token? - # How do we know the user? - - # What if the user isn't authorized? OAuth Flow? - # handle token refresh? - try: - credentials = Credentials( - token=token, - secret=secret) - except Exception as e: - # Start the OAuth flow? - # redirect ? how do we know the user? - # handle token refresh? - # what are the right scopes? - # handle errors? - # for EVERY SERVICE? - - # Call the API - service = build('gmail', 'v1', credentials=credentials) - - messages = service.users().messages().list( - userId='me', maxResults=max_results - ).execute() - - return messages - -# Problems: -# - Hardcoded credentials means no multi-user support -# - Security risks from exposing secrets/tokens/keys -# - Manual OAuth flow implementation, if any -# - Manually updated tool definitions -# - No standard format translated across LLMs -``` - - | -- -```python -# Building a Gmail tool with Arcade SDK - -from arcade.sdk import ToolContext, tool -from arcade.sdk.auth import Google -from google.oauth2.credentials import Credentials -from googleapiclient.discovery import build - - -# Define the tool in code, automatically generate -# tool definition for all LLMs -@tool( - requires_auth=Google( - scopes=["https://www.googleapis.com/auth/gmail.readonly"], - ) -) # Automatically generated tool definition from annotations -async def list_emails( - context: ToolContext, - max_results: Annotated[int, "Maximum emails to return"] = 10, -) -> Annotated[dict, "List of emails"]: - """Lists emails in the user's Gmail inbox.""" - - # Auth token automatically provided and managed by Arcade - # Token is guaranteed to be valid for the user of the agent - token = context.authorization.token - - # No need to manually refresh tokens or handle OAuth flows - # Credentials are automatically refreshed as needed - service = build('gmail', 'v1', credentials=token) - - messages = service.users().messages().list( - userId='me', maxResults=max_results - ).execute() - - return messages - -# Solutions with Arcade: -# - Multi-tenant (works for any user) -# - Compliant and secure token, secret, and key management -# - Can access any user's data or services AS the user -# - Tool definition is created automatically -# - Formatted for all LLMs and ready to use -``` - - | -