AI agent that monitors Telegram groups, detects bug reports using LangChain + LangGraph + Qdrant, and automatically creates tasks in Taiga via MCP.
Telegram long-polling (MCP)
│
▼
Embedding (Ollama / bge)
│
▼
Qdrant ANN + Reranker
│ score > threshold?
▼
LLM Classification (LangGraph node)
│ is_bug = true?
▼
LLM Draft Builder
│
▼
Taiga MCP → create_issue()
| Service | Image | Port |
|---|---|---|
qdrant |
qdrant/qdrant |
6333 (REST), 6334 (gRPC) |
ollama |
ollama/ollama |
11434 |
telegram-mcp |
guangxiangdebizi/telegram-mcp |
3000 |
taiga-mcp |
built from ./pytaiga-mcp |
8001 |
agent |
built from ./agent |
— |
# 1. Copy and fill env vars
cp .env.example .env
$EDITOR .env
# 2. Build images
make build
# 3. Start everything
make up
# 4. Pull Ollama models (first run only)
make pull-models
# 5. Follow logs
make logs-agentReply to any message in a monitored chat and add @bug-agent — the agent
will create a task immediately, bypassing the score threshold.
Теперь есть отдельный веб-дашборд на базе LangGraph CLI/Studio для быстрого тестирования и перенастройки логики без правок файлов.
Если Studio открывается с ошибкой
TypeError: NetworkError when attempting to fetch resource, не используйтеbaseUrl=http://0.0.0.0:8123. Рабочий вариант: вручную замените baseUrl наhttp://localhost:8123. Пример:https://smith.langchain.com/studio/thread?baseUrl=http%3A%2F%2Flocalhost%3A8123&mode=graph&render=interact
runtime_overridesдля live-настроек
Пример runtime_overrides:
mcp.taiga_url— переопределить Taiga MCP URLmcp.sources.telegram— переопределить MCP URL источникаdetection.rerank_score_threshold/detection.bug_classify_thresholdtask_tracker.*(project, placement, work_item_type, uniqueness_check_enabled)llm.*(provider, cloud_model, ollama_model, vllm_base_url, llamacpp_base_url)
Это позволяет из веба быстро:
- Подключать другие MCP серверы,
- Крутить пороги/политику дедупликации,
- Менять placement/тип задачи,
- Проверять поведение графа на тестовых сообщениях.
- Messengers are connected via
sourcesinconfig.yaml. - Usetransport: rabbitmqfor push delivery from a bot adapter queue. - Usetransport: mcpfor polling adapters implementing the same MCP contract. - Task trackers are connected via
task_trackerinconfig.yamlandTASK_TRACKER_PROVIDERin.env. - Current plugin:taiga. - To add a new tracker, implement one adapter inagent/src/trackers/(factory + adapter class), no graph rewrite required.
Container liveness for internal MCP services is organized as event heartbeats:
telegram-mcp,taiga-mcp, andagentpublish heartbeat events to RabbitMQ routing keyservice.health.agentsubscribes toservice.healthand logs stale services when heartbeat is missing longer thanSERVICE_HEALTH_STALE_SEC.
This avoids aggressive HTTP health polling between containers and reduces startup-time probe storms.
Edit tags.md at any time. The agent reloads it on every LLM call — no
restart needed.
See .env.example for full documentation.
Key variables:
| Variable | Description |
|---|---|
LLM_PROVIDER |
ollama | vllm | llamacpp | openai | openrouter | anthropic |
TELEGRAM_CHAT_IDS |
Comma-separated chat IDs to monitor |
TAIGA_PROJECT_SLUG |
Target Taiga project |
TASK_TRACKER_PROVIDER |
Task tracker adapter (taiga) |
TASK_TRACKER_PROJECT |
Generic tracker project key/slug |
RERANK_SCORE_THRESHOLD |
Min reranker score to send to LLM (default 0.65) |
BUG_CLASSIFY_THRESHOLD |
Min LLM confidence to create task (default 0.75) |
RERANK_OPERATOR |
Rerank backend: qdrant, vllm, llamacpp, ollama or ann_only |
RERANK_BASE_URL |
Rerank operator address (defaults to QDRANT_URL) |
RERANK_MODEL |
Reranker model name used by operator |
TgTasksBot/
├── docker-compose.yml
├── .env.example
├── config.yaml # static config (mounted into agent)
├── tags.md # dynamic tags (hot-reloaded)
├── Makefile
├── agent/ # Python AI agent
│ ├── Dockerfile
│ ├── pyproject.toml
│ └── src/
│ ├── main.py # entrypoint + polling loop
│ ├── config.py # settings
│ ├── dedup.py # seen-message deduplication
│ ├── agent/
│ │ ├── graph.py # LangGraph compiled graph
│ │ ├── nodes.py # node implementations
│ │ └── state.py # AgentState dataclass
│ ├── qdrant_store/
│ │ └── client.py # embeddings + rerank search
│ ├── mcp/
│ │ ├── taiga_mcp.py # Taiga MCP client
│ │ └── telegram_mcp.py # Telegram MCP client (file download etc.)
│ └── telegram/
│ └── polling.py # long-polling loop
└── pytaiga-mcp/ # Taiga MCP server (submodule)