1. 项目概述:为AI智能体构建“自我意识”与记忆中枢

如果你正在开发或使用AI智能体,无论是个人助手、客服机器人还是自动化工作流,一个核心的痛点很快就会浮现: 它们没有记忆,更没有“自我意识” 。每一次对话都是孤岛,智能体无法从历史中学习,无法识别你的习惯,更无法在长期互动中与你共同成长。今天要拆解的这个项目——Graph Memory Suite,正是为了解决这个根本性问题而生。它不是一个简单的聊天记录数据库,而是一个基于 Neo4j图数据库 Graphiti时序知识图谱 构建的、专为AI智能体设计的“大脑皮层”与“海马体”基础设施。

简单来说,这个项目能让你的AI智能体记住过去发生的每一件事(记忆),理解这些事情之间的关联(知识),并基于这些积累进行自我反思和主动干预(自我意识)。它特别适合那些深度依赖AI进行日常任务管理、创意协作或长期项目推进的开发者、研究者和高阶用户。无论你是想打造一个永不遗忘的个人数字伴侣,还是希望你的自动化工作流能越用越聪明,这套工具都提供了一个坚实、可私有化部署的起点。

2. 核心架构与设计哲学:为什么是“图”+“时序”?

在深入代码之前,我们必须先理解其设计哲学。为什么选择图数据库(Neo4j)和时序知识图谱(Graphiti)作为核心,而不是传统的关系型数据库或向量数据库?这背后是对智能体记忆本质的深刻洞察。

2.1 记忆的本质是关联与时间线

人类的记忆不是孤立的文件柜,而是一张巨大的、动态关联的网。提到“上周的会议”,你可能会联想到“参会者张三”、“讨论的项目Alpha”、“会上做的决策B”,以及“会后产生的待办事项C”。这些元素(实体)通过“参与”、“讨论”、“产生”等关系(边)连接在一起,并且每个事件都锚定在具体的时间点(时序)。

  • 图数据库(Neo4j)的优势 :天然擅长存储和查询这种复杂的、多对多的关系网络。查询“所有与项目Alpha相关且张三参与了的会议”在关系型数据库中可能需要多次JOIN,在图数据库中则是一次高效的图遍历。
  • 时序知识图谱(Graphiti)的加持 :Graphiti在普通知识图谱之上增加了时间维度。它不仅能回答“什么和什么相关”,还能回答“A事件发生在B事件之前还是之后?”、“某个模式是何时开始出现的?”。这对于分析行为趋势、检测模式漂移至关重要。

2.2 从被动存储到主动感知的跨越

大多数记忆系统止步于“存储与检索”。Graph Memory Suite的野心在于“感知与预警”。其自我意识套件(Self-Awareness Suite)包含了16个功能模块,它们像一组持续运行的“后台守护进程”,不断分析知识图谱中新增的数据,寻找有意义的模式。

例如, drift-detection.js 会监测智能体在不同会话或使用不同模型(如GPT-4与Claude)时,其回应风格、决策逻辑是否出现不一致,这类似于检测“人格分裂”。 loop-hunter.js 会寻找那些开启了但从未被标记为结束的对话或任务线程,防止事情石沉大海。 stress-precursor.js 则尝试在用户或智能体表现出明显的疲惫或低效之前,通过分析任务密度、决策频率等模式,提前发出预警。

设计心法 :这个架构的核心思想是 “将智能体的运行状态数据化,将数据图谱化,再对图谱进行实时分析,从而产生高阶认知信号” 。它把智能体从一个执行命令的黑箱,变成了一个可以自我审视、具备一定“元认知”能力的白箱系统。

2.3 技术栈选型背后的务实考量

