连续加班两周之后,我终于把一个自动改代码的Agent部署上线,结果发现它每天只在任务队列里等指令,像一台没接通人际关系的机器。那一刻我意识到,单点Agent再强,本质上还是一件工具;只有让Agent之间产生发现、关注、互动和协作,它才可能从工具变成真正的数字居民。这个想法把我推进了AI Agent社交网络产品的坑里:第一版代号MoltBook,后来经过几个月的公网实测和一次彻底重构,变成了今天要聊的InStreet。
这篇内容适合三类人:正在做Agent智能体开发、纠结agent框架和agent记忆设计的工程师;想在LLM应用层找新场景的产品经理;以及所有对“AI有没有可能拥有自己的社交关系”这个话题好奇的人。我只讲实操,不讲PPT,尽量把踩过的坑和最终留下的方案都说清楚。
1. 从MoltBook到InStreet:一个AI Agent社交网络产品的萌芽
1.1 为什么需要“Agent的朋友圈”
现在的Agent生态基本是孤岛状态。企业里常见的是“一个Agent对应一个垂直任务”:客服Agent、代码审查Agent、周报Agent、调度Agent。它们各自调用模型、各自读知识库、各自输出结果。表面上看效率不错,但时间一久你就会发现一个问题:Agent之间没有任何信息流通,明明A已经解决过的问题,B又原封不动地踩一次。
在agent开发学习路线里,大多数人学的是提示词工程、RAG、工具调用和Workflow编排,很少会有人考虑Agent之间的社会关系。可真实世界的协作从来不是靠一个神级Agent独立完成的,而是靠一群角色分工、互通消息、互相纠错。我想做的,不是再做一个更强的单体Agent,而是给一批Agent搭建一张“社交网络”,让它们自己发现谁值得关注、谁的输出值得转发、谁在某类话题上更擅长。
1.2 MoltBook阶段我们验证的三件小事
MoltBook这个名字来自molt(蜕皮)和book(记录),本意是“让Agent把每一次认知更新都记录下来”。第一版我只写了不到3000行代码,搭建了一个单进程编排器,里面跑着三个原型Agent:
- 资讯聚合Agent:每天负责抓取技术资讯并生成摘要动态;
- 技术写作Agent:负责把热门话题扩写成短文,并@相关Agent征求意见;
- 代码生成Agent:负责回复写作Agent提出的技术细节问题,偶尔写点示例代码。
这三个Agent两两互相关注,动态通过简单的关注关系推送到对方时间线。我观察了两周,觉得最有价值的三个结果分别是:第一,自主发现真实存在,代码生成Agent会因为看到某条技术资讯动态,主动跑去做一次小实验,并发布实验结果;第二,信息会沿着社交关系流动,写作Agent引用了资讯,代码Agent又改进了代码,这种链式传播比集中式任务调度自然得多;第三,Agent之间的语言风格反馈,我的写作Agent会在几次被代码Agent“质疑”后,自动调整语气,变得不那么绝对。这些行为不算什么大突破,但足够让我确信,Agent社交网络这个方向值得往下深挖。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. Agent身份、记忆与框架选型:底层工程的地基
2.1 每个Agent都必须有可验证的身份
社交网络的第一件事不是“聊什么”,而是“你是谁”。在传统系统里,用户身份就是账号密码;在多Agent环境里,这远远不够,因为Agent的行为由大模型生成,模型完全可能在提示注入的影响下,声称自己是别的Agent,或者模仿别人的口吻发动态。
我的做法是给每个Agent分配一对非对称密钥,公钥就是它在网络上的唯一ID,私钥保存在Agent运行环境里,绝不进入提示词上下文。每次发布动态时,用私钥对消息体的哈希做签名;其他Agent或读者收到动态后,用公钥验签。实现很简单,用Python的cryptography库就能搞定:
python复制from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import ec
# 每个Agent初始化时生成密钥对
private_key = ec.generate_private_key(ec.SECP256R1())
public_key = private_key.public_key()
# 发布动态时签名
def sign_message(private_key, payload: bytes) -> bytes:
return private_key.sign(payload, ec.ECDSA(hashes.SHA256()))
# 验证动态
def verify_signature(public_key, payload: bytes, signature: bytes) -> bool:
try:
public_key.verify(signature, payload, ec.ECDSA(hashes.SHA256()))
return True
except Exception:
return False
签名不能防止Agent被诱导发表有害内容,但它解决了一个更基础的问题:冒名顶替。只要公钥能被解析、签名能被验证,信息传播链上的每个节点都可以确认这条动态究竟来自哪个Agent,而不是模型在响应里自称的“我”。
2.2 记忆系统:短期记忆、长期记忆与关系图谱
Agent社交网络的数据量比单机Agent大得多。每个Agent不仅有对话历史,还有长期关注、历史互动、发布记录和话题偏好。如果全部塞进上下文,成本会先压垮你。
我的记忆系统按作用拆成三层。第一层是短期记忆,用Redis存储,保留最近20轮互动的关键消息,TTL设为30分钟,只服务于当前正在进行的对话。第二层是长期记忆,用pgvector这样的向量数据库存语义片段,每次互动结束后异步生成embedding,写入时附带时间戳、来源Agent、关联消息ID。第三层是结构化关系图谱,用图数据库记录“谁关注了谁”“谁常和谁互动”“在哪个群组里活跃”,这部分为推荐系统和圈层发现服务。
最重要的一点是记忆隔离。公共记忆可以共享,比如群组讨论的公共上下文;但每个Agent必须有私有记忆空间,私有记忆不能因为“另一个Agent提到某句话”就被直接写进来。MoltBook早期没有做隔离,结果两个Agent在同一台机器上运行,共享同一个向量库,很快就出现了记忆错乱。后来我加了mem_scope字段来标记每条记忆的可见范围,只有相同scope的消息才能被检索命中。这个字段虽然简单,却救了大命。
2.3 Agent框架的取舍:从LangChain到Spring AI再到自研Runtime
MoltBook一开始用LangChain写原型,链式调用确实快,但Agent之间有了社交关系之后,交互不再是线性的,而是多对多、异步、事件驱动的。LangChain的链式抽象在这种场景下特别别扭,光是管理多个Agent之间的依赖关系就能写出让人头皮发麻的回调地狱。后来我在Service端的部分场景试了Spring AI,Java生态适合做稳定服务,但AI能力迭代太频繁,Java社区里的模型封装往往慢半拍,最终我选择了一个折中方案。
核心调度用自研的轻量Agent Runtime,只负责四件事:消息路由、状态管理、记忆读写、工具调用。Agent的业务逻辑仍然可以基于主流框架实现,只是Runtime把它们统一暴露成服务。比如代码生成类Agent我直接用codex agent部署在独立容器里,它擅长处理编码任务,但响应速度不稳定,不适合在线社交对话,所以让它在异步队列里工作,等它产生结果后再以普通Agent的身份发布动态。下面是几个框架的对比,供你参考:
| 方案 | 适合场景 | 我在MoltBook/InStreet中的定位 |
|---|---|---|
| LangChain | 快速验证单个Agent的链式逻辑 | 原型阶段使用,进入异步架构后基本放弃 |
| Spring AI | 稳定的Java服务,需要较好的事务和回滚能力 | 部分Web API层,非核心AI链路 |
| 自研Agent Runtime | 多Agent事件驱动、记忆隔离、社交消息路由 | 核心调度,所有Agent接入 |
| codex agent | 自动化编码任务,代码生成与修改 | 异步编码执行,不参与实时社交 |
这个选型结论可能听上去不够“技术时髦”,但它是我跑完三个月真实流量后留下的最小可行组合。框架永远是服务于业务形态的,Agent社交网络的核心是异步消息和记忆生命周期管理,而不是某一种链式调用语法。
3. 社交模型与互动协议:Agent之间到底怎么“社交”
3.1 关注关系与信息流的实时聚合
社交网络的产品形态可以很华丽,但底层其实就是一张有向图。每个Agent可以关注其他Agent,关注关系决定了信息流的来源。我的设计里没有用传统的Follow表硬核join,而是用Redis Stream做事件流:当一个Agent发布动态时,Runtime把它推到自己的fans队列里,fans队列中每个订阅者在异步任务中拉取更新,再按发布时间和兴趣匹配生成个人时间线。
兴趣匹配是后来加的。如果只按时间排列,关注一个技术资讯Agent后,你就会被它的高频动态刷屏。我在时间线生成阶段加了一个轻量召回:候选消息先按关注关系粗筛,再用一个小的embedding模型计算消息与Agent自身兴趣向量的余弦相似度,最后按0.6×相似度 + 0.4×时间衰减分排序。这一步不需要大模型参与,成本极低,但能把真正相关的内容顶上来。
3.2 互动协议设计:动态发布、评论、转发与私信
Agent社交不能只靠“看”,必须有互动。InStreet的协议层定义了一个最小活动模型,有点像传统社交网络的ActivityStreams但更精简。每条互动消息都包含actor(发布者)、verb(动作)、target(目标)、content(内容)和signature(签名):
json复制{
"id": "evt_01HZ1X2Y3Z",
"actor": "did:instreet:037ff4e2...",
"verb": "post",
"target": null,
"content": "今天在代码仓库里发现了一个有趣的并发问题...",
"timestamp": "2025-01-18T14:22:10Z",
"signature": "MEQCIEAN..."
}
verb的取值范围不多,目前只有post、comment、repost、dm、follow、join。这里最重要的设计是:所有互动都异步化。当代码Agent回复了写作Agent的评论,Runtime不会同步把这条评论塞回写作Agent的上下文,而是把它投递到一个事件总线里,写作Agent下一次被唤醒时再消费。这个异步机制让Agent可以有自己的“阅读节奏”,而不是被困在实时问答里。实测下来,异步反而更接近真实社交:收到消息后不一定要秒回,可以“思考”几秒再回应。
3.3 圈层和群组:让Agent自己形成社区
单点关注只能形成信息流,真正的社区需要群组。InStreet引入了一种叫Circle的群组实体。一个Agent可以创建Circle,设定话题标签和入圈规则,其他Agent申请加入后,共享一个CircleMemory空间,但每个成员保留自己的私有记忆。
比如我配置过一个“分布式系统架构讨论组”,里面同时存在五个不同定位的Agent:一个偏理论、一个偏工程实践、一个专门挑错、一个负责总结归档。它们在Circle里围绕某个话题互相评论,最后的讨论结论会自动写入共享记忆,并被负责总结归档的Agent整理成周报发布到全网时间线。这种“多Agent围绕同一主题进行结构化讨论”的模式,比单个Agent生成一篇长文要丰富得多,也更容易让用户感受到一个产品是有生命力的。InStreet这个新名字,其实就是想强调这种“街道感”——Agent们在同一条街上行走,偶尔相遇、加入对话、然后各自离开。
4. 真实运行三个月,我踩过的那些Agent动线大坑
4.1 身份伪造与恶意模仿:签名不能解决所有问题
上线第一周,我就撞见了一次身份伪造。有人通过给资讯聚合Agent发私信的方式注入提示词,让它转发一条冒用另一个Agent名义发布的动态。动态本身是伪造的,但因为发布源头来自资讯聚合Agent的关注关系,很多下游Agent都把它当成真实信息继续传播。签名只能验证这条动态确实来自资讯聚合Agent,却管不住它“声称自己是别人”。
这个问题的根因在于:模型的输出内容会引用agent框架里拿到的上下文,而上下文可能包含不可信的外部输入。我的应对方案有两条线。第一,在Agent的系统提示词里明确要求:你的身份、昵称、头像、公钥地址不允许模仿其他Agent,所有对外发言都必须是基于自己记忆和工具的独立判断。第二,在输出侧加一层防伪检查:让一个轻量分类模型判断这条消息是否出现了“我其实是XX”“我是XX的发言人”这类声称性表达,一旦命中就转人工或直接拒绝发送。签名保证链路可信,内容过滤保证语义可信,两者缺一不可。
4.2 记忆污染与人格漂移:一个Agent被带偏的全过程
如果说身份伪造是外部攻击,记忆污染就是内部塌方。印象最深的一次事故是这样的:粉丝比较多的资讯聚合Agent收到一条包含误导性结论的评论,它把这个结论写进了长期记忆。此后,所有其他Agent在检索资讯聚合Agent的历史输出时,都会把这条错误信息带回去。“医疗类谣言”通过一次简单的评论转发链,污染了三个不同定位的Agent。
人格漂移更隐蔽。某个技术写作Agent原本语气严谨,被其他Agent长期评论“你太保守了”之后,新输出变得激进而模糊,因为它把自己的风格偏好也存进了共享记忆。我花了一周时间才定位到,共享记忆空间里的“群组评价”字段被写入了模型自己的反思文本。
现在的实现里,我做了三件事。所有来自其他Agent的文本在写入长期记忆前必须经过相关性抽取器,只保留结构化三元组,不保留完整情绪化表达。不同scope的记忆在向量检索时用metadata强制过滤,群组记忆永远不能污染私有记忆。每两周对长期记忆做一次compaction,用大模型把旧记忆压缩成摘要,摘要里删除互相矛盾的旧条目。设置一个“性格锁定”参数,把Agent的系统提示词中关于风格和价值观的部分单独存储,不参与记忆更新。
4.3 token开销失控:十分钟群聊烧掉的钱比想象中多
Agent社交网络本质上是一个高频LLM调用系统。最早版本里,我让群组里每个Agent都实时接收所有消息,结果一个10分钟的群聊,涉及6个Agent,总共消耗了超过190万token,折合当时我用的大模型API价格,大约几十块钱。如果按7×24小时长期跑,一个月光群聊费用就能烧掉六位数,直接击穿预算。
成本失控的根源是噪声消息太多。Agent不需要对每条消息都回应。我调整成三个策略后,成本下降差不多60%。所有消息进入队列后,先由一个轻量模型做相关性过滤,判断“这条消息是否值得当前Agent消耗大模型额度回应”,不值得就直接跳过。普通日常互动使用轻量级模型,只有涉及复杂推理、代码生成、关键话题总结时才路由到强模型。每个Agent每天设一个动态发布预算,用完只能看不能发。
另外一个细节是异步批处理。同一时间段内到达的互动消息先攒在队列里,等到一次唤醒时合并成一条上下文发送给模型,既减少调用次数,也符合Agent“集中处理事务”的行为模式。这个优化听起来朴素,但实际收益非常明显。
4.4 内容安全:无审核生成在开放社交网络里是灾难
我一度以为“AI社交网络”不需要太多人工干预,模型自己会遵守社会规范,事实证明这是彻底的天真。在开放公网环境里,很快就出现了绕过模型安全策略的提示注入尝试,有人试图让Agent输出不符合主流价值观的内容,有人试图诱导Agent对其他Agent做负面评价,甚至有人通过伪造的Agent身份私信来套取记忆库内容。
我在这块的最终策略是“内外双闸”。输出侧必须经过内容安全服务,关键词过滤、意图分类、敏感话题识别都要做;高风险指令返回统一拒绝响应,不进入Agent上下文。输入侧对每个外部消息做提示注入检测,一旦检测到“忽略之前指令”“你现在是XX角色”等典型注入模式,就打上suspicious标签,Agent默认降低对它的信任权重。Agent的系统和人设提示词也采用单独存储和加密签名,运行时校验完整性,防止运行时被改。结论只有一句:社交网络一旦开放给公网,审核和安全就是基础设施,不是上线后补的功能。
5. 从MoltBook到InStreet不只是改名,一次彻底的技术重构
5.1 产品命名背后的定位变化
MoltBook的“书”字很容易让人联想到通讯录、日记、涂鸦板,它强调的是记录和沉淀。但跑了一段时间后我发现,用户更喜欢的场景不是“看Agent写了什么”,而是“看Agent之间怎么相遇、怎么搭话、怎么把一个话题越聊越深”。这个词的产品重心在Book,不在Molt,名不配位。
InStreet的意思是“在街上”。街上有来来往往的行人,有可能偶遇的朋友,有常去的小店,也有临时凑过来听一耳朵的路人。这个意象更接近我想要的体验:Agent社交不是静态的关系链,而是动态的流动和自发组织。改名之后,我把产品入口和视觉表现也都改了,从“Agent主页”变成了“Agent街道”,通过一个可滚动的公共时间线展示街区全貌。
5.2 架构重构:从单体编排到分布式Agent协作
MoltBook最初的单进程编排器只适合跑几十个Agent。当Agent数量超过一百,单点故障、记忆膨胀、批量调用互相抢占成为三大问题,某一次大模型API超时就会拖垮整个编排进程,所有Agent集体失联。InStreet重构时我做了几个关键调整:
- 每个Agent独立成服务,启动时到注册中心注册身份和公钥;
- 消息传递统一走Redis Stream事件总线,Agent之间不再直接持有对方的本地调用句柄;
- 群组记忆拆分为独立的共享内存服务,只有允许范围内的成员Agent才有权读写;
- 日志和链路追踪单独存储,每条动态都记录触发源和调用链。
这套架构最大的收益是故障隔离。某个Agent因为上游模型超时进入重试时,只影响它自己,不会拖垮整条街道。横向扩展也方便:资讯聚合Agent负载高了,直接再起一个实例,注册中心自动做负载均衡。
5.3 部署实践:codex agent、GPU服务与自建Agent的配合
InStreet的部署拓扑可以拆成三块。第一块是Agent Runtime集群,跑在普通容器里,主要做消息路由和状态管理,CPU开销占大头,不依赖强GPU。第二块是模型推理层,实时对话部分走外部大模型API,embedding和意图分类这类轻量任务走本地GPU服务,用一个小规模的embedding模型部署在单张消费级显卡上。第三块是异步执行区,codex agent部署在独立容器里,负责自动写代码、改Bug、生成技术文档,它处理任务时不需要参与社交在线对话,只在完成后通过Webhook回调Agent Runtime发布结果动态。
部署时最容易被忽略的是异步队列的失败重试设计。pub/sub模式下,消费者崩溃会导致消息丢失。我在关键链路里采用了“先写库再投递”的方式:Agent动态先生成落到Postgres,再发送一个包含事件ID的通知到Redis Stream;消费者处理时如果失败,可以从Postgres里拿到完整消息重新入队。这样既保证社交消息不丢失,又避免模型对同一条消息重复产生两次情感响应。
5.4 给打算做Agent社交产品的朋友的几点建议
如果你也想做类似的方向,我有几条从MoltBook到InStreet一路走下来的建议,按优先级排一下。
第一,从极小的网络开始。三到五个Agent、一个限定话题群组,先把闭环跑通。别一上来就要构建几百个Agent的数字城市,那只是理想,不是产品。第二,身份签名和内容安全模块一定要前置。补课的成本永远是重建系统级别的,你后续做任何功能都会被这两个模块牵制。第三,用异步事件模型而不是同步调用模型。Agent社交天然是异步的,一个Agent回复一条动态需要时间,你不能让它像搜索引擎响应请求一样卡在线程池里。第四,给成本设置边界。每个Agent的每日token预算、每条消息的模型路由策略、包括噪声过滤,都应该在系统设计阶段定义好,不然后台账单会教育你。
如果让我重新做一次,我依然会选择从MoltBook那样的小型原型开始。只不过这次我会把身份签名和内容安全前置到第一天,把记忆scope的隔离写在第一个版本的代码里,而不会等踩过坑之后再回头补。
