跳到主要內容
邊界實驗室 · Boundary Lab

邊界實驗室 · Article

脈絡邊界 — Context window 是 AI 的盲區

AI 不會因為 session 結束就忘記被污染的脈絡。這篇從 ZombieAgent 與長期受污染的 RAG 記憶層切入,拆解 context boundary、哨兵令牌與 fail-closed 偵測,說清楚為什麼 memory 比你以為的更難管。

2026-04-26Lab-confirmedmemory-hallmk-brain

Lab-confirmed:本文 reference 實作來自我(Maki)自家在跑的個人 PKI(mk-brain / ERIKA Bot / Inbox Bot 等),不是 enterprise production case study。Code snippet 為 reference 設計,非實際在跑的版本。


你以為對話結束了,污染卻還留在裡面

很多人把 context 想成一個會自己蒸發的東西。

這一輪對話結束,視窗清空,模型就重來。

但只要你的 agent 背後接了 memory、vector store、長期筆記、RAG cache,情況就完全不同。

你不是在管理一段 prompt。

你是在管理一個會累積、被重複引用、還可能跨 session 存活的脈絡層。

ZombieAgent 讓很多人第一次真正意識到這件事。

研究者展示的不是單次 jailbreak 多精彩。

而是污染一旦種進 memory 或 retrieval layer,下一次 query 依然可能把它撈回來。

也就是說,對話可以結束,攻擊不會自動結束。

這對 builder 很麻煩,因為多數團隊對 context 的治理幾乎只有「看起來能用」。

很少有人替 namespace 種 canary。

很少有人替記憶寫入做 ACL。

更少有人規定:LLM 自己生成的內容不能直接升格成之後的依據。

所以真正危險的,不是 agent 某一天突然講錯一句話。

而是它已經連續半年在錯的脈絡上繼續推理,團隊還以為那叫 personalization。

Context boundary 的工作,就是把這條「一次失誤變成長期污染」的路先截斷。


Context Boundary:上下文能留多久、污染多遠

當 memory 和 context layer 變成持久層,偵測就不能只靠人盯 dashboard。

Case

:ZombieAgent attack technique(2026-01 LinkedIn 安全社群揭露)——研究者展示 AI agent 透過 memory / context layer 的持續資料洩漏(persistent data leakage)。即使對話結束、session 結束、agent 重啟,毒已經種在 vector store 裡,下一次 query 仍會被污染

:你的 RAG 知識庫被污染半年——完全不知道。沒人 audit、沒 alert、沒監控。直到客戶投訴「你的 AI 客服說了奇怪的事」才發現。這是 zh-TW 工程社群最常 vent 的 sentiment:「公司搞 RAG 但完全沒人在意 source 可信度」。

核心問題:怎麼deterministic 早期偵測而不靠盯 dashboard?

RuleCanary Tokens(中文我建議叫「哨兵令牌」)。在你的記憶體 / RAG 庫塞一個「絕對不該出現在 LLM output」的隨機字串,例如 MK_CANARY_<random>。output 偵測到 canary echo → fail-closed + log。

這裡的關鍵不是多做觀測,而是讓污染第一次外露時就留下可機器判斷的訊號。

ThreatMitigationValidated in (reference)
RAG / memory 污染半年沒人發現每 namespace 至少 1 個 canary entry;output redaction layer 偵測;fail-closed + weekly digest(不做 daily dashboard,反 L4)memory-hall + mk-brain
Memory & Context Poisoning(ASI06)寫入 path 加 HMAC signature;讀取 path 加 ACL;「LLM 自己想寫」這條路徑 deny by defaultmemory-hall write hygiene
Misinformation(LLM09)放大引用必須 trace 到 raw_source tier;llm_derived 不得當「事實」呈現mk-brain Observatory layer

Reference 實作(示意非 production code,依你環境調整):

# Canary tokens — deterministic 早警,不靠盯 dashboard
import secrets

CANARY_PREFIX = "MK_CANARY_"

def plant_canary(namespace: str) -> str:
    """每個 RAG namespace 至少種一顆 canary"""
    canary = f"{CANARY_PREFIX}{secrets.token_hex(8)}"
    db.insert(MemoryEntry(
        content=f"Canary marker: {canary}",
        source_tier="canary",  # 不會被 RAG 正常 surface
        upstream_ids=[],
        provenance_hash=hmac_sign(canary),
    ))
    return canary

def detect_canary_leak(llm_output: str, known_canaries: list[str]):
    """LLM output 偵測到 canary echo → fail-closed"""
    for canary in known_canaries:
        if canary in llm_output:
            log_incident(f"CANARY LEAK detected: {canary}")
            raise SecurityError("RAG 被污染或 LLM exfil canary")

對應 OWASP:這篇先看哪幾條

  • ASI06 Memory & Context Poisoning:這篇處理的核心就是污染如何從單次上下文擴散成持久狀態。
  • LLM08:2025 Vector and Embedding Weaknesses:當持久 context 依賴向量檢索,檢索層就是污染傳播器。
  • LLM09:2025 Misinformation:context 被污染之後,模型輸出的錯誤會以看似有根據的形式持續放大。

想動手做? 這篇文的概念有對應的 5 課完整課程: 脈絡邊界 101 →

也可以接著看下一個邊界:攻擊面邊界