项目选择了Docker Compose一键部署Neo4j和Graphiti,并通过简单的HTTP API提供服务,这体现了极强的务实性。

  1. 低耦合与易集成 :智能体通过HTTP调用Graphiti API,这意味着无论你的智能体是用Python、JavaScript、Go还是任何其他语言编写的,都能轻松接入。没有复杂的SDK绑定,符合微服务的设计理念。
  2. 数据主权与隐私 :所有数据(对话记录、实体关系)都运行在你本地的Docker容器中。你的记忆不会上传到任何第三方服务器,这对于处理敏感或私人信息的场景是必须的。
  3. 成本可控 :唯一的外部依赖是OpenAI API,且仅用于生成文本的向量嵌入(Embeddings),以支持语义搜索。这部分成本极低(每百万tokens约0.13美元),而核心的图存储、计算和分析都是免费的本地资源。

3. 核心模块深度解析与实操要点

了解了“为什么”之后,我们进入“是什么”和“怎么用”。项目结构清晰,我们可以将其分为三大功能层:记忆存储层、自动化采集层和意识分析层。

3.1 记忆存储层: graphiti-memory.js

这是与Graphiti API交互的核心桥梁,提供了记忆的增删改查(CRUD)基础操作。理解其数据模型是关键。

核心数据模型:Episode(事件片段) 在Graphiti中,最基本的记忆单元是 Episode 。你可以把它理解为一段有意义的对话回合、一个完成的任务记录或任何你想记住的离散事件。

一个典型的Episode JSON结构如下:

{
  "group_id": "work-project-alpha",
  "name": "kickoff-meeting-2023-10-27",
  "episode_body": "今天与团队召开了项目Alpha的启动会。确定了张三为前端负责人,李四负责后端。主要技术栈定为React + Node.js。第一版原型 deadline 定在两周后。会上我(智能体)承诺负责编写项目初始化脚本。",
  "source_description": "团队Slack频道会议纪要",
  "source": "slack"
}
  • group_id :命名空间。用于隔离不同项目、不同用户或不同智能体的记忆。这是实现多租户或场景隔离的关键字段。
  • episode_body :记忆的内容本体。这部分文本会被自动拆解:实体(如“张三”、“项目Alpha”、“React”)和关系(如“负责”、“定为”、“承诺”)会被提取并存入图谱;同时,文本整体会通过OpenAI接口转换为向量,供后续语义搜索。
  • source source_description :元数据。记录这段记忆的来源,便于追溯和分类处理。

实操要点与避坑指南:

  1. group_id 的设计策略 :不要随意设置。建议按“智能体名称-场景”的格式规划,如 “main-assistant-work” “email-agent-personal” 。清晰的隔离能保证搜索和分析的准确性,避免记忆串扰。
  2. episode_body 的撰写质量 :这是记忆的“原材料”。为了获得更好的图谱提取效果,尽量使用陈述句,明确主语、谓语、宾语。例如,“我告诉张三下周开会”不如“我(智能体)于2023年10月27日,通过Slack向张三发送了消息,内容是关于安排下周项目评审会。”后者包含了更清晰的时间、实体和动作。
  3. 批量操作与性能 :直接使用 curl fetch 进行单条插入在测试时没问题,但在生产环境回填大量历史数据时,务必使用项目提供的 scripts/backfill-graphiti.js 脚本。它内部会做批量处理和简单的错误重试,避免频繁HTTP调用导致的性能瓶颈或API限制。

3.2 自动化采集层: auto-capture.js 与配套脚本

记忆系统如果不能自动积累,其价值就大打折扣。项目提供了开箱即用的自动化方案,主要针对与 OpenClaw (一个AI智能体框架)的集成。

auto-capture.js 的工作流程:

  1. 监听 :监控指定目录(默认是OpenClaw的会话存档目录 ~/.openclaw/agents/main/sessions/ )下的新文件。
  2. 解析 :读取新的会话文件(通常是JSON或文本格式),将其内容结构化。
  3. 提取与增强 :调用本地或云端的NLP服务(项目默认用OpenAI的嵌入模型),从会话文本中提取实体、关系和情感倾向(如果实现)。
  4. 存储 :将结构化后的数据作为一个新的 Episode ,通过 graphiti-memory.js 存入Graphiti知识图谱。

