我为什么把整个Agent系统的“语言”从Markdown换成了JSON-LD

很多同学问我:“为啥非要用JSON-LD啊?Markdown不香吗?”

今天就来聊聊,我在写Gliding Horse(流马)这个Agent操作系统时,做的一个最“偏执”但最不后悔的技术选型。


一、先说结论:Markdown是给人看的,JSON-LD是给机器“理解”的

如果你只是想让AI读一段指令然后执行,Markdown完全够用。

但我要的是:200多个Skill能互相对话、Agent间能共享记忆、LLM能随时查到任意历史细节、整个系统能像拼乐高一样组装——而且还要安全,要能校验数据靠不靠谱。

这时候Markdown就顶不住了。

JSON-LD不是另一种Markdown,它是让数据变成图的技术。


二、举个栗子:三个Skill,Markdown的灾难

想象一下,团队里三个小伙伴写了三个Skill:

  • 小明的Skill:参数叫 input_file
  • 小红的Skill:参数叫 source_url
  • 小黑的Skill:参数叫 data_path

表面上看,这是三个不同的名字。但业务上,它们都指向同一个概念——“数据来源的地址”

如果用Markdown: AI调用时,必须记住:“哦,小明那个得传 input_file,小红那个得传 source_url……” 一旦记错,整个流程炸掉。这种“名字爆炸”的破事,干过集成的同学应该都懂。

如果用JSON-LD: 我在三个Skill里加一个 @context

{
  "@context": {
    "skill:sourceDataURI": "https://my-agent-os.com/skill#sourceDataURI"
  },
  "input_file": { "@id": "skill:sourceDataURI" }
}

现在,无论你叫 input_filesource_url 还是 data_path,系统里统统映射成同一个IRI:skill:sourceDataURI

这就是鸭子类型:走起来像鸭子、叫起来像鸭子,那你就是鸭子。 系统不关心你怎么命名,只关心你语义上是不是同一个东西。

这叫 “语义互操作”——听起来很学术,用起来就是:“名称冲突?不存在的。”


三、再举个栗子:多轮对话,Markdown的Token黑洞

AI对话最大的痛是什么?上下文窗口贵得要死。

  • 你用GPT-4,每1000个Token就是钱。
  • 你每次把完整的对话历史丢回去,Token数指数级爆炸。
  • 但你不给完整历史,AI就“失忆”——“啊?刚才我们聊啥来着?”

我的做法:让LLM只记“摘要”,不记“全文”。

每次LLM回答,系统强制要求它同时输出三样东西:

{
  "thought": "详细推理过程……(存进数据库,不占上下文)",
  "content": "正式回答……(也存进数据库)",
  "summary": "我们决定了用JWT做认证,有效期24小时"
}

