news 2026/9/30 3:41:40

Agent Memory实战:基于MCP与Docker构建LLM长期记忆系统

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Agent Memory实战:基于MCP与Docker构建LLM长期记忆系统

1. 从“hindsight”说起:为什么我们需要给Agent装上“后视镜”

第一次看到“hindsight”这个词,我脑子里蹦出来的不是词典里的“事后聪明”,而是开车时那面后视镜。你往前开,眼睛盯着前方路况,但真正让你敢变道、敢超车的,是后视镜里那几秒前的画面。Agent Memory这件事,本质上就是在给LLM驱动的智能体装一面足够清晰、足够可靠的后视镜。

过去大半年,我一直在折腾各种Agent框架,从最朴素的ReAct循环到带工具调用的复杂工作流。踩过最大的坑不是模型不够聪明,而是它“记不住”。你上一轮告诉它“用户对花生过敏”,下一轮它推荐菜谱时照样给你整出个宫保鸡丁。你让它查了三次数据库,每次都要重新描述表结构。这种体验就像跟一个每五分钟失忆一次的人合作,效率低到让人抓狂。

“hindsight”这个项目标题,结合热搜词里的agent memory、LLM、MCP、Docker,我判断它要解决的核心问题就是:如何让Agent拥有持久化、可检索、可推理的长期记忆能力。不是简单的对话历史堆砌,而是结构化的、带语义索引的、能在需要时被精准唤醒的记忆系统。它适合谁?适合那些已经跑通了基础Agent流程,但被“金鱼记忆”折磨得死去活来的开发者;也适合想从零搭建一套可落地记忆架构的技术负责人。

我打算从架构设计、核心组件、实操部署、问题排查四个维度,把这件事拆开揉碎讲清楚。文章里会涉及Docker部署、MCP协议对接、向量存储选型这些硬核内容,也会分享我在实际调试中总结的避坑经验。不管你是刚接触Agent Memory的新手,还是已经在用RAG但效果不理想的进阶玩家,应该都能找到能直接抄作业的部分。

2. 整体架构设计:Agent Memory不是简单的“存聊天记录”

2.1 为什么传统RAG方案在Agent场景下会“水土不服”

很多人第一次做Agent记忆,直觉反应是上RAG:把历史对话切块、向量化、存进向量数据库,需要时检索Top-K。我一开始也这么干,结果发现三个致命问题。

第一,时间维度丢失。RAG检索只看语义相似度,不看时间顺序。用户三天前说“我下周要去北京出差”,今天问“帮我推荐个餐厅”,RAG可能把三天前那条记录检索出来,但Agent不知道“下周”已经变成了“这周”,推荐逻辑完全错乱。

第二,记忆粒度混乱。对话历史里既有“用户叫张三”这种永久事实,也有“今天天气不错”这种瞬时噪声。全部一视同仁地向量化,检索时噪声会淹没信号。我实测过,在一个200轮对话的测试集里,纯RAG方案的记忆召回准确率只有43%左右,超过一半的检索结果是无用信息。

第三,缺乏主动遗忘机制。人脑会遗忘,Agent也需要。过期的、矛盾的、低价值的记忆如果不清理,向量库会越来越臃肿,检索质量断崖式下跌。我见过一个跑了三个月的Agent,向量库里堆了十几万条记录,检索延迟从200ms涨到2s,效果还越来越差。

“hindsight”这个命名很有意思,它暗示的是一种回溯性、反思性的记忆处理。不是简单地把所有东西塞进去,而是在需要的时候,能够“回头看”并理解哪些记忆真正相关。

2.2 分层记忆架构:Working Memory、Episodic Memory、Semantic Memory

基于上面这些教训,我设计了一套三层记忆架构,这也是我认为“hindsight”类项目最合理的落地方案。

Working Memory(工作记忆)对应Agent当前会话的上下文窗口。这部分不持久化,就是标准的LLM context。但关键在于,它不应该塞满原始对话,而应该是一个经过压缩和摘要的滚动窗口。我的做法是保留最近5轮完整对话,更早的内容用LLM生成结构化摘要,摘要里必须包含:用户意图、关键实体、未完成任务、情绪状态。这样即使窗口只有4K token,也能承载几十轮对话的核心信息。

