Enterprise WeChat AI Auto-Reply System Troubleshooting Record (Docker + FastAPI + Redis)
This troubleshooting journey covered a typical “enterprise‑level AI message‑processing pipeline” — from Webhook → Redis queue → Worker → AI → Enterprise WeChat sending. Almost every layer of the chain presented a pitfall.
The entire set of issues can be summarised in one sentence:
It wasn’t that the system wasn’t running, but rather that the combination of “multi‑layer structure + configuration + indentation + imports + startup methods” broke the entire chain.
1. System Architecture Design (Target State)
The overall system design was as follows:
Enterprise WeChat message
↓
FastAPI Webhook (wecom-bot)
↓
Redis Queue (decoupling)
↓
Worker consumes the queue
↓
DeepSeek / AI analysis
↓
Enterprise WeChat send API
2. Initial Symptoms
After starting the system, the following problems appeared:
- ❌ No auto‑reply received in Enterprise WeChat
- ❌ Worker container kept restarting
- ❌ Redis queue had data but no response
- ❌ FastAPI API logs looked normal but no result was produced
3. Full Troubleshooting Process (Key Pitfalls)
1️⃣ Worker crashed immediately: missing Python packages
Error log:
ModuleNotFoundError: No module named 'app'
Cause:
Python in the Docker container did not have the module path set.
Fix:
environment:
PYTHONPATH: /app
2️⃣ Incorrect docker-compose build structure
Error:
services.wecom-worker.build must be a string
Cause:
The older Compose format does not support:
build:
context: .
dockerfile: Dockerfile
Fix:
build: .
3️⃣ YAML indentation disaster (the most fatal issue)
Error:
did not find expected '-' indicator
Root causes:
- Mixed tabs and spaces
- Incorrect indentation levels for
environment/command/depends_on - The entire
workerblock was misaligned
4️⃣ Worker did not execute the sending logic
Although the worker could consume messages from the queue:
- No log output for
send - No response from Enterprise WeChat
5️⃣ Design error in the internal_reply interface
Problem:
token = get_access_token()
But the function was not defined → immediate NameError.
6️⃣ Architecture confusion: two workers coexisted
The system contained both:
worker.py(the correct one)worker_lead.py(old logic)
This led to:
- Inconsistent message routing
- Confused sending flow
- Difficult debugging
4. Final Fixes
✔ Unified Worker
Finally adopted:
python app/worker.py
✔ Standardised docker-compose configuration
wecom-worker:
build: .
container_name: wecom-worker
restart: always
working_dir: /app
volumes:
- ./app:/app/app
environment:
TZ: Asia/Shanghai
REDIS_HOST: redis
REDIS_PORT: 6379
PYTHONUNBUFFERED: 1
PYTHONPATH: /app
command: python app/worker.py
depends_on:
- redis
✔ Confirmed Redis decoupling structure
- The webhook only enqueues messages
- The worker handles the processing
- FastAPI does not perform AI computations
5. Final Running State
After the fixes, the system became stable:
✔ Webhook receives messages normally
✔ Redis queue flows correctly
✔ Worker consumes messages normally
✔ AI returns responses normally
✔ Enterprise WeChat sends messages successfully
Example logs:
processed: {'content': 'hello', 'intent': 'chat'}
🤖 reply: Received, thank you for your message
📤 sent result: {"errcode":0}
6. Key Lessons Learned (Very Important)
1️⃣ Docker environment issues > code issues
Many so‑called “code bugs” were actually caused by:
PYTHONPATH- Volume overrides
- Inconsistent
working_dir
2️⃣ YAML is the number‑one pitfall in production
- 80% of Compose issues are indentation‑related
- Tabs are always hidden bombs
3️⃣ Multiple worker architectures must have a single entry point
Otherwise:
- Message paths split
- Debugging becomes uncontrollable
- Behaviour becomes unpredictable
4️⃣ FastAPI and Worker must have clear separation of concerns
Correct structure:
| Module | Responsibility |
|---|---|
| webhook | Receive messages |
| redis | Decouple |
| worker | Process business logic |
| sender | Send messages |
7. Final Architecture Suggestions (for Production)
If going to production, consider upgrading to:
- Single worker entry point
- Redis Streams (instead of lists)
- Unified logging with
trace_id - Retry queue mechanism
- Dead‑letter queue
8. Summary in One Sentence
The essence of this incident was not that “the program had errors”, but that “small mistakes accumulated across multiple layers (Docker + YAML + Python + architecture) and eventually broke the entire chain”.
If you plan to build an upgraded version next, you can directly create:
🚀 Enterprise‑Grade AI Lead‑Generation System V2
- n8n + Redis Streams + FastAPI
- Automatic lead scoring
- Intelligent Enterprise WeChat distribution
- Support for DeepSeek / Claude / OpenAI
- Built‑in monitoring + retries + failure queues