Triển khai AI agent tự động có tool-calling trên VPS

Bạn có một VPS Ubuntu 24.04 đang chạy, và bạn muốn biến nó thành một "nhân viên AI" tự động: nhận yêu cầu, tự đọc dữ liệu, tự gọi lệnh, tự trả kết quả. Đó chính là lúc cần đến AI agent có tool-calling. Bài này sẽ hướng dẫn bạn triển khai một AI agent tự động có tool-calling trên VPS, dùng Python và API của OpenAI, từ khâu chuẩn bị môi trường đến verify hoạt động thực tế.
Yêu cầu trước khi bắt đầu
Trước khi đi vào chi tiết, bạn cần chuẩn bị một số thứ sau:
- Một VPS chạy Ubuntu 24.04 LTS với quyền root hoặc user có sudo. Có thể dùng VPS Linux của thueVPS với IPv4 Việt Nam, NVMe tốc độ cao.
- Một API key của OpenAI (hoặc nhà cung cấp LLM khác hỗ trợ function calling). Chi phí tính theo số token sử dụng, không cần đầu tư trước.
- Kiến thức cơ bản về Python và dòng lệnh Linux: biết dùng
cd, tạo file bằngnano, chạy script Python. - Port cần mở: không cần mở thêm port nào nếu agent chỉ gọi ra API bên ngoài (outbound request). Nếu muốn expose qua webhook thì cần mở port 8000 hoặc dùng reverse proxy.
Vì sao nên chạy AI agent trên VPS thay vì máy cá nhân?
AI agent có tool-calling thường cần chạy liên tục, theo lịch trình (cron job), hoặc phục vụ nhiều người dùng cùng lúc. Máy cá nhân có thể tắt, rớt mạng, hoặc bị giới hạn bởi NAT. Một VPS với IP tĩnh, uptime 99.9%, full root access là môi trường lý tưởng.
Ngoài ra, VPS cho phép bạn cô lập môi trường (venv, Docker), cài thêm các công cụ phụ trợ (database, Redis, queue), và dễ dàng mở rộng khi agent phức tạp hơn. Với mức giá từ khoảng 189.000đ/tháng, bạn có thể bắt đầu với gói nhỏ nhất và nâng cấp sau.
Bước 1 - Cài đặt môi trường Python và thư viện
Đầu tiên, SSH vào VPS và cập nhật hệ thống:
sudo apt update && sudo apt upgrade -y
sudo apt install -y python3 python3-venv python3-pip
Python 3.12 là bản mặc định trên Ubuntu 24.04, đủ dùng cho hầu hết thư viện AI hiện nay. Tiếp theo, tạo thư mục dự án và môi trường ảo:
mkdir ~/ai-agent && cd ~/ai-agent
python3 -m venv venv
source venv/bin/activate
Cài thư viện OpenAI SDK và python-dotenv để quản lý biến môi trường:
pip install openai python-dotenv
Verify: chạy python --version phải ra Python 3.12.x, và pip list | grep openai phải thấy gói openai đã cài.
Bước 2 - Tạo API key và file cấu hình
Tạo tài khoản OpenAI, vào mục API keys, tạo một key mới. Lưu key ở nơi an toàn, không commit lên git.
Tạo file .env trong thư mục dự án:
nano .env
Nội dung file:
OPENAI_API_KEY=sk-your-api-key-here
OPENAI_MODEL=gpt-4o-mini
gpt-4o-mini là model có giá rẻ, hỗ trợ tool-calling tốt, phù hợp để thử nghiệm. Nếu bạn muốn dùng model mạnh hơn, đổi thành gpt-4o hoặc gpt-4.1 (kiểm tra bản mới nhất trong tài liệu OpenAI).
Verify: chạy source .env && echo $OPENAI_API_KEY sẽ in ra key (hoặc bạn dùng python-dotenv để load trong code).
Bước 3 - Viết agent đơn giản có tool-calling
Ý tưởng cốt lõi của tool-calling: bạn định nghĩa một hàm Python, mô tả nó cho model biết (tên, tham số, mô tả). Khi model thấy cần dùng hàm đó, nó trả về một "tool call" chứ không phải câu trả lời trực tiếp. Code của bạn thực thi hàm, rồi gửi kết quả lại cho model để tổng hợp câu trả lời cuối.
Tạo file agent.py:
import os
import json
from dotenv import load_dotenv
from openai import OpenAI
load_dotenv()
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
def get_server_uptime():
"""Lấy thời gian uptime của server."""
return os.popen("uptime -p").read().strip()
def get_disk_usage():
"""Lấy dung lượng ổ đĩa đã dùng."""
return os.popen("df -h / | tail -1").read().strip()
tools = [
{
"type": "function",
"function": {
"name": "get_server_uptime",
"description": "Lấy thời gian server đã chạy (uptime)",
}
},
{
"type": "function",
"function": {
"name": "get_disk_usage",
"description": "Lấy dung lượng ổ đĩa đã sử dụng",
}
}
]
def run_agent(user_message):
messages = [{"role": "user", "content": user_message}]
response = client.chat.completions.create(
model=os.getenv("OPENAI_MODEL"),
messages=messages,
tools=tools,
tool_choice="auto"
)
msg = response.choices[0].message
if msg.tool_calls:
messages.append(msg)
for call in msg.tool_calls:
if call.function.name == "get_server_uptime":
result = get_server_uptime()
elif call.function.name == "get_disk_usage":
result = get_disk_usage()
else:
result = "Unknown tool"
messages.append({
"role": "tool",
"tool_call_id": call.id,
"content": result
})
final = client.chat.completions.create(
model=os.getenv("OPENAI_MODEL"),
messages=messages
)
return final.choices[0].message.content
return msg.content
if __name__ == "__main__":
while True:
user_input = input("Bạn: ")
if user_input.lower() in ["exit", "quit"]:
break
print("Agent:", run_agent(user_input))
Giải thích một chút: tools là danh sách mô tả hàm cho model. Trong vòng lặp, agent gọi API, nếu model trả về tool_calls thì code thực thi hàm tương ứng, rồi gọi lại API với kết quả để có câu trả lời cuối.
Verify: chạy thử script:
python agent.py
Hỏi: "Server đã chạy được bao lâu?" Agent phải trả lời kèm số liệu uptime thật. Hỏi tiếp: "Ổ đĩa còn bao nhiêu dung lượng?" để test tool thứ hai.
Bước 4 - Nâng cấp: cho phép agent tự chọn tool và xử lý lỗi
Bản trên mới xử lý 2 tool cứng. Muốn agent tự chọn trong nhiều tool, bạn nên dùng một vòng lặp while và dictionary ánh xạ tên hàm:
def run_agent_loop(user_message):
messages = [{"role": "user", "content": user_message}]
available_functions = {
"get_server_uptime": get_server_uptime,
"get_disk_usage": get_disk_usage
}
for _ in range(5): # giới hạn số vòng lặp tránh lặp vô hạn
response = client.chat.completions.create(
model=os.getenv("OPENAI_MODEL"),
messages=messages,
tools=tools,
tool_choice="auto"
)
msg = response.choices[0].message
if not msg.tool_calls:
return msg.content
messages.append(msg)
for call in msg.tool_calls:
fn = available_functions.get(call.function.name)
if fn:
result = fn()
else:
result = "Lỗi: tool không tồn tại"
messages.append({
"role": "tool",
"tool_call_id": call.id,
"content": str(result)
})
return "Đã quá số lần gọi tool, dừng lại."
Điểm mấu chốt: luôn giới hạn số vòng lặp. Nếu không, agent có thể gọi tool liên tục, tốn token và treo vì lỗi logic. Con số 5 là an toàn cho demo; với production bạn có thể để 10 nhưng nên log lại mỗi lần gọi.
Bước 5 - Chạy agent nền (background) và log kết quả
Vì agent chạy interactive (nhập từ bàn phím) không phù hợp cho automation. Bạn cần chạy nó ở chế độ nền và ghi log. Sửa lại để nhận yêu cầu từ đối số dòng lệnh:
# agent_cli.py
import sys
from agent import run_agent_loop
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Cách dùng: python agent_cli.py 'câu hỏi của bạn'")
sys.exit(1)
query = " ".join(sys.argv[1:])
result = run_agent_loop(query)
print(result)
Chạy thử với câu hỏi cụ thể:
python agent_cli.py "Kiểm tra uptime và dung lượng ổ đĩa"
Kết quả in ra màn hình. Để tự động hóa, bạn dùng cron job hoặc systemd timer gọi script này theo lịch. Ví dụ tạo file agent.log lưu output:
python agent_cli.py "Tổng kết trạng thái server" >> agent.log 2>&1
Có thể đưa câu lệnh này vào crontab -e để chạy mỗi giờ. Nếu muốn agent chạy liên tục lắng nghe yêu cầu từ webhook (ví dụ Telegram bot), bạn cần một server nhỏ (FastAPI/Flask) hoặc tích hợp vào VPS n8n để quản lý luồng.
Xử lý lỗi thường gặp
Lỗi 401 Unauthorized khi gọi API: Kiểm tra API key trong file .env, đảm bảo không có dấu cách thừa. Chạy source .env && python -c "from dotenv import load_dotenv; load_dotenv(); import os; print(os.getenv('OPENAI_API_KEY'))" để chắc chắn key được load.
Model không trả về tool_calls: Mô tả tool phải rõ ràng, đặc biệt phần description. Nếu model vẫn không gọi, kiểm tra model có hỗ trợ function calling không (gpt-4o-mini thì có, nhưng một số model cũ thì không).
Lỗi JSON parse khi model trả tham số phức tạp: Với tool có tham số, model trả về arguments dạng JSON string. Bạn phải json.loads(call.function.arguments) trước khi gọi hàm. Ví dụ:
import json
args = json.loads(call.function.arguments) if call.function.arguments else {}
result = fn(**args)
Nếu không parse, hàm sẽ lỗi "missing required positional argument".
Agent gọi tool lặp vô hạn: Luôn đặt max_iterations (số vòng lặp tối đa) trong code, không để while True ở production.
Câu hỏi thường gặp
AI agent có tool-calling là gì?
AI agent có tool-calling là hệ thống AI (thường dựa trên LLM) có khả năng gọi các hàm hoặc API bên ngoài để hoàn thành tác vụ. Model không chỉ trả lời văn bản, mà còn quyết định "tôi cần gọi công cụ X" dựa trên yêu cầu người dùng.
VPS cần cấu hình tối thiểu bao nhiêu để chạy AI agent?
Agent chỉ gọi API bên ngoài (như OpenAI) thì không cần GPU, chỉ cần VPS 1 vCPU, 1GB RAM là đủ. Nếu bạn muốn tự host model (Ollama, LocalAI) thì cần RAM 8GB trở lên. Tham khảo thêm bài self-host API LLM với Ollama trên VPS.
Chi phí chạy AI agent trên VPS là bao nhiêu?
Chi phí gồm hai phần: tiền VPS (từ khoảng 189.000đ/tháng) và tiền API (tính theo token). Với gpt-4o-mini, một phiên hội thoại 10 tin nhắn tốn khoảng vài trăm đồng. Tổng chi phí thấp hơn nhiều so với thuê dịch vụ agent có sẵn.
Tool-calling và function-calling có khác nhau không?
Không. Hai thuật ngữ này cùng một khái niệm: model được cung cấp danh sách hàm, tự chọn hàm để gọi. OpenAI gọi là function calling, Anthropic gọi là tool use. Cách triển khai tương tự.
Tôi có thể dùng agent này để tự động hóa việc quản trị server không?
Có. Bạn có thể định nghĩa thêm tool như: khởi động lại service, xem log, kiểm tra traffic. Tuy nhiên, cần cẩn thận về bảo mật: chỉ cho agent các quyền cần thiết, không cho quyền xóa dữ liệu. Bài bảo mật n8n self-host có nhiều nguyên tắc áp dụng được cho agent.
Bài viết liên quan
- Dựng AI agent đầu tiên trên n8n với LLM tool và memory
- Self-host API LLM với Ollama trên VPS
- Xây backend chatbot AI cho website trên VPS
- Tự host RAG trên VPS với vector DB và LLM


