๐ท Core
trusted
bx-ai-tools
Use this skill when creating AI tools (function calling) with aiTool(): parameter descriptions, tool registries, using tools with aiChat() and agents, the aiToolRegistry() BIF, global skills with aiglobalSkills(), and best practices for tool design.
bx-ai: AI Tools (Function Calling)
aiTool() BIF
// Signature
aiTool( name, description, handler, params={} )
nameโ unique tool identifier (snake_case recommended)descriptionโ what the tool does (clear, imperative language)handlerโ lambda/closure called when AI invokes the toolparamsโ additional parameter schema hints
Creating Tools
// Simple tool โ single parameter
weatherTool = aiTool(
"get_weather",
"Get the current weather for a given location",
location -> getWeatherData( location )
)
// Multi-parameter tool โ use parameter descriptions
searchTool = aiTool(
"search_database",
"Search the products database by keyword and category",
( keyword, category ) -> {
return queryExecute(
"SELECT * FROM products WHERE name LIKE :kw AND category = :cat",
{ kw: "%#keyword#%", cat: category }
)
}
)
Describing Parameters
Use fluent describe*() methods to tell the AI what each parameter means:
// The method name is describe + TitleCase(parameterName)
weatherTool = aiTool(
"get_weather",
"Get current weather for a location",
location -> getWeatherAPI( location )
).describeLocation( "City and country, e.g. 'Boston, MA' or 'Paris, France'" )
searchTool = aiTool(
"search_products",
"Search the product catalog",
( keyword, category, maxResults ) -> {
return productService.search( keyword, category, maxResults )
}
)
.describeKeyword( "Search keyword or product name" )
.describeCategory( "Product category: electronics, clothing, food, or all" )
.describeMaxResults( "Maximum number of results (1-50)" )
Using Tools with aiChat()
tools = [
aiTool( "get_time", "Get current server time", () -> now() ),
aiTool( "get_uptime", "Get server uptime in hours", () -> getServerUptime() ),
aiTool( "calc", "Evaluate a math expression", expr -> evaluate( expr ) )
.describeExpr( "Math expression as a string, e.g. '(15 * 3) + 7'" )
]
result = aiChat(
"What time is it and what is 15% of 320?",
{},
{ tools: tools }
)
Using Tools on an Agent
// Prefer passing tools to aiAgent() for reusable agents
agent = aiAgent(
name : "SystemAgent",
instructions: "Use the provided tools to answer system questions accurately",
tools : [
aiTool( "get_users", "List all users", () -> entityLoad( "User" ) ),
aiTool( "get_stats", "Get system stats", () -> getSystemStats() ),
aiTool( "send_email", "Send an email",
( to, subject, body ) -> mailService.send( to, subject, body ) )
.describeTo( "Recipient email address" )
.describeSubject( "Email subject line" )
.describeBody( "Email body in plain text or HTML" )
]
)
aiToolRegistry() โ Shared Tool Collections
// Build a reusable tool registry
registry = aiToolRegistry()
.register( aiTool( "weather", "Get weather", loc -> getWeather( loc ) ) )
.register( aiTool( "stocks", "Get stock price", sym -> getStock( sym ) ) )
.register( aiTool( "currency", "Convert currency",
( amount, from, to ) -> convertCurrency( amount, from, to ) ) )
// Share across multiple agents
agentA = aiAgent( name: "A", tools: registry.getTools() )
agentB = aiAgent( name: "B", tools: registry.getTools() )
aiGlobalSkills() โ Application-Wide Skills
// Register skills available to ALL agents in the application
aiGlobalSkills([
aiSkill( ".ai/skills/company-guidelines/SKILL.md" ),
aiSkill( ".ai/skills/brand-tone/SKILL.md" )
])
Tool Design Best Practices
- Name tools clearly โ use snake_case verbs:
get_weather,search_products,send_email - Write actionable descriptions โ describe what the tool DOES, not what it IS
- โ "Get the current weather for a city and country"
- โ "Weather tool"
- Describe every parameter โ vague parameters lead to incorrect AI usage
- Return structured data โ structs and arrays are easier for AI to reason about than raw strings
- Keep tools focused โ one tool, one responsibility
- Handle errors gracefully โ return an error struct rather than throwing exceptions
// Good error handling in a tool
dbTool = aiTool(
"query_user",
"Look up a user by ID",
userId -> {
try {
var user = entityLoadByPK( "User", userId )
return isNull( user ) ? { found: false } : { found: true, data: user.getMemento() }
} catch ( any e ) {
return { error: true, message: e.message }
}
}
).describeUserId( "Numeric user ID" )
Common Pitfalls
- โ Do NOT access
argumentsscope inside tool closures โ use bare parameter names- โ
location -> getWeather( arguments.location ) - โ
location -> getWeather( location )
- โ
- โ Avoid throwing exceptions inside tools โ return error structs instead
- โ Always describe parameters for tools that take arguments
- โ Test tools independently before connecting them to agents