scripts/graphiti-auto-capture.js 的价值 : 这是一个“生产就绪”的守护进程脚本。它被设计成可以由 cron 定时任务调用(如每15分钟一次)。它的核心逻辑是:

  • 记录上次检查的时间点。
  • 只处理自上次检查以来新增或修改的会话文件。
  • 包含基本的日志输出和错误处理,适合在无人值守的环境下运行。

重要提示 :如果你使用的不是OpenClaw,这个脚本需要适配。关键在于理解你的智能体是如何存储会话历史的。无论是数据库中的一张表、一个日志文件,还是一个消息队列,你都需要修改脚本中的数据读取部分,将其转换为Graphiti可接受的 Episode 格式。这是一个一次性的集成工作,但却是实现自动化记忆的关键一步。

3.3 意识分析层:自我意识套件(16个模块)精讲

这是项目的精髓所在,我们挑选几个最具代表性的模块,看看它们是如何将“数据”转化为“洞察”的。

3.3.1 drift-detection.js (漂移检测)

  • 问题它解决 :你的智能体今天用GPT-4,明天换成了Claude 3,或者同样的提示词在不同时间得到了风格迥异的回答。这会导致用户体验不一致。更严重的是,在长期运行中,智能体的“行为模式”可能无声无息地发生变化。
  • 工作原理
    1. 特征提取 :从智能体的回复中提取可量化的特征。这可以是:平均句子长度、词汇复杂度、情感倾向值(积极/消极)、特定领域术语的使用频率、决策的冒险倾向评分(例如,选择“尝试新方案” vs “沿用旧方法”的比率)。
    2. 基线建立 :在初始“稳定”阶段,收集一定数量的回复,计算这些特征的平均值和标准差,建立基线模型。
    3. 持续比对 :将新的回复特征与基线进行比对。使用统计方法(如Z-score)计算偏离程度。当多个特征的综合偏离度超过预设阈值时,触发警报。
    4. 上下文关联 :警报不仅会说“检测到漂移”,还会通过知识图谱关联到发生漂移的具体会话上下文( group_id , episode_id ),方便你回溯查看“是什么话题导致了这次反常的回答”。
  • 实操配置 :关键在阈值设定。太敏感会警报泛滥,太迟钝会漏报。建议在测试期观察一段时间,根据日志手动调整 drift_threshold 参数。可以将不同 group_id (如“creative-writing” vs “code-review”)设置不同的基线,因为不同场景下智能体的合理行为模式本就不同。

3.3.2 loop-hunter.js (循环猎人)

  • 问题它解决 :在开放式对话或任务管理中,一个话题可能被暂时搁置,然后就永远被遗忘了。或者,用户和智能体陷入了一种重复性的、没有推进的对话循环。
  • 工作原理
    1. 模式定义 :“未闭合循环”在图中表现为一种特定结构。例如:一个类型为 “Task” 的节点,有 “created_at” 属性,有 “discussed_in” 关系指向多个 Episode ,但没有 “finished_at” 属性,也没有 “resolved_by” 关系。或者,在连续多个 Episode 中,出现了高度相似的关键实体组合(如反复讨论“预算”和“审批”,但没有出现“已批准”)。
    2. 图遍历查询 :模块会定期(如每天一次)在知识图谱中执行一个预定义的Cypher(Neo4j查询语言)查询,寻找所有符合“未闭合循环”模式的子图。
    3. 优先级排序 :找到的循环可能很多。它会根据循环的“年龄”(创建多久了)、关联的 Episode 数量(被讨论的热度)、以及涉及实体(如是否关联到高优先级项目)来给循环打分排序。
    4. 生成提示 :将排名最高的1-3个未闭合循环,以一种友好的方式(例如,“嘿,我注意到我们上周三讨论的‘设计官网配色方案’这个话题,后来好像没有再跟进,需要我帮你起草几个方案吗?”)插入到智能体的下一个对话回合中。
  • 避坑技巧 :小心“误报”。有些话题的讨论本就是长期和间歇性的。可以通过在 Episode 中打上 “status: paused” “next_action_date: 2023-11-15” 这样的标签,并在 loop-hunter 的查询中将这些情况排除,来减少干扰。

