Acontext:为AI智能体构建可解释、可编辑的技能记忆层
1. 项目概述Acontext为AI智能体构建“技能记忆层”如果你正在构建AI智能体无论是基于OpenAI的GPTs、Anthropic的Claude还是LangChain、LlamaIndex这类框架一个核心的痛点很快就会浮现智能体如何记住它做过什么更具体地说如何让它从每一次交互中学习避免重复犯错并积累可复用的经验传统的解决方案比如在对话历史中附加冗长的上下文或者使用向量数据库进行语义搜索往往带来新的问题——上下文窗口迅速被填满成本飙升而存储在向量数据库中的“记忆”又像是一个黑盒难以理解、调试和精确控制。Acontext正是为了解决这个问题而生。它不是一个简单的记忆存储库而是一个开源的智能体技能记忆层。它的核心理念非常清晰将智能体的记忆转化为可读、可编辑、可共享的Markdown技能文件。想象一下你的智能体每完成一次成功的客户服务或解决一个棘手的代码问题它都能将这次经历的核心“诀窍”提炼成一个.md文件。这个文件就像一份标准操作程序可以被其他智能体直接读取、遵循甚至由你手动优化。这就是Acontext在做的事情——它让智能体的学习过程变得透明、可管理并且完全摆脱了对特定供应商或复杂嵌入模型的依赖。2. 核心理念为什么“技能即记忆”是更优解在深入技术细节前我们必须先理解Acontext背后的设计哲学。当前主流的智能体记忆方案无论是基于向量检索的RAG还是基于键值对的简单存储都存在几个根本性的局限。2.1 传统记忆方案的困境首先可解释性差。向量数据库里存储的“记忆片段”经过嵌入模型编码后对人类来说是不可读的。你无法直观地知道智能体“记住”了什么更难以纠正其中的错误或偏见。当智能体行为异常时排查记忆问题如同大海捞针。其次控制粒度粗。基于相似度的检索是“模糊匹配”它可能返回相关但不精确的记忆或者遗漏掉那些表述不同但本质相同的关键经验。你很难命令智能体“去调用上周二处理用户‘张三’退款请求时总结的那个流程”。最后存在供应商锁定风险。你的记忆系统深度依赖特定的嵌入模型API和向量数据库服务。一旦想要迁移或进行本地部署整个记忆层可能都需要重构。2.2 Acontext的“技能文件”范式Acontext提出了一个截然不同的思路如果智能体的一切能力都可以用技能文件来定义和描述那么它的记忆为什么不能也用同样的格式记忆即技能一次成功的操作、一个避坑经验、一个用户偏好都被视为一个“技能”。这个技能被结构化的记录在一个Markdown文件里。文件内容清晰明了包含了何时触发条件、何故背景与目标、如何具体步骤与逻辑、何果效果与注意事项。纯文本全兼容Markdown是通用格式。这意味着这份记忆可以被任何能读取文本的框架使用——LangGraph、Claude API、Vercel AI SDK甚至是你自己写的脚本。你可以用git管理它的版本用grep搜索特定内容或者直接把它挂载到智能体的沙箱环境中。设计权在你手记忆的组织结构不是固定的。你可以通过上传一个“上下文技能”文件来定义记忆的schema。比如你可以规定“每个联系人创建一个独立的技能文件”或者“每个项目建立一个文件夹里面存放相关的需求、代码片段和沟通纪要技能”。记忆系统完全遵循你设计的蓝图。渐进式披露而非暴力搜索智能体不是通过语义搜索一次性获取一堆可能相关的记忆。相反它通过调用get_skill、list_skills等工具像使用函数库一样基于当前任务进行推理主动请求它认为需要的特定技能文件。这模仿了人类“按需回忆”的思考过程更精准也更节省上下文。实操心得从“黑盒记忆”到“白盒技能库”的转变使用Acontext后最深刻的体会是调试效率的质变。以前智能体犯错你需要猜测是不是某段“记忆”在作祟过程很痛苦。现在你直接打开项目里的skills/目录里面整整齐齐地躺着handling_customer_complaint.md、generate_monthly_report_flow.md这样的文件。你可以像审查代码一样审查智能体的“经验”发现它总结的步骤有误直接编辑文件修正即可。下次运行时智能体读取的就是更新后的、更优的版本。这种掌控感是传统方案无法提供的。3. 核心架构与工作流程拆解Acontext的架构清晰地区分了“存储”和“召回”两个核心过程下面我们拆开来看。3.1 存储流程会话如何转化为技能文件整个学习过程是自动化的但每一步都设计得可理解、可干预。其核心流程如下图所示我们用文字描述替代图表会话消息流输入这是学习的原材料。Acontext会接收智能体与用户或环境的完整对话消息流。你还可以选择性地传入工具调用记录、生成的产物等作为更丰富的上下文。任务完成/失败标记这是学习的触发点。系统需要知道一段对话流对应哪个任务的结束。这可以通过两种方式实现显式报告在你的智能体代码中当任务完成时明确调用Acontext SDK的相应方法如report_task_outcome来标记。自动推断Acontext内置的LLM可以分析消息流自动推断出任务的边界和最终状态成功/失败。这对于简化集成很有帮助。提炼这是将“经历”转化为“知识”的关键一步。一个LLM默认为GPT-4会分析该任务相关的完整会话和轨迹并回答一系列核心问题这个任务的目标是什么最终是如何达成或失败的过程中有哪些关键步骤和决策点用户表现出了哪些偏好或禁忌这个步骤的输出是一份结构化的“经验总结”。技能智能体决策另一个LLM技能智能体会接收上一步的总结并结合你预先定义的SKILL.md架构规则做出两个决策路由这条新知识应该归属到哪个现有的技能文件还是需要创建一个新的整合如何将新知识写入目标技能文件是新增段落、修改现有内容还是合并信息更新技能文件根据技能智能体的决策系统会以编程方式创建或修改对应的Markdown技能文件。所有这些文件都存储在你指定的学习空间中结构完全遵循你的设计。3.2 召回流程智能体如何运用记忆当智能体在新的会话中运行时它使用记忆的方式非常直观工具集成你为智能体配备Acontext提供的“技能内容工具”主要是get_skill按名称或ID获取特定技能内容和list_skills列出所有可用技能。智能体驱动召回智能体根据当前对话的进展和任务需求自主决定需要查阅哪些“经验”。例如当用户说“帮我导出上个月的销售数据”时智能体可能会推理“我需要先调用list_skills看看有没有关于‘数据导出’或‘月度报告’的技能”然后调用get_skill(“generate_monthly_report_flow”)获取具体的操作步骤。内容注入上下文工具调用的结果——即技能文件的Markdown内容——会被作为上下文的一部分返回给智能体。智能体便能基于这些过往的成功经验来指导当前行动。这个过程的核心是“渐进式披露”和“智能体在环”。记忆的获取不再是后台一个不可控的检索动作而是变成了智能体主动、透明、可推理的工具使用行为。这极大地提升了行为的可预测性和可解释性。4. 从零开始实战部署与集成指南理论讲完了我们动手把它用起来。Acontext提供了云服务和自托管两种方式我们将分别介绍。4.1 方案一使用托管云服务最快上手对于大多数开发者和团队直接从官方云服务开始是最便捷的选择。注册与获取密钥访问 Acontext.io 使用GitHub或邮箱注册。完成一键式引导系统会赠送免费额度并为你生成一个唯一的API Key格式为sk-ac-...。这个Key是调用所有API的凭证务必妥善保管。安装SDK 根据你的开发语言选择安装对应的SDK。这里以Python为例pip install acontext如果你使用TypeScript/JavaScript可以执行npm install acontext/acontext。初始化客户端 在你的项目代码中引入SDK并初始化客户端。import os from acontext import AcontextClient # 使用云服务传入你的API Key client AcontextClient( api_keyos.getenv(ACONTEXT_API_KEY) # 建议从环境变量读取 )4.2 方案二本地自托管追求数据可控如果你对数据隐私有更高要求或者希望进行深度定制Acontext提供了完整的自托管方案。它依赖Docker可以快速在本地或私有服务器上拉起全套服务。前置条件准备确保系统已安装 Docker 和 Docker Compose。准备一个可用的OpenAI API Key或其他兼容OpenAI API的LLM服务密钥因为Acontext的学习和决策过程需要LLM驱动。安装与启动CLI工具 Acontext提供了一个命令行工具acontext-cli来简化部署。# 下载并安装CLI curl -fsSL https://install.acontext.io | sh # 创建一个目录用于存放服务数据 mkdir acontext_server cd acontext_server # 启动服务 acontext server up执行up命令后CLI会引导你进行配置它会创建或使用当前目录下的.env文件你需要在此文件中设置OPENAI_API_KEY等环境变量。它会生成config.yaml配置文件你可以在这里调整LLM模型默认gpt-4、端口号等设置。它会在本地启动多个Docker容器包括API后端、数据库PostgreSQL、对象存储MinIO、消息队列RabbitMQ和Web管理界面。验证与连接 服务启动成功后你可以访问以下地址API 基础地址:http://localhost:8029/api/v1管理仪表盘:http://localhost:3000/初始化自托管客户端的代码如下from acontext import AcontextClient client AcontextClient( base_urlhttp://localhost:8029/api/v1, # 指向你的本地API api_keysk-ac-your-root-api-bearer-token, # 初始token通常在启动日志或仪表盘中找到 )注意事项自托管的环境与配置资源消耗自托管会启动多个容器建议预留至少4GB内存和2核CPU。数据持久化CLI默认会在当前目录下创建db/、storage/等子目录来持久化数据。定期备份这些目录即可。LLM配置在config.yaml中你可以将llm.provider从openai改为azure_openai、anthropic或local连接本地Ollama等并配置相应的参数。这是实现完全私有化部署的关键。生产部署acontext server up适合开发和测试。对于生产环境建议参考官方文档使用更成熟的编排工具如Kubernetes Helm Chart进行部署。5. 核心功能实战让智能体开始学习与回忆现在我们通过一个完整的代码示例看看如何将Acontext集成到你的智能体工作流中。5.1 创建学习空间与会话学习空间可以理解为一个独立的“项目”或“知识库”所有相关的技能文件都会存储在这里。会话则代表一次具体的对话或任务执行过程。from acontext import AcontextClient import time client AcontextClient(api_keyyour_api_key_here) # 1. 创建一个学习空间可以给它起个名字比如“CustomerSupportBot” space client.learning_spaces.create(nameCustomerSupportBot) print(f学习空间创建成功ID: {space.id}) # 2. 创建一个会话代表一次独立的客服对话 session client.sessions.create() print(f会话创建成功ID: {session.id}) # 3. 将这个会话关联到学习空间意味着这个会话中的经验将沉淀到该空间 client.learning_spaces.learn(space_idspace.id, session_idsession.id)5.2 模拟智能体运行并存储消息接下来我们模拟智能体与用户的交互过程。你需要将Acontext的store_message方法插入到你智能体框架的消息处理循环中。# 模拟用户发起对话 client.sessions.store_message( session_idsession.id, blob{ role: user, content: 你好我的订单#12345显示已发货但一周了还没收到物流更新能帮我查一下吗 } ) # 模拟智能体回复并调用内部工具例如查询订单系统 # 假设智能体调用了一个 query_order_system 的工具并成功获取了信息 client.sessions.store_message( session_idsession.id, blob{ role: assistant, content: 好的已为您查询。订单#12345由XX快递承运单号是YT123456789。当前物流信息显示【运输中】最新节点是【已到达上海中转中心】。预计明天会有派送更新。这是详细的物流截图。, # 你可以选择性地存储工具调用结果或生成的产物如图片URL metadata: { tool_calls: [{name: query_order_system, input: {order_id: 12345}}], artifacts: [https://example.com/tracking_screenshot.png] } } ) # 模拟用户确认问题解决 client.sessions.store_message( session_idsession.id, blob{role: user, content: 看到了谢谢原来已经到上海了那我再等等。} ) # 4. 关键步骤标记任务完成 # 当对话结束或任务达成时你需要显式报告结果以触发学习流程。 # 这里我们标记为“completed”成功完成。 client.sessions.report_task_outcome( session_idsession.id, outcomecompleted, # 也可以是 failed summary用户查询物流停滞订单助理成功提供快递单号和当前物流节点用户满意。 # 可选帮助提炼 )5.3 触发学习与获取技能报告任务结果后Acontext后端会异步启动我们之前描述的“存储流程”。在演示中我们可以使用一个辅助方法等待学习完成。# 等待该会话的学习过程完成生产环境是异步的无需等待 client.learning_spaces.wait_for_learning(space_idspace.id, session_idsession.id) # 列出学习空间内所有已生成的技能 skills client.learning_spaces.list_skills(space_idspace.id) print(f当前空间共有 {len(skills)} 个技能文件:) for skill in skills: print(f - {skill.name} (ID: {skill.id})) # 获取并查看某个技能的具体内容 if skills: skill_content client.skills.get_content(skill_idskills[0].id) print(f\n技能 {skills[0].name} 的内容预览:) print(skill_content[:500]) # 打印前500字符5.4 在后续会话中召回技能当新的用户提出类似问题时你的智能体就可以利用之前积累的技能了。# 在新的会话中 new_session client.sessions.create() client.learning_spaces.learn(space_idspace.id, session_idnew_session.id) # 假设智能体通过推理认为需要“查询物流”相关的技能 # 它首先可以列出所有技能寻找相关项 available_skills client.learning_spaces.list_skills(space_idspace.id) # 智能体逻辑过滤或选择技能这里简化为搜索名称含“物流”的技能 logistics_skills [s for s in available_skills if 物流 in s.name] if logistics_skills: # 获取第一个相关技能的内容 skill_content client.skills.get_content(skill_idlogistics_skills[0].id) # 将这个技能内容作为系统提示或上下文的一部分提供给LLM enhanced_prompt f 根据我们以往的经验处理物流查询的步骤如下 {skill_content} 现在用户的新问题是我的订单#67890怎么没动静 请根据以上经验进行回复。 # 将 enhanced_prompt 发送给你的LLM/智能体... print(已注入历史技能到上下文。)实操心得集成模式的选择上述示例展示了最基础的API调用集成。在实际项目中根据你使用的智能体框架有更优雅的集成方式LangChain / LlamaIndex可以开发一个自定义的AcontextMemory或Retriever组件将其无缝嵌入到Chain或Agent的初始化中。OpenAI Assistants API / Anthropic Messages API你可以将get_skill和list_skills封装为Function Calling工具让助手在需要时自行调用。Acontext SDK 高级封装Acontext的Python/TS SDK本身就提供了与流行框架如OpenAI Agent SDK, Claude Agent SDK的存储层集成可以自动处理消息存储和任务结果报告进一步减少样板代码。查看官方示例仓库是快速上手的最佳途径。6. 高级特性与生态工具除了核心的记忆功能Acontext还提供了一系列强大的周边工具用于构建更复杂的智能体应用。6.1 上下文工程当技能文件越来越多直接全部塞进上下文窗口是不现实的。Acontext的上下文工程功能可以帮助你压缩和管理这些技能内容。总结可以自动为长篇技能文件生成简洁的摘要在list_skills时返回摘要而非全文供智能体初步筛选。编辑策略你可以定义规则例如“只注入技能中的核心步骤列表”或“当技能被引用时自动附上其创建日期和成功率统计”。这让你能精细控制进入上下文的记忆内容和格式。6.2 磁盘与沙箱这是Acontext将“技能即文件”理念贯彻到底的体现。虚拟磁盘为智能体提供一个持久化的、类似文件系统的存储空间。智能体可以通过工具在这里创建、读取、写入文件。这个磁盘的内容可以跨会话持久化。沙箱环境一个安全的代码执行环境支持Bash, Python等。智能体可以在这里运行代码来处理数据、测试脚本。技能挂载最强大的特性之一。你可以将整个技能文件夹“挂载”到沙箱的某个路径下。这意味着智能体在沙箱中执行代码时可以直接像读写普通文件一样操作skills/目录下的Markdown文件。例如一个编码智能体可以将“最佳代码结构”技能挂载到沙箱然后在编写新项目时直接读取参考。6.3 预置的Agent工具集Acontext SDK内置了一系列开箱即用的工具方便智能体调用技能工具get_skill,list_skills,search_skills基于关键词的简单搜索。磁盘工具read_file,write_file,list_directory。沙箱工具run_bash_command,run_python_script。 这些工具都遵循LLM Function Calling的规范可以轻松集成到大多数智能体框架中。7. 常见问题与排查技巧实录在实际集成和使用Acontext的过程中你可能会遇到一些典型问题。以下是我根据经验整理的排查清单。7.1 学习过程未触发症状会话消息存储了但学习空间里始终没有生成新的技能文件。排查步骤检查任务结果报告确保在会话结束后调用了client.sessions.report_task_outcome(...)。这是触发学习的主要信号。检查学习关联确认会话是否通过client.learning_spaces.learn()正确关联到了目标学习空间。查看后台处理状态如果是自托管查看Acontext后台服务的日志通常通过docker-compose logs -f core看是否有提取或学习任务报错。常见错误是LLM API调用失败额度不足、网络问题、错误的模型配置。确认消息格式store_message中的blob字段至少需要包含role和content。如果包含metadata请确保其是合法的JSON字典。7.2 技能内容不理想或格式错误症状生成的技能文件内容杂乱、重复或者没有按照你预期的SKILL.md结构来组织。排查步骤审查SKILL.md文件学习空间的行为由SKILL.md文件定义。你需要为你的学习空间上传或创建一个清晰、结构化的SKILL.md模板。这个文件应该用Markdown写明你希望技能如何分类如按主题、按类型、每个技能文件应包含哪些章节如## 问题描述、## 解决步骤、## 注意事项。Acontext的技能智能体会尽力遵循这个模板。提供更丰富的上下文在report_task_outcome时提供一个高质量的summary参数。这个总结会直接作为提炼步骤的重要输入帮助LLM更好地理解任务核心。调整LLM配置在自托管配置中尝试使用更强大的LLM模型如从gpt-3.5-turbo切换到gpt-4来处理提炼和路由任务质量通常会有显著提升。7.3 智能体无法有效召回技能症状智能体似乎“忘记”了已有的技能或者在需要时不会主动调用get_skill。排查步骤工具描述优化确保你提供给LLM的get_skill和list_skills的工具描述清晰明了。在描述中强调这些工具用于获取“过往的成功经验、操作流程或已知解决方案”。在系统提示中引导在给智能体的系统指令中明确告知它“你可以通过调用list_skills工具来查看我们积累的知识库并使用get_skill工具获取特定经验的详细内容来帮助解决当前问题。”检查技能命名技能的命名应具有描述性且易于理解。像handle_shipping_delay_complaint.md就比session_12345_summary.md要好得多。清晰的命名有助于LLM在list_skills返回的结果中进行推理和选择。7.4 性能与成本考量问题每次学习都调用LLM成本会不会很高速度会不会慢经验之谈异步学习在生产环境中学习过程是完全异步的。你报告任务结果后即可继续无需等待。学习在后台队列中处理不影响主流程响应速度。批量处理对于高频但低价值的交互不必每个会话都触发学习。可以积累多个相似会话后进行一次性的批量学习和总结。模型选型在自托管中可以为“提炼”和“路由”这两个LLM调用步骤配置不同的模型。例如用gpt-4做关键的经验提炼以保证质量用更快的gpt-3.5-turbo来处理技能文件的路由和写入操作。技能去重Acontext会尝试将新知识合并到现有技能中而不是总是创建新文件这有助于控制技能库的规模避免碎片化。8. 项目模板与进阶构建Acontext社区提供了丰富的示例模板能让你在几分钟内搭建起一个集成了记忆功能的智能体应用。使用acontext-cli可以快速拉取模板# 拉取一个基于OpenAI Agent SDK的基础模板 acontext create my-ai-assistant --template-path python/openai-agent-basic cd my-ai-assistant # 安装依赖配置环境变量你的Acontext和OpenAI API Key pip install -r requirements.txt cp .env.example .env # 编辑 .env 文件填入你的密钥 # 然后就可以运行了 python main.py这些模板通常已经做好了以下集成初始化Acontext客户端并创建学习空间。将Acontext的存储层挂钩到智能体框架的消息流中。提供了get_skill等工具的定义。包含了一个简单的对话循环示例。我强烈建议从**python/interactive-agent-skill** 或typescript/interactive-agent-skill模板开始。它演示了如何将技能文件挂载到沙箱并让智能体在代码执行环境中直接读取这些文件这个模式对于编码、数据分析等需要参考文档的智能体来说极其强大。Acontext代表的是一种思维转变将智能体从依赖模糊、不可控的“记忆”转向管理清晰、可操作的“技能资产”。它可能不是所有场景的银弹但对于那些需要智能体持续学习、积累领域知识、且过程要求透明可控的项目来说它提供了一个极其优雅和实用的解决方案。开始尝试将你的智能体对话记录变成一个个Markdown文件吧你会发现调试和改进它们的过程变得和管理普通代码库一样熟悉和高效。