AI Agent 上下文污染踩坑实录:用 pytest + Redis 揪出 3 类记忆串号 bug,排查 6 小时
AI Agent ä¸ä¸ææ±¡æè¸©åå®å½ï¼ç¨ pytest + Redis æªåº 3 类记å¿ä¸²å· bugï¼ææ¥ 6 å°æ¶
ç¨æ·05954017446 2026-08-15 13 é 读1åé忍䏤ç¹ï¼ç¨æ·ç¾¤é忥ä¸å¼ æªå¾ï¼AI 客æåå¤å·¥åæ¶ï¼æå¦ä¸ä¸ªç¨æ·çææºå·åæ¶è´§å°å带äºåºæ¥ãæç¬¬ä¸ååºæ¯æ¨¡åå¹»è§ï¼ç»ææ¥ Redis åç°ï¼ä¸¤ä¸ªä¸å user_id çä¼è¯å
±ç¨äºåä¸ä¸ª session_id ä½ä¸º keyï¼ä¸ä¸æç´æ¥ä¸²å·ãè¿ä¸æ¯æ¨¡åçé®é¢ï¼æ¯è®°å¿å±å¨è£¸å¥ã忥æç¨ pytest + Redis æäºä¸å¥ä¸è´æ§éªè¯ï¼ææè¿ç±» bug ææ»ã
é®é¢æè§£
AI Agent çè®°å¿åå¨è·æ®éç¼åä¸ä¸æ ·ï¼ç¼å丢äºåªæ¯æ ¢ä¸ç¹ï¼è®°å¿ä¸²äºä¼ç´æ¥æ³é²éç§ã带å对è¯ãæä»¬å¢éç¨ Redis å Agent ççæè®°å¿ï¼å¤è½®å¯¹è¯é å®ä¿æè¿è´¯ãä¸çº¿åå¶ååºç° A ç¨æ·çå° B çå岿¶æ¯ãæ ¹å 䏿¯æ¨¡åï¼èæ¯è®°å¿å±çä¸ç±»é®é¢ï¼key 设计缺å°ç¨æ·ç»´åº¦ãTTL å·æ°é»è¾æ··ä¹±ãåºåååè®®ä¸ç»ä¸ãå¸¸è§æ¹æ¡ä¸ºä»ä¹ä¸è¡ï¼é code review åæå·¥æµè¯åç°ä¸äºï¼å ä¸ºä¸²å·æ¯å¹¶åãè¾¹çæ¡ä»¶å å åçç»æï¼mock Redis åéªè¯ä¸äºçå® TTL åååæ§ãæåæå³å®æè®°å¿å±å½åºç¡è®¾æ½ï¼ç¨ pytest + Redis åä¸è´æ§æµè¯ã
æ¹æ¡è®¾è®¡
é pytest + Redis è䏿¯åæµ mockï¼æ ¸å¿åå æ¯ Redis ççå®è¡ä¸ºââTTL 计ç®ãWATCH ä¹è§éãåºåååçäºè¿å¶å·®å¼ââæ¯ mock 模æä¸åºæ¥çãpytest ç fixture å¯ä»¥ç»æ¯ä¸ªæµè¯ä¸ä¸ªå¹²åç dbï¼çå® Redis ç¨ Docker èµ·ä¸ä¸ªå³å¯ãè®¾è®¡ä¸æä»¬æè®°å¿è¯»åå°è£
æ MemoryStoreï¼ç¶åé对ä¸ç±»ä¸åéåæµè¯ï¼key é离æ§ãTTL ä¸çæ¬å
¼å®¹ãå¹¶å追å ä¸è´æ§ã为ä»ä¹ä¸éç´æ¥ç¨çäº§åºæµï¼å¤ªå±é©ï¼ä¸ºä»ä¹ä¸éåªååæµï¼å ä¸ºåæµä¼æ Redis 彿®é dict ç¨ï¼æ©ç TTL åå¹¶åé®é¢ã
æ ¸å¿å®ç°
è¿æ®µä»£ç è§£å³æµè¯é离é®é¢ï¼æ¯ä¸ªæµè¯ç¨ä¾æ¿å°ä¸ä¸ªç¬ç«ç Redis dbï¼é¿å æ°æ®ä¸²å·å½±åæè¨ã
# conftest.py
import pytest
import redis
@pytest.fixture
def redis_client():
"""è¿æ¥æ¬å° Redisï¼æµè¯åæ¸
空å½å dbï¼ä¿è¯é离"""
client = redis.Redis(host="localhost", port=6379, db=15, decode_responses=True)
client.flushdb()
yield client
client.flushdb()
client.close()
è¿ä¸ªç±»å°è£ äºç产级ç Redis è®°å¿è¯»åï¼å å« key å½å空é´ãJSON çæ¬åãSETEX TTLã以åå¹¶åå®å ¨ç WATCH 追å ãå ³é®è¡å äºæ³¨éã
# memory_store.py
import json
from typing import Any, Dict, List, Optional
import redis
from redis.exceptions import WatchError
class MemoryStore:
"""AI Agent çæè®°å¿åå¨ï¼è´è´£ key é离ãTTL åçæ¬ååºåå"""
def __init__(self, client: redis.Redis, ttl: int = 3600):
self.client = client
self.ttl = ttl
self.version = 1 # åºåå
Aitishiku.com