3.3.3 energy-predictor.js (能量预测器)

  • 问题它解决 :无论是用户还是智能体协作流程,都有状态起伏。在“崩溃”或“倦怠”发生后才干预,为时已晚。这个模块试图预测低能量期。
  • 工作原理 :这是一个更复杂的、基于时间序列的模式识别。
    1. 指标收集 :从 Episode 和相关实体中提取潜在的压力指标。例如:
      • 决策密度 :单位时间(如每小时)内,对话中出现的 “决定”、“选择”、“我认为” 等决策相关词汇的频率。
      • 任务切换频率 :在会话中,话题在不同项目/任务间跳转的次数。
      • 交互节奏 :用户两次输入之间的时间间隔突然变长或变短。
      • 文本特征 :回复文本的情感值趋向负面,或不确定性词汇( “可能”、“也许”、“不确定” )增加。
    2. 窗口滑动分析 :模块以滑动时间窗口(如过去24小时)为单位,计算上述指标的聚合值。
    3. 模式匹配与预测 :将当前时间窗口的特征向量,与历史数据中标记为“高压力期”或“低效期”之前的时间窗口特征进行相似度匹配。如果匹配度超过阈值,则预测在未来几个小时内可能进入低能量状态,并提前发出“建议休息”或“简化待办事项”的提示。
  • 注意事项 :这个模块的准确性严重依赖于高质量的历史数据和准确的“低能量期”标注。在项目初期,可以将其运行在“只记录,不报警”的学习模式下,手动标记你认为效率低下的时间段,积累训练数据。

4. 从零到一的完整部署与集成实战

理论说得再多,不如动手搭一个。下面我们走一遍从环境准备到第一个自我意识警报产生的全流程。

4.1 基础环境搭建与验证

步骤1:克隆与准备

git clone <repository-url>
cd graph-memory-suite

将项目中的 docker-compose.yml .env.example 文件仔细看一遍。 .env.example 里通常包含了需要配置的环境变量,如OpenAI API密钥和Neo4j密码。复制它并填写你的信息:

cp .env.example .env
# 使用你的编辑器打开 .env,设置 OPENAI_API_KEY 和 NEO4J_PASSWORD

步骤2:一键启动核心服务

docker compose up -d

这个命令会启动两个容器:Neo4j数据库和Graphiti API服务。 -d 参数让它们在后台运行。

步骤3:服务健康检查(关键步骤) 启动后别急着下一步,务必验证服务是否真的就绪。

# 检查Neo4j浏览器(管理界面)是否可访问
curl -s -o /dev/null -w "%{http_code}" http://localhost:17474
# 应该返回 200

# 检查Graphiti API健康端点
curl http://localhost:18000/healthcheck
# 应该返回 {"status":"healthy"}

如果返回错误或连接拒绝,使用 docker compose logs 查看容器日志,常见问题是端口冲突或Neo4j启动较慢(首次启动可能需要一分钟以上)。

步骤4:写入与查询你的第一条记忆 使用项目提供的示例 curl 命令,但让我们理解得更透彻一点:

# 添加一个事件片段(Episode)
curl -X POST http://localhost:18000/v1/episodes \
  -H "Content-Type: application/json" \
  -d '{
    "group_id": "my-first-agent",
    "name": "understanding-graph-memory",
    "episode_body": "我今天部署了Graph Memory Suite,并成功写入了第一条测试记忆。它的架构基于Neo4j图数据库,这让我能存储实体间的关系。",
    "source_description": "终端命令行测试",
    "source": "cli"
  }'