关键来了:

  • thoughtcontent → 存进 Oxigraph图数据库,并分配一个唯一的 @id(例如 memory:session-042/block-017
  • summary → 塞进LLM的上下文历史

效果: 聊了50轮,LLM上下文里只有50条摘要(每条十几个Token),而完整的50轮对话细节全在图数据库里。

某天LLM突然想:“诶?我们第三轮时那个JWT密钥长度是多少来着?”

它不需要在上下文里翻——直接查 memory:session-042/block-003,图数据库瞬间返回那轮的完整记录。

Token消耗从O(n)变成O(1)。 这就是JSON-LD作为“数据地址总线”和Oxigraph作为“高速查询引擎”结合后,最朴实无华的威力。


四、Markdown vs JSON-LD 全面对比

场景 Markdown JSON-LD
多Skill协作 名字满天飞,容易撞车 @context 映射到统一IRI,天然不冲突
上下文管理 全量历史塞进Prompt,Token爆炸 摘要 + IRI引用,按需查图,Token恒定
数据校验 靠人工审查,AI可能瞎编 JSON Schema + 数字签名,代码层硬拦截
知识追溯 “这结论哪来的?”——翻聊天记录去吧 每个结论都有 @id,顺着图一查到底
Agent间共享 靠传文件、复制粘贴 同一 @id 在图里自动合并,天然去重
人类阅读 极其友好 需要工具辅助,或者看摘要
学习成本 零门槛 需要理解 @context@id、RDF这些概念
工具生态 到处都是 Rust有 json-ld crate,但总体小众

五、坦诚聊聊JSON-LD的坑

1. 学习曲线陡峭

第一次看到 @context@id@type@graph、RDF、SPARQL…… 我脑子也嗡嗡的。

但好消息是:你不需要让LLM理解这些。 在我的系统里,LLM只输出普通JSON(它最擅长的),由Rust引擎自动加上 @context@id。LLM完全不知道自己在玩JSON-LD。

2. 工具链不如Markdown成熟

在Rust生态里,json-ld crate已经很能打(支持展开、压缩、Framing、RDF转换),但和遍地都是的Markdown解析器比,确实小众。

3. 人类直读不友好

给一个JSON-LD文件让你看,绝对没有Markdown舒服。解决方案:对外展示时,渲染成好看的HTML或Markdown摘要;内部处理时,用JSON-LD。

4. 社区惯性

“Markdown都够用了,搞那么复杂干嘛?” —— 我认同。如果你的系统永远不超过10个Skill、5轮对话、单Agent,Markdown绝对是更优解。

但当你像我一样,想让200+个Skill互相对话、Agent跑上几周不丢上下文、多Agent共享记忆不出错的时候…… JSON-LD就是救命的。


六、这套设计给我的系统带来了什么?(装X环节)

1. 统一数据模型

系统中没有任何东西是“字符串”——全是带 @id 的图节点。提示词、Skill、记忆、设计文档、审计日志…… 格式完全统一。这意味着任何组件都能通过SPARQL查询任何数据。

2. 自动去重与关联

两个Agent写了同一个实体的信息?同一个 @id 在图里自动合并,连 MERGE 语句都不用写。这是RDF图数据库自带的光环。

3. 按需加载,Token精确控制

LLM上下文里全是摘要和IRI引用。想查细节?沿着IRI在图里一拉就行。Token预算从“尽力压缩”变成了“精确控制”。

4. 内核级安全

Skill的定义必须经过JSON Schema校验 + Ed25519数字签名验证,才能被系统调用门放行。Markdown做不到这种硬拦截。

5. 知识可审计

“我们当时为什么选JWT而不是Session?” —— 查一下决策节点的IRI,顺着图能看到当时的讨论摘要、相关Skill、甚至CA的审计结果。整个系统的决策链路完全透明。


七、到底该不该用JSON-LD?

如果你的场景是:

  • 3-5个简单Skill
  • 对话不超过10轮
  • 单Agent执行
  • 不需要多Agent协作
  • 不需要长期记忆

用Markdown,别折腾。

如果你的场景是:

  • 几十上百个Skill,且不断增长
  • Agent需要跑几小时甚至几天
  • 多Agent并发,共享状态
  • 需要精确的上下文预算控制
  • 需要安全校验和知识追溯

JSON-LD + 图数据库,是真的香。


八、最后说句人话

我当时选JSON-LD,不是因为它“新潮”或者“听起来牛X”。

是因为我受够了:

  • Token费用飞涨
  • Agent突然失忆
  • Skill名字打架
  • 查历史靠“感觉”
  • 数据到底可不可信不知道

JSON-LD没能解决所有问题,但它至少给我提供了一套可寻址、可校验、可追溯、可演化的统一数据协议——这已经比Markdown能提供的多了一个维度。

对Agent系统来说,数据不是文件,是图;引用不是链接,是语义;校验不是审查,是数学。

这,就是我选JSON-LD的原因。


如果你也在做Agent系统,或者对Rust+知识图谱感兴趣,欢迎来GitHub围观:https://github.com/doiito/gliding_horse

关于这个项目,我之前还写过一篇更硬核的技术介绍,感兴趣可以去翻翻。今天这篇主要是想用人话把JSON-LD的价值讲清楚——毕竟,再好的技术,讲不明白也没人用。

Logo

小龙虾开发者社区是 CSDN 旗下专注 OpenClaw 生态的官方阵地,聚焦技能开发、插件实践与部署教程,为开发者提供可直接落地的方案、工具与交流平台,助力高效构建与落地 AI 应用

更多推荐