Cấu hình Redis để lưu trữ trạng thái hội thoại
Chúng ta sẽ triển khai một instance Redis trong cụm Kubernetes để đóng vai trò là bộ nhớ ngắn hạn (short-term memory) và lưu trữ lịch sử chat (chat history) cho các Agent.
Việc này giúp Agent nhớ ngữ cảnh qua nhiều phiên (session) và đảm bảo dữ liệu không bị mất khi Pod của Agent bị restart do lỗi hoặc bảo trì.
1. Tạo PersistentVolumeClaim cho Redis
Trước khi chạy Redis, ta cần một volume lưu trữ bền vững. Khi Pod Redis bị xóa, dữ liệu vẫn nằm trên disk và được mount lại khi Pod mới khởi động.
File cấu hình: /k8s/redis-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: redis-data-pvc
namespace: ai-agent-platform
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
storageClassName: standard
Kết quả mong đợi: PVC được tạo thành công với trạng thái Bound, sẵn sàng nhận dữ liệu từ Pod Redis.
Verify bằng lệnh:
kubectl get pvc redis-data-pvc -n ai-agent-platform
2. Triển khai Redis StatefulSet với Storage
Deploy Redis sử dụng StatefulSet để đảm bảo tính ổn định và mount PVC vừa tạo vào đường dẫn dữ liệu mặc định của Redis.
File cấu hình: /k8s/redis-statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: redis
namespace: ai-agent-platform
spec:
serviceName: redis
replicas: 1
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
spec:
containers:
- name: redis
image: redis:7-alpine
ports:
- containerPort: 6379
volumeMounts:
- name: redis-storage
mountPath: /data
resources:
limits:
memory: "256Mi"
cpu: "250m"
volumeClaimTemplates:
- metadata:
name: redis-storage
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 5Gi
Kết quả mong đợi: Pod Redis chạy với trạng thái Running và đã mount volume dữ liệu.
Verify bằng lệnh:
kubectl get pods -n ai-agent-platform | grep redis
3. Tạo Service để Agent kết nối
Expose Redis ra nội bộ cụm mạng (ClusterIP) để các Pod Agent có thể connect qua hostname redis.ai-agent-platform.svc.cluster.local.
File cấu hình: /k8s/redis-service.yaml
apiVersion: v1
kind: Service
metadata:
name: redis
namespace: ai-agent-platform
spec:
selector:
app: redis
ports:
- port: 6379
targetPort: 6379
type: ClusterIP
Kết quả mong đợi: Service được tạo và các Pod khác trong namespace có thể resolve tên này.
Verify bằng lệnh:
kubectl get svc redis -n ai-agent-platform
Tích hợp Redis vào Code LangGraph
Bây giờ ta điều chỉnh code Python của Agent để sử dụng Redis thay vì bộ nhớ RAM mặc định. Điều này đảm bảo state được lưu vào database bên ngoài.
1. Cài đặt thư viện cần thiết
Cập nhật Dockerfile của Agent để include thư viện redis và cấu hình langgraph hỗ trợ persistence.
File cấu hình: /docker/Dockerfile (thêm dòng vào phần requirements hoặc install)
RUN pip install --no-cache-dir redis langgraph langgraph-supervisor
Kết quả mong đợi: Image Docker mới được build chứa các dependency cần thiết.
2. Cấu hình Redis trong ứng dụng LangGraph
Thay đổi file main.py (hoặc app.py) để khởi tạo RedisSaver. Ta sẽ dùng biến môi trường để lấy hostname Redis từ Kubernetes.
File code: /src/main.py
import os
import redis
from langgraph.checkpoint.redis import RedisSaver
from langgraph.graph import StateGraph
# Lấy thông tin kết nối từ Environment Variables
REDIS_HOST = os.getenv("REDIS_HOST", "redis")
REDIS_PORT = int(os.getenv("REDIS_PORT", "6379"))
REDIS_DB = int(os.getenv("REDIS_DB", "0"))
# Khởi tạo client Redis
redis_client = redis.Redis(
host=REDIS_HOST,
port=REDIS_PORT,
db=REDIS_DB,
decode_responses=True
)
# Cấu hình Saver để lưu state
# Thread ID dùng để phân biệt các session hội thoại khác nhau
saver = RedisSaver(redis_client)
# Khởi tạo Graph
workflow = StateGraph(...)
# Thêm checkpoint vào graph
app = workflow.compile(checkpointer=saver)
Kết quả mong đợi: Code không lỗi cú pháp và sẵn sàng connect vào Redis khi khởi động.
Verify bằng cách chạy local test hoặc build image mới:
docker build -t ai-agent:v2 .
Triển khai Agent với Cấu hình Persistence
Cập nhật Deployment của Agent để inject các biến môi trường cần thiết và đảm bảo nó có thể talk với Redis Service.
1. Cập nhật Deployment Agent
Thay đổi file agent-deployment.yaml để thêm env block chỉ rõ đường dẫn Redis.
File cấu hình: /k8s/agent-deployment.yaml (phần spec của container)
apiVersion: apps/v1
kind: Deployment
metadata:
name: ai-agent
namespace: ai-agent-platform
spec:
replicas: 2
selector:
matchLabels:
app: ai-agent
template:
metadata:
labels:
app: ai-agent
spec:
containers:
- name: agent
image: ai-agent:v2
ports:
- containerPort: 8000
env:
- name: REDIS_HOST
value: "redis"
- name: REDIS_PORT
value: "6379"
- name: REDIS_DB
value: "0"
- name: THREAD_ID
value: "default-session" # Hoặc lấy từ header request
resources:
limits:
memory: "512Mi"
cpu: "500m"
Kết quả mong đợi: Pod mới được tạo với các biến môi trường đã được set đúng.
Verify bằng lệnh:
kubectl describe pod -l app=ai-agent -n ai-agent-platform | grep -A 5 "Env:"
2. Kiểm tra tính nhất quán khi Restart
Để đảm bảo state được lưu bền vững, ta sẽ thực hiện một cuộc hội thoại, sau đó force restart Pod và kiểm tra xem Agent có nhớ lịch sử không.
Thực hiện các bước sau:
- Gửi request đầu tiên để tạo state.
- Xóa Pod để trigger restart.
- Gửi request thứ hai, yêu cầu Agent nhớ nội dung trước đó.
File script test: /test/restart-test.sh
#!/bin/bash
# 1. Gửi message đầu tiên (Giả sử có endpoint /chat)
echo "Gửi message đầu tiên..."
curl -X POST http://localhost:8000/chat \
-H "Content-Type: application/json" \
-d '{"message": "Tên tôi là Nguyen Van A", "thread_id": "test-session-1"}'
# 2. Restart Pod Agent (Force kill để kiểm tra persistence)
echo "Đang restart Pod Agent..."
kubectl rollout restart deployment ai-agent -n ai-agent-platform
# 3. Chờ Pod mới sẵn sàng
echo "Chờ Pod mới up..."
kubectl rollout status deployment ai-agent -n ai-agent-platform --timeout=60s
# 4. Gửi message thứ hai (Yêu cầu nhắc lại tên)
echo "Gửi message thứ hai để kiểm tra memory..."
curl -X POST http://localhost:8000/chat \
-H "Content-Type: application/json" \
-d '{"message": "Bạn nhớ tên tôi là gì không?", "thread_id": "test-session-1"}'
echo "Hoàn thành test."
Kết quả mong đợi: Response của request thứ hai phải trả về "Nguyen Van A". Nếu trả về "Tôi không biết", thì Redis chưa được cấu hình đúng hoặc thread_id không khớp.
Chạy script:
chmod +x /test/restart-test.sh && /test/restart-test.sh
Triển khai Vector Database (Optional cho Long-term Memory)
Nếu cần lưu trữ kiến thức dài hạn (RAG), ta sẽ bổ sung một Vector DB (ví dụ: Qdrant hoặc Weaviate). Dưới đây là ví dụ với Qdrant.
1. PVC cho Vector DB
Tạo volume riêng cho Vector DB vì dữ liệu vector nặng hơn và cần I/O cao.
File cấu hình: /k8s/qdrant-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: qdrant-storage
namespace: ai-agent-platform
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
storageClassName: standard
Kết quả mong đợi: PVC qdrant-storage được tạo.
2. Deploy Qdrant
Deploy Qdrant với mount volume.
File cấu hình: /k8s/qdrant-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: qdrant
namespace: ai-agent-platform
spec:
replicas: 1
selector:
matchLabels:
app: qdrant
template:
metadata:
labels:
app: qdrant
spec:
containers:
- name: qdrant
image: qdrant/qdrant:latest
ports:
- containerPort: 6333
volumeMounts:
- name: qdrant-vol
mountPath: /qdrant/storage
resources:
limits:
memory: "1Gi"
cpu: "500m"
volumes:
- name: qdrant-vol
persistentVolumeClaim:
claimName: qdrant-storage
Kết quả mong đợi: Qdrant chạy và lưu vector vào PVC.
3. Tích hợp Vector Store vào LangGraph/CrewAI
Cập nhật code Python để kết nối Qdrant. Sử dụng qdrant_client và tích hợp vào LangChain hoặc LangGraph.
File code: /src/vector_store.py
import os
from qdrant_client import QdrantClient
from langchain_qdrant import QdrantVectorStore
QDRANT_HOST = os.getenv("QDRANT_HOST", "qdrant")
QDRANT_PORT = int(os.getenv("QDRANT_PORT", "6333"))
# Kết nối Qdrant
client = QdrantClient(
host=QDRANT_HOST,
port=QDRANT_PORT
)
# Khởi tạo Vector Store
# Collection name có thể tùy chỉnh
vector_store = QdrantVectorStore(
client=client,
collection_name="agent_knowledge",
)
# Hàm để search kiến thức trước khi trả lời
def search_knowledge(query: str):
docs = vector_store.similarity_search(query, k=3)
return [doc.page_content for doc in docs]
Kết quả mong đợi: Code có thể truy vấn dữ liệu vector từ Qdrant.
Verify bằng cách thêm env vào Deployment Agent:
kubectl set env deployment/ai-agent QDRANT_HOST=qdrant -n ai-agent-platform
Verify toàn bộ hệ thống Memory
Thực hiện kiểm tra cuối cùng để đảm bảo cả Short-term (Redis) và Long-term (Vector DB) đều hoạt động đồng bộ.
1. Kiểm tra dữ liệu trong Redis
Connect trực tiếp vào Pod Redis để xem keys đã được lưu chưa.
kubectl exec -it $(kubectl get pods -n ai-agent-platform -l app=redis -o jsonpath='{.items[0].metadata.name}') -n ai-agent-platform -- redis-cli
Trong shell Redis, chạy lệnh:
keys "*"
Kết quả mong đợi: Xuất hiện các key chứa thông tin state của thread_id đã test.
2. Kiểm tra dữ liệu trong Vector DB
Connect vào Pod Qdrant để verify collection.
kubectl exec -it $(kubectl get pods -n ai-agent-platform -l app=qdrant -o jsonpath='{.items[0].metadata.name}') -n ai-agent-platform -- qdrant --list-collections
Kết quả mong đợi: Xuất hiện collection agent_knowledge (hoặc tên bạn đặt).
3. Test kịch bản mất Pod hoàn toàn
Scale Pod Agent xuống 0, sau đó scale lên 1, và gửi request mới.
kubectl scale deployment ai-agent --replicas=0 -n ai-agent-platform && sleep 5 && kubectl scale deployment ai-agent --replicas=1 -n ai-agent-platform
Chờ Pod lên xong, gửi request yêu cầu nhớ thông tin cũ.
Verify kết quả: Agent trả lời chính xác dựa trên dữ liệu đã lưu trong Redis/Vector DB.
Điều hướng series:
Mục lục: Series: Xây dựng nền tảng AI Agent tự động hóa với LangGraph, CrewAI và Kubernetes
« Phần 6: Tối ưu hiệu năng với Horizontal Pod Autoscaler (HPA)
Phần 8: Xây dựng Gateway API để điều phối Agent từ bên ngoài »