成功后会返回一个包含 episode_id 的JSON响应,记下这个ID。

接着,进行搜索测试。这里的搜索是 语义搜索 ,不是简单的关键词匹配:

curl -X POST http://localhost:18000/v1/search \
  -H "Content-Type: application/json" \
  -d '{
    "group_id": "my-first-agent",
    "query": "这个记忆系统用了什么数据库?",
    "limit": 5
  }'

即使你的查询词“数据库”没有在原文“Neo4j图数据库”中完全出现,由于向量嵌入的作用,它也能找到最相关的记忆片段并返回,返回结果会包含相似度分数。

4.2 与你的智能体集成

假设你有一个用Python写的简单聊天机器人(使用OpenAI API)。你需要修改它的代码,在每次有意义的对话结束后,将对话内容发送到Graphiti。

示例:Python智能体集成片段

import requests
import json

GRAPHITI_API_URL = "http://localhost:18000/v1/episodes"

def save_to_graph_memory(group_id, conversation_summary, user_query, ai_response):
    """
    将一轮对话总结保存到Graph Memory Suite。
    conversation_summary: 本轮对话的精华总结,用于生成高质量的记忆。
    user_query: 用户原始输入(可选,用于溯源)。
    ai_response: AI的原始回复(可选,用于溯源)。
    """
    episode_body = f"用户询问:{user_query}\\n\\n我的回答:{ai_response}\\n\\n总结:{conversation_summary}"
    
    payload = {
        "group_id": group_id,
        "name": f"chat-{int(time.time())}", # 用时间戳生成唯一名称
        "episode_body": episode_body,
        "source_description": "AI Chatbot Dialogue",
        "source": "python-chatbot"
    }
    
    try:
        response = requests.post(GRAPHITI_API_URL, json=payload, timeout=5)
        response.raise_for_status() # 检查HTTP错误
        print(f"Memory saved. Episode ID: {response.json().get('id')}")
    except requests.exceptions.RequestException as e:
        print(f"Failed to save memory: {e}")
        # 在生产环境中,这里应该加入重试逻辑或降级处理

# 在你的聊天主循环中调用
# 当一轮对话结束时:
save_to_graph_memory(
    group_id="personal-assistant",
    conversation_summary="用户询问了关于图数据库Neo4j的优势,我解释了其在处理关联数据时的性能特点。",
    user_query="Neo4j比MySQL好在哪里?",
    ai_response=ai_generated_response
)

集成策略建议

  • 异步写入 :不要让记忆写入阻塞主对话流程。可以将记忆保存任务放入一个队列(如Redis list),由后台工作线程消费。项目中的 auto-capture.js 本质上就是一个异步消费者。
  • 摘要生成 :直接保存冗长的原始对话可能不是最优的。可以先用LLM(如GPT-3.5-turbo)对对话进行摘要,提炼核心事实、决策和待办事项,再将摘要作为 episode_body 存入。这样能提升记忆质量和后续分析的效果。
  • 错误处理与降级 :网络或Graphiti服务可能暂时不可用。你的智能体应该能处理这种异常,比如将未保存的记忆暂存到本地文件,待服务恢复后重试,而不是直接崩溃。

4.3 启用自我意识模块

自我意识模块是独立的Node.js脚本,它们需要被调度执行。最简单的方式是使用系统的 cron

配置一个监测“未闭合循环”的定时任务:

  1. 首先,直接运行一次 loop-hunter.js ,确保它工作正常,并查看输出格式。
    node path/to/loop-hunter.js
    
    它可能会输出JSON格式的检测结果,或者直接调用某个通知接口(取决于脚本的具体实现,你可能需要根据 EXAMPLES.md 进行配置)。
  2. 编辑cron任务表:
    crontab -e
    
  3. 添加一行,表示每天上午9点运行一次循环检测:
    0 9 * * * cd /path/to/graph-memory-suite && /usr/bin/node ./self-awareness-suite/loop-hunter.js >> /tmp/loop-hunter.log 2>&1
    
    >> /tmp/loop-hunter.log 2>&1 将脚本的输出和错误都重定向到一个日志文件,便于调试。