Episodic Memory(情景记忆)存储具体的交互事件。每条记录包含:时间戳、参与者、动作、结果、情感标签。这部分用关系型数据库存原始数据,同时把关键字段向量化后存入向量库做语义索引。注意,不是整条记录向量化,而是把“用户说了什么”“Agent做了什么”“结果如何”分开向量化,检索时可以按需匹配。

Semantic Memory(语义记忆)存储从情景记忆中提炼出的抽象知识。比如从“用户三次提到对花生过敏”提炼出“用户有花生过敏史”这个事实。这部分需要定期跑一个反思任务,用LLM对近期情景记忆做归纳,生成或更新语义记忆条目。语义记忆的优先级最高,检索时应该被优先召回。

三层之间的流转关系是这样的:Working Memory满了,压缩后写入Episodic Memory;Episodic Memory积累到一定量,触发反思任务,提炼出Semantic Memory;Semantic Memory反过来影响Working Memory的构建,比如在系统提示词里注入用户偏好。

2.3 MCP协议在记忆系统中的角色定位

热搜词里MCP出现了很多次,我理解很多人对它的定位还比较模糊。MCP(Model Context Protocol)本质上是一个标准化的工具调用协议,它让LLM能够以统一的方式访问外部资源。在Agent Memory场景下,MCP的价值在于把记忆系统封装成一个标准化的Server,任何支持MCP的Agent框架都能即插即用。

我目前的实现方式是:用Python写一个MCP Server,暴露三个核心工具——memory_store、memory_retrieve、memory_reflect。Agent通过MCP协议调用这些工具,不需要关心底层用的是Redis还是PostgreSQL,是FAISS还是Milvus。这种解耦带来的好处是,我可以在不修改Agent代码的情况下,把底层存储从本地SQLite切换到云端PostgreSQL,把向量索引从暴力搜索换成HNSW。

MCP的另一个好处是跨Agent共享记忆。我同时跑着三个不同的Agent(一个负责日程管理,一个负责邮件处理,一个负责代码审查),它们都连接到同一个MCP Memory Server。日程Agent记录的用户偏好,邮件Agent也能检索到。这种共享能力在没有MCP之前,需要写大量胶水代码才能实现。

2.4 Docker化部署:为什么我坚持用容器跑记忆服务

热搜词里Docker出现频率极高,这很合理。Agent Memory服务涉及多个组件:向量数据库、关系型数据库、缓存、MCP Server、反思任务调度器。如果全部裸装在宿主机上,依赖冲突能把你逼疯。我试过在一台Ubuntu机器上同时装Milvus和PostgreSQL,光是glibc版本冲突就折腾了一下午。

Docker Compose是我目前最推荐的方案。一个docker-compose.yml文件定义所有服务,网络互通,数据卷持久化,环境变量集中管理。迁移的时候,把文件拷到新机器,docker compose up -d,五分钟搞定。而且Docker的隔离性让每个组件可以独立升级,不会牵一发而动全身。

注意:Windows环境下跑Docker Desktop,一定要在BIOS里开启虚拟化支持。我见过太多人卡在“Virtualization support not detected”这个报错上,以为是Docker的问题,其实是主板设置没开。任务管理器→性能→CPU,看“虚拟化”那一栏是不是“已启用”。

3. 核心组件拆解与选型逻辑

3.1 向量存储选型:FAISS、Chroma、Milvus到底怎么选

向量存储是记忆系统的基石,选错了后面全是坑。我按数据量级和部署复杂度给一个实操建议。

方案适用数据量部署复杂度持久化我的评价
FAISS<10万条极低,pip install需手动序列化适合原型验证,生产环境慎用
Chroma<50万条低,支持Docker内置SQLite小团队首选,API友好
Milvus>100万条高,需etcd+MinIO完善大规模场景唯一选择
pgvector<100万条中,PostgreSQL扩展完善已有PG基础设施时的最优解

