實現(xiàn)指南)
Agent Memory 記憶管理系統(tǒng)可以理解為給 AI Agent 增加一套長期記憶倉庫對話結(jié)束后關(guān)鍵信息仍然保留下次交互Agent 能直接讀取舊記憶并繼續(xù)工作。在 2026 中國國際大學(xué)生創(chuàng)新大賽的 openEuler 方向賽題里這套系統(tǒng)還要求跑在鯤鵬平臺上這就把問題從“寫一個功能 Demo”變成了“在 ARM 架構(gòu) openEuler 環(huán)境里做一次完整可驗證的工程實現(xiàn)”。這篇文章適合準(zhǔn)備參賽、需要從零搭建項目的學(xué)生團(tuán)隊也適合剛接觸 openEuler 和 Agent 應(yīng)用的后端開發(fā)者。我會按照“先理解命題再搭環(huán)境再設(shè)計系統(tǒng)再實現(xiàn)驗證”的順序把整個項目的關(guān)鍵環(huán)節(jié)拆開講。1. 先想清楚 Agent Memory 在這道賽題里要解決什么問題1.1 記憶能力為什么是 Agent 從“能用”到“好用”的拐點大部分 Agent 在沒有記憶系統(tǒng)時本質(zhì)上只是一個“無狀態(tài)函數(shù)調(diào)用器”每次請求進(jìn)來它只能看到當(dāng)前用戶輸入和有限的上下文窗口。用戶上次說過什么、做過什么選擇、有哪些長期偏好它一概不知道。比如用戶在第一輪對話里明確說“我以后希望所有報告都用簡潔風(fēng)格”下一輪如果 Agent 生成內(nèi)容時完全忽略這句話體驗就會非常割裂。Agent Memory 要解決的就是這個狀態(tài)管理問題。記憶系統(tǒng)通常在 Agent 外部保存結(jié)構(gòu)化或半結(jié)構(gòu)化的記憶數(shù)據(jù)在每次交互前把相關(guān)記憶取出拼入 Prompt 或作為上下文輸入。這樣 Agent 不用把全部歷史都塞進(jìn)有限窗口也能做到“記住該記住的忘掉該忘掉的”。從大賽角度看這個方向的價值在于大模型能力已經(jīng)比較強(qiáng)但工程落地時??ㄔ谏舷挛拈L度、多輪一致性、個性化體驗這些問題上。一個設(shè)計得當(dāng)?shù)?Agent Memory 模塊能讓整個 Agent 系統(tǒng)的智能感提升一個檔次而且可以獨立演示、獨立測試非常適合做項目創(chuàng)新點。1.2 賽題隱藏的考察點不只是功能而是平臺適配能力這道賽題的題目里明確出現(xiàn)了“鯤鵬平臺”和“openEuler”這是很多團(tuán)隊容易低估的地方。許多學(xué)生在筆記本上寫完 Python 代碼x86 架構(gòu)運行沒問題就以為項目完成了。但到比賽演示或評測時評委可能要求現(xiàn)場跑在鯤鵬服務(wù)器上或者要求提供在 ARM 架構(gòu)下的運行記錄。這時候才發(fā)現(xiàn)依賴包沒有 ARM 版本、Docker 鏡像拉不下來、某個 C 擴(kuò)展需要本地編譯整個項目直接卡住。所以Agent Memory 這道題真正考核的不只是“你會不會用 Redis 存記憶”而是能不能在 openEuler 系統(tǒng)上穩(wěn)定安裝依賴能不能在 ARM 架構(gòu)下處理兼容性問題能不能給出清晰的部署、驗證和性能測試流程能不能展示記憶系統(tǒng)在鯤鵬硬件上的實際運行效果。這個理解會直接影響你的項目計劃。我建議團(tuán)隊一拿到題不要先急著寫 AI 邏輯而是先把 openEuler 環(huán)境搭起來把最基礎(chǔ)的“寫入一條記憶、讀取一條記憶”跑通。平臺穩(wěn)了后面所有功能才有意義。2. 基于鯤鵬平臺的項目前置準(zhǔn)備openEuler、SSH、yum 源和 Docker2.1 環(huán)境選型openEuler 版本、架構(gòu)和機(jī)器規(guī)格openEuler 的版本選擇直接影響軟件包兼容性。常見做法是選擇長期支持LTS版本比如 openEuler 22.03 LTS SP4 或更新的 SP 版本。這類版本維護(hù)周期長軟件源比較穩(wěn)定適合比賽項目踩坑。如果你們是從 CentOS 7.5 這類舊系統(tǒng)遷移過來查兼容性時也要優(yōu)先看 openEuler 版本升級文檔而不是憑印象直接替換。裝系統(tǒng)前先確認(rèn)機(jī)器是鯤鵬 920 這類 ARM 處理器還是 x86 架構(gòu)??梢杂眠@條命令看體系結(jié)構(gòu)uname -m如果在鯤鵬上正常輸出是aarch64。這個信息很重要因為后面安裝任何軟件、拉取 Docker 鏡像、下載預(yù)編譯 wheel 包都要判斷是否有對應(yīng)的 ARM 版本。硬件規(guī)格方面我建議最低 4 核 CPU、8GB 內(nèi)存。如果 Agent 記憶系統(tǒng)里要跑向量檢索或者同時演示多個服務(wù)內(nèi)存最好升到 16GB。磁盤至少預(yù)留 40GB因為 Docker 鏡像和編譯工具鏈會占用不少空間。要注意能在低配機(jī)器上跑通和能在批量任務(wù)下長期穩(wěn)定跑是完全不同的兩件事。比賽演示可以先用小規(guī)格但寫文檔時要說明生產(chǎn)環(huán)境建議的規(guī)格。2.2 系統(tǒng)初始化SSH、用戶權(quán)限、yum 源openEuler 安裝完成后第一步是開啟 SSH 遠(yuǎn)程登錄。很多團(tuán)隊習(xí)慣在自己電腦上寫代碼然后把代碼傳到服務(wù)器上跑沒有 SSH 會非常難受。安裝系統(tǒng)時如果沒有選擇安裝 SSH Server可以用下面的命令啟動systemctl enable --now sshd然后檢查服務(wù)狀態(tài)systemctl status sshd如果用的是云主機(jī)或?qū)嶒炂脚_還要在安全組或防火墻放行 22 端口。這一步看起來基礎(chǔ)但每年都有團(tuán)隊到了演示前才發(fā)現(xiàn)遠(yuǎn)程連不上。接下來是配置 yum 源。openEuler 默認(rèn)會帶官方軟件源但如果你的機(jī)器在同一時間大量安裝依賴或者網(wǎng)絡(luò)環(huán)境特殊建議先確認(rèn)源可用yum repolist如果需要更換為鏡像源或內(nèi)網(wǎng)源先備份原始配置cp /etc/yum.repos.d/openEuler.repo /etc/yum.repos.d/openEuler.repo.bak然后根據(jù)你的 openEuler 版本選擇合適的鏡像源地址。這里不要照抄別人的配置因為不同版本的倉庫路徑可能不一樣。配置完成后執(zhí)行yum clean all yum makecache看到元數(shù)據(jù)緩存完成再繼續(xù)后續(xù)安裝。如果這一步失敗不要急著裝其他軟件先把源修好否則后面會連環(huán)報錯。2.3 在 openEuler 上安裝 Docker 并準(zhǔn)備項目運行環(huán)境Agent Memory 系統(tǒng)一般會依賴 Redis、數(shù)據(jù)庫或向量檢索服務(wù)用手動安裝方式也能跑但 Docker 能把環(huán)境隔離做得更干凈尤其適合比賽現(xiàn)場演示一個docker-compose up就能拉起整套服務(wù)。openEuler 上安裝 Docker可以使用系統(tǒng)軟件源也可以使用 Docker 官方源。以系統(tǒng)源安裝為例yum install -y docker安裝完成后啟動服務(wù)systemctl enable --now docker然后驗證docker info如果沒有報錯說明 Docker 基本可用。但要注意鯤鵬平臺的 Docker 鏡像必須支持linux/arm64架構(gòu)。拉取 Redis 鏡像時可以指定平臺參數(shù)docker pull --platform linux/arm64 redis:7如果網(wǎng)絡(luò)環(huán)境下載很慢可以配置鏡像加速器。但比賽節(jié)點上不要過度依賴公網(wǎng)拉取最好提前把需要的鏡像docker save保存下來現(xiàn)場docker load導(dǎo)入。這是很容易被忽略的細(xì)節(jié)但也是最容易在演示時救命的操作。如果你們的 Agent 邏輯用 Python 寫我還會先裝好編譯工具鏈和虛擬環(huán)境依賴yum install -y gcc gcc-c make python3-devel python3 -m venv venv source venv/bin/activate pip install --upgrade pip為什么要先裝python3-devel因為有些 Python 依賴包在 ARM 架構(gòu)下沒有預(yù)編譯 wheelpip 會嘗試從源碼編譯。沒有編譯工具鏈安裝會直接失敗。提前裝好能少踩很多坑。如果項目里必須使用 conda 管理環(huán)境也要先確認(rèn) conda 是否能安裝在aarch64架構(gòu)上并選擇對應(yīng)版本。同樣如果團(tuán)隊里有人習(xí)慣 Java 1.8 環(huán)境也要先驗證鯤鵬 openEuler 下 JDK 的兼容性。這些都屬于前置準(zhǔn)備越早確認(rèn)越好。3. Agent Memory 系統(tǒng)的核心設(shè)計存儲什么、怎么存、怎么讀3.1 記憶類型的劃分短期會話、長期偏好、事實型知識設(shè)計記憶系統(tǒng)之前首先要區(qū)分記憶的類型。不同類型的記憶留存時間、訪問頻率和一致性要求都不一樣。我見過很多項目把用戶所有歷史都丟進(jìn)一個 JSON 字段里看著簡單但后續(xù)檢索和清理會非常痛苦。比較常用的劃分方式有三種短期會話記憶當(dāng)前一次會話中的上下文。比如上一輪的 query、回復(fù)、臨時狀態(tài)。這種記憶只在會話活躍期有意義過期時間通常設(shè)置為幾十分鐘到幾小時。長期偏好記憶用戶明確的偏好和習(xí)慣。比如“使用中文回答”“報告要簡潔”“我經(jīng)常在晚上使用”。這類記憶需要跨會話保留并且可以由用戶主動修改或刪除。事實型知識記憶從對話中提取出來的客觀信息。比如“用戶所在城市是深圳”“項目截止日期是 6 月 1 日”。這類信息需要準(zhǔn)確、可核對不能隨便被覆蓋。在項目代碼里應(yīng)該用memory_type字段明確標(biāo)記每一條記憶。這樣后續(xù)寫清理策略時就能針對不同類別使用不同的 TTL 和優(yōu)先級而不是一刀切。3.2 存儲選型Redis、關(guān)系型、向量檢索的取舍存儲選型是 Agent Memory 系統(tǒng)里最核心的決策之一。比賽項目不需要追求大而全但要能講清楚為什么選某個存儲。如果你的重點是“記憶管理”也就是存儲、更新、過期、檢索那么 Redis 是一個非常合適的選擇。Redis 的鍵值結(jié)構(gòu)天然適合寫入和讀取高頻記憶TTL 機(jī)制可以方便地處理短期記憶過期。項目演示時用redis-cli直接查看記憶條目的變化也非常直觀。如果記憶數(shù)據(jù)需要復(fù)雜的條件查詢比如按用戶 ID 和時間范圍篩選可以引入關(guān)系型數(shù)據(jù)庫比如 openEuler 上運行 PostgreSQL 或 openGauss。但這會增加部署復(fù)雜度。比賽項目里我更建議以 Redis 為主關(guān)系型作為可選項。如果 Agent 需要做“語義檢索”也就是根據(jù)用戶當(dāng)前的表述找到歷史上含義相近的記憶而不是只做精確匹配那么需要引入向量數(shù)據(jù)庫或向量檢索能力。常見做法是把記憶內(nèi)容用 Embedding 模型轉(zhuǎn)成向量然后用 faiss、Milvus 等工具做相似度檢索。但要注意Embedding 模型參數(shù)量不小在鯤鵬平臺 CPU 環(huán)境下運行耗時不可忽略。如果比賽時間緊張可以先不做向量檢索用關(guān)鍵詞匹配 標(biāo)簽組合檢索來演示效果也足夠。下面是一個簡單的存儲選型對比存儲方案適用場景優(yōu)勢需要關(guān)注的坑Redis短期記憶、偏好記憶、緩存快、支持 TTL、操作簡單內(nèi)存容量有限需要清理策略關(guān)系型數(shù)據(jù)庫事實型知識、審計記錄查詢靈活、事務(wù)可靠部署和建模成本高向量數(shù)據(jù)庫語義檢索、相似記憶召回能處理模糊匹配依賴 Embedding耗時和資源消耗高本地文件極小規(guī)模演示零依賴并發(fā)訪問容易出問題3.3 記憶生命周期寫入、更新、過期、清理策略記憶不能只負(fù)責(zé)寫進(jìn)去還要考慮什么時候失效、什么時候清理。沒有清理機(jī)制系統(tǒng)跑一天內(nèi)存就會漲滿沒有更新機(jī)制用戶改了口徑系統(tǒng)還保留舊記憶就會答非所問。我建議給每條記憶定義這樣幾個字段{ memory_id: uuid, agent_id: agent_01, user_id: user_42, memory_type: preference, content: 用戶喜歡簡潔風(fēng)格, metadata: { source: chat, importance: 0.8 }, created_at: 2026-06-01T10:00:00Z, updated_at: 2026-06-01T10:00:00Z, expire_at: 2026-06-08T10:00:00Z }寫入時要注意冪等。同一用戶同一類型的同一內(nèi)容不應(yīng)該反復(fù)寫入多條。更合理的做法是先查重如果已經(jīng)存在就更新updated_at和content即可。過期策略可以根據(jù)memory_type區(qū)分短期會話記憶TTL 設(shè)為 30 分鐘或 1 小時。長期偏好記憶不設(shè)置過期但允許用戶主動刪除或修改。事實型知識記憶設(shè)置較長 TTL比如 30 天并且可以人工回滾。清理策略建議用定期掃描而非等內(nèi)存爆了再做。在 Redis 中可以用SCAN命令遍歷帶有過期時間的鍵或者依賴 Redis 自身的 TTL 機(jī)制惰性清理。如果整體偏工程化可以寫一個調(diào)度任務(wù)每小時清理一次過期記憶并記錄清理數(shù)量到日志。還要考慮隱私邊界。比賽項目在宣傳時不要承諾“永久保存用戶所有數(shù)據(jù)”而是應(yīng)該在設(shè)計文檔里說明用戶有權(quán)刪除記憶系統(tǒng)不會主動記錄明文密碼、銀行卡號等敏感信息。這一點評委很看重也符合行業(yè)規(guī)范。4. 從零實現(xiàn)一個可演示的 Agent Memory 模塊4.1 工程目錄和最小能跑通的結(jié)構(gòu)一個適合比賽的 Agent Memory 項目不需要一開始就設(shè)計成微服務(wù)架構(gòu)。我建議用單服務(wù) Redis 的方式先把主流程跑通再考慮擴(kuò)展。下面是一個參考目錄agent-memory/ ├── app/ │ ├── __init__.py │ ├── main.py # FastAPI / Flask 入口 │ ├── memory_store.py # 記憶存儲接口 │ ├── agent_service.py # Agent 主邏輯 │ ├── config.py # 配置項 │ └── prompts.py # Prompt 拼接 ├── scripts/ │ ├── reset_demo.sh # 清理數(shù)據(jù)并重啟服務(wù) │ └── test_demo.py # 演示測試腳本 ├── requirements.txt ├── docker-compose.yml └── README.md這個結(jié)構(gòu)的好處是入口、存儲、Agent 邏輯分離即使團(tuán)隊分工也不會互相阻塞。而且演示時可以直接說“這是存儲層這是業(yè)務(wù)層”讓評委看到你的設(shè)計思路。4.2 記憶寫入與檢索接口示例我用 Python Redis 寫一個簡化版存儲接口。代碼不復(fù)雜但足夠演示核心邏輯。import json import uuid from datetime import datetime, timedelta, timezone import redis r redis.Redis(hostlocalhost, port6379, db0, decode_responsesTrue) def memory_key(user_id: str, memory_id: str) - str: return fagent:main:user:{user_id}:memory:{memory_id} def save_memory( user_id: str, memory_type: str, content: str, metadata: dict | None None, ttl_seconds: int | None None, ) - str: memory_id str(uuid.uuid4()) now datetime.now(timezone.utc).isoformat() expire_at None if ttl_seconds: expire_at (datetime.now(timezone.utc) timedelta(secondsttl_seconds)).isoformat() memory_data { memory_id: memory_id, agent_id: main, user_id: user_id, memory_type: memory_type, content: content, metadata: metadata or {}, created_at: now, updated_at: now, expire_at: expire_at, } key memory_key(user_id, memory_id) r.set(key, json.dumps(memory_data, ensure_asciiFalse)) # 維護(hù)一個按用戶區(qū)分的記憶ID列表便于批量獲取 list_key fagent:main:user:{user_id}:memory_ids r.sadd(list_key, memory_id) # 如果設(shè)置了 TTL同時給 key 設(shè)置 Redis 過期時間 if ttl_seconds: r.expire(key, ttl_seconds) return memory_id檢索時可以按用戶拿到全部記憶 ID再讀取內(nèi)容。如果要做簡單的關(guān)鍵詞過濾可以在 Python 層做也可以使用 Redis 的集合和哈希組合。下面是一個按用戶和記憶類型讀取的示例def get_memories(user_id: str, memory_type: str | None None) - list[dict]: list_key fagent:main:user:{user_id}:memory_ids memory_ids r.smembers(list_key) result [] for memory_id in memory_ids: key memory_key(user_id, memory_id) raw r.get(key) if not raw: r.srem(list_key, memory_id) continue data json.loads(raw) if memory_type and data.get(memory_type) ! memory_type: continue result.append(data) # 按創(chuàng)建時間倒序 result.sort(keylambda x: x.get(created_at, ), reverseTrue) return result這段代碼里有兩個細(xì)節(jié)值得注意一是存儲時用ensure_asciiFalse保證中文內(nèi)容在 Redis 里可讀二是讀取時如果 key 已經(jīng)不存在就從集合里移除。這個“惰性清理”能在演示時避免臟數(shù)據(jù)殘留。4.3 把記憶接入 Agent 對話流程有了存儲接口下一步就是接進(jìn) Agent 對話流程。最簡單的接法是用戶輸入前先取出歷史記憶拼入系統(tǒng) Prompt。def build_agent_prompt(user_id: str, user_input: str) - str: memories get_memories(user_id) memory_context \n.join( f[{m[memory_type]}] {m[content]} for m in memories ) system_prompt f 你是基于鯤鵬平臺運行的 Agent 助手。 以下是用戶的長期記憶回答時請合理參考 {memory_context} 當(dāng)前用戶輸入{user_input} return system_prompt這里沒有強(qiáng)制要求 Agent 一定要用某一個大模型。比賽項目里可以用云端 API也可以本地部署一個較小的開源模型。但要注意如果現(xiàn)場網(wǎng)絡(luò)不穩(wěn)定模型調(diào)用會失敗。更穩(wěn)妥的方式是提供一個“演示模式”在模型不可用時用規(guī)則匹配返回預(yù)設(shè)答案保證記憶模塊本身可以被獨立驗證。對話主流程可以這樣設(shè)計用戶輸入。調(diào)用get_memories獲取相關(guān)記憶。拼到 Prompt 中。調(diào)用大模型獲得回復(fù)?;貜?fù)結(jié)束后從對話中提取新的記憶調(diào)用save_memory保存。返回回復(fù)給用戶。記憶提取這一步最簡單的方法是規(guī)則提取比如識別“我喜歡 XXX”“我不喜歡 XXX”“我在 XXX”這樣的句式。如果要做得更智能可以額外調(diào)用一次大模型做信息抽取但會增加延遲。比賽演示時規(guī)則提取已經(jīng)足夠。5. 在鯤鵬環(huán)境里做驗證性能、并發(fā)和穩(wěn)定性怎么判斷5.1 功能驗證一條消息記住上下文功能驗證的目標(biāo)是回答一個問題Agent 到底有沒有真的記住。我建議寫一個自動化演示腳本流程如下第1輪用戶輸入 我喜歡極簡風(fēng)格 第2輪用戶輸入 以后生成的報表都用什么風(fēng)格 預(yù)期Agent 回答包含 極簡風(fēng)格這個測試看起來很基礎(chǔ)但非常關(guān)鍵。它能同時驗證記憶寫入、記憶讀取、Prompt 拼接和 Agent 回復(fù)四個環(huán)節(jié)是否正常。如果第 2 輪沒有命中記憶說明問題可能出在寫入、讀取或排序任一環(huán)節(jié)需要用日志和 Redis 里的實際數(shù)據(jù)進(jìn)一步定位。除了正確性還要驗證“記憶更新”是否生效。比如第 1 輪說“我喜歡極簡風(fēng)格”第 2 輪說“我現(xiàn)在更喜歡商務(wù)風(fēng)格”第 3 輪問“報表風(fēng)格”應(yīng)該返回“商務(wù)風(fēng)格”。如果系統(tǒng)返回舊記憶說明更新邏輯有問題。5.2 性能驗證吞吐、延遲、資源占用比賽答辯時評委很可能會問“你們的記憶系統(tǒng)性能怎么樣”這時候如果沒有數(shù)據(jù)回答就會很空。我建議至少測三個指標(biāo)延遲從發(fā)起請求到返回結(jié)果統(tǒng)計 P50、P95、P99 延遲。吞吐單位時間內(nèi)能處理多少次記憶寫入或讀取。資源占用Redis 內(nèi)存、Python 進(jìn)程 CPU、系統(tǒng)內(nèi)存等??梢詫懸粋€簡單的并發(fā)壓測腳本用協(xié)程模擬多個用戶同時寫入記憶。注意不要一上來就開 1000 并發(fā)先跑 10、50、100 個用戶觀察延遲變化。一個常見的結(jié)果是并發(fā)數(shù)較低時延遲穩(wěn)定并發(fā)數(shù)升高后P99 延遲快速上升這時候要檢查 Redis 連接池、Python GIL 和機(jī)器核數(shù)。在鯤鵬平臺上的一個優(yōu)勢是核心數(shù)通常較多適合并發(fā)任務(wù)。你可以嘗試把并發(fā)數(shù)設(shè)置為 CPU 核數(shù)的 2 到 4 倍觀察資源利用情況。如果 CPU 沒有跑滿但延遲已經(jīng)很高問題往往不在硬件而在代碼里的串行等待。5.3 穩(wěn)定性驗證批量任務(wù)和長時間運行性能好的系統(tǒng)不一定穩(wěn)定。比賽項目至少要跑一次長時間穩(wěn)定性測試比如連續(xù)運行 2 小時不斷寫入臨時記憶然后觀察 Redis 內(nèi)存是否持續(xù)增長、是否出現(xiàn)連接超時、短期記憶是否按 TTL 過期。批量任務(wù)還要看失敗重試和輸出一致性。寫入 10000 條記憶中間有網(wǎng)絡(luò)抖動Redis 連接斷開系統(tǒng)能不能恢復(fù)建議在代碼里給 Redis 操作加簡單的重試機(jī)制def save_with_retry(user_id, memory_type, content, retries3): for i in range(retries): try: return save_memory(user_id, memory_type, content) except redis.exceptions.ConnectionError: print(fRedis connection error, retry {i 1}) time.sleep(0.5) raise RuntimeError(save memory failed after retries)如果是在鯤鵬平臺演示 Docker 服務(wù)穩(wěn)定性測試還可以包含“重啟 Docker 容器后數(shù)據(jù)是否還在”。這取決于 Redis 是否開啟了持久化。如果使用默認(rèn)配置容器重啟可能丟失內(nèi)存數(shù)據(jù)。比賽演示前最好確認(rèn) Redis 持久化策略或者演示腳本里明確“這是一個可重置的示例環(huán)境”避免評委誤以為數(shù)據(jù)永久丟失。6. 參賽落地最容易踩的坑和對應(yīng)排查順序6.1 環(huán)境坑版本、架構(gòu)、依賴編譯很多團(tuán)隊剛開始在本地 x86 上一切正常一到鯤鵬服務(wù)器就報錯。最常見的問題有uname -m顯示 aarch64但 pip 嘗試安裝 x86 的 wheel。openEuler 默認(rèn) Python 版本和本地不同某些依賴沒有 ARM 編譯產(chǎn)物。Docker 鏡像沒有 arm64 版本拉下來后啟動失敗。編譯 C 擴(kuò)展時報缺少頭文件本質(zhì)是沒裝python3-devel和 gcc。遇到這類問題不要急著改代碼。先按這個順序排查1. 確認(rèn)系統(tǒng)架構(gòu)uname -m 2. 確認(rèn) openEuler 版本cat /etc/openEuler-release 3. 確認(rèn) Python 版本python3 --version 4. 確認(rèn)是否安裝了編譯工具鏈gcc --version 5. 確認(rèn) Redis 是否正常運行redis-cli ping 6. 確認(rèn) Docker 鏡像平臺docker inspect image | grep Architecture只要環(huán)境沒問題很多“代碼報錯”其實不會發(fā)生。6.2 數(shù)據(jù)坑序列化、過期、臟數(shù)據(jù)記憶系統(tǒng)最容易出的數(shù)據(jù)問題有三個第一個是序列化混亂。Python 里存的是 dict取出來如果是字符串沒有做json.loads后續(xù)訪問字段就會報錯。排查時直接在 Redis 里查看 key 對應(yīng)的值確認(rèn)保存的格式。第二個是過期時間設(shè)錯。有些短期記憶本來應(yīng)該幾十秒后過期結(jié)果忘了設(shè)置ttl_seconds導(dǎo)致 Redis 內(nèi)存一直上漲。排查時可以執(zhí)行redis-cli info memory看到used_memory持續(xù)上漲優(yōu)先檢查有沒有大量沒有 TTL 的 key。第三個是臟數(shù)據(jù)殘留。用戶刪除了某條記憶但記憶 ID 列表里還保留著 ID。所以讀取時要像 4.2 節(jié)那樣做一次“key 不存在就從集合里移除”的清理。否則列表越來越大最終影響性能。6.3 演示坑日志、可觀測性、恢復(fù)演示比賽演示不像平時開發(fā)現(xiàn)場壓力下大概率會出現(xiàn)意外。最怕的不是報錯而是報錯后不知道發(fā)生了什么。所以我建議從第一天就重視日志。日志至少要包含這些信息每次記憶寫入的關(guān)鍵字段用戶 ID、記憶類型、TTL。每次記憶讀取命中的條數(shù)和內(nèi)容摘要。Redis 連接異常時的堆棧。模型調(diào)用失敗時的降級方案。可以在入口處打印簡化日志print(f[MEMORY] save user{user_id} type{memory_type} content{content}) print(f[MEMORY] get user{user_id} hit{len(memories)})演示腳本要準(zhǔn)備一個reset_demo.sh一鍵清理數(shù)據(jù)、重啟 Redis、啟動服務(wù)。這樣如果現(xiàn)場數(shù)據(jù)被改亂可以快速恢復(fù)#!/bin/bash echo Stopping services... docker-compose down echo Cleaning data... rm -rf ./data echo Starting services... docker-compose up -d echo Waiting for Redis... sleep 3 echo Demo environment reset done.最后一點大模型調(diào)用必須有降級方案。比賽現(xiàn)場如果公網(wǎng)模型 API 超時不要卡在那里??梢杂谩半x線模式”返回基于記憶的規(guī)則回答讓評委看到記憶系統(tǒng)本身是工作的只是模型服務(wù)臨時不可用。這個細(xì)節(jié)做得好會給評委留下工程準(zhǔn)備充分的印象。踩過幾次之后我發(fā)現(xiàn)這類賽題真正拉開差距的不是誰用了更炫的模型而是誰能把環(huán)境、數(shù)據(jù)、驗證這三件事處理得更干凈。用鯤鵬平臺的時候很多問題其實不是代碼邏輯而是系統(tǒng)的版本和依賴沒有對齊。如果你們團(tuán)隊準(zhǔn)備報名我建議第一天就把 openEuler 環(huán)境裝好把最小的“寫入-讀取-清理”流程跑通再往里面加 Agent 對話和大模型能力。