- OpenWebUI Tools System cho phép viết Python tool tích hợp vào chat UI, Claude/GPT tự gọi khi cần.
- Use case: query DB realtime, fetch CRM data, gọi API external, execute SQL, web search, calculator.
- Setup chỉ cần Python class với function decorator, không cần code complex.
- Tool share giữa user trong team, version control qua git, audit log mỗi lần gọi.
- Combine với Claude Sonnet 4.7 function calling cho agent autonomous workflow trong chat.
OpenWebUI chat thuần đã đủ cho most case, nhưng khi cần AI thực sự tự lập (lookup data, gọi API, execute action), bạn cần Tools System. Đây là tính năng mạnh nhất của OpenWebUI 2026: viết Python class với function decorator, AI tự discover và call tool khi user hỏi. Không cần MCP server riêng, không cần API gateway phức tạp.
Mình đã build 20+ custom tool cho 3 client trong 2025: lookup user info, query analytics SQL, send Slack message, create Jira issue, fetch weather, calculator. Workflow này biến OpenWebUI thành internal AI agent platform mạnh, gần như ChatGPT GPTs nhưng self-host. Bài này hướng dẫn build tool từ A đến Z.
1. Tools System hoạt động thế nào
User prompt: "Order #ORD123 có ship chưa?"
-> OpenWebUI gửi prompt + tool definitions tới Claude/GPT
-> Model identify intent: cần tool "get_order_status"
-> Model return tool call: get_order_status(order_id="ORD123")
-> OpenWebUI execute Python function trong sandbox
-> Function gọi DB/API, return result JSON
-> OpenWebUI gửi result back tới model
-> Model format response cho user: "Order ORD123 đang ship, ETA ngày mai"
-> User thấy response trong chat2. Cài đặt Claude với function calling enable
# Trong OpenWebUI Settings -> Connections -> Anthropic
API Key: sk-ant-...
Models: claude-sonnet-4-7-20260520, claude-haiku-4-20260101
# Enable function calling cho model
Settings -> Models -> Edit "Claude Sonnet 4.7"
Capabilities: vision, citations, tool_use (bật all)3. Tool đầu tiên: get current time
"""
title: Time Tools
description: Get current time and date in various timezones
author: tnd.vn
version: 1.0.0
"""
import datetime
from zoneinfo import ZoneInfo
class Tools:
def __init__(self):
self.citation = True
def get_current_time(self, timezone: str = "Asia/Ho_Chi_Minh") -> str:
"""
Get the current date and time in the specified timezone.
:param timezone: IANA timezone name (e.g., "Asia/Ho_Chi_Minh", "America/New_York")
:return: Current date and time as ISO 8601 string
"""
try:
tz = ZoneInfo(timezone)
now = datetime.datetime.now(tz)
return f"Current time in {timezone}: {now.isoformat()}"
except Exception as e:
return f"Error: {str(e)}"
def days_until(self, date_str: str) -> str:
"""
Calculate days until a specific date.
:param date_str: Target date in YYYY-MM-DD format
:return: Number of days until the date
"""
try:
target = datetime.datetime.strptime(date_str, "%Y-%m-%d").date()
today = datetime.date.today()
delta = (target - today).days
return f"{delta} days until {date_str}"
except Exception as e:
return f"Error: {str(e)}"Upload vào OpenWebUI Workspace -> Tools -> + Add Tool. Paste code, save. Trong chat, model tự discover tool, gọi khi user hỏi "mấy giờ rồi?" hoặc "còn bao nhiêu ngày tới Tết?".
4. Tool query Postgres database
"""
title: Database Query
description: Query Postgres read-only for business data
requirements: psycopg2-binary
"""
import psycopg2
import os
from typing import List, Dict
class Tools:
def __init__(self):
self.db_url = os.environ.get("ANALYTICS_DB_URL")
def query_orders(
self,
status: str = None,
days_ago: int = 7,
limit: int = 10
) -> List[Dict]:
"""
Query recent orders from database.
:param status: Filter by status (pending, paid, shipped, completed)
:param days_ago: Look back N days (default 7)
:param limit: Max rows return (default 10, max 50)
:return: List of order records
"""
limit = min(limit, 50)
sql = """
SELECT id, customer_name, total, status, created_at
FROM orders
WHERE created_at >= NOW() - interval '%s days'
"""
params = [days_ago]
if status:
sql += " AND status = %s"
params.append(status)
sql += " ORDER BY created_at DESC LIMIT %s"
params.append(limit)
try:
conn = psycopg2.connect(self.db_url)
cur = conn.cursor()
cur.execute(sql, params)
cols = [d[0] for d in cur.description]
results = [dict(zip(cols, row)) for row in cur.fetchall()]
for r in results:
r['created_at'] = r['created_at'].isoformat()
r['total'] = float(r['total'])
return results
finally:
conn.close()
def get_customer_summary(self, email: str) -> Dict:
"""
Get customer purchase summary by email.
:param email: Customer email
:return: Customer summary with total orders, total spent, last order date
"""
try:
conn = psycopg2.connect(self.db_url)
cur = conn.cursor()
cur.execute("""
SELECT
COUNT(*) as order_count,
SUM(total) as total_spent,
MAX(created_at) as last_order
FROM orders
WHERE customer_email = %s
""", [email])
row = cur.fetchone()
return {
"email": email,
"order_count": row[0],
"total_spent": float(row[1] or 0),
"last_order": row[2].isoformat() if row[2] else None
}
finally:
conn.close()Set ANALYTICS_DB_URL trong env OpenWebUI (chỉ readonly user). User hỏi "đơn pending hôm nay có bao nhiêu?", Claude tự gọi query_orders(status="pending", days_ago=1), trả kết quả formatted.
5. Tool gọi API external
"""
title: External API
description: Call internal APIs to fetch data and trigger actions
requirements: requests
"""
import requests
import os
from typing import Dict
class Tools:
def __init__(self):
self.api_base = os.environ.get("INTERNAL_API_BASE", "https://api.your-domain.com")
self.api_token = os.environ.get("INTERNAL_API_TOKEN")
def get_inventory(self, sku: str) -> Dict:
"""
Get current inventory level for a SKU.
:param sku: Product SKU
:return: Inventory data
"""
r = requests.get(
f"{self.api_base}/inventory/{sku}",
headers={"Authorization": f"Bearer {self.api_token}"},
timeout=10
)
r.raise_for_status()
return r.json()
def send_slack_message(self, channel: str, message: str) -> str:
"""
Send notification to Slack channel.
:param channel: Slack channel (e.g., "#general")
:param message: Message text
:return: Success status
"""
webhook = os.environ.get("SLACK_WEBHOOK_URL")
r = requests.post(webhook, json={
"channel": channel,
"text": message,
"username": "OpenWebUI Bot"
})
return "Sent successfully" if r.ok else f"Failed: {r.status_code}"
def create_jira_issue(
self,
project_key: str,
summary: str,
description: str,
priority: str = "Medium"
) -> Dict:
"""
Create new Jira issue.
:param project_key: Jira project key (e.g., "ENG", "OPS")
:param summary: Issue title
:param description: Detailed description
:param priority: Priority (Low, Medium, High, Critical)
:return: Created issue with key and URL
"""
r = requests.post(
"https://your-domain.atlassian.net/rest/api/3/issue",
auth=(os.environ['JIRA_USER'], os.environ['JIRA_TOKEN']),
json={
"fields": {
"project": {"key": project_key},
"summary": summary,
"description": {
"type": "doc", "version": 1,
"content": [{"type": "paragraph", "content": [{"type": "text", "text": description}]}]
},
"issuetype": {"name": "Task"},
"priority": {"name": priority}
}
}
)
data = r.json()
return {
"key": data['key'],
"url": f"https://your-domain.atlassian.net/browse/{data['key']}"
}6. Citation và transparency
Tools System hỗ trợ Citation: model trả lời có inline citation chỉ ra tool nào trả data nào. User thấy rõ source, không phải hallucination:
class Tools:
def __init__(self):
self.citation = True # bật citation auto
def get_user_info(self, user_id: int) -> str:
# ... query db
return "User found: John, joined 2024-01-15"
# Response trong chat sẽ có:
# "User là John, đăng ký từ tháng 1/2024 [1]"
# [1] Source: get_user_info tool returned: User found...7. Permission và RBAC tool
Settings -> Tools -> Edit tool -> Access Control:
- Public: mọi user trong workspace dùng được
- Private: chỉ owner dùng
- Group: assign tool cho role cụ thể (admin, hr_team, sales_team)
Critical cho tool nhạy cảm (create_jira_issue, send_slack, query production DB). HR team không nên có quyền gọi tool engineering.
8. Combine với Knowledge Collection (RAG)
Tool + Knowledge collection tạo agent đầy đủ:
- Knowledge: upload tài liệu policy HR, product catalog
- Tool: query employee DB, query sales DB
- Tạo Model preset "HR Bot" assign cả Knowledge + Tool
- User hỏi: "Lương cơ bản nhân viên Nguyễn Văn A là bao nhiêu? Có theo policy mới không?"
- Bot: gọi tool lookup employee A salary + retrieve policy doc + compare
- Trả lời comprehensive trong 1 turn
9. Tool versioning và git management
Tool code Python lưu trong DB OpenWebUI. Backup vào git repo:
# Export tools qua API
curl -H "Authorization: Bearer $TOKEN"
https://ai.your-domain.com/api/v1/tools
> tools-backup-$(date +%F).json
# Tách từng tool ra file Python riêng để code review
python3 split-tools.py tools-backup.json --output ./tools/
# Commit lên git
git add tools/ && git commit -m "Update tools v1.2" && git pushCI/CD: trên git push, auto deploy tool mới lên OpenWebUI qua API. Workflow chuyên nghiệp cho team scale.
10. Audit log mỗi tool call
# Pipeline custom log mọi tool call
class Pipeline:
def __init__(self):
self.name = "Tool Audit Logger"
async def outlet(self, body: dict, user: dict) -> dict:
if 'tool_calls' in body.get('messages', [{}])[-1]:
for tc in body['messages'][-1]['tool_calls']:
await log_to_db({
'user_id': user['id'],
'tool': tc['function']['name'],
'args': tc['function']['arguments'],
'timestamp': datetime.now(),
'session_id': body.get('session_id')
})
return bodyAudit log critical cho compliance, debug, và phát hiện abuse. Lưu vào Postgres riêng, review weekly.
11. Performance: cache tool result
from functools import lru_cache
import redis
r = redis.Redis(host='localhost')
class Tools:
def get_weather(self, city: str) -> str:
"""Get current weather (cached 30 min)."""
cache_key = f"weather:{city}"
cached = r.get(cache_key)
if cached:
return cached.decode()
# Fetch from API
result = fetch_weather_api(city)
r.setex(cache_key, 1800, result) # cache 30 min
return resultTool gọi API external nên cache result. Tiết kiệm latency và quota API.
12. Security: sandboxing và secret handling
- Bắt đầu 5-10 tool core cho team: time, calculator, web search, SQL query
- Thêm tool business specific: CRM, ERP, ticketing
- Build agent preset chuyên dụng: HR Bot, Sales Bot, DevOps Bot
- Integrate với automation platform (n8n) cho workflow multi-step
- Monitor cost và usage, optimize prompt và caching
VPS chạy OpenWebUI Tools + Claude function calling
Cloud VPS TND sẵn AlmaLinux 9, Ubuntu 22/24, Debian 12/13. SSD CEPH, snapshot 1-click, backup hằng ngày, network 200Mbps trong nước. Cloud VPS 80 (4GB RAM, 799k) đủ chạy OpenWebUI + custom tools cho team 10-30 user với Claude API.
Xem 8 cấu hình Cloud VPS →FAQ
Tools System khác MCP server thế nào?
Tools System tích hợp native vào OpenWebUI, đơn giản Python class. MCP server là chuẩn protocol riêng (Anthropic), chạy process external, complex hơn nhưng tái sử dụng được giữa nhiều client (Claude Desktop, Cursor). Cho OpenWebUI use case thuần, Tools System đủ và dễ hơn.
Model nào hỗ trợ function calling tốt nhất?
Claude Sonnet 4.7 và GPT-4o tốt nhất hiện tại 2026. Claude precise hơn về tool selection, GPT-4o nhanh hơn. Local model: Qwen 2.5 hỗ trợ function calling nhưng accuracy thấp hơn 20-30%. Cho task quan trọng, dùng cloud model.
Tool có chạy được code arbitrary nguy hiểm không?
Tools chạy trong container OpenWebUI với resource limit. Tuy nhiên admin upload tool code có thể chạy mọi thứ Python OS calls. Restrict ai có quyền create tool, audit code trước khi enable Public. Sandbox tighter với gVisor nếu cần security cao.
Có debug được tool khi gọi sai không?
Có, Settings -> Tool Logs xem mọi call: arguments, response, error stack trace. Test tool standalone trong Python REPL trước khi upload. Combine với audit log Pipeline, debug nhanh.
Có giới hạn số tool trong 1 chat không?
Claude support 100+ tool trong 1 conversation, nhưng practice không nên enable quá 20 tool/chat vì context size tăng và model bị confused khi nhiều choice. Tách workspace theo domain: HR workspace 5 tool HR, Engineering workspace 10 tool engineering.
17. Tổng kết và workflow chuẩn cho team Việt Nam
OpenWebUI Tools System + Claude function calling là combo cực mạnh cho team Việt Nam 2026. Setup ban đầu 1 buổi cho 5 tool core, tăng dần lên 20-30 tool theo nhu cầu. Combine với Knowledge Collection và preset Model tạo thành agent platform full-stack, replace gần như mọi SaaS GPT Builder đắt tiền. Đặc biệt hữu ích cho doanh nghiệp Việt Nam ngại data leak và muốn customize sâu theo nghiệp vụ nội bộ. Workflow này biến OpenWebUI từ chat tool đơn thuần thành internal AI agent platform mạnh, thúc đẩy productivity team 30-50% theo report mình đo từ 3 client production.
- Tool chạy trong container OpenWebUI, có giới hạn network và filesystem
- Secret (API key, DB password) lưu trong env, không hardcode trong tool code
- Input validation: regex check, type check, max length
- SQL tool chỉ SELECT, reject INSERT/UPDATE/DROP/EXEC
- Rate limit per tool: max 60 call/user/giờ
- Log mọi failed call, alert admin nếu pattern bất thường
13. Marketplace community
OpenWebUI có community marketplace cho tool. Browse 100+ tool community contribute: web search, wolfram alpha, weather, code interpreter, image gen, finance, calendar, email, etc. Install 1 click, customize cho use case của bạn.
Đóng góp tool tự build cho community: clean code, doc rõ, license MIT. Marketing channel cho dev có brand.
14. Use case advanced: agentic workflow
# User: "Customer XXX phàn nàn về order chậm. Xử lý help họ."
# Agent flow:
# 1. Gọi get_customer_summary(email="[email protected]") -> biết history
# 2. Gọi query_orders(customer_email="xxx", days_ago=30) -> latest orders
# 3. Identify order chậm: order_id ABC123 đã 5 ngày chưa ship
# 4. Gọi get_shipment_status(order_id="ABC123") -> carrier issue
# 5. Gọi create_jira_issue("OPS", "Order ABC123 stuck at carrier", ...)
# 6. Gọi send_email(to="[email protected]", subject="Cập nhật đơn ABC123", body="...")
# 7. Trả về user: "Đã tạo Jira #OPS-456, gửi email khách hàng, ETA mới 2 ngày"Multi-tool workflow trong 1 chat turn. Customer support 1 hỗ trợ được 10x case so với manual.
15. Cost so với SaaS GPT Builder
| Setup | Cost/tháng |
|---|---|
| OpenAI ChatGPT Team (10 user) với GPTs | ~250 USD ~6.250k |
| OpenWebUI self-host + Tools custom | 799k VPS + ~500k API tuỳ use |
| Tiết kiệm | ~80% |
Bonus: data nội bộ không gửi OpenAI, tool code mở để audit, không lock-in.
16. Roadmap mở rộng
- Bắt đầu 5-10 tool core cho team: time, calculator, web search, SQL query
- Thêm tool business specific: CRM, ERP, ticketing
- Build agent preset chuyên dụng: HR Bot, Sales Bot, DevOps Bot
- Integrate với automation platform (n8n) cho workflow multi-step
- Monitor cost và usage, optimize prompt và caching
VPS chạy OpenWebUI Tools + Claude function calling
Cloud VPS TND sẵn AlmaLinux 9, Ubuntu 22/24, Debian 12/13. SSD CEPH, snapshot 1-click, backup hằng ngày, network 200Mbps trong nước. Cloud VPS 80 (4GB RAM, 799k) đủ chạy OpenWebUI + custom tools cho team 10-30 user với Claude API.
Xem 8 cấu hình Cloud VPS →FAQ
Tools System khác MCP server thế nào?
Tools System tích hợp native vào OpenWebUI, đơn giản Python class. MCP server là chuẩn protocol riêng (Anthropic), chạy process external, complex hơn nhưng tái sử dụng được giữa nhiều client (Claude Desktop, Cursor). Cho OpenWebUI use case thuần, Tools System đủ và dễ hơn.
Model nào hỗ trợ function calling tốt nhất?
Claude Sonnet 4.7 và GPT-4o tốt nhất hiện tại 2026. Claude precise hơn về tool selection, GPT-4o nhanh hơn. Local model: Qwen 2.5 hỗ trợ function calling nhưng accuracy thấp hơn 20-30%. Cho task quan trọng, dùng cloud model.
Tool có chạy được code arbitrary nguy hiểm không?
Tools chạy trong container OpenWebUI với resource limit. Tuy nhiên admin upload tool code có thể chạy mọi thứ Python OS calls. Restrict ai có quyền create tool, audit code trước khi enable Public. Sandbox tighter với gVisor nếu cần security cao.
Có debug được tool khi gọi sai không?
Có, Settings -> Tool Logs xem mọi call: arguments, response, error stack trace. Test tool standalone trong Python REPL trước khi upload. Combine với audit log Pipeline, debug nhanh.
Có giới hạn số tool trong 1 chat không?
Claude support 100+ tool trong 1 conversation, nhưng practice không nên enable quá 20 tool/chat vì context size tăng và model bị confused khi nhiều choice. Tách workspace theo domain: HR workspace 5 tool HR, Engineering workspace 10 tool engineering.
17. Tổng kết và workflow chuẩn cho team Việt Nam
OpenWebUI Tools System + Claude function calling là combo cực mạnh cho team Việt Nam 2026. Setup ban đầu 1 buổi cho 5 tool core, tăng dần lên 20-30 tool theo nhu cầu. Combine với Knowledge Collection và preset Model tạo thành agent platform full-stack, replace gần như mọi SaaS GPT Builder đắt tiền. Đặc biệt hữu ích cho doanh nghiệp Việt Nam ngại data leak và muốn customize sâu theo nghiệp vụ nội bộ. Workflow này biến OpenWebUI từ chat tool đơn thuần thành internal AI agent platform mạnh, thúc đẩy productivity team 30-50% theo report mình đo từ 3 client production.



