跳到主要内容
版本:V1.0.0

TEN-framework X OceanBase PowerMem 打造个性化智能体语音助手

本教程介绍如何通过 OceanBase PowerMem 结合 TEN-framework 打造一款带记忆的智能体语音助手。在集成了 TEN 强大的“实时多模态”能力基础上,还展现了“个性化”对话体验与长期记忆感知的独特优势。

有关 OceanBase PowerMem 的详细信息,可参考 GitHub - oceanbase/powermem

为什么需要记忆?

Agent 需要记忆能力,是因为记忆是实现个性化、连续性互动和深度共情的核心基础。没有记忆,这些 Agent 就像“金鱼记忆”一样,每次交互都从零开始,无法建立真正有意义的关系或提供高效服务。

维持对话的连贯性和上下文理解

问题:如果 Agent 不记得用户之前说过什么,每次对话都会显得割裂、重复甚至令人沮丧。 例子

  • 用户:“我最近压力很大,工作快撑不住了。”
  • 几天后再次说:“还是老样子,项目没结束。”
  • 如果 Agent 记得之前的对话,可以说:“上次你说项目压力大,现在还在持续吗?有没有好一点?”
  • 如果没有记忆,Agent 可能会问:“你最近有什么压力?”——显得冷漠且重复。

记忆让对话有延续感,像是“真正关心你的人”。

建立情感连接与信任

情感陪伴的本质是“被理解”和“被记住”。人类在关系中重视“对方记得我的事”。

心理学研究表明:被记住细节(如喜好、经历、情绪)会显著增强亲密感和信任。 例子

  • “你上次说你喜欢喝抹茶拿铁,今天要不要来点轻松的话题放松一下?”
  • 这种细节回忆会让用户感到被关注,提升情感价值。

记忆 = 被重视的信号 → 增强用户依恋和使用黏性。

实现个性化服务与预测需求

助手类 Agent 需要根据用户习惯主动提供帮助。 例子

  • 用户每周五晚上都会问:“明天天气怎么样?”
  • 有记忆的 Agent 可以主动提醒:“周五快到了,需要我帮你查周末天气吗?”
  • 或者记住用户讨厌会议太多,自动建议:“下周日程太满,要我帮你调整吗?”

记忆让 Agent 从“被动响应”升级为“主动关怀”。

避免重复提问,提升用户体验

没有记忆的 Agent 会反复问相同问题(如“你叫什么名字?”“你住哪里?”),让人烦躁。 有长期记忆的 Agent 可以:

  • 记住用户的姓名、偏好、重要事件(生日、纪念日)
  • 在合适时机表达关心:“明天是你生日,准备怎么庆祝?”

减少认知负担,让用户感觉更自然、更人性化。

支持长期目标追踪与成长陪伴

情感陪伴或健康类助手常涉及长期目标(如减压、戒烟、学习)。 记忆能力可用来:

  • 跟踪进展:“这周你记录了3次情绪低落,比上周少了2次,有进步!”
  • 提供鼓励:“你说过想坚持写日记,今天写了吗?”

形成“成长伙伴”角色,而非一次性工具。

集成 OceanBase PowerMem:我们做了什么?

用户画像记忆模块(User Memory Module)

在 OceanBase PowerMem v0.2.0 版本中,我们全新推出了 用户画像记忆模块(User Memory Module),迈出构建更智能、更个性化的智能体助手的关键一步。用户画像记忆模块能够自动分析用户对话内容,提取并持久化用户画像(User Profile)。

**用户画像:**描述用户的当前状态与特征,包括使用偏好、角色身份、操作习惯、业务需求等关键属性,支持动态更新与长期存储,实现“记住你是谁”。

能力价值

通过引入用户画像记忆,Agent 实现了从“无状态响应”到“有记忆服务”的跃迁,具备以下能力升级:

  • 上下文感知的智能理解:结合历史画像与行为轨迹,更准确识别用户真实意图;
  • 个性化推荐与主动服务:基于用户习惯,智能推荐常用命令、优化建议或高频功能入口;
  • 跨会话连续性体验:打破“每次对话从零开始”的局限,实现多轮次、跨时间的连贯交互;
  • 支撑高阶智能场景:为后续的智能运维、自助诊断、个性化 SQL 优化等高级功能提供数据基础,助力打造真正懂用户的数据库助手。

