• 自己使用C++开发的仿OpenClaw、Hermes智能体工具


    使用C++开发的原因是我只会C/C++,虽然熟悉一点Python,但只能勉强上手,对于开发复杂度较高的项目,就会捉襟见肘。相较于Python、TypeScript等脚本语言,使用C++开发的难度比较大,由于缺少第三方库的原因,很多看似简单的功能都要亲自实现,哪怕是json解析。
    比如一开始就遇到的通信问题,也就是大模型的流式(SSE)输出,尤其是这种输出是以chunk的方式到来。对于Python来说,通信这块可能连问题都算不上,因为只需要导入OpenAI库,就能解决所有的通信问题。
    对于C++来说,现有的HTTP API显然无法满足这种要求,因此实现一个基于HTTP协议的、稳定的、健壮的、异步的通信就只能亲自动手实现了。这就意味要用原始socket实现一边接收数据,一边组装数据,一边解析数据,一遍展现数据。

    实际上即使你完成了上述通信工作,也仅仅是个开始,接下来还有更多的来自业务层的问题等待你去解决:

    1、通信过程中用户取消了会话;
    2、多轮会话中用户取消了当前会话;
    3、如何处理工具调用超时或异常,比如始终无法与一个远程MCP服务建立通信,或者外部工具一直不返回结果;
    4、如何处理多工具调用:是多线程并发处理还是一个一个处理?如果其中一个异常该如何解决?
    5、工具调用过程中,如果用户取消会话如何处理?如何优雅的解决掉正在执行中的工具调用?
    6、工具返回数据过大如何处理,比如通过工具读取文件内容?
    7、多轮会话如何防止上下文窗口爆炸?
    8、多轮会话如何实现实时持久化,从而保证用户取消或程序异常退出时能够恢复当前会话?
    ...

    上述这些不是异常,而是业务层实实在在会遇到的问题,一旦处理不好则会导致灾难性的后果,除非你只是写一个demo。

    即使处理好上述工作也仅仅是让你的Agent实现了基本的chat功能,如何让Agent拥有“记忆”和“自我进化”的能力才是目前主流Agent的发展趋势,这也就是OpenClaw和Hermes流行的原因。
    上述基础开发工作已经让我精疲力竭,“记忆”和“自我进化”只能在理解上述两个Agent的基础上去尽可能的实现,功能不是最重要的,设计思想才是最重要的
    没苦硬吃的好处就是可以完全理解大模型和Agent之间的工作原理,以及可能会遇到的各种坑。下面介绍一下AIAgent特点,先放一段视频:
    Agent基本演示之多轮会话

    一、软件开发特点

    • 完全使用C++开发,除Openssl和Sqlite外未使用任何第三方库,自主实现如下功能:
      异步网络通信、HTTP会话、SSE流式数据解析、多轮会话管理、工具调用及MCP管理、长期记忆管理、技能沉淀等功能;
    • 纯绿色软件,除依赖库外不到800K,无需安装,拷贝即可使用,
      C++开发难点也是它的优点,就是没有部署依赖,既不需要安装Python也不用安装Node.js,以及对应庞杂的依赖库。

    下载地址:http://www.softlee.cn/AIAgent.zip
    使用前先设置DeepSeek的API Key,请前往 DeepSeek官网申请API Key
    PS:zip包中AIAgent.exe是主执行程序,AIMemory.exe为记忆管理工具,AIAgent会调用AIMemory进行记忆和技能沉淀。

    二、支持上下文管理和长期记忆

    • 支持长期记忆管理:使用文件、数据库、向量数据库三种存储方式实现不同层次的记忆保存

      1.1 文件:全量保存每轮会话的全部内容,用于历史会话恢复以及后续数据挖掘(持续优化记忆功能);
      1.2 数据库:仅保存每轮会话问答,不保存工具调用结果,方便用户按关键字查找历史会话消息;
      多轮会话可能存在大量的“非显示”工具调用内容,用户一般无法感知,这些工具调用结果可能会比较大,比如文件读取,
      这种非显示的工具调用结果只是中间数据,不是最终结论,用户其实无需关心。
      1.3 向量库:保存重要会话的“压缩”摘要,实现语义级搜索,方便Agent进行历史消息查找;

    • 支持记忆沉淀和跨会话记忆恢复,围绕用户(人)和工作(事)两个维度沉淀长期记忆。
      1.1、用户相关记忆包括:用户的身份、行事风格、工作习惯、行为偏好等;
      1.2、工作相关记忆包括:用户使用的开发工具、语言、环境等,可能从事的工作领域和常用的办公软件等;

    • 支持可控上下文管理
      1.1、支持滑动上文窗口管理,可手动配置窗口大小;
      1.2、支持上下文长度报警,当上下文超过手动设定的阀值触发报警;

    • 长期记忆的提取和沉淀时机。采用如下两种方式:
      1.1、一种是LLM根据当前会话内容自主判断是否具备沉淀价值,如果具备则触发记忆沉淀,即调用子Agent(AIMemory.exe)进行记忆提取和沉淀;
      1.2、另一种是用户手动进行记忆沉淀,手动也分两种方式:一种运行时沉淀,用户在对话过程中明确要求沉淀,比如告诉LLM帮我记住此次会话或其它类似表达方式。另一种是事后沉淀,用户可通过查看历史消息并对有价值的对话进行记忆沉淀。
      通过上述两种方式,可以确保记忆不被“遗忘”。如果Agent没有及时沉淀记忆,用户还可以进行“补救”操作。

      为何这样设计?
      Agent在记忆方面是“慢热”的,需要长期积累,也就是说他和用户之间有一个熟悉过程。在此过程中就不可避免的会出现LLM觉得无需沉淀,但用户觉得可以沉淀的情况。通常LLM会被Prompt严格限制,因此更加趋于“保守”
      通常用户在编写Prompt时会要求Agent沉淀最重要的、具有长期价值的会话,而不是闲聊。无论你如何设计Prompt都很难在早期避免这种情况,
      如果Prompt写的过于宽松,就会导致记忆过载,一旦记忆过载或被“污染”,则记忆本身的价值就失去了。只有用多了,Agent才能知道哪些内容对用户是有价值的,用户关心的是什么,这就是小龙虾为何要用“养”这个字,Hermes为何越用越懂你的原因。

    记忆这块不存在最好的解决方案,只有最合适的解决方案,不同业务模式和流程对应的记忆侧重点可能是完全不同的。
    比如面向编程业务的Claude Code,此时不仅要记住过往的重点内容,还要记忆当前的工作状态,即最近用户操作的文件、函数、错误日志、解决方案等。如果你面临的业务是电商,显然无法套用Claude Code的记忆管理方式。
    正因如此原封不动的保留原始会话的内容非常重要和关键,因为记忆的提取、归纳和召回是可以在后续不断改进和优化的,只要原始对话数据存在,这种优化改进才能在以后得以实现。整个Agent的工作其实大部分就是围绕“记忆”的保存、提取和召回开展的。

    图一、历史会话消息,以文件形式保存,方便Agent恢复会话

    AIAgent_会话记录

    图二、会话详情

    AIAgent_对话详情

    图三、 历史会话消息,保存于Sqlite数据库,方便用户查找

    AIAgent_数据库存储

    三、支持技能自主沉淀;

    • 内置CLI功能(支持cmd和powershell)和文件读写操作;
    • Agent通过上述内置功能自主实现skill的沉淀;

    个人认为,CLI对于Agent而言就是最好、最合适的工具! 如果不加限制的使用CLI,你的Agent一定可以做出很多你想不到的事情。
    理论上Agent可以通过CLI操作所有工具,甚至可以调用CLI安装它所需要的工具,并进行学习使用,从而完成自主学习
    很多CLI工具,其命令行参数非常庞大,一般用户很难记住,但对于大模型来说则完全不是问题。
    对于大模型,Python是其最熟悉的语言,甚至比大部分开发人员更加熟悉,起码编写后不会出现语法错误。
    正因如此,开放文件的读写就显得非常重要,对于复杂的任务,Agent完全可以通过文件操作写一段Python脚本,并将其执行,从而实现最终的目的。
    在此过程中skill的积累是自然而然的,你只需要让Agent知道需要进行Skill积累这件事就行了,它通常比你还了解这些“技能”以及使用过程中踩过的坑,因此它会比你亲自管理这些技能要好很多。

    基于上述原因,内置CLI和文件读写操作就非常有必要,它几乎是一个通用Agent的标配

    四、其它特色功能

    • 支持远程MCP功能管理,按需启动远程工具;
    • 提供MCP的ToolCall编辑功能;
    • 支持OpenAI和Anthropic两种API数据格式;
    • 支持微信接入(考虑到微信几乎是国民必备,优先实现微信接入,用C++开发有难度,实在无力接入太多);
    • 支持多轮会话中的查找:按词查找和按会话查找;

    远程MCP管理

    AIAgent_MCP管理

    微信ClawBot接入会话

    AIAgent_weixin

    多轮会话内容查找

    AIAgent_chat_search

  • 相关阅读:
    C++闲谈04——设计模式
    目前和未来的缓存构建
    【工作总结】工作累死累活,结果越做越差怎么办?
    【Linux】软件管理yum | 编辑器vim | vim插件安装
    JVM_逃逸分析
    数据结构(递归,链表实现递归)
    springBoot入门
    网络编程:网络超时检测(select poll setsockopt alarm)
    virtualbox基本配置
    需求文档中的“项目前景与范围”
  • 原文地址:https://www.cnblogs.com/softlee/p/20120277