更高级的调度:使用主协调器 项目提供了一个 self-awareness-suite.js 作为主协调器。你可以配置一个 cron 任务只运行这个主脚本,然后在主脚本内部配置各个子模块(漂移检测、循环猎人、能量预测等)的运行频率(例如,漂移检测每4小时一次,循环猎人每天一次)。这样更易于集中管理。

4.4 历史数据回填

如果你有过去的聊天日志、邮件归档或项目笔记,可以使用 scripts/backfill-graphiti.js 脚本进行批量导入。 这是赋予你的智能体“前世记忆”的关键一步。

操作流程:

  1. 数据准备 :脚本默认期望OpenClaw的会话格式。你需要修改脚本的 readSessionsFromDirectory 函数,使其能解析你的历史数据格式。核心是将每条历史记录转换成符合 Episode 结构的对象。
  2. 分批处理 :在脚本中,找到插入数据的循环,建议增加分批逻辑(例如,每100条数据暂停1秒),避免对本地API造成过大压力。
  3. 运行与监控
    node scripts/backfill-graphiti.js
    
    由于需要为每条记录计算向量嵌入(调用OpenAI API),回填大量数据可能需要较长时间并产生一些API费用(但很低)。务必监控进程和OpenAI API的使用量。

5. 常见问题、故障排查与性能调优

在实际部署和运行中,你一定会遇到各种问题。这里记录了一些典型场景和解决思路。

5.1 部署与连接问题

问题1: docker compose up 后, curl http://localhost:18000/healthcheck 返回 Connection refused

  • 排查步骤
    1. docker ps 检查两个容器( neo4j graphiti )是否都处于 Up 状态。
    2. 如果 graphiti 容器不断重启或处于 Exited 状态,使用 docker logs graph-memory-suite-graphiti-1 (容器名可能不同)查看其日志。最常见的原因是环境变量(如 OPENAI_API_KEY )未正确设置,或者Neo4j连接失败。
    3. 检查Neo4j是否已完全启动: docker logs graph-memory-suite-neo4j-1 ,等待出现类似“Started.”的日志。首次启动Neo4j需要初始化数据库,可能需要1-2分钟。
    4. 检查端口冲突: lsof -i :18000 lsof -i :17474 查看端口是否被其他程序占用。

问题2:写入Episode成功,但语义搜索查不到刚写入的内容。

  • 原因 :向量嵌入是异步处理的。Graphiti在接收到新的 Episode 后,会将其放入处理队列,由后台任务调用OpenAI API生成向量。这有轻微延迟(通常几秒到几十秒)。
  • 解决方案 :写入后等待片刻再搜索。在生产代码中,如果你的应用强依赖即时搜索,可以考虑在写入API的响应中等待嵌入完成(如果API支持),或者实现一个轮询机制。

5.2 自我意识模块不报警或误报太多

问题: drift-detection.js 从未触发过警报。

  • 检查基线 :该模块需要先积累一定数据(如50-100条智能体回复)才能建立有意义的基线。检查模块的日志或数据存储,看基线是否已成功创建。
  • 调整阈值 :默认的 drift_threshold 可能对你智能体的行为变化不敏感。尝试逐步调低阈值,观察日志输出,找到一个平衡点。
  • 检查特征提取 :确认模块从你的 episode_body 中提取的特征是有效的。如果所有回复的文本特征都极其相似(例如,都是简短的命令确认),那么漂移检测将无法工作。你可能需要自定义特征提取逻辑,使其更贴合你的场景。

