Services
Service vs Tools
Understand when to write a tool, when to write a service, and how the two can work together
Service vs Tools
This is one of the easiest extension decisions to get wrong at first.
One-sentence version
- a tool is better for one call
- a service is better for a long-lived owner
Better fits for a tool
- one-shot functional capability
- one query
- one transformation
- no long-lived state
- no background lifecycle
Examples:
- reading one file
- calling one external API
- performing one text transformation
Better fits for a service
- needs long-lived state
- needs a worker
- owns a connection or session pool
- should be shared across many sessions
- groups a family of related actions under one long-lived object
Examples:
- chat channel integration
- shell session management
- memory runtime
- task scheduler
Three practical judgment calls
"I only need one execution capability"
Prefer a tool first.
"I need a runtime object that stays alive"
Prefer a service.
"I need long-lived state, but I also want model-facing tool-style calls"
A common pattern is:
- the service owns the long-lived state
- a tool acts as the thin facade into that service or its runtime
This kind of combination is especially common for shell-like and chat-like capabilities.
Practical advice for SDK users
For your first extension, do not default everything into services.
The safer sequence is usually:
- confirm whether a simple tool is enough
- only promote it to a service when you clearly need long-lived state
A useful rule of thumb
If you find yourself adding these around a tool:
- a global map
- a long-lived connection
- a worker
- cache lifecycle logic
that usually means the capability is starting to look like a service.