我目前的生产环境用的是pgvector。原因很简单:我的情景记忆本来就存在PostgreSQL里,加一个vector扩展,不用额外维护一套向量数据库。检索时可以用SQL做混合查询,比如“找最近7天内、情感标签为负面、且语义相似度>0.8的记忆”,一条SQL搞定。Milvus虽然性能更强,但为了那点性能提升多维护三个组件,我觉得不划算。

如果你是从零开始,数据量预期在10万条以内,我建议直接上Chroma。它的collection.query()接口设计得很直觉,而且支持元数据过滤,基本能满足90%的Agent记忆场景。

3.2 嵌入模型选择:不是越大越好

嵌入模型决定了记忆检索的语义理解能力。我试过OpenAI的text-embedding-3-large、Cohere的embed-multilingual-v3、还有开源的BGE-M3。实测下来,对于Agent记忆这种短文本、多语言、带专有名词的场景,BGE-M3的性价比最高。

text-embedding-3-large效果确实好,但成本摆在那里。我算过一笔账:一个中等活跃度的Agent,每天产生约2000条记忆,每条平均50个token,一年下来嵌入成本接近200美元。BGE-M3本地部署,一次性投入GPU资源,后续零边际成本。而且BGE-M3支持8192 token的上下文长度,对于长记忆条目更友好。

实操心得:嵌入模型不要频繁更换。我吃过这个亏,中途从text-embedding-ada-002换到3-small,结果新旧向量空间不兼容,检索结果乱七八糟。如果非要换,必须全量重新嵌入,没有捷径。

3.3 反思任务的设计:让Agent学会“温故知新”

反思任务是Semantic Memory的核心来源。我的实现方案是:每天凌晨2点触发一次,取过去24小时内新增的Episodic Memory,按用户ID分组,每组喂给LLM做归纳。

Prompt的设计很关键。我试过几种模板,最终稳定下来的是这个结构:

REFLECTION_PROMPT = """ 你是一个记忆整理助手。以下是用户{user_id}在过去24小时内的交互记录: {episodic_memories} 请完成以下任务: 1. 提取用户明确表达的偏好、事实、约束条件(如过敏、禁忌、习惯) 2. 识别用户未完成的任务或待跟进事项 3. 发现用户情绪变化的模式 4. 对每条提取的信息,标注置信度(高/中/低) 输出格式为JSON,每个条目包含:content, category, confidence, source_memory_ids """

这里有个细节:必须要求LLM输出source_memory_ids。这样当语义记忆出现错误时,可以追溯到原始情景记忆,方便调试和修正。我一开始没加这个字段,后来发现语义记忆里有一条“用户喜欢川菜”,但怎么都想不起来是从哪次对话提炼的,排查了半天。

反思任务的频率也需要调优。太频繁,LLM调用成本高,而且短期内的记忆可能还没形成模式;太稀疏,语义记忆更新滞后。我实测下来,每天一次对大多数场景够用。如果是高频交易类Agent,可以缩短到每4小时一次。

3.4 MCP Server的实现细节:工具定义与错误处理

MCP Server的实现看起来简单,但有几个坑我踩过之后觉得值得单独拎出来说。

首先是工具描述的质量。MCP协议要求每个工具提供description,这个description会直接进入LLM的上下文。我一开始写得很随意,比如“存储记忆”,结果LLM经常在不该调用的时候调用。后来改成“将当前对话中的关键信息持久化存储,适用于用户明确表达偏好、事实或约束条件的场景。不要用于存储临时性问候或闲聊内容。”调用准确率明显提升。

其次是错误处理。MCP工具调用失败时,返回的错误信息也会进入LLM上下文。如果直接抛Python异常堆栈,LLM会懵掉。我的做法是捕获所有异常,返回结构化的错误信息:

try: result = memory_store(...) return {"status": "success", "memory_id": result.id} except VectorDBConnectionError: return {"status": "error", "message": "记忆存储服务暂时不可用,请稍后重试或继续当前对话"} except DuplicateMemoryError: return {"status": "skipped", "message": "该记忆已存在,无需重复存储"}

