ic-llm
A library for making requests to the LLM canister on the Internet Computer.
Supported Models
Models are identified by their string name (passed to ic_llm::prompt and
ic_llm::chat). The available models are:
| Model string | Pricing |
|---|---|
"llama3.1:8b" |
Free |
"qwen3:32b" |
Free |
"llama4-scout" |
Free |
"qwen2.5:0.5b" |
Free |
"gemma3:27b" |
Paid |
"z-ai:glm-5.2" |
Paid |
Models are added frequently — see the LLM canister for the authoritative, up-to-date list.
Paying for models
send() automatically attaches 100B cycles to every request. Paid models are
charged from those cycles (any unused portion is refunded); free models refund
the full amount. Because cycles are always attached, the calling canister must
hold at least 100B cycles when send() runs, or the call traps — this applies
even when using a free model.
Local Development
When developing locally, the architecture differs slightly from mainnet: instead of relying on AI workers, the LLM canister connects directly to a local Ollama instance. The interface is identical to mainnet — see How Does it Work? for details.
Before running an agent locally, start Ollama and pull the model you intend to use:
For complete, working project setups — including how to deploy the LLM canister
locally — see the examples in this repository (e.g.
examples/quickstart-agent-rust).
Usage
Basic Usage
Prompting (Single Message)
The simplest way to interact with a model is by sending a single prompt:
async
Chatting (Multiple Messages)
For more complex interactions, you can send multiple messages in a conversation:
use ChatMessage;
async
Choosing the LLM canister
By default the SDK addresses the mainnet LLM canister (w36hm-eqaaa-aaaal-qr76a-cai).
When your canister is deployed with icp deploy, the SDK transparently picks up
PUBLIC_CANISTER_ID:llm if it has been auto-injected — so the same code works
against a local llm canister whose principal differs from mainnet, with no
caller-side changes.
For other cases (a fork, a mock, a staging deployment under a different name), override the canister explicitly:
use Principal;
async
Advanced Usage with Tools
Understanding Tools
Tools are custom functions that you define and make available to the LLM. They allow the AI to perform actions beyond just generating text responses. When you provide tools to the LLM, it can decide when and how to use them based on the user's request.
Common use cases for tools:
- Data retrieval: Fetching real-time information (prices, weather, account balances)
- External API calls: Integrating with third-party services
- Calculations: Performing complex computations
- Database operations: Querying or updating data
- Custom business logic: Executing domain-specific functions
How it works:
- You define available tools with their parameters
- The LLM analyzes the user's request
- If a tool would be helpful, the LLM returns a "tool call" instead of a direct answer
- Your code executes the requested tool with the LLM's provided parameters
- You send the tool's result back to the LLM
- The LLM incorporates the result into its final response
Defining and Using a Tool
You can define tools that the LLM can use to perform actions:
use ;
async
Handling Tool Calls from the LLM
When the LLM decides to use one of your tools, you can handle the call:
use ;
async
// Mock function for getting weather
async
Complete Tool Usage Example
Here's a more complete example showing how to handle tool calls and continue the conversation:
use ;
async
// Example tool implementations
async
async