问题: loop-hunter.js 每天报出大量无关紧要的“循环”。

  • 优化查询模式 :默认的“未闭合循环”Cypher查询可能过于宽泛。你需要根据你的数据模型对其进行精细化。例如,只将超过7天未更新且关联了高优先级标签 P0 P1 的任务视为需要报警的循环。
  • 引入白名单 :在脚本中维护一个“忽略列表”,将某些特定类型或标签的话题排除在检测之外。
  • 聚合与摘要 :不要直接报告所有循环。让脚本对相似的循环进行聚类(例如,都关于“文档撰写”),然后每天只报告最突出的1-3个类别。

5.3 性能与扩展性考量

场景:记忆条目超过10万条后,搜索速度变慢。

  • Graphiti/Neo4j索引优化 :确保为常用的查询字段建立了索引。在Neo4j Browser中执行 CREATE INDEX ON :Episode(group_id) CREATE INDEX ON :Episode(created_at) 可以加速按组和按时间的筛选。
  • 向量搜索优化 :Graphiti底层可能使用某种向量索引(如HNSW)。查看Graphiti文档,确认向量索引是否已自动创建,以及是否有参数可以调整(如 efConstruction M )以在精度和速度间取得平衡。
  • 分页查询 :在前端或客户端实现分页,不要一次性拉取过多结果。Graphiti的搜索API通常支持 limit offset 参数。

场景:自我意识模块越来越多,cron管理变得混乱。

  • 容器化与编排 :将每个自我意识模块封装为一个独立的、无状态的Docker容器。使用 docker-compose 扩展文件或更高级的编排工具(如Kubernetes的CronJob)来管理它们的调度和生命周期。
  • 消息队列驱动 :将架构改为事件驱动。当新的 Episode 被创建时,Graphiti API可以发布一个事件到消息队列(如Redis Pub/Sub或RabbitMQ)。各个自我意识模块作为消费者订阅它们感兴趣的事件类型(如“新对话事件”、“任务状态变更事件”),进行实时处理,而非定时轮询。这能大大降低延迟和系统负载。

5.4 定制化开发指南

项目提供的16个模块是绝佳的起点,但真正的力量来自于你根据自身需求定制和创造新的“意识”。

如何创建一个新的自我意识模块? 以“检测用户对某个话题的兴趣衰减”为例,我们称其为 interest-decay.js

  1. 定义模式 :在知识图谱中,什么代表“兴趣”?可能是用户主动询问某个主题(如“机器学习”)的频率,或是围绕该主题对话的深度。衰减则表现为频率下降或深度变浅。
  2. 编写Cypher查询 :编写一个查询来量化“兴趣度”。例如,计算过去7天内,包含实体“机器学习”的 Episode 数量,并与再之前7天的数量做对比,计算下降百分比。
    // 伪代码示例
    MATCH (e:Episode)-[:CONTAINS_ENTITY]->(ent:Entity {name: '机器学习'})
    WHERE e.created_at > date().duration('-14 days')
    WITH 
      sum(CASE WHEN e.created_at > date().duration('-7 days') THEN 1 ELSE 0 END) AS recent_count,
      sum(CASE WHEN e.created_at <= date().duration('-7 days') AND e.created_at > date().duration('-14 days') THEN 1 ELSE 0 END) AS previous_count
    RETURN recent_count, previous_count, (1.0 * recent_count / NULLIF(previous_count, 0)) AS ratio
    
  3. 实现逻辑 :在Node.js脚本中执行该查询。如果 ratio 低于某个阈值(如0.5),且 previous_count 足够大(避免从1次降到0次的误报),则触发逻辑。
  4. 生成洞察 :触发后,可以生成一条自然语言消息:“注意到您最近一周讨论‘机器学习’的次数比前一周下降了60%,需要我为您整理一些该领域的最新动态吗?”
  5. 集成到系统 :将你的 interest-decay.js 加入到 self-awareness-suite.js 的调度列表中,或者为其单独设置一个 cron 任务。

这个从数据到洞察的闭环,正是Graph Memory Suite赋予你的核心能力——将冰冷的交互日志,转化为有温度的、可行动的智能。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