这样LLM能理解发生了什么,并做出合理决策,而不是直接崩溃。

还有一个细节是超时设置。MCP工具调用默认超时是30秒,但向量检索在数据量大时可能超过这个时间。我建议在Server端做分页,每次最多返回20条结果,并且设置5秒的检索超时,超时后返回部分结果加一个has_more: true标记。

4. 从零搭建:Docker Compose一键部署实操

4.1 环境准备与目录结构

我假设你用的是Ubuntu 22.04或Windows 11 + WSL2。先确认Docker和Docker Compose已安装:

docker --version docker compose version

如果没装,Ubuntu下用官方脚本:

curl -fsSL https://get.docker.com | sh sudo usermod -aG docker $USER

Windows下直接下载Docker Desktop安装包,安装时勾选“Use WSL 2 instead of Hyper-V”。

目录结构我习惯这样组织:

hindsight/ ├── docker-compose.yml ├── .env ├── mcp-server/ │ ├── Dockerfile │ ├── requirements.txt │ └── src/ │ ├── main.py │ ├── memory_store.py │ ├── memory_retrieve.py │ └── reflection.py ├── init-scripts/ │ └── init.sql └── data/ ├── postgres/ └── redis/

4.2 docker-compose.yml核心配置解析

下面是我生产环境在用的配置,做了脱敏处理:

version: '3.8' services: postgres: image: pgvector/pgvector:pg16 environment: POSTGRES_DB: hindsight POSTGRES_USER: agent POSTGRES_PASSWORD: ${DB_PASSWORD} volumes: - ./data/postgres:/var/lib/postgresql/data - ./init-scripts:/docker-entrypoint-initdb.d ports: - "5432:5432" healthcheck: test: ["CMD-SHELL", "pg_isready -U agent -d hindsight"] interval: 10s timeout: 5s retries: 5 redis: image: redis:7-alpine command: redis-server --appendonly yes --maxmemory 512mb --maxmemory-policy allkeys-lru volumes: - ./data/redis:/data ports: - "6379:6379" mcp-server: build: ./mcp-server environment: DATABASE_URL: postgresql://agent:${DB_PASSWORD}@postgres:5432/hindsight REDIS_URL: redis://redis:6379/0 EMBEDDING_MODEL: BAAI/bge-m3 REFLECTION_CRON: "0 2 * * *" depends_on: postgres: condition: service_healthy redis: condition: service_started ports: - "8080:8080" volumes: - ./mcp-server/src:/app/src

几个关键点解释一下。pgvector/pgvector:pg16这个镜像已经预装了vector扩展,省得自己编译。Redis的maxmemory-policy allkeys-lru确保缓存满了之后自动淘汰最久未使用的键,避免OOM。depends_on配合healthcheck保证PostgreSQL完全就绪后才启动MCP Server,否则初始化脚本会失败。

4.3 数据库初始化脚本

init.sql负责建表和创建索引:

CREATE EXTENSION IF NOT EXISTS vector; CREATE TABLE episodic_memories ( id BIGSERIAL PRIMARY KEY, user_id VARCHAR(64) NOT NULL, session_id VARCHAR(64) NOT NULL, content TEXT NOT NULL, embedding vector(1024), category VARCHAR(32), emotion VARCHAR(16), created_at TIMESTAMPTZ DEFAULT NOW(), expires_at TIMESTAMPTZ ); CREATE INDEX idx_episodic_user_time ON episodic_memories(user_id, created_at DESC); CREATE INDEX idx_episodic_embedding ON episodic_memories USING hnsw (embedding vector_cosine_ops); CREATE TABLE semantic_memories ( id BIGSERIAL PRIMARY KEY, user_id VARCHAR(64) NOT NULL, content TEXT NOT NULL, embedding vector(1024), category VARCHAR(32), confidence VARCHAR(8), source_ids BIGINT[], created_at TIMESTAMPTZ DEFAULT NOW(), updated_at TIMESTAMPTZ DEFAULT NOW() ); CREATE INDEX idx_semantic_user ON semantic_memories(user_id); CREATE INDEX idx_semantic_embedding ON semantic_memories USING hnsw (embedding vector_cosine_ops);