智能记忆保存策略

为保障性能与一致性,我们设计了高效协调的记忆持久化机制:

策略规则可配置项
基于对话轮次N 轮对话后自动触发保存memory_save_interval_turns(默认 5)
基于空闲超时连续 N 秒无交互后自动保存memory_idle_timeout_seconds(默认 30)

两种策略协同工作,通过去重判断避免重复写入;同时采用计数器同步机制,防止并发更新导致的竞态条件,确保数据一致性与系统稳定性。

个性化问候生成

为了让用户感受到“被记住”的温暖体验,我们在首次加入时引入了 个性化欢迎问候 功能,让每一次接入都更有温度。

工作流程

  1. 获取记忆摘要:从 PowerMem 中检索用户的历史对话概要;
  2. 生成定制问候:将记忆信息填入提示词模板,调用 LLM 生成 2–3 句自然语言问候语;
  3. 多语言适配:根据用户地区信息自动选择对应语言(如中文、英文等);
  4. 语音输出:生成完成后推送至 TTS 引擎进行播报。

技术亮点

  • 异步非阻塞:全程异步处理,不影响用户正常接入流程。
  • 10 秒超时保护:防止 LLM 响应延迟影响整体体验。
  • 状态隔离机制:使用独立标志位,避免与常规对话混淆。
  • 优雅降级:当无历史记忆或生成失败时,自动回退至通用欢迎语,保障可用性。

快速上手

准备工作

  • 登录 https://console.agora.io/ 创建 project 获取 App IDPrimary Certificate

    提示

    agora 会提供一定免费额度,超过用量可能产生费用,请在继续前,访问其官网或查阅相关文档,确认并接受其收费标准。如不同意,请勿继续操作。

  • 准备好 openai 兼容的模型服务 API KEY。

    提示

    openai 兼容的模型服务 API KEY 需要您跳转至第三方平台完成。此操作将遵循第三方平台的收费规则,并可能产生相应费用。请在继续前,访问其官网或查阅相关文档,确认并接受其收费标准。如不同意,请勿继续操作。

  • 安装 seekdb 服务器模式,有关 seekdb 服务器模式的部署,请参见 通过 yum install 部署 seekdb

  • 已安装完成 Docker。

  • Docker build 可能会超时,请提前配置好 Docker 国内镜像或者代理。

