| .. | ||
| llm-tools.gbdata | ||
| llm-tools.gbdialog | ||
| llm-tools.gbot | ||
| README.md | ||
LLM Tools Template (llm-tools.gbai)
A General Bots template demonstrating how to create and register custom tools (functions) that LLMs can call during conversations.
Overview
The LLM Tools template shows how to extend your bot's capabilities by creating tools that the AI can invoke automatically. Tools enable the LLM to perform actions like database lookups, API calls, calculations, and more—all triggered naturally through conversation.
Features
- Custom Tool Registration - Define tools the LLM can call
- Parameter Validation - Type-safe tool parameters with descriptions
- Knowledge Base Integration - Combine tools with RAG
- Natural Interaction - Users don't need to know tool names
- Extensible Architecture - Easy to add new tools
Package Structure
llm-tools.gbai/
├── README.md
├── llm-tools.gbdata/ # Data files for tools
│ └── products.csv # Product catalog
├── llm-tools.gbdialog/
│ ├── start.bas # Main dialog with tool registration
│ └── get-price.bas # Example tool implementation
├── llm-tools.gbkb/ # Knowledge base
│ └── products.gbkb/ # Product documentation
└── llm-tools.gbot/
└── config.csv # Bot configuration
Scripts
| File | Description |
|---|---|
start.bas |
Registers tools, configures context, and sets system prompt |
get-price.bas |
Example tool that looks up product prices |
How Tools Work
1. Tool Registration
In start.bas, tools are registered with ADD TOOL:
ADD TOOL "get-price"
USE KB "products.gbkb"
CLEAR SUGGESTIONS
ADD SUGGESTION "price" AS "Check product price"
ADD SUGGESTION "products" AS "View products"
ADD SUGGESTION "help" AS "How to use"
BEGIN TALK
**Product Assistant**
I can help you check product prices and information.
Just ask me about any product and I'll look it up for you.
END TALK
BEGIN SYSTEM PROMPT
You are a product assistant with access to internal tools.
When get-price returns -1, the product does not exist.
When asked about a price, use the get-price tool and return the result.
Do not expose tool names to users - just act on their requests naturally.
END SYSTEM PROMPT
2. Tool Implementation
Each tool is a separate .bas file with PARAM and DESCRIPTION:
PARAM product AS STRING LIKE "fax" DESCRIPTION "Name of the product to get price for"
DESCRIPTION "Get the price of a product by name from the product catalog"
productRecord = FIND "products.csv", "name = ${product}"
IF productRecord THEN
RETURN productRecord.price
ELSE
RETURN -1
END IF
3. LLM Invocation
When a user asks "How much is the fax machine?", the LLM:
- Recognizes this requires price information
- Calls
get-pricewithproduct="fax" - Receives the price (or -1 if not found)
- Formulates a natural response
Creating Custom Tools
Tool Anatomy
Every tool needs:
- PARAM declarations - Input parameters with types and examples
- DESCRIPTION - What the tool does (for LLM understanding)
- Implementation - The actual logic
- RETURN - The output value
Parameter Types
| Type | Description | Example |
|---|---|---|
STRING |
Text input | PARAM name AS STRING LIKE "John" |
NUMBER |
Numeric input | PARAM quantity AS NUMBER LIKE 5 |
INTEGER |
Whole numbers | PARAM count AS INTEGER LIKE 10 |
BOOLEAN |
True/false | PARAM active AS BOOLEAN |
DATE |
Date values | PARAM start AS DATE LIKE "2024-01-15" |
EMAIL |
Email addresses | PARAM email AS EMAIL |
PHONE |
Phone numbers | PARAM phone AS PHONE |
OBJECT |
JSON objects | PARAM data AS OBJECT |
Example Tools
Database Lookup Tool
' lookup-customer.bas
PARAM customer_id AS STRING LIKE "CUST-001" DESCRIPTION "Customer ID to look up"
DESCRIPTION "Retrieve customer information by ID"
customer = FIND "customers.csv", "id = ${customer_id}"
IF customer THEN
WITH result
name = customer.name
email = customer.email
status = customer.status
since = customer.created_at
END WITH
RETURN result
ELSE
RETURN NULL
END IF
Calculation Tool
' calculate-discount.bas
PARAM original_price AS NUMBER LIKE 100 DESCRIPTION "Original product price"
PARAM discount_percent AS NUMBER LIKE 15 DESCRIPTION "Discount percentage"
DESCRIPTION "Calculate the final price after applying a discount"
discount_amount = original_price * (discount_percent / 100)
final_price = original_price - discount_amount
WITH result
original = original_price
discount = discount_amount
final = final_price
savings = discount_percent + "% off"
END WITH
RETURN result
API Integration Tool
' check-inventory.bas
PARAM sku AS STRING LIKE "SKU-12345" DESCRIPTION "Product SKU to check"
PARAM warehouse AS STRING LIKE "main" DESCRIPTION "Warehouse location" OPTIONAL
DESCRIPTION "Check real-time inventory levels for a product"
IF NOT warehouse THEN
warehouse = "main"
END IF
SET HEADER "Authorization" AS "Bearer " + GET ENV "INVENTORY_API_KEY"
response = GET "https://api.inventory.com/stock/" + sku + "?warehouse=" + warehouse
IF response.error THEN
RETURN {"available": false, "error": response.error}
END IF
WITH result
sku = sku
available = response.quantity > 0
quantity = response.quantity
warehouse = warehouse
last_updated = response.timestamp
END WITH
RETURN result
Email Sending Tool
' send-notification.bas
PARAM recipient AS EMAIL LIKE "user@example.com" DESCRIPTION "Email recipient"
PARAM subject AS STRING LIKE "Order Confirmation" DESCRIPTION "Email subject"
PARAM message AS STRING DESCRIPTION "Email body content"
DESCRIPTION "Send an email notification to a customer"
SEND EMAIL recipient, subject, message
WITH result
sent = true
recipient = recipient
timestamp = NOW()
END WITH
RETURN result
Tool Registration Patterns
Single Tool
ADD TOOL "get-price"
Multiple Tools
ADD TOOL "get-price"
ADD TOOL "check-inventory"
ADD TOOL "lookup-customer"
ADD TOOL "calculate-discount"
ADD TOOL "send-notification"
Conditional Tools
user_role = GET SESSION "user_role"
ADD TOOL "get-price"
ADD TOOL "check-inventory"
IF user_role = "admin" THEN
ADD TOOL "update-price"
ADD TOOL "delete-product"
END IF
System Prompt Best Practices
Guide the LLM on when and how to use tools:
BEGIN SYSTEM PROMPT
You are a helpful product assistant with access to the following capabilities:
**Available Tools:**
- get-price: Look up product prices by name
- check-inventory: Check stock availability
- calculate-discount: Calculate prices with discounts
**Guidelines:**
1. When users ask about prices, use the get-price tool
2. When asked about availability, use check-inventory
3. If a tool returns an error, explain politely that the item wasn't found
4. Never mention tool names to users - just provide the information naturally
5. Combine multiple tool results when needed to answer complex questions
**Error Handling:**
- If get-price returns -1, the product doesn't exist
- If check-inventory shows quantity 0, inform the user it's out of stock
END SYSTEM PROMPT
Configuration
Configure in llm-tools.gbot/config.csv:
| Parameter | Description | Example |
|---|---|---|
LLM Provider |
AI provider | openai |
LLM Model |
Model for tool calls | gpt-4o |
Tool Timeout |
Max tool execution time | 30 |
Max Tool Calls |
Limit per conversation | 10 |
Example Conversations
Price Lookup
User: How much does the wireless mouse cost?
Bot: [Calls get-price with product="wireless mouse"]
Bot: The wireless mouse is $29.99.
User: What about the keyboard?
Bot: [Calls get-price with product="keyboard"]
Bot: The standard keyboard is $49.99. We also have a mechanical
keyboard for $89.99.
Combined Tool Use
User: Is the laptop in stock and what's the price?
Bot: [Calls get-price with product="laptop"]
Bot: [Calls check-inventory with sku="LAPTOP-001"]
Bot: The laptop is $999. Good news - we have 12 units available
in our main warehouse and can ship today!
With Calculations
User: I want to buy 3 monitors with my 20% employee discount
Bot: [Calls get-price with product="monitor"]
Bot: [Calls calculate-discount with original_price=299, discount_percent=20]
Bot: Each monitor is $299, but with your 20% employee discount,
you'll pay $239.20 each. For 3 monitors, your total would be $717.60
(saving $179.40)!
Error Handling
In Tool Implementation
' get-price.bas with error handling
PARAM product AS STRING LIKE "laptop" DESCRIPTION "Product name"
DESCRIPTION "Get product price with error handling"
ON ERROR GOTO HandleError
productRecord = FIND "products.csv", "name LIKE '%" + product + "%'"
IF productRecord THEN
RETURN productRecord.price
ELSE
RETURN {"error": "not_found", "message": "Product not in catalog"}
END IF
HandleError:
RETURN {"error": "system_error", "message": "Unable to look up price"}
In System Prompt
BEGIN SYSTEM PROMPT
When tools return errors:
- "not_found": Apologize and suggest similar products
- "out_of_stock": Offer to notify when back in stock
- "system_error": Ask user to try again later
END SYSTEM PROMPT
Testing Tools
Manual Testing
' test-tools.bas
result = CALL "get-price", {"product": "laptop"}
TALK "Price result: " + JSON(result)
result = CALL "check-inventory", {"sku": "LAPTOP-001"}
TALK "Inventory result: " + JSON(result)
Conversation Testing
Test various phrasings to ensure tool invocation:
- "What's the price of X?"
- "How much does X cost?"
- "Price for X please"
- "X price?"
- "Can you tell me what X costs?"
Best Practices
- Clear descriptions - Help the LLM understand when to use each tool
- Good examples - LIKE clauses guide parameter format
- Handle errors - Always return meaningful error responses
- Validate input - Check parameters before processing
- Log tool calls - Track usage for debugging
- Keep tools focused - One tool, one purpose
- Test thoroughly - Various phrasings should trigger correct tools
Related Templates
llm-server.gbai- Headless API with LLM processingcrm.gbai- CRM with many tool examplesstore.gbai- E-commerce with product toolstalk-to-data.gbai- Data query tools
Use Cases
- Product Lookup - Price, availability, specifications
- Customer Service - Order status, account info
- Calculations - Quotes, discounts, shipping
- Integrations - CRM, ERP, external APIs
- Data Access - Database queries, report generation
License
AGPL-3.0 - Part of General Bots Open Source Platform.
Pragmatismo - General Bots