當AI 智能體(Agent)在多輪對話或執行連續任務時,往往因為缺乏對歷史資訊的有效記憶而無法記住使用者的偏好、歷史指令或上下文,導致互動體驗中斷、任務執行效率低下。PolarSearch記憶容器(Memory Container)專為解決此問題而設計。它為AI智能體提供了一個內建於PolarDB PostgreSQL版的長短期記憶管理系統。通過該功能,智能體能夠自動地將對話資訊結構化、持久化,並能在後續互動中通過語義檢索快速調用相關記憶,從而為使用者提供真正連續、個人化且高效的服務。
PolarSearch記憶容器功能目前處於灰階階段。若您有相關需求,請提交工單聯絡我們為您處理。
工作原理
PolarSearch記憶容器通過一套自動化的處理流程,將非結構化的對話資料轉化為可檢索、可利用的結構化記憶。其核心在於三級儲存架構和智能化的記憶處理流程。
三級儲存架構
為了平衡不同時效性記憶的儲存和檢索效率,記憶容器採用了分層設計:
記憶類型 | 索引類型 | 核心作用 |
短期記憶 (Working Memory) | 倒排索引 | 儲存原始的、未經處理的短期會話資訊,使用倒排索引進行快速檢索,主要用於維持目前的交談的上下文。 |
長期記憶 (Long-Term Memory) | 向量索引+倒排索引 | 通過大語言模型(LLM)從對話中提取關鍵事實(Facts),並將其向量化後儲存。這部分記憶支援KNN語義搜尋,用於深層次的經驗和知識檢索。 |
記憶歷史 (Memory History) | 倒排索引 | 記錄每一次記憶操作(如新增、修改),形成完整的審計日誌,確保記憶的演變過程可追溯。 |
記憶處理流程
當智能體接收到新的資訊時,記憶容器會觸發一系列處理動作,實現記憶的自動攝取、持久化和檢索。
記憶攝取:
輸入與預先處理:使用Elasticsearch協議接收來自智能體的對話輸入,並可調用大語言模型(LLM)進行摘要產生、意圖分類或標籤提取等預先處理。
路由決策:記憶路由(Memory Router)分析輸入內容,並與現有記憶進行比對,決策是新增(ADD)、更新(UPDATE)還是刪除(DELETE)一條記憶。
記憶持久化:
短期記憶:原始對話內容存入短期記憶。
長期記憶:由LLM抽取的結構化記憶事實,經過Embedding模型向量化後,存入長期記憶。
記憶歷史:所有操作記錄寫入記憶歷史,形成審計軌跡。
記憶檢索:
輸入解析:接收檢索條件,通過Elasticsearch協議解析多模態檢索請求,調用許可權驗證模組確認資料訪問邊界。
混合索引檢索:在長期記憶中執行混合檢索(ANN向量相似性搜尋和倒排索引過濾),並在短期記憶中進行關鍵詞匹配。同時根據記憶時間戳記進行權重調整。
結果整合:重排模型(Reranker)對檢索結果進行最佳化排序,並根據時間戳記等資訊消除衝突,最終將最相關的記憶返回給智能體。
功能優勢
能力維度 | 傳統方案 | PolarSearch解決方案 |
記憶利用率 | 歷史資料沉澱低於30%,難以有效利用。 | 通過LLM抽取事實,結合語義索引,將有效資訊利用率提升至85%以上。 |
檢索效率 | 依賴關鍵詞匹配,準確率≤60%。 | 採用向量與倒排混合索引,並進行重排序(Rerank),語義檢索準確率可達95%以上。 |
企業合規 | 多租戶隔離和許可權管控實現複雜。 | 原生支援多租戶隔離、RBAC許可權控制和Action Trail,滿足企業級安全要求。 |
系統擴充性 | 單點儲存容量上限TB級。 | 雲端式原生分布式儲存架構,儲存容量可擴充至PB級。 |
開發成本 | 功能需定製開發,周期長。 | 提供開箱即用的API和SDK,簡化開發流程,協助您快速整合。 |
適用範圍
功能節點:為您的叢集添加PolarSearch搜尋節點。
帳號許可權:建立建立搜尋節點管理員帳號,用於執行外掛程式啟用和資源建立等操作。
快速開始
本指南將引導您完成從環境準備到成功存入並檢索一條記憶的全過程。
整體流程:準備環境 -> 啟用外掛程式 -> 註冊模型 -> 建立記憶容器 -> 存入與驗證記憶。
步驟一:配置訪問憑證與環境變數
在開始操作前,請先準備好以下資訊,並設定為環境變數。這將有效簡化後續的curl命令,避免重複修改。統一管理所有配置和憑證,方便後續命令的複製和執行。
變數名 | 含義 | 樣本值 |
| PolarSearch節點的串連地址與連接埠。 |
|
| PolarSearch節點的管理員帳號。 |
|
| 阿里雲大模型服務平台百鍊的API Key。 |
|
操作步驟: 在您的終端中執行以下命令,將樣本值替換為您的真實資訊。
# 設定 PolarSearch 訪問地址和連接埠
export POLARSEARCH_HOST_PORT="pc-xxx.polardbsearch.rds.aliyuncs.com:3001"
# 設定 PolarSearch 管理員密碼
export USER_PASSWORD="polarsearch_user:your_assword"
# 設定您的千問 API Key
export YOUR_API_KEY="sk-xxxxxxxxxxxxxxxxxxxxxxxx"步驟二:啟用記憶容器外掛程式
執行以下命令,在PolarDB叢集中啟用記憶容器功能。
命令列
curl -XPUT "http://${POLARSEARCH_HOST_PORT}/_cluster/settings" \
--user "${USER_PASSWORD}" \
-H 'Content-Type: application/json' \
-d '{
"persistent": {
"plugins.ml_commons.agentic_memory_enabled": true
}
}'Dashboard
PUT _cluster/settings
{
"persistent": {
"plugins.ml_commons.agentic_memory_enabled": true
}
}步驟三:註冊模型
您需要向PolarSearch註冊一個用於事實抽取的LLM和一個用於語義化的Embedding模型。
註冊文本向量化模型(Embedding)
建立一個連接器(Connector)指向阿里雲大模型服務平台百鍊的Embedding模型服務,並將其註冊為PolarSearch可調用的模型。
設定可信端點:將模型的API Endpoint添加到可信列表,允許PolarSearch調用。
命令列
curl -XPUT "http://${POLARSEARCH_HOST_PORT}/_cluster/settings" \ --user "${USER_PASSWORD}" \ -H 'Content-Type: application/json' \ -d '{ "persistent": { "plugins.ml_commons.trusted_connector_endpoints_regex": [ "^https://dashscope.aliyuncs.com/compatible-mode/v1/.*$" ] } }'Dashboard
PUT _cluster/settings { "persistent": { "plugins.ml_commons.trusted_connector_endpoints_regex": [ "^https://dashscope.aliyuncs.com/compatible-mode/v1/.*$" ] } }建立模型連接器:配置串連
text-embedding-v4模型的參數。說明pre_process_function和post_process_function用於適配不同模型服務的請求和響應格式。此處使用內建的openai.embedding格式轉換函式,因為它與阿里雲大模型服務平台百鍊相容模式的格式一致。命令列
curl -XPOST "http://${POLARSEARCH_HOST_PORT}/_plugins/_ml/connectors/_create" \ --user "${USER_PASSWORD}" \ -H 'Content-Type: application/json' \ -d '{ "name": "qwen embedding connector", "description": "The connector to qwen embedding model", "version": 1, "protocol": "http", "parameters": { "model": "text-embedding-v4", "endpoint": "dashscope.aliyuncs.com/compatible-mode" }, "credential": { "api_key": "${YOUR_API_KEY}" }, "actions": [ { "action_type": "predict", "method": "POST", "headers": { "Authorization": "Bearer ${credential.api_key}", "content-type": "application/json" }, "url": "https://${parameters.endpoint}/v1/embeddings", "request_body": "{ \"model\": \"${parameters.model}\", \"input\": ${parameters.input} }", "pre_process_function": "connector.pre_process.openai.embedding", "post_process_function":"connector.post_process.openai.embedding" } ] }'Dashboard
重要請替換以下命令中的
<YOUR_API_KEY>為您真實的阿里雲大模型服務平台百鍊的API Key。POST _plugins/_ml/connectors/_create { "name": "qwen embedding connector", "description": "The connector to qwen embedding model", "version": 1, "protocol": "http", "parameters": { "model": "text-embedding-v4", "endpoint": "dashscope.aliyuncs.com/compatible-mode" }, "credential": { "api_key": "<YOUR_API_KEY>" }, "actions": [ { "action_type": "predict", "method": "POST", "headers": { "Authorization": "Bearer ${credential.api_key}", "content-type": "application/json" }, "url": "https://${parameters.endpoint}/v1/embeddings", "request_body": "{ \"model\": \"${parameters.model}\", \"input\": ${parameters.input} }", "pre_process_function": "connector.pre_process.openai.embedding", "post_process_function":"connector.post_process.openai.embedding" } ] }執行成功後,系統會返回一個
connector_id。請記錄該ID,後續步驟將使用。{"connector_id": "LBFt6ZsBk04xxx"}註冊模型:此步驟將上一步建立的Connector註冊為一個模型。
命令列
curl -XPOST "http://${POLARSEARCH_HOST_PORT}/_plugins/_ml/models/_register" \ --user "${USER_PASSWORD}" \ -H 'Content-Type: application/json' \ -d '{ "name": "qwen embedding model", "function_name": "remote", "description": "Embedding model for memory", "connector_id": "LBFt6Zsxxx" }'Dashboard
POST _plugins/_ml/models/_register { "name": "qwen embedding model", "function_name": "remote", "description": "Embedding model for memory", "connector_id": "LBFt6ZsBk04xxx" }執行成功後,系統會返回一個
model_id。請記錄該 ID,後續步驟將使用。# 記錄返回的 model_id {"task_id": "LRFx6ZsBk04ixxx","status": "CREATED","model_id": "LhFx6ZsBk04xxx"}測試模型:通過下述查詢可以直接與大模型對話並查看大模型返回結果。
命令列
curl -XPOST "http://${POLARSEARCH_HOST_PORT}/_plugins/_ml/_predict/text_embedding/<上一步擷取的模型ID>" \ --user "${USER_PASSWORD}" \ -H 'Content-Type: application/json' \ -d'{ "text_docs":[ "Bob likes swimming. Context: He expressed his interest in swimming."], "return_number": true, "target_response": ["sentence_embedding"] }'Dashboard
POST _plugins/_ml/_predict/text_embedding/<上一步擷取的模型ID> { "text_docs":[ "Bob likes swimming. Context: He expressed his interest in swimming."], "return_number": true, "target_response": ["sentence_embedding"] }預期返回結果如下:
{ "inference_results": [ { "output": [ { "name": "sentence_embedding", "data_type": "FLOAT32", "shape": [ 1024 ], "data": [ 0.019752666354179382, -0.03468115255236626, 0.05591931194067001, ... ] } ], "status_code": 200 } ] }
註冊文本產生模型(LLM)
建立並註冊一個串連到阿里雲大模型服務平台百鍊qwen-plus大模型的連接器。
建立模型連接器(Connector):
命令列
curl -XPOST "http://${POLARSEARCH_HOST_PORT}/_plugins/_ml/connectors/_create" \ --user "${USER_PASSWORD}" \ -H 'Content-Type: application/json' \ -d '{ "name": "QWen LLM Connector", "description": "The connector to qwen LLM", "version": 1, "protocol": "http", "parameters": { "model": "qwen-plus", "endpoint": "dashscope.aliyuncs.com/compatible-mode" }, "credential": { "api_key": "${YOUR_API_KEY}" }, "actions": [ { "action_type": "predict", "method": "POST", "headers": { "Authorization": "Bearer ${credential.api_key}", "content-type": "application/json" }, "url": "https://${parameters.endpoint}/v1/chat/completions", "request_body": "{ \"model\":\"${parameters.model}\", \"system\": \"${parameters.system_prompt}\", \"messages\": [ { \"role\": \"system\", \"content\": \"${parameters.system_prompt}\" }, { \"role\": \"user\", \"content\": \"${parameters.user_prompt}\" } ], \"response_format\": { \"type\": \"json_object\" } }" } ] }'Dashboard
重要請替換以下命令中的
<YOUR_API_KEY>為您真實的阿里雲大模型服務平台百鍊的API Key。POST /_plugins/_ml/connectors/_create { "name": "QWen LLM Connector", "description": "The connector to qwen LLM", "version": 1, "protocol": "http", "parameters": { "model": "qwen-plus", "endpoint": "dashscope.aliyuncs.com/compatible-mode" }, "credential": { "api_key": "<YOUR_API_KEY>" }, "actions": [ { "action_type": "predict", "method": "POST", "headers": { "Authorization": "Bearer ${credential.api_key}", "content-type": "application/json" }, "url": "https://${parameters.endpoint}/v1/chat/completions", "request_body": "{ \"model\":\"${parameters.model}\", \"system\": \"${parameters.system_prompt}\", \"messages\": [ { \"role\": \"system\", \"content\": \"${parameters.system_prompt}\" }, { \"role\": \"user\", \"content\": \"${parameters.user_prompt}\" } ], \"response_format\": { \"type\": \"json_object\" } }" } ] }執行成功後,系統會返回一個
connector_id。請記錄該ID,後續步驟將使用。{"connector_id": "PRGy6ZsBk04xxx"}註冊模型:此步驟將上一步建立的Connector註冊為一個模型。
命令列
curl -XPOST "http://${POLARSEARCH_HOST_PORT}/_plugins/_ml/models/_register" \ --user "${USER_PASSWORD}" \ -H 'Content-Type: application/json' \ -d '{ "name": "qwen llm model", "function_name": "remote", "description": "LLM model for memory", "connector_id": "PRGy6ZsBk04xxx" }'Dashboard
POST _plugins/_ml/models/_register { "name": "qwen llm model", "function_name": "remote", "description": "LLM model for memory", "connector_id": "PRGy6ZsBk04xxx" }執行成功後,系統會返回一個
model_id。請記錄該 ID,後續步驟將使用。# 記錄返回的 model_id {"task_id": "PhGy6ZsBk04xxx","status": "CREATED","model_id": "PxGy6ZsBk04xxx"}發布模型:
命令列
curl -XPOST "http://${POLARSEARCH_HOST_PORT}/_plugins/_ml/models/<上一步擷取的模型ID>/_deploy" \ --user "${USER_PASSWORD}"Dashboard
POST _plugins/_ml/models/<上一步擷取的模型ID>/_deploy執行成功後,如果
status為COMPLETED代表已部署成功。{"task_id": "NxGI6ZsBk04xxx","task_type": "DEPLOY_MODEL","status": "COMPLETED"}測試模型:通過下述查詢可以直接與大模型對話並查看大模型返回結果。
命令列
curl -XPOST "http://${POLARSEARCH_HOST_PORT}/_plugins/_ml/models/<上一步擷取的模型ID>/_predict" \ --user "${USER_PASSWORD}" \ -H 'Content-Type: application/json' \ -d'{ "parameters": { "system_prompt": "<ROLE>You are a USER PREFERENCE EXTRACTOR, not a chat assistant. Your only job is to output JSON facts. Do not answer questions, make suggestions, ask follow-ups, or perform actions.</ROLE>\n\n<SCOPE>\n• Extract preferences only from USER messages. Assistant messages are context only.\n• Explicit: user states a preference (\"I prefer/like/dislike ...\"; \"always/never/usually ...\"; \"set X to Y\"; \"run X when Y\").\n• Implicit: infer only with strong signals: repeated choices (>=2) or clear habitual language. Do not infer from a single one-off.\n</SCOPE>\n\n<EXTRACT>\n• Specific, actionable, likely long-term preferences (likes/dislikes/choices/settings). Ignore non-preferences.\n</EXTRACT>\n\n<STYLE & RULES>\n• One sentence per preference; merge related details; no duplicates; preserve user wording and numbers; avoid relative time; keep each fact < 350 chars.\n• Format: \"Preference sentence. Context: <why/how>. Categories: cat1,cat2\"\n</STYLE & RULES>\n\n<OUTPUT>\nReturn ONLY one minified JSON object exactly as {\"facts\":[\"Preference sentence. Context: <why/how>. Categories: cat1,cat2\"]}. If none, return {\"facts\":[]}. The first character MUST be '{' and the last MUST be '}'. No preambles, explanations, code fences, XML, or other text.\n</OUTPUT>", "user_prompt": "I am Alice, I like travel." } }'Dashboard
POST _plugins/_ml/models/<上一步擷取的模型ID>/_predict { "parameters": { "system_prompt": "<ROLE>You are a USER PREFERENCE EXTRACTOR, not a chat assistant. Your only job is to output JSON facts. Do not answer questions, make suggestions, ask follow-ups, or perform actions.</ROLE>\n\n<SCOPE>\n• Extract preferences only from USER messages. Assistant messages are context only.\n• Explicit: user states a preference (\"I prefer/like/dislike ...\"; \"always/never/usually ...\"; \"set X to Y\"; \"run X when Y\").\n• Implicit: infer only with strong signals: repeated choices (>=2) or clear habitual language. Do not infer from a single one-off.\n</SCOPE>\n\n<EXTRACT>\n• Specific, actionable, likely long-term preferences (likes/dislikes/choices/settings). Ignore non-preferences.\n</EXTRACT>\n\n<STYLE & RULES>\n• One sentence per preference; merge related details; no duplicates; preserve user wording and numbers; avoid relative time; keep each fact < 350 chars.\n• Format: \"Preference sentence. Context: <why/how>. Categories: cat1,cat2\"\n</STYLE & RULES>\n\n<OUTPUT>\nReturn ONLY one minified JSON object exactly as {\"facts\":[\"Preference sentence. Context: <why/how>. Categories: cat1,cat2\"]}. If none, return {\"facts\":[]}. The first character MUST be '{' and the last MUST be '}'. No preambles, explanations, code fences, XML, or other text.\n</OUTPUT>", "user_prompt": "I am Alice, I like travel." } }預期返回結果如下:
{ "inference_results": [ { "output": [ { "name": "response", "dataAsMap": { "choices": [ { "message": { "role": "assistant", "content": """{"facts":["I like travel. Context: Stated preference. Categories: interest"]}""" }, "finish_reason": "stop", "index": 0, "logprobs": null } ], "object": "chat.completion", "usage": { "prompt_tokens": 325, "completion_tokens": 17, "total_tokens": 342, "prompt_tokens_details": { "cached_tokens": 0 } }, "created": 1769152651, "system_fingerprint": null, "model": "qwen-plus", "id": "chatcmpl-50c6bfc9-xxx-xxx-xxx-1a39cfe080f5" } } ], "status_code": 200 } ] }
步驟四:建立記憶容器
建立一個記憶容器執行個體,並配置其使用的模型、儲存策略和自動化行為。執行以下命令建立一個名為
agentic memory test的記憶容器。命令列
curl -XPOST "http://${POLARSEARCH_HOST_PORT}/_plugins/_ml/memory_containers/_create" \ --user "${USER_PASSWORD}" \ -H 'Content-Type: application/json' \ -d'{ "name": "my agentic memory test", "description": "Store conversations with semantic search and summarization", "configuration": { "embedding_model_type": "TEXT_EMBEDDING", "embedding_model_id": "<上一步擷取的Embedding模型ID>", "embedding_dimension": 1024, "llm_id": "<上一步擷取的LLM模型ID>", "index_prefix": "mem_test", "index_settings": { "short_term_memory_index": { "index": { "number_of_shards": "2", "number_of_replicas": "2" } }, "long_term_memory_index": { "index": { "number_of_shards": "2", "number_of_replicas": "2" } }, "long_term_memory_history_index": { "index": { "number_of_shards": "2", "number_of_replicas": "2" } } }, "strategies": [ { "type": "SEMANTIC", "namespace": ["user_id"], "configuration": { "llm_result_path": "$.choices[0].message.content" } }, { "type": "USER_PREFERENCE", "namespace": ["user_id"], "configuration": { "llm_result_path": "$.choices[0].message.content" } }, { "type": "SUMMARY", "namespace": ["agent_id"], "configuration": { "llm_result_path": "$.choices[0].message.content" } } ], "parameters": { "llm_result_path": "$.choices[0].message.content" } } }'Dashboard
POST _plugins/_ml/memory_containers/_create { "name": "my agentic memory test", "description": "Store conversations with semantic search and summarization", "configuration": { "embedding_model_type": "TEXT_EMBEDDING", "embedding_model_id": "<上一步擷取的Embedding模型ID>", "embedding_dimension": 1024, "llm_id": "<上一步擷取的LLM模型ID>", "index_prefix": "mem_test", "index_settings": { "short_term_memory_index": { "index": { "number_of_shards": "2", "number_of_replicas": "2" } }, "long_term_memory_index": { "index": { "number_of_shards": "2", "number_of_replicas": "2" } }, "long_term_memory_history_index": { "index": { "number_of_shards": "2", "number_of_replicas": "2" } } }, "strategies": [ { "type": "SEMANTIC", "namespace": ["user_id"], "configuration": { "llm_result_path": "$.choices[0].message.content" } }, { "type": "USER_PREFERENCE", "namespace": ["user_id"], "configuration": { "llm_result_path": "$.choices[0].message.content" } }, { "type": "SUMMARY", "namespace": ["agent_id"], "configuration": { "llm_result_path": "$.choices[0].message.content" } } ], "parameters": { "llm_result_path": "$.choices[0].message.content" } } }參數說明
index_prefix:為該容器建立的內部索引(如短期、長期記憶索引)的統一首碼。index_settings:可為不同記憶索引配置分區(shards)和副本(replicas)數量,以實現高可用。strategies:定義自動化策略。本例中定義了一個SEMANTIC策略,它會在user_id這個命名空間 (Namespace) 下,自動從對話中提取語義事實。llm_result_path:使用JSONPath文法,指定如何從LLM返回的JSON響應中提取核心內容。$.choices[0].message.content適配了阿里雲大模型服務平台百鍊相容模式的響應結構。
執行成功後,系統會返回一個
memory_container_id。請記錄該 ID,後續步驟將使用。# 記錄返回的 model_id {"memory_container_id": "QRHF6ZsBk04xxx","status": "created"}建立記憶容器後,實際將建立以下索引和管道(pipeline):
.plugins-ml-am-mem_test-memory-long-term .plugins-ml-am-mem_test-memory-working .plugins-ml-am-mem_test-memory-history .plugins-ml-am-mem_test-memory-long-term-embedding" : { "description" : "Agentic Memory Text embedding pipeline", "processors" : [ { "text_embedding" : { "model_id" : "QRHF6ZsBk04xxx", "field_map" : { "memory" : "memory_embedding" } } } ] }
步驟五:存入與驗證記憶
向記憶容器中添加一段對話,並驗證其是否被正確地存入短期和長期記憶中。
存入記憶: 向容器中POST一段關於使用者Bob的對話。
"infer": true參數會觸發之前配置的SEMANTIC策略,調用LLM提取事實。命令列
curl -XPOST "http://${POLARSEARCH_HOST_PORT}/_plugins/_ml/memory_containers/<上一步建立的記憶容器ID>/memories" \ --user "${USER_PASSWORD}" \ -H 'Content-Type: application/json' \ -d'{ "messages": [ { "role": "user", "content": [ { "text": "I am Bob, I really like swimming.", "type": "text" } ] }, { "role": "assistant", "content": [ { "text": "Cool, nice. Hope you enjoy your life.", "type": "text" } ] } ], "namespace": { "user_id": "bob" }, "tags": { "topic": "personal info" }, "infer": true, "memory_type": "conversation" }'Dashboard
POST _plugins/_ml/memory_containers/<memory_container_id>/memories { "messages": [ { "role": "user", "content": [ { "text": "I am Bob, I really like swimming.", "type": "text" } ] }, { "role": "assistant", "content": [ { "text": "Cool, nice. Hope you enjoy your life.", "type": "text" } ] } ], "namespace": { "user_id": "bob" }, "tags": { "topic": "personal info" }, "infer": true, "memory_type": "conversation" }驗證短期記憶: 直接查詢為短期記憶建立的索引,可以看到原始對話被完整儲存。
命令列
curl -XGET "http://${POLARSEARCH_HOST_PORT}/.plugins-ml-am-<上一步建立的記憶容器index_prefix>-memory-working/_search?pretty" \ --user "${USER_PASSWORD}" \Dashboard
GET .plugins-ml-am-<上一步建立的記憶容器index_prefix>-memory-working/_search?pretty預期輸出(部分展示):
{ "_source" : { "memory_container_id": "QRHF6ZsBk04xxx", "payload_type" : "conversational", "messages" : [ { "role" : "user", "content": [{ "text": "I am Bob, I really like swimming.","type": "text"}] }, { "role" : "assistant", "content": [{ "text": "Cool, nice. Hope you enjoy your life.","type": "text"}] } ], "namespace" : { "user_id" : "bob" } } }驗證長期記憶: 查詢長期記憶索引,可以看到LLM成功提取了核心事實“Bob likes swimming”,並由Embedding模型產生了對應的向量
memory_embedding。命令列
curl -XGET "http://${POLARSEARCH_HOST_PORT}/.plugins-ml-am-<上一步建立的記憶容器index_prefix>-memory-long-term/_search?pretty" \ --user "${USER_PASSWORD}" \Dashboard
GET .plugins-ml-am-<上一步建立的記憶容器index_prefix>-memory-long-term/_search?pretty預期輸出(部分展示):
{ "_source" : { "created_time": 1769155210918, "memory": "Bob likes swimming.", "memory_container_id": "QRHF6ZsBk04xxx", "tags": { "topic": "personal info" }, "last_updated_time": 1769155210918, "memory_embedding" : [ 0.0195..., -0.0387..., ... ], "namespace" : { "user_id" : "bob" } } }查看記錄歷史,
memory-history索引中有兩條ADD記錄和對應的記憶時間戳記。命令列
curl -XGET "http://${POLARSEARCH_HOST_PORT}/.plugins-ml-am-<上一步建立的記憶容器index_prefix>-memory-history/_search?pretty" \ --user "${USER_PASSWORD}" \Dashboard
GET .plugins-ml-am-<上一步建立的記憶容器index_prefix>-memory-history/_search?pretty預期輸出(部分展示):
{ "_source": { "created_time": 1769155211164, "memory_id": "TBHe6ZsBk04xxx", "namespace_size": 1, "namespace": { "user_id": "bob" }, "action": "ADD", "memory_container_id": "QRHF6ZsBk04xxx", "after": { "memory": "Bob likes swimming." }, "tags": { "topic": "personal info" } } }
至此,您已成功為AI智能體存入了一條可供長期檢索的記憶。
步驟六:(可選)更新記憶
記憶容器能夠提取和更新長期記憶。
首先插入一段記憶:
命令列
curl -XPOST "http://${POLARSEARCH_HOST_PORT}/_plugins/_ml/memory_containers/<上一步建立的記憶容器ID>/memories" \ --user "${USER_PASSWORD}" \ -H 'Content-Type: application/json' \ -d'{ "messages": [ { "role": "user", "content": [ { "text": "我叫NameA,我來自AreaA,目前我居住在AreaB.", "type": "text" } ] }, { "role": "assistant", "content": [ { "text": "你好,NameA!很高興認識你.", "type": "text" } ] } ], "namespace": { "user_id": "NameA" }, "tags": { "topic": "personal info" }, "infer": true, "memory_type": "conversation" }'Dashboard
POST _plugins/_ml/memory_containers/<memory_container_id>/memories { "messages": [ { "role": "user", "content": [ { "text": "我叫NameA,我來自AreaA,目前我居住在AreaB.", "type": "text" } ] }, { "role": "assistant", "content": [ { "text": "你好,NameA!很高興認識你.", "type": "text" } ] } ], "namespace": { "user_id": "NameA" }, "tags": { "topic": "personal info" }, "infer": true, "memory_type": "conversation" }搜尋長期記憶索引:
命令列
curl -XGET "http://${POLARSEARCH_HOST_PORT}/.plugins-ml-am-<上一步建立的記憶容器index_prefix>-memory-long-term/_search" \ --user "${USER_PASSWORD}" \ -H 'Content-Type: application/json' \ -d'{ "_source": { "excludes": ["memory_embedding"] }, "query": { "match_all": {} } }'Dashboard
GET .plugins-ml-am-<上一步建立的記憶容器index_prefix>-memory-long-term/_search { "_source": { "excludes": ["memory_embedding"] }, "query": { "match_all": {} } }預期輸出(部分展示):
{ "hits": [ { "_source": { "created_time": 1769156096335, "memory": "NameA is from AreaA.", "last_updated_time": 1769156096335, "namespace": { "user_id": "NameA" }, "memory_container_id": "QRHF6ZsBk04xxx", "tags": { "topic": "personal info" } } }, { "_source": { "created_time": 1769156096335, "memory": "NameA currently resides in AreaB.", "last_updated_time": 1769156096335, "namespace": { "user_id": "NameA" }, "memory_container_id": "QRHF6ZsBk04xxx", "tags": { "topic": "personal info" } } } ] }再次插入一段記憶,記憶內容與先前插入的存在衝突:
命令列
curl -XPOST "http://${POLARSEARCH_HOST_PORT}/_plugins/_ml/memory_containers/<上一步建立的記憶容器ID>/memories" \ --user "${USER_PASSWORD}" \ -H 'Content-Type: application/json' \ -d'{ "messages": [ { "role": "user", "content": [ { "text": "我叫NameA,目前我居住在AreaC.", "type": "text" } ] }, { "role": "assistant", "content": [ { "text": "你好,NameA!很高興認識你.", "type": "text" } ] } ], "namespace": { "user_id": "NameA" }, "tags": { "topic": "personal info" }, "infer": true, "memory_type": "conversation" }'Dashboard
POST _plugins/_ml/memory_containers/<memory_container_id>/memories { "messages": [ { "role": "user", "content": [ { "text": "我叫NameA,目前我居住在AreaC.", "type": "text" } ] }, { "role": "assistant", "content": [ { "text": "你好,NameA!很高興認識你.", "type": "text" } ] } ], "namespace": { "user_id": "NameA" }, "tags": { "topic": "personal info" }, "infer": true, "memory_type": "conversation" }再次搜尋長期記憶索引看到內容已經更新(部分展示):
{ "hits": [ { "_source": { "created_time": 1769156096335, "memory": "NameA resides in AreaC.", "last_updated_time": 1769156493970, "namespace": { "user_id": "NameA" }, "memory_container_id": "QRHF6ZsBk04xxx", "tags": { "topic": "personal info" } } } ] }
情境實踐:構建一個旅行記憶智能體
本節將展示如何利用記憶容器的API,構建一個可以記錄使用者旅行偏好並提供個人化建議的Python智能體。
準備工作
在運行代碼前,請確保已安裝必要的Python庫。在requirements.txt檔案中添加如下依賴庫。
requests
openai執行pip install -r requirements.txt進行安裝。
核心代碼解析
以下是與記憶容器互動的關鍵函數:
opensearch_request():封裝了對PolarSearch API的HTTP請求,統一處理認證和錯誤。add_memory():調用記憶容器的memories介面,將新的對話資訊存入記憶。search_memories():調用_search介面,在長期和短期記憶中檢索與使用者查詢相關的資訊。generate_response_with_memories():將檢索到的記憶作為上下文,連同使用者當前問題一起提交給LLM,產生更具個人化的回複。
完整範例程式碼
以下是經過安全修複和邏輯最佳化的完整Python指令碼。請將代碼儲存為trip_agent.py,並根據提示設定環境變數。
運行與互動
設定環境變數:在終端中設定指令碼所需的環境變數。
運行指令碼:
python trip_agent.py互動樣本:
API 參考
本指南中主要使用了以下API,更多詳細用法請參考OpenSearch官方文檔:
Create Memory Container API:用於建立和配置記憶容器。
Agentic memory APIs:包含了對記憶進行增、刪、改、查的完整介面。
計費說明
使用 PolarSearch 記憶容器功能會涉及以下幾部分費用,請在生產使用前仔細評估:
計算節點費用:作為PolarDB的一部分,PolarSearch節點會產生相應的節點計算節點費用。
模型服務費用:調用外部模型(如阿里雲大模型服務平台百鍊)進行事實抽取和向量化會產生相應的API調用費用。