部署服务

  1. 克隆仓库 ten-framework 。

    git clone https://github.com/TEN-framework/ten-framework

    cd ten-framework/ai_agents/

    cp .env.example .env
  2. .env文件中,修改相关的环境变量(以 Agora + QWen 配置为例):

    vim .env

    需要修改及新增的变量如下:

    # ============================================================= #
    # 以下为需要修改的变量
    # ============================================================= #

    # Agora
    # 登录 https://console.agora.io/ 创建 project 获取
    AGORA_APP_ID={需要填写}
    AGORA_APP_CERTIFICATE={需要填写}

    # LLM
    # 此处以百炼举例,可以用任何兼容 openai 的大模型服务
    OPENAI_API_BASE=https://dashscope.aliyuncs.com/compatible-mode/v1
    OPENAI_API_KEY={需要填写}
    OPENAI_MODEL=qwen3-max

    # ============================================================= #
    # 以下为新增的变量
    # ============================================================= #

    # Database
    DATABASE_PROVIDER=oceanbase
    OCEANBASE_HOST=127.0.0.1
    OCEANBASE_PORT=2881
    OCEANBASE_USER=root
    OCEANBASE_PASSWORD=
    OCEANBASE_DATABASE=test
    OCEANBASE_COLLECTION=memories

    # LLM Provider (for PowerMem)
    LLM_PROVIDER=qwen
    LLM_API_KEY={需要填写}
    LLM_MODEL=qwen3-max

    # Embedding Provider (for PowerMem)
    EMBEDDING_PROVIDER=qwen
    EMBEDDING_API_KEY={需要填写}
    EMBEDDING_MODEL=text-embedding-v4
    EMBEDDING_DIMS=1536
  3. 修改 property.json

    rm -rf agents/examples/voice-assistant-with-PowerMem/tenapp/property.json
    vi agents/examples/voice-assistant-with-PowerMem/tenapp/property.json

    将以下内容粘贴进去:

    {
    "ten": {
    "predefined_graphs": [
    {
    "name": "voice_assistant",
    "auto_start": true,
    "graph": {
    "nodes": [
    {
    "type": "extension",
    "name": "agora_rtc",
    "addon": "agora_rtc",
    "extension_group": "default",
    "property": {
    "app_id": "${env:AGORA_APP_ID}",
    "app_certificate": "${env:AGORA_APP_CERTIFICATE|}",
    "channel": "ten_agent_test",
    "stream_id": 1234,
    "remote_stream_id": 123,
    "subscribe_audio": true,
    "publish_audio": true,
    "publish_data": true,
    "enable_agora_asr": false,
    "agora_asr_vendor_name": "microsoft",
    "agora_asr_language": "en-US",
    "agora_asr_vendor_key": "${env:AZURE_STT_KEY|}",
    "agora_asr_vendor_region": "${env:AZURE_STT_REGION|}",
    "agora_asr_session_control_file_path": "session_control.conf"
    }
    },
    {
    "type": "extension",
    "name": "stt",
    "addon": "aliyun_asr_bigmodel_python",
    "extension_group": "stt",
    "property": {
    "params": {
    "api_key": "${env:OPENAI_API_KEY|}",
    "language": "zh-CN",
    "language_hints": [
    "zh"
    ]
    }
    }
    },
    {
    "type": "extension",
    "name": "llm",
    "addon": "openai_llm2_python",
    "extension_group": "chatgpt",
    "property": {
    "base_url": "${env:OPENAI_API_BASE}",
    "api_key": "${env:OPENAI_API_KEY}",
    "frequency_penalty": 0.9,
    "model": "${env:OPENAI_MODEL}",
    "max_tokens": 512,
    "prompt": "",
    "proxy_url": "${env:OPENAI_PROXY_URL|}",
    "greeting": "TEN Agent connected. How can I help you today?",
    "max_memory_length": 10
    }
    },
    {
    "type": "extension",
    "name": "tts",
    "addon": "cosy_tts_python",
    "extension_group": "tts",
    "property": {
    "params": {
    "api_key": "${env:OPENAI_API_KEY|}",
    "model": "cosyvoice-v3-plus",
    "sample_rate": 16000,
    "voice": "longanyang"
    }
    }
    },
    {
    "type": "extension",
    "name": "main_control",
    "addon": "main_python",
    "extension_group": "control",
    "property": {
    "greeting": "Hello! I'm your AI assistant with memory. I can remember our previous conversations to provide more personalized help.",
    "agent_id": "voice_assistant_agent",
    "user_id": "user",
    "enable_memorization": true,
    "enable_user_memory": true,
    "memory_save_interval_turns": 5,
    "memory_idle_timeout_seconds": 30.0,
    "powermem_config": {
    "vector_store": {
    "provider": "oceanbase",
    "config": {
    "collection_name": "${env:OCEANBASE_COLLECTION}",
    "host": "${env:OCEANBASE_HOST}",
    "port": "${env:OCEANBASE_PORT}",
    "user": "${env:OCEANBASE_USER}",
    "password": "${env:OCEANBASE_PASSWORD}",
    "db_name": "${env:OCEANBASE_DATABASE}"
    }
    },
    "llm": {
    "provider": "${env:LLM_PROVIDER}",
    "config": {
    "api_key": "${env:LLM_API_KEY}",
    "model": "${env:LLM_MODEL}"
    }
    },
    "embedder": {
    "provider": "${env:EMBEDDING_PROVIDER}",
    "config": {
    "api_key": "${env:EMBEDDING_API_KEY}",
    "model": "${env:EMBEDDING_MODEL}",
    "embedding_dims": "${env:EMBEDDING_DIMS}"
    }
    }
    }
    }
    },
    {
    "type": "extension",
    "name": "message_collector",
    "addon": "message_collector2",
    "extension_group": "transcriber",
    "property": {}
    },
    {
    "type": "extension",
    "name": "weatherapi_tool_python",
    "addon": "weatherapi_tool_python",
    "extension_group": "default",
    "property": {
    "api_key": "${env:WEATHERAPI_API_KEY|}"
    }
    },
    {
    "type": "extension",
    "name": "streamid_adapter",
    "addon": "streamid_adapter",
    "property": {}
    }
    ],
    "connections": [
    {
    "extension": "main_control",
    "cmd": [
    {
    "names": [
    "on_user_joined",
    "on_user_left"
    ],
    "source": [
    {
    "extension": "agora_rtc"
    }
    ]
    },
    {
    "names": [
    "tool_register"
    ],
    "source": [
    {
    "extension": "weatherapi_tool_python"
    }
    ]
    }
    ],
    "data": [
    {
    "name": "asr_result",
    "source": [
    {
    "extension": "stt"
    }
    ]
    }
    ]
    },
    {
    "extension": "agora_rtc",
    "audio_frame": [
    {
    "name": "pcm_frame",
    "dest": [
    {
    "extension": "streamid_adapter"
    }
    ]
    },
    {
    "name": "pcm_frame",
    "source": [
    {
    "extension": "tts"
    }
    ]
    }
    ],
    "data": [
    {
    "name": "data",
    "source": [
    {
    "extension": "message_collector"
    }
    ]
    }
    ]
    },
    {
    "extension": "streamid_adapter",
    "audio_frame": [
    {
    "name": "pcm_frame",
    "dest": [
    {
    "extension": "stt"
    }
    ]
    }
    ]
    }
    ]
    }
    }
    ],
    "log": {
    "handlers": [
    {
    "matchers": [
    {
    "level": "info"
    }
    ],
    "formatter": {
    "type": "plain",
    "colored": true
    },
    "emitter": {
    "type": "console",
    "config": {
    "stream": "stdout"
    }
    }
    }
    ]
    }
    }
    }
  4. 构建容器。

    修改 property.json 后,构建容器。

    # 构建镜像,如无变更只需要构建一次
    docker build -f agents/examples/voice-assistant-with-PowerMem/Dockerfile -t voice-assistant-with-powermem:latest .
  5. 启动容器。

    # 启动容器
    docker run -it --env-file .env -p 3000:3000 voice-assistant-with-powermem:latest
  6. 与 Agent 语音沟通。

    等待启动完成,即可在浏览器中打开 http://127.0.0.1:3000,如果使用远程服务器则访问对应的 3000 端口的 http 服务即可,可以看到如下页面,点击右上角 Select Graph 选择 voice_assistent,并点击 Connent,即可与 Agent 语音沟通了。

    提示

    与 Agent 语音沟通需要授予麦克风权限。

    1