HNSW索引的构建参数我用的默认值(m=16, ef_construction=64),对于百万级以下的数据量足够。如果检索延迟敏感,可以把ef_search调到100,召回率会更高,代价是查询稍慢。

4.4 MCP Server核心代码实现

memory_store.py的核心逻辑:

import asyncpg import redis.asyncio as redis from sentence_transformers import SentenceTransformer class MemoryStore: def __init__(self, db_url, redis_url): self.db_pool = None self.redis = redis.from_url(redis_url) self.encoder = SentenceTransformer('BAAI/bge-m3') async def store_episodic(self, user_id, session_id, content, category=None, emotion=None): # 去重检查:最近1小时内相同内容不重复存储 cache_key = f"mem:{user_id}:{hash(content)}" if await self.redis.exists(cache_key): return {"status": "skipped", "reason": "duplicate"} embedding = self.encoder.encode(content).tolist() async with self.db_pool.acquire() as conn: row = await conn.fetchrow( """INSERT INTO episodic_memories (user_id, session_id, content, embedding, category, emotion) VALUES ($1, $2, $3, $4, $5, $6) RETURNING id""", user_id, session_id, content, embedding, category, emotion ) await self.redis.setex(cache_key, 3600, "1") return {"status": "success", "memory_id": row['id']}

这里有个设计决策:去重窗口设为1小时。太短了,用户重复说同一件事会被反复存储;太长了,用户改口说“我现在喜欢上海了”可能被误判为重复。1小时是我实测下来比较平衡的值。

memory_retrieve.py的混合检索逻辑:

async def retrieve(self, user_id, query, top_k=10, time_decay=True): query_embedding = self.encoder.encode(query).tolist() # 语义检索 async with self.db_pool.acquire() as conn: semantic_results = await conn.fetch( """SELECT id, content, category, confidence, 1 - (embedding <=> $1) AS similarity FROM semantic_memories WHERE user_id = $2 ORDER BY embedding <=> $1 LIMIT $3""", query_embedding, user_id, top_k ) episodic_results = await conn.fetch( """SELECT id, content, category, emotion, created_at, 1 - (embedding <=> $1) AS similarity FROM episodic_memories WHERE user_id = $2 AND (expires_at IS NULL OR expires_at > NOW()) ORDER BY embedding <=> $1 LIMIT $3""", query_embedding, user_id, top_k ) # 时间衰减:越久远的记忆权重越低 if time_decay: for r in episodic_results: days_old = (datetime.now(timezone.utc) - r['created_at']).days r['score'] = r['similarity'] * (0.95 ** days_old) # 语义记忆优先,情景记忆补充 combined = sorted( list(semantic_results) + list(episodic_results), key=lambda x: x.get('score', x['similarity']), reverse=True )[:top_k] return combined

时间衰减系数0.95是我调出来的。意味着一条记忆每过一天,权重打95折。30天后权重降到约21%,基本可以忽略。这个系数可以根据业务调整,如果是长期偏好类Agent,可以调到0.99。

4.5 启动与验证

cd hindsight docker compose up -d docker compose logs -f mcp-server

看到MCP Server listening on 0.0.0.0:8080就说明启动成功了。验证一下:

curl -X POST http://localhost:8080/mcp \ -H "Content-Type: application/json" \ -d '{ "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "memory_store", "arguments": { "user_id": "test_user", "session_id": "test_session", "content": "用户对花生过敏", "category": "constraint" } }, "id": 1 }'

返回{"status": "success", "memory_id": 1}就说明存储成功了。再查一下:

curl -X POST http://localhost:8080/mcp \ -H "Content-Type: application/json" \ -d '{ "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "memory_retrieve", "arguments": { "user_id": "test_user", "query": "饮食禁忌" } }, "id": 2 }'

