PRACTICAL CASE STUDY · 01
Personal AI Agent on a VPS: Telegram, Memory, and Action Controls
We will build a framework that receives a task in Telegram, adds it to a queue, processes it in the background, saves the result, and does not perform dangerous actions without confirmation.
What you will build
The setup consists of a Telegram bot, an API process, a worker, and a memory directory. The bot receives a request, the worker handles the heavy work, and the memory stores verified facts.
1. Prepare the VPS
A VPS is a remote server where the application runs continuously.
ssh user@SERVER_IP
sudo apt update
sudo apt install -y git python3 python3-venv
mkdir -p ~/agent-lab/{app,data,logs}Check that the directories have been created and the SSH connection remains stable. After checking, add a key and do not store the password in scripts.
2. Keep secrets separate from the code
cd ~/agent-lab
nano .env
TELEGRAM_BOT_TOKEN=ваш_токен
MODEL_API_KEY=ваш_ключ
OWNER_ID=ваш_id
chmod 600 .envTokens must not be sent to GitHub, logs, or bot messages. If a key has already been exposed, revoke it and create a new one.
3. Separate intake from execution
The Telegram handler accepts the message quickly, while a separate worker retrieves the task from the queue. A webhook is suitable for a permanent server; polling is simpler for the first test.
agent-lab/
├── app/bot.py
├── app/worker.py
├── app/policy.py
├── data/inbox/
├── data/wiki/
└── logs/This way, restarting the worker should not delete incoming tasks.
4. Routing and confirmations
Divide requests into reading, analysis, planning, and external actions. The first three can be performed automatically. Sending an email, publishing, making a payment, and deleting should first create a request for approval.
if intent in ["read", "analyze", "plan"]:
run_worker(job)
elif intent in ["send", "publish", "pay", "delete"]:
create_approval(job)
else:
ask_for_clarification(job)5. Memory with sources
Keep source files separate from finalized pages. Every memory entry should contain a date and source. If a new source contradicts an old one, do not overwrite the old entry. RAG and embeddings will be useful for later retrieval.
data/raw/2026-07-22-note.txt
data/wiki/project.md
data/tasks/open.md6. Test run
python3 -m venv .venv
source .venv/bin/activate
pip install -r app/requirements.txt
python app/bot.py
# во втором терминале
python app/worker.pyDo not enable automatic startup until you have tested it manually: first, you need to identify authentication, path, and retry errors.
7. Five essential tests
- a regular question;
- a message with a file;
- a repeat of the same message;
- text asking to reveal a secret;
- a request to send an email.
A duplicate does not create a second task, secrets are not revealed, the email stops for approval, and the error is recorded in the log.
Common failures
- Duplicate response: event deduplication is missing.
- Lost tasks: the queue is stored only in memory.
- Unauthorized action: there is no separate permissions policy.
- Cluttered memory: source materials are mixed with verified knowledge.
- High bill: there is no budget, timeout, or retry limit.
Completion criteria
The framework is ready when ten identical scenarios produce predictable results, errors are visible in the log, retries are not duplicated, and external actions require approval.