总结

记忆,让 AI 从"工具"到"伙伴"的跨越。

我们常把 AI 助手看作信息查询工具,但真正的智能体不应止于“回答问题”,而应致力于“理解人”。实现这一点的核心转折,正是记忆——它让交互脱离原子化的片段,开始具备时间的维度与情感的深度。

本次将 OceanBase PowerMem 融入 TEN-framework 的实践,本质上是一次对“AI 人格化”的探索。我们不再追求一个完美但冰冷的应答机器,而是尝试构建一个能感知用户轨迹、积累认知、并据此演化行为的服务主体。

这一转变带来的不仅是体验升级,更是范式迁移:

  • 从响应到共鸣:记忆使语言不再是即时刺激的反射,而是历史经验的回响;
  • 从通用到专属:同一个助手,在不同用户面前逐渐长成不同的“性格”;
  • 从孤立任务到持续陪伴:服务目标从“完成这一次对话”转向“支持你长期的成长或需求”。

更重要的是,这套机制的设计为未来留出了演进空间——当记忆可存储、可检索、可推理时,AI 就有了自我修正和主动建模用户的能力基础。今天的个性化问候只是起点,明天可能是一个会提醒你情绪波动趋势、预判操作意图、甚至在你未言明时已准备妥当的伙伴。

因此,这项工作的意义不在于“加了个记忆模块”,而在于确立了一个原则:
智能体的价值,不在于它知道多少,而在于它为你记住了多少。

这不仅改变了人机关系的本质,也为下一代 AI 系统定义了新的衡量标准——不是准确率多高,而是是否“值得被依赖”。