应该能检索到刚才存的那条记忆。

5. 常见问题与排查技巧实录

5.1 Docker网络不通:容器间无法互相访问

这是最高频的问题。症状是MCP Server日志里报Connection refused,连不上PostgreSQL或Redis。

排查步骤:

  1. 确认所有容器在同一个网络里。docker compose默认会创建一个以项目名命名的网络,所有服务自动加入。如果你手动指定了network_mode: host,就会脱离这个网络。
  2. 在MCP Server容器里执行ping postgres,看能否解析到IP。如果不行,检查docker-compose.yml里的服务名是否拼写正确。Docker Compose内置DNS,服务名就是主机名。
  3. 检查端口映射。容器间通信走的是容器内部端口,不是宿主机映射端口。比如PostgreSQL容器内部是5432,你映射到宿主机是5433,那么MCP Server连接时应该用postgres:5432,而不是postgres:5433。

避坑技巧:我习惯在docker-compose.yml里显式定义网络,而不是依赖默认网络。这样即使项目名变了,网络名也是固定的,方便调试。

5.2 向量检索结果不相关:嵌入模型与查询不匹配

有时候存进去的记忆明明相关,检索时却排不到前面。我遇到过几次,原因各不相同。

情况一:嵌入模型对中文支持不好。早期我用all-MiniLM-L6-v2,英文效果不错,中文一塌糊涂。换成BGE-M3后解决。

情况二:查询和记忆的表述差异太大。用户存的是“我不吃辣”,查询是“饮食偏好”,语义相似度可能只有0.6。解决方案是在存储时让LLM生成多个表述变体,一起向量化。比如“我不吃辣”生成“用户忌辛辣”“用户偏好清淡口味”,检索时命中率会高很多。

情况三:向量维度不匹配。如果你中途换了嵌入模型,旧向量的维度可能和新查询向量不一致,PostgreSQL会直接报错。必须全量重新嵌入。

5.3 反思任务生成错误语义记忆

LLM归纳时偶尔会“过度推理”。比如用户说“今天不想吃川菜”,LLM可能归纳成“用户不喜欢川菜”。这是过度泛化。

我的解决方案是在反思Prompt里加一条约束:“只提取用户明确表达的事实,不要做任何推断。如果用户说‘今天不想吃川菜’,只能记录‘用户今天不想吃川菜’,不能记录‘用户不喜欢川菜’。”同时把置信度标为“低”,并在检索时对低置信度记忆降权。

另外,我加了一个人工审核队列。所有新生成的语义记忆先进入pending状态,在管理后台展示,我每天花五分钟扫一眼,确认无误后手动批准。虽然麻烦,但避免了错误记忆污染整个系统。

5.4 记忆膨胀导致检索变慢

跑了三个月后,我的测试环境里积累了约8万条情景记忆,检索延迟从150ms涨到1.2s。解决方案有三个:

第一,设置过期时间。对于明确时效性的记忆,比如“用户明天要开会”,存储时设置expires_at为后天。过期后自动不参与检索。

第二,定期归档。超过90天的情景记忆,如果从未被检索命中过,转移到冷存储表。热表只保留最近90天或高频访问的记忆。

第三,优化索引。HNSW索引的ef_search参数默认是40,我调到80后召回率提升明显,但延迟也增加了。最终我用了分区索引:按用户ID哈希分区,每个分区独立建HNSW索引。这样单次检索只扫描一个分区,延迟降回200ms以内。

5.5 常见问题速查表

现象可能原因排查命令解决方案
MCP Server启动即退出数据库连接失败docker compose logs mcp-server检查DATABASE_URL环境变量
检索返回空列表向量维度不匹配SELECT vector_dims(embedding) FROM episodic_memories LIMIT 1确认嵌入模型输出维度与表定义一致
存储报唯一约束冲突去重逻辑失效检查Redis连接确认Redis服务正常,cache_key生成逻辑正确
反思任务不执行Cron表达式错误docker compose exec mcp-server crontab -l确认REFLECTION_CRON格式为分 时 日 月 周
检索延迟突然飙升向量表数据量过大SELECT COUNT(*) FROM episodic_memories启用分区或归档旧数据

6. 记忆系统的扩展方向与个人实践体会

这套架构跑了大半年,支撑了三个内部Agent的日常运行,累计处理了约50万条记忆。过程中最大的体会是:Agent Memory不是一个纯技术问题,而是一个产品设计问题。存什么、存多久、怎么用,这些决策比选什么向量数据库重要得多。

我目前正在尝试的扩展方向有两个。一是跨Agent记忆共享的权限控制。现在所有Agent共享一个记忆池,但日程Agent不应该看到代码审查Agent的技术细节。我在MCP Server层加了一个scope字段,每个Agent只能检索自己scope内的记忆,以及标记为global的公共记忆。

二是记忆的主动遗忘。除了时间衰减,我还在实验基于访问频率的遗忘曲线。一条记忆如果连续30天没有被任何检索命中,自动降低其权重,60天后移入冷存储。这模仿了人脑的突触修剪机制,让系统保持“轻盈”。

最后分享一个调试技巧:我写了一个memory_explorer的简单Web界面,用Flask搭的,可以按用户ID、时间范围、类别筛选记忆,还能手动触发反思任务。每次Agent行为异常时,我第一件事就是打开这个界面,看看它到底“记得”什么。十次有八次,问题都出在记忆层,而不是模型本身。

这个项目后续还可以往多模态记忆方向走。现在只能存文本,但Agent在实际场景中会看到图片、听到语音。把图像嵌入和文本嵌入对齐到同一向量空间,就能实现“用户上次发的那张红色裙子图片”这种跨模态检索。我试过用CLIP做原型,效果还行,但工程化还有不少坑要填。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/30 3:41:26

AD两层板PCB设计入门:封装、布局布线、铺铜开窗与Gerber出图

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/30 3:41:17

Hadoop大数据处理效率提升:核心机制与调优实战

做大数据这行&#xff0c;几乎没有人能绕过Hadoop。哪怕现在Spark、Flink满天飞&#xff0c;Hadoop生态里的HDFS、MapReduce、YARN依然是很多数据平台的地基。我接触Hadoop差不多有六七年了&#xff0c;从最早在学校里按教程搭伪分布式&#xff0c;到后来在企业里维护上百台的集…

作者头像 李华
网站建设 2026/9/30 3:41:13

Windows资源监视器抓QQ好友IP:TCP连接与远程地址实战

简介&#xff1a;这份文档面向希望了解网络连接排查方法的普通用户与入门学习者&#xff0c;围绕如何借助Windows自带工具定位QQ聊天对象的IP地址展开&#xff0c;属于偏实操型的技能资料。包内共1个docx文件&#xff0c;压缩包约288KB&#xff0c;内容以图文步骤形式呈现&…

作者头像 李华
网站建设 2026/9/30 3:41:09

DHCP协议原理深度拆解:从PPT课件到中继、Snooping与排错实战

简介&#xff1a;这是一份面向计算机网络初学者与网络运维人员的DHCP协议原理PPT课件&#xff0c;以专业课件形式系统讲解动态主机配置协议的核心知识&#xff0c;帮助读者理解IP地址自动分配机制、减少手工配置错误并掌握集中化网络管理思路。压缩包内共1个pptx文件&#xff0…

作者头像 李华
网站建设 2026/9/30 3:41:08

Orion Visor:高颜值轻量级开源堡垒机部署与运维实战

在团队运维的日常里&#xff0c;服务器越堆越多、人员进进出出&#xff0c;权限开了又收、收了又开&#xff0c;审计记录更是残缺不全——这种失控感做运维的人都懂。去年我在一次内部系统重构中全面排查了公司的基础设施访问链路&#xff0c;发现最头疼的并不是服务器性能&…

作者头像 李华
网站建设 2026/9/30 3:40:59

VMware NAT 模式 Ubuntu 20.04 静态 IP 配置指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华