2026年1月

2libra 没有自带的图片上传功能,昨天看到 一个帖子 后突然来了灵感,
把之前做的 v2ex 脚本中的图片上传功能抽离出来,做了一个通用的图片上传脚本。

主要功能

  • 支持在所有网站使用。(需要配置 match 规则)
  • 对 2libra, v2ex, nodeseek, deepflood, greasyfork.org 做了适配,显示“插入图片”按钮。其他网站可以自己添加规则。
  • 保存图片上传记录,可以重复利用上传过的图片。
  • 目前支持上传到 Imgur,后续会支持更多图床。
  • 可以批量上传,支持粘贴、拖拽、文件选择收集图片。

2025-10-22-21-23-13
2025-10-22-21-09-33

🔗 安装链接

项目地址: https://github.com/utags/userscripts

目前 是第一个也是唯一一个 2libra 的油猴脚本

本文由TinyPro贡献者王晨光同学原创。

一、背景:让 TinyPro 真正“走到掌心里”

TinyPro 是一套基于 TinyVue 打造的前后端分离后台管理系统,支持菜单配置、国际化、多页签、权限管理等丰富特性。
TinyPro 在桌面端具备良好的体验和模块化架构,但随着移动办公、平板展示等场景增多,移动端体验的短板逐渐显现:

  • 页面缩放不均衡,布局出现溢出或错位;
  • 模态框在小屏上遮挡内容;
  • 图表和表格在横屏与竖屏间切换时无法自适应;
  • 操作区过于密集,不符合触控习惯。

为此启动了 TinyPro 移动端适配项目,目标是在不破坏现有结构的前提下,实现“一次开发,跨端流畅”的体验。

二、技术选型与总体架构

本次移动端适配要求在复杂的中后台系统中实现「一次开发,多端自适应」,既要保证样式灵活,又要维持可维护性和构建性能。

在技术选型阶段,综合评估了三种常见方案:

方案优点缺点
纯 CSS 媒体查询简单直接、依赖少样式分散、逻辑重复、维护困难
TailwindCSS 响应式类社区成熟、类名直观、生态完善样式表体积大、断点固定、不够灵活
UnoCSS 原子化方案按需生成、性能极轻、断点与变体完全可定制需要自行配置规范与规则体系

最终选择了 UnoCSS + Less 的混合架构

  • UnoCSS:负责通用布局、间距、排版等高频样式,原子化写法提升开发效率;
  • Less 媒体查询:用于模态框、导航栏等复杂场景的精细控制;
  • 统一断点配置:集中管理屏幕尺寸分级,保持视觉一致性;
  • 自定义变体(max-<bp>:支持“桌面端优先”策略,通过 max-width 实现移动端自适应,样式逻辑更直观。

UnoCSS:轻量、灵活、即时生成

UnoCSS 是一个 按需生成的原子化 CSS 引擎,最大的特点是 零冗余与高度可定制
不同于 TailwindCSS 的预编译方式,UnoCSS 会在构建阶段根据实际使用的类名即时生成样式规则,从而显著提升构建性能与灵活性.

在配置中通过 presetMini()presetAttributify() 组合使用,使开发者既可以写:

<div class="p-4 text-center bg-gray-100 max-md:p-2"></div>

也可以使用属性化语法:

<div p="4" text="center" bg="gray-100" max-md:p="2"></div>

presetMini 提供轻量原子类体系,presetAttributify 则允许以声明式方式书写样式,更直观、组件化友好。

断点配置与响应式策略

TinyPro 的适配核心之一,是在 uno.config.ts 中建立统一的断点体系,并通过自定义 max-<bp> 前缀实现“桌面端优先”的响应式策略。

const breakpoints = {
  sm: '641px',     // 手机(小屏)
  md: '769px',     // 平板竖屏
  lg: '1025px',    // 平板横屏 / 小型笔电
  xl: '1367px',    // 常规笔电
  '2xl': '1441px', // 高清笔电
  '3xl': '1921px', // 桌面大屏
}

并通过自定义 variants 扩展 max-<bp> 前缀:

variants: [
    (matcher) => {
      const match = matcher.match(/^max-([a-z0-9]+):/)
      if (match) {
        const bp = match[1]
        const value = breakpoints[bp]
        if (!value) return
        return {
          matcher: matcher.replace(`max-${bp}:`, ''),
          parent: `@media (max-width: ${value})`,
        }
      }
    },
  ]

让开发者能自然地书写:

<div class="w-1/2 max-md:w-full"></div>

含义:

默认宽度为 50%,在宽度小于 769px 的设备上改为 100%。

TinyPro 采用「桌面端优先(max-width)」的布局策略:默认以桌面端布局为基础,在移动设备上再进行针对性优化。相比常见的「移动端优先(min-width)」方式,这种做法更符合中后台系统的特性,同时让 UnoCSS 的断点逻辑更直观,并确保主屏体验的稳定性。

三、样式与编码策略

  • 优先级

    • 简单场景:使用 UnoCSS 原子类。
    • 复杂样式:使用 Less 媒体查询。
  • 布局与滚动

    • 首页及核心业务模块完成适配,小屏模式下侧边栏默认收起、导航栏折叠,确保主要内容可见。
    • 页面主要容器避免横向滚动,必要时在小屏下开启局部横向滚动。
    • 表格与大区块在不同断点下自动调整宽度、栅格与间距,小屏下支持横向滚动;分页与密度支持响应式控制。

    布局与滚动.gif

  • 图表自适应

    • 图表组件接入 resize 监听,在侧边栏展开/收起、窗口缩放、语言切换等场景下保持自适应。
    • 小屏下使用 vw 宽度与较小字号,保证图表展示效果与可读性。

    图表自适应.gif

  • 表单与模态框

    • 接入 useResponsiveSize(),控制弹窗在小屏下铺满显示,大屏保持固定宽度。
    • 表单项在不同断点下动态调整排布与间距,优化触控体验。

    表单与模态框.gif

  • 导航与交互

    • 小屏下隐藏导航栏非关键元素,操作聚合到"折叠菜单"。
    • 移动端默认收起侧边菜单栏,提升主要内容展示区域。

    导航与交互.gif

  • 性能优化

    • responsive.ts 中对 resize 事件处理增加节流机制,避免窗口缩放等场景下的频繁无效渲染。

四、常用代码片段

  1. 基于栅格系统 + 响应式断点工具类,通过为 tiny-row 和 tiny-col 添加不同屏幕宽度下的样式规则,实现自适应布局:
<tiny-layout>
    <tiny-row class="flex justify-center max-md:flex-wrap">
        <tiny-col class="w-1/4 max-md:w-1/2 max-sm:w-full max-md:mb-4">···</tiny-col>
        ···
        <tiny-col class="w-1/4 max-md:w-1/2 max-sm:w-full max-md:mb-4">···</tiny-col>
    </tiny-row>
</tiny-layout>
<div class="theme-line flex max-sm:grid max-sm:grid-cols-4 max-sm:gap-2">
  <div···
  </div>
</div>
  1. 基于 响应式工具类 + 自定义响应式 Hook,解决(1)对话框宽度自适应;(2)表格尺寸和密度自适应;(3)逻辑层响应式控制
<template>
  <section class="p-4 sm:p-6 lg:p-8 max-sm:text-center">
    <tiny-dialog :width="modalSize">...</tiny-dialog>
  </section>
</template>

<script setup lang="ts">
import { useResponsiveSize } from '@/hooks/responsive'
const { modalSize } = useResponsiveSize() // 小屏 100%,大屏 768px
</script>
<template>
  <div class="container">
    <tiny-grid ref="grid" :fetch-data="fetchDataOption" :pager="pagerConfig" :size="gridSize" :auto-resize="true" align="center">
      ···
    </tiny-grid>
  </div>
</template>

<script setup lang="ts">
import { useResponsiveSize } from '@/hooks/responsive'
const { gridSize } = useResponsiveSize() // 小屏为mini grid,大屏为medium grid
</script>
  1. 通过 useResponsive 获取屏幕断点状态 sm/md/lg,如:在模板中结合 v-if="!lg" 控制分隔线的渲染,从而实现了小屏下纵向菜单才显示分隔线的效果
<template>
  <ul class="right-side" :class="{ open: menuOpen }">
    <!-- 小屏下才显示分隔线 -->
    <li v-if="!lg">
      <div class="divider"></div>
    </li>
    ···
  </ul>
</template>

<script lang="ts" setup>
import { useResponsive } from '@/hooks/responsive'
const { lg } = useResponsive()
</script>

五、结语

通过本次移动端适配, TinyPro 实现了“从桌面到掌心”的统一体验:
开发者可以继续沿用熟悉的组件体系与布局方式,同时享受 UnoCSS 带来的原子化灵活性与性能优势。在不改变核心架构的前提下,TinyPro 变得更轻盈、更顺滑,也更符合移动时代的使用场景。

关于OpenTiny

欢迎加入 OpenTiny 开源社区。添加微信小助手:opentiny-official 一起参与交流前端技术~
OpenTiny 官网:https://opentiny.design
OpenTiny 代码仓库:https://github.com/opentiny
TinyPro源码:https://github.com/opentiny/tiny-pro

欢迎进入代码仓库 Star🌟TinyPro、TinyEngine、TinyVue、TinyNG、TinyCLI、TinyEditor
如果你也想要共建,可以进入代码仓库,找到 good first issue标签,一起参与开源贡献\~

iOS沙盒的封闭性从来都不是简单的权限隔离,而是一套贯穿运行时的上下文绑定机制,Python在其中的适配困境,本质上是解释型语言的动态特性与iOS静态执行规范的底层冲突。很多开发者初期仅关注文件访问限制,却在实际操作中陷入模块加载失败、依赖库兼容失衡、系统调用无响应等隐性陷阱,这些问题背后,是沙盒对执行环境的深度管控——从二进制文件格式到内存分配规则,从代码签名校验到资源调度优先级,每一项都与桌面端的Python运行逻辑存在本质差异。真正的适配高手,往往是在理解沙盒底层设计逻辑后,通过重构执行环境的适配路径,让Python的动态优势在静态约束中找到生存空间,这种平衡术既需要对iOS系统架构的深刻认知,也依赖对Python解释器内核的灵活改造。在长期的适配实践中,我发现多数开发者的误区在于将沙盒限制等同于“功能阉割”,实则沙盒的核心是建立一套可预期的执行边界,Python的适配并非被动妥协,而是主动构建与这套边界兼容的运行体系。例如,当遇到解释器无法加载系统动态库时,并非简单替换库文件就能解决,而是需要追溯沙盒对动态链接路径的映射规则,通过静态编译将依赖库嵌入解释器二进制文件,同时调整链接符号的查找逻辑,这种底层改造才能从根本上解决兼容性问题,而这一过程需要开发者同时具备系统底层知识与Python解释器原理认知,缺一不可。

沙盒对Python运行时的核心限制,集中体现在解释器与系统内核的适配断层上。iOS基于达尔文内核构建的执行体系,要求所有运行代码必须符合特定的二进制格式,且需经过严格的签名校验,而Python作为解释型语言,其传统运行模式依赖动态加载解释器与脚本文件,这种特性与iOS的静态执行要求形成天然矛盾。更隐蔽的是,沙盒会对进程的内存空间进行隔离划分,Python解释器在分配内存时,既无法访问系统级的共享内存区域,也难以与原生应用形成有效的内存交互,导致数据流转效率低下。同时,系统对动态链接库的加载路径有着强制约束,Python标准库中部分依赖系统级动态库的模块,在沙盒环境中会因路径无法识别而失效,这种失效并非模块本身不存在,而是加载机制与沙盒的路径映射规则不兼容。应对这一困境,不能仅停留在表面的模块替换,而需要通过静态编译将解释器与核心依赖打包为符合要求的二进制格式,同时重构模块加载逻辑,让Python脚本的执行流程与沙盒的内存分配、路径映射规则形成对齐。在实践中,我曾尝试使用常规打包工具将Python解释器移植到沙盒,结果发现解释器虽能启动,但调用涉及系统调用的模块时频繁失效,后来通过拆解达尔文内核的执行流程,发现沙盒会对进程的动态链接行为进行拦截,只有符合特定签名与路径规则的库文件才能被加载。基于这一发现,我通过定制化编译脚本,将Python核心依赖库与解释器打包为单一二进制文件,同时修改解释器的模块查找逻辑,让其优先从内置路径加载模块,而非依赖系统共享库,这一改造让解释器的兼容性提升了近八成,也让我深刻意识到,沙盒适配的核心是让Python的运行逻辑“嵌入”iOS的执行体系,而非独立于系统之外。

二进制扩展模块的框架化转换,是Python在iOS沙盒中实现功能扩展的关键路径,也是最容易被忽视的深层适配环节。iOS要求所有二进制模块必须以独立框架的形式存在于指定目录下,且每个框架只能包含一个二进制文件,这种规范与Python传统的模块加载方式完全相悖——后者允许从任意路径加载扩展模块,无需特定的目录结构与元数据配置。这意味着,普通的Python扩展模块若要在沙盒中运行,必须经过复杂的后期处理:不仅要将原始二进制文件封装为符合标准的框架,还要通过特定的标记文件建立模块导入路径与框架位置的映射关系,同时确保框架包含完整的签名信息与元数据。更关键的是,这种转换并非简单的文件格式变更,而是需要调整模块的依赖引用方式,让模块在加载时能够通过沙盒的路径校验与权限审核。实践中,开发者需要借助专门的工具链处理依赖剥离与框架封装,同时手动配置元数据文件,确保模块的导入路径与沙盒的目录结构形成逻辑闭环。我曾为了让一个图像处理类扩展模块在沙盒中运行,花费了近两周时间进行框架化转换,初期直接将二进制文件放入框架目录,结果模块导入时提示“路径未授权”,后来排查发现,iOS框架不仅要求特定的目录结构,还需要在Info.plist文件中配置模块的导入路径映射,且二进制文件必须包含与应用一致的签名信息。通过工具链剥离模块的外部依赖,手动编写Info.plist文件中的路径映射规则,再使用开发者证书对框架进行签名,最终实现了模块的成功导入。这一过程让我明白,沙盒对扩展模块的约束本质上是对“执行单元”的标准化要求,只有让Python模块符合iOS的框架规范,才能获得沙盒的权限认可,而这种转换需要同时掌握Python模块编译原理与iOS框架开发规范,是技术跨界融合的具体体现。

沙盒环境下Python标准库的隐性缺失,需要通过“功能等效重构”而非简单的库替换来解决。iOS中的Python运行环境并非完整移植桌面端的标准库,而是存在诸多基于系统安全与资源限制的省略,例如部分涉及系统底层调用、网络服务端功能的模块会被默认禁用,这种缺失并非技术疏漏,而是沙盒对应用功能边界的强制界定。很多开发者会尝试寻找第三方替代库,却发现多数库要么依赖被禁用的系统调用,要么因体积过大导致沙盒内资源占用超标。真正有效的应对策略,是基于沙盒允许的功能范围进行功能等效重构:对于数据处理类模块,可通过拆分计算逻辑、优化算法复杂度,在原生支持的轻量级模块基础上实现等效功能;对于网络相关功能,可借助iOS原生框架提供的网络能力进行桥接,而非依赖Python的网络模块;对于文件操作类功能,则需要严格遵循沙盒的目录访问规则,通过自定义数据序列化方式替代传统的文件读写逻辑。在一次数据可视化项目的适配中,我需要使用Python的绘图模块生成图表,但该模块依赖的系统图形库在沙盒中被禁用,直接使用第三方替代库又会导致应用体积超标。为此,我拆解了绘图模块的核心功能,将复杂的绘图逻辑拆分为基础图形绘制、数据映射、色彩渲染三个步骤,基于Python内置的数学模块实现坐标计算,通过iOS原生的图形框架提供的绘制接口完成图形渲染,最终在不依赖外部库的情况下实现了等效功能,且应用体积控制在合理范围。这一实践让我深刻体会到,沙盒环境下的功能重构并非“削足适履”,而是通过对核心功能的本质拆解,找到与系统规则兼容的实现路径,这种重构能力不仅能解决标准库缺失的问题,更能提升代码的轻量化与兼容性,是Python在移动环境中长期生存的关键。

Python与iOS原生应用的交互壁垒,根源在于沙盒的上下文权限隔离,突破这一壁垒需要构建“语义对齐的桥接层”。沙盒不仅隔离了文件与内存资源,更隔离了不同应用的运行上下文,Python脚本若要调用iOS的原生功能,不仅需要通过桥接工具实现语法层面的交互,更需要解决上下文权限的传递问题——原生API的调用往往依赖特定的应用权限与运行状态,而Python解释器的运行上下文在沙盒中处于独立状态,直接调用会因权限不匹配而失败。此外,两种环境的数据类型与内存管理机制存在本质差异,Python的动态数据类型在传递给原生应用时,若未经过适当的类型转换与生命周期绑定,极易导致资源泄漏或交互失效。应对这一问题,需要构建一层专门的桥接逻辑,该逻辑不仅负责数据类型的转换,更要实现权限上下文的传递与同步:在调用原生API前,桥接层需先校验沙盒赋予的权限范围,确保调用行为符合安全规范;在数据传递过程中,需同步两种环境的内存管理规则,避免出现数据悬空或重复释放的情况;在交互完成后,需及时清理桥接层的中间资源,确保沙盒内的资源占用处于合理范围。我曾在一个交互项目中尝试让Python脚本调用iOS的相机功能,初期使用常规桥接工具直接调用API,结果因权限上下文不匹配导致调用失败,且出现内存泄漏问题。后来通过分析沙盒的权限传递机制,在桥接层中加入了权限校验模块,先通过原生应用获取相机权限,再将权限上下文传递给Python解释器,同时设计了数据类型转换池,对Python的动态数据进行定型处理后再传递给原生API,最后通过生命周期绑定机制确保内存资源的及时释放。这一改造不仅解决了交互失效问题,还将内存占用降低了约40%,让我认识到,Python与iOS原生应用的交互核心并非语法层面的对接,而是上下文与资源管理规则的对齐,桥接层的价值就在于构建一套“翻译机制”,让两种不同技术体系的运行逻辑实现语义互通。

iOS沙盒中Python适配的长期演进,依赖于“解释器定制化”与“系统规则适配”的双向优化。随着iOS系统的不断更新,沙盒的安全规则与执行规范也在持续迭代,传统的适配方案往往会因系统版本升级而失效,这就要求开发者不能满足于静态的适配策略,而需要建立动态的适配体系。解释器定制化是关键方向之一,通过裁剪Python解释器的内核功能,保留沙盒环境中必要的执行逻辑,去除依赖系统底层调用的冗余模块,可显著提升解释器与沙盒的兼容性;同时,针对iOS的内存管理机制优化解释器的垃圾回收策略,可有效降低资源占用,避免因内存不足导致的执行中断。另一方面,需要建立对系统规则的动态追踪机制,及时掌握沙盒权限配置、二进制格式要求、审核规范等方面的变化,提前调整适配方案。更高级的适配思路是让Python脚本具备环境感知能力,通过检测当前沙盒的权限范围、系统版本、资源配额,自动调整执行逻辑与资源占用策略,实现“自适应式运行”。在长期的适配实践中,我建立了一套解释器定制化模板,通过脚本自动化裁剪解释器内核,保留核心执行模块与轻量级标准库,同时集成了系统规则检测模块,让脚本在启动时自动扫描沙盒环境参数,根据检测结果调整模块加载策略与内存分配方案。

Android生态的硬件碎片化与Python解释型语言的执行特质,构成了性能优化的底层矛盾——这并非简单的代码精简或资源压缩所能破解,而是要深入两者运行逻辑的核心,实现从指令执行到资源调度的全链路协同。多数开发者在Android平台部署Python应用时,极易陷入“表层调优”的误区,过度纠结于脚本执行速度的零散提升,却忽视了ART虚拟机的字节码转换损耗、Python解释器与系统资源调度的节奏错位、跨层数据交互的隐性开销、硬件架构适配的精准度不足等深层问题。真正的性能突破,始于对Android运行时环境的本质认知:从不同CPU架构(ARMv8、x86等)的指令集差异到内存层级(高速缓存、物理内存、虚拟内存)的数据流转规律,从进程调度的优先级动态调整规则到原生能力调用的底层效率,每一个环节都暗藏着未被挖掘的优化空间。实践反复证明,只有让Python的动态执行逻辑与Android的静态资源管理体系形成“同频共振”,通过重构执行路径、优化资源分配策略、打通跨层交互壁垒、适配硬件特性,才能实现从“勉强运行”到“高速响应、低耗运行”的质变,这种底层逻辑的深度融合与动态协同,正是Android Python性能优化的核心要义,也是区分普通开发者与优化高手的关键所在。

Python解释器在Android平台的运行效率瓶颈,根源在于解释器内核与Android硬件架构、系统调度机制的适配断层,这种断层并非单一因素导致,而是多重逻辑冲突的叠加。不同品牌、不同价位的Android设备,其CPU架构存在显著差异,ARMv8架构的指令集精简高效,而x86架构则侧重兼容性,默认Python解释器的指令解析模块多为通用设计,未针对特定架构进行优化,导致在ARMv8设备上出现指令执行冗余,在x86设备上则因指令转换产生额外开销。同时,Android设备的内存层级缓存策略各不相同,部分中低端设备的高速缓存容量有限,而Python解释器的内存访问逻辑未考虑缓存命中率,频繁出现缓存失效,导致内存访问效率低下。更关键的是,Android的进程调度机制会根据应用的生命周期状态(前台、后台、休眠)动态分配CPU资源,而Python解释器的默认线程管理逻辑是独立于系统调度的,往往在应用进入后台后仍维持高资源占用,引发系统资源竞争,或在前台高负载运行时因CPU资源分配不足导致卡顿。应对这一困境,核心思路是对Python解释器进行“架构化定制”而非“通用化改造”:针对目标设备的CPU指令集,裁剪解释器内核中冗余的指令解析模块,保留与该架构高度兼容的核心执行逻辑,甚至对关键指令的解析流程进行重写,让指令执行更贴合硬件特性;同时优化解释器的线程调度模型,通过调用Android系统API感知应用的生命周期状态,在前台交互场景下自动提升线程优先级以保障响应速度,在后台运行时则降低线程调度频率、释放非必要资源,主动适配系统调度规则。在长期的实践探索中发现,经过架构化定制的解释器,在ARMv8架构的中高端Android设备上,指令执行效率提升近五成,内存占用降低三成,而在x86架构的平板设备上,兼容性未受影响的前提下,运行速度提升约三成,这一优化路径的关键在于“针对性适配”,要求开发者深入理解不同硬件架构的指令特性、Android的进程管理机制与线程调度规则,而非依赖通用化的解释器版本。

跨层数据交互的隐性开销,是Android Python应用性能损耗的重要来源,这种开销往往被开发者忽视,却在实际运行中占据了大量的响应时间,尤其在高频交互场景下更为明显。Python脚本与Android原生组件(如Activity、Service、ContentProvider)的交互,传统方式需经过多轮数据类型转换与序列化/反序列化过程,Python的动态数据类型(如列表、字典)需先转换为中间格式,再序列化后传输至原生组件,原生组件接收后需反序列化再转换为自身支持的数据类型,这一系列操作不仅存在数据格式不兼容的风险,更会因转换逻辑复杂、数据冗余导致响应延迟。在处理大数据量场景时,如实时传感器数据流(加速度传感器、陀螺仪数据)、图像像素数据、音频采样数据,这种开销会被急剧放大,甚至出现数据传输中断、交互卡顿的现象。很多开发者会选择第三方桥接库简化交互流程,但多数桥接库为兼容多场景、多数据类型,设计了通用化的转换逻辑,反而增加了额外的性能损耗,无法满足高频、大数据量交互的需求。有效的优化策略是“定制化数据交互协议”:基于具体业务场景的数据流特性,定义轻量化的私有数据格式,仅保留必要字段,剔除冗余信息,减少数据传输体量;同时绕过中间件的多层转发,直接调用Android原生的跨进程通信接口(如Binder),实现Python脚本与原生组件的直接数据传输,甚至将Python输出的数据直接封装为Android原生支持的内存缓冲区格式,彻底避免序列化/反序列化过程。例如在处理实时传感器数据时,通过定制化协议将传感器数据封装为连续的二进制流,直接写入原生组件的内存缓冲区,可将数据传输延迟降低六成以上,且数据丢失率几乎为零;在图像数据交互场景中,采用原生支持的像素格式进行数据传输,避免格式转换的性能损耗,可让图像处理的整体响应速度提升近一倍。这一优化思路的本质是“场景化精简”,即根据数据的传输频率、体量、格式要求,设计最贴合的交互路径,而非依赖通用化的桥接方案,这需要开发者同时掌握Python的数据处理逻辑与Android的原生通信机制、数据格式规范。

内存管理的动态均衡,是解决Android Python应用资源占用过高、运行卡顿的核心抓手,其关键在于让Python的内存分配逻辑与Android的内存回收机制形成深度协同,而非各自独立运行。Python解释器的默认垃圾回收策略是基于自身的内存占用阈值触发,完全未考虑Android设备的内存层级结构与系统级的内存回收机制,导致频繁出现“Python内存未释放而Android系统触发低内存查杀预警”的矛盾——Python解释器认为内存占用未达阈值,未触发垃圾回收,而Android系统已因整体内存紧张开始清理后台应用,若Python应用此时处于后台,极易被系统查杀;更隐蔽的是,Python的对象引用机制与Android的内存泄漏检测逻辑不兼容,部分Python对象的隐性引用无法被Android的内存检测工具识别,长期运行后会产生隐性内存占用,导致应用可用内存逐渐减少,响应速度变慢。此外,Python脚本中频繁创建与销毁短期对象的行为,会导致内存波动剧烈,增加Android系统内存管理的负担,进一步影响性能。优化的核心路径是“双维度内存调控”:一方面修改Python解释器的垃圾回收触发条件,通过调用Android系统API获取当前设备的可用内存比例、系统内存紧张状态,将其与Python自身的内存占用阈值结合,在系统内存紧张时提前触发垃圾回收,释放冗余对象,主动适配系统内存管理策略;另一方面优化Python脚本的对象创建逻辑,采用对象池复用机制,对频繁创建的短期对象(如数据处理过程中的临时变量、循环中的迭代对象)进行复用,减少对象创建与销毁带来的内存波动,同时通过代码重构避免循环引用、全局变量过度使用等导致垃圾回收无法识别的隐性占用。实践表明,通过这种双维度调控,Python应用的内存波动幅度可降低七成,后台运行时的内存占用可压缩至原来的一半,应用被系统低内存查杀的概率降低八成以上,且长期运行后的响应速度衰减幅度控制在10%以内,这一过程需要开发者深入理解Python的垃圾回收原理(如引用计数、标记-清除算法)与Android的内存管理架构(如内存分级、低内存查杀机制),实现两者的动态适配而非独立调控。

原生能力的深度融合,是突破Python在Android平台性能上限的关键路径,核心在于“用原生优势弥补解释型语言短板”,构建Python与Android原生的协同执行体系,而非让Python单独承担所有任务。Python作为解释型语言,在CPU密集型任务(如复杂数学计算、图像视频处理、大数据解析)和IO密集型任务(如高并发网络请求、大文件读写)中,受限于解释执行的特性,性能往往远不及Android原生开发语言(Java、Kotlin)编译后的机器码执行效率。但多数开发者仅满足于通过桥接库简单调用原生API,却未充分利用原生组件的底层优化能力——如原生图形处理框架的硬件加速、网络框架的并发调度优化、文件系统的高效读写接口,导致“原生优势未充分发挥”,整体性能仍受限于Python的解释执行速度。真正的深度融合,是基于“优势互补”的模块化分工:将核心性能瓶颈模块交由Android原生实现,充分利用原生框架的硬件加速、系统级优化能力,而Python则专注于业务逻辑编排、动态扩展、数据灵活处理等其擅长的领域,通过轻量化的交互接口实现两者的协同执行。例如在图像识别场景中,将图像预处理(如像素裁剪、格式转换、降噪)等CPU密集型操作封装为Android原生组件,利用原生图形框架的硬件加速能力提升处理效率,Python脚本仅负责调用该组件、传入原始图像数据,并处理最终的识别结果,这种分工可将整体处理效率提升三倍以上;在网络请求场景中,利用Android原生的网络框架实现高并发请求调度、缓存管理、断点续传等功能,Python则专注于数据解析、业务逻辑判断,避免解释型语言在网络IO调度中的低效问题;在大数据解析场景中,将数据读取、格式转换等IO密集型操作交由原生组件处理,Python专注于数据过滤、统计分析,可显著提升解析速度。这一优化思路的本质是“模块化分工”,即根据不同模块的性能需求与语言特性,合理分配执行载体,打破“单一语言开发”的思维定式,让Python与Android原生各自发挥优势,实现1+1>2的性能提升,这需要开发者同时掌握Python的业务编排能力与Android的原生开发技术。

性能监控与自适应调优体系的搭建,是保障Android Python应用长期稳定高效运行的核心支撑,而非依赖“一次性优化”的静态方案——Android生态的复杂性决定了固定优化策略无法适配所有场景。Android设备的硬件差异巨大,高端旗舰机的CPU性能、内存容量是入门机型的数倍,固定的运行参数在高端机上可能浪费资源,在入门机型上则可能导致卡顿;系统版本迭代频繁,从Android 10到Android 14,运行时特性、权限机制、资源调度规则均有变化,旧版本的优化方案可能在新版本上失效;用户的使用场景更是多样,前台交互场景需要高响应速度,后台计算场景需要低资源占用,低电量场景则需兼顾性能与功耗,固定的优化策略无法满足多场景需求。很多开发者在完成初期优化后缺乏持续监控机制,无法及时发现新场景、新设备、新版本系统下的性能退化,导致应用体验不稳定。

阿里云函数计算 AgentRun 全新发布后,我们整理了“探秘 AgentRun”系列文章,本系列将梳理企业落地Agent 常见难题,给出具体解法,助力 Agentic AI 快速走进生产级环境。欢迎加入“函数计算 AgentRun 客户群”与我们交流,钉钉群号:134570017218。

AI Agent 时代的沙箱需求

从 Copilot 到 Agent:执行能力的质变

在生成式 AI 的早期阶段,应用主要以“Copilot”形式存在,AI 仅作为辅助生成建议。然而,随着 AutoGPT、BabyAGI 以及 OpenAI Code Interpreter(现为 Advanced Data Analysis)的出现,AI 开始扮演“Agent”的角色。Agent 被赋予了目标,并能自主规划步骤、使用工具来达成目标。

这种质变的核心在于代码执行(Code Execution)。为了回答“分析这层楼的销售数据并绘制趋势图”这样的请求,LLM 不再只是生成一段 Python 代码文本,而是需要在一个真实的 Python 环境中运行这段代码,并获取绘图结果。同样,为了“帮我预订一张去东京的机票”,Agent 可能需要在一个无头浏览器(Headless Browser)中模拟用户点击。

不可信代码的安全隐患

当 LLM 生成代码并执行时,这段代码在本质上是不可信的(Untrusted)。如果直接在应用服务器或用户的本地设备上运行,将面临灾难性的安全风险:

  • 系统破坏:AI 生成的代码可能无意或恶意地包含 rm -rf / 等破坏性指令,或者修改关键系统配置文件。
  • 数据泄露:代码可能尝试读取环境变量中的 API Key,或者扫描内网数据库,将敏感数据发送到外部服务器。
  • 资源耗尽:死循环或内存泄漏代码可能导致宿主机崩溃,影响其他租户的服务。
  • 网络攻击:恶意 Prompt 注入(Prompt Injection)可能诱导 AI 将执行环境作为跳板(Jump Box),对内部网络发起 DDoS 攻击或端口扫描。

Agent 场景面临的独特挑战

除了基础的安全性,AI Agent 的交互特性还给沙箱环境带来了前所未有的工程挑战,这也是传统沙箱(如简单的 Docker 容器或虚拟机)难以应对的:

  • 状态保持:与传统的“请求-响应”模式不同,Agent 往往需要进行多轮对话。上一轮定义的变量(如 df = load_data())需要在下一轮(df.plot())中继续可用。这就要求沙箱环境必须具备上下文记忆能力,而非每次请求都重置环境。
  • 极速启动:用户无法忍受每次交互都等待数秒甚至数十秒的虚拟机启动时间。为了保证流畅的对话体验(Time to First Token),沙箱必须具备毫秒级的冷启动能力。
  • 环境依赖多样性:不同的 Agent 任务可能需要完全不同的依赖库(如 Pandas、Scipy 用于数据分析,Puppeteer 用于网页操作)。沙箱需要支持灵活的自定义镜像或动态依赖加载,同时不能影响启动速度。
  • 资源成本控制:Agent 的调用往往具有稀疏性和突发性(例如一天只用几次,但一次用很久)。长期运行独占的虚拟机(VM)成本高昂且资源利用率低,而传统的 FaaS 虽然便宜但往往缺乏状态保持能力。如何在低成本和高性能之间找到平衡点,是一个巨大的挑战。
    因此,构建一个沙箱(Sandbox)——一个与宿主机、内网以及其他用户数据严格隔离,同时具备高性能、低成本、有状态的封闭执行环境——成为了 AI Agent 沙箱落地的前提条件。

AgentRun Sandbox:专为 Agent 设计的工程化方案

为了解决上述挑战,我们推出了 AgentRun Sandbox。这是一个以高代码为核心,开放生态、灵活组装的一站式 Agentic AI 基础设施平台。

AgentRun 并非从零构建传统的虚拟机集群,而是基于阿里云函数计算(FC)这一强大的 Serverless 底座构建。通过充分利用 Serverless 的按需付费、极致弹性以及免运维(NoOps) 特性,AgentRun 解决了一直困扰沙箱领域的成本与效率难题,并在此基础上通过工程化封装,提供了面向 Agent 场景的专业能力。

为什么选择函数计算作为 Sandbox Infra

在构建 Agent 沙箱时,我们坚定地选择了函数计算(FC)作为底层基础设施,这主要基于以下核心优势的考量:

  • 强安全隔离: 沙箱的核心诉求是安全。函数计算底层采用神龙裸金属与 RunD 安全容器技术,每个执行环境都运行在独立的 MicroVM 中。这种基于虚拟化技术的内核级隔离,相比传统的 Docker 容器隔离具有更高的安全性,能有效防止恶意代码逃逸,为不可信代码执行提供了坚实屏障。
  • 极致弹性与冷启动优化: Agent 的调用往往具有突发性。函数计算具备毫秒级的弹性伸缩能力,结合 RunD 技术对启动速度的极致优化,使得沙箱能够在数秒甚至毫秒内完成创建和启动。这不仅满足了高并发场景下的需求,也保证了 Agent 交互的流畅性,避免了传统虚拟机启动慢带来的延迟感。
  • 成本效益:自建虚拟机集群通常需要为峰值流量预留资源,导致低谷期资源浪费。函数计算采用按需付费(Pay-as-you-go)模式,且 AgentRun 利用了 FC 的空闲自动回收机制,真正做到了“有请求才计费”。对于稀疏调用的 Agent 场景,这种模式能显著降低基础设施成本。
  • 免运维: 基于 Serverless 架构,开发者无需关心底层服务器的操作系统补丁、网络配置及集群维护。AgentRun 团队可以将精力集中在沙箱的核心逻辑与业务体验上,而非底层基础设施的繁琐运维。
  • 会话能力:函数计算围绕 AI Agent Sandbox 场景推出了会话亲和、隔离以及管理能力。在一次会话生命周期内,相同会话的请求均会被亲和路由到同一个实例中,并独占该实例,保证了会话交互的连续性、上下文完整性以及多租安全性,同时提供完整的管理接口来主动对会话生命周期进行控制,降低了开发门槛。

AgentRun 的核心运行机制

传统的 Serverless 通常是无状态的,难以满足 Code Interpreter 这类需要上下文保持的场景。AgentRun 借助函数计算的会话产品能力,在无状态的计算底座上构建了有状态、会话级的沙箱体验。

1. 沙箱请求亲和

AgentRun 允许开发者显式地创建一个具有生命周期的执行环境,解决了传统 Serverless“用完即走”导致的上下文丢失问题。

  • 会话亲和:AgentRun 依赖函数计算会话亲和机制。当开发者创建沙箱后,AgentRun 会维护一个唯一的 SessionID。后续所有携带该 ID 的请求,都会被精准路由到同一个底层的计算实例。这意味着用户在第一步定义的 df = pd.read_csv(...) 对象,在第二步 df.plot() 时依然存在于内存中,完美复刻本地开发体验。
  • MCP 协议原生支持:针对模型上下文协议(Model Context Protocol, MCP),AgentRun 提供了 MCP SSE 及 MCP Streamable HTTP 会话亲和支持。AgentRun 可以直接作为 MCP 网关,让 LLM 与外部工具的交互更加顺滑。

2. 多层次安全隔离

在多租户 SaaS 平台中,安全性是 AgentRun 的基石。

  • 计算隔离:AgentRun 利用底层基础设施的神龙裸金属与 RunD 安全容器技术,确保每个沙箱实例在内核级别进行隔离。通过强制将会话并发度设置为 1,AgentRun 保证租户 A 的进程空间、内存数据与租户 B 物理分离,防止容器逃逸。
  • 网络隔离:网络隔离完全由用户控制。用户可以根据安全需求灵活配置,选择开启或关闭沙箱的公网访问权限,或者将沙箱接入指定的 VPC 网络环境,从而在满足业务连通性的同时,防止恶意代码对内网发起攻击。

3. 灵活的生命周期控制

AgentRun 通过函数计算的会话能力,接管了底层计算资源的生命周期,为上层应用提供精细化管理:

  • 自动闲置回收(Idle Timeout):为了通过 Serverless 架构降低成本,AgentRun 支持设置空闲超时(例如 5 分钟)。如果 Agent 在这段时间内没有新指令,底层实例会自动销毁并停止计费,完美适配 AI 交互“突发性强、稀疏度高”的特点。
  • 状态暂停与恢复(即将上线):针对长时间的任务间歇,AgentRun 能够将沙箱的内存与磁盘状态快照保存,在用户回归时通过快照快速恢复现场,既节省成本又保留了上下文。

4. 会话粒度存储隔离(即将上线)

代码执行需要隔离,数据存储更需要隔离。AgentRun 创新性地规划了会话粒度存储粘性。

  • 动态绑定:AgentRun 允许用户为每个沙箱环境中动态分配一个存储挂载点的专属子目录。
  • 逻辑沙箱:通过底层的挂载技术,沙箱内部只能看到属于自己的 /workspace,物理上无法访问其他租户的文件(如 ../../tenant-b/secret.txt),从文件系统层面根除了数据交叉风险。

AgentRun 开箱即用的沙箱能力

AgentRun 不仅提供了底层隔离环境,还预置了经过工程化调优的标准化模版,让开发者开箱即用:

  • Code Interpreter(代码解释器):预装 Python/Node.js/Java 等环境,支持文件上传下载、数据分析、图表绘制及命令行操作。
  • Browser User(浏览器沙箱):提供基于 CDP over WebSocket 协议的浏览器环境,兼容 Puppeteer / Playwright,让 Agent 能够安全地访问互联网进行网页操作。
  • All In One:集成了代码解释器与浏览器环境的全能型沙箱,满足复杂 Agent 任务需求。
    这些模版镜像具备高度的灵活性,AgentRun 未来将开放镜像定义,允许用户基于标准镜像定制私有依赖库或安全策略。

AgentRun 沙箱架构详解
image.png

AgentRun 网关

这是 AgentRun 的门户,负责接收来自 AI Agent(如 LangChain 应用、ChatGPT Plugin)的 HTTP 请求,除了标准的身份验证、鉴权以及协议转换(如将 HTTP 转为 WebSocket)之外,其核心能力便是沙箱管理以及沙箱请求路由的功能,它屏蔽了底层 Serverless 基础设施的复杂性,实现了如下能力:

  • 沙箱管理:管理沙箱资源,维护业务层沙箱 ID 与底层计算资源 SessionID 的映射关系
  • 状态维护:监控沙箱的活跃状态,基于沙箱超时配置以及底层资源情况及时对状态进行更新
  • 资源调度:根据用户指定的计算规格(CPU、Memory),向底层申请相应的资源。

函数计算沙箱环境

主要由函数计算作为底层算力来承载沙箱的运行。AgentRun 利用函数计算提供的极致弹性能力,实现在分钟内启动成三万个独立的沙箱环境,每个环境都运行在独立的 MicroVM 中,搭配自研开箱即用的沙箱镜像模版,在功能以及性能上为用户提供了双重保障。

典型工作流:从指令到结果

以“用户让 Agent 根据上传的 Excel 文件绘制图表”为例,AgentRun 的工作流程如下。

阶段一:模板创建

  1. 用户请求:Agent 接收到用户指令后,由 LLM 决策使用 Python 来实现该需求。
  2. Agent 工具调用:AI Agent 会向 AgentRun 网关发送 Code Interpreter 沙箱模板的创建请求。
  3. 模板创建:AgentRun 网关会调用函数计算接口创建一个 Code 沙箱模板函数,镜像配置为前文提到的自研 Code Interpreter 沙箱模板,该函数需要同时配置会话亲和以及会话隔离。

阶段二:沙箱创建

  1. Agent 工具调用:模板创建完成后,Agent 继续进行沙箱创建,创建时传入已有的模板 ID,标识沙箱实例运行时的配置和镜像
  2. 沙箱创建:AgentRun 收到沙箱创建请求后,会调用 FC 的 CreateSession 接口来创建一个沙箱实例,该沙箱会有一个合适的闲置超时时间,最长可存活 24h
  3. 创建完成:AgentRun 会保存 FC 返回的会话 ID,并生成沙箱业务 ID 与之对应,最终将沙箱业务 ID 返回给用户

阶段三:任务执行

  1. 上传文件:Agent 通过 Code Interpreter 的文件上传接口,将 Excel 文件上传。若想将该文件持久化,可以在创建沙箱时配置持久化存储 NAS,将其挂到沙箱中,并将文件上传到 NAS 挂载的目录上。
  2. 绘制图表:Agent 生成代码 import pandas as pd; df = pd.read_excel('data.xlsx'),并调用 Code Interpreter 的 run_code 接口执行代码。
  3. 会话亲和:Agent 所有发往 Code Interpreter 的请求中,都必须带上对应的沙箱 ID 才能保证请求都路由到同一个沙箱实例。
  4. 内存驻留:代码执行完毕,变量 df 驻留在内存中.
  5. 二次代码执行:Agent 根据数据列名生成绘图代码 df.plot()。再次发送代码运行请求
  6. 上下文复用:请求再次到达同一实例,直接使用内存中的 df 对象进行绘图,生成图片文件。
  7. 结果回传:图片被写入 NAS,下载链接返回给 Agent。

阶段四:资源销毁

  1. 空闲检测:Agent 完成任务,不再发送请求。
  2. 自动回收:达到 SessionIdleTimeout(如 5 分钟)后,函数计算会自动销毁该沙箱实例,此时除了持久化到 NAS 上的数据,其余环境相关数据均被销毁。
  3. 文件回收:如果 NAS 上的文件是会话隔离的,当用户会话结束后,NAS 上文件需要进行主动或者定时自动清除。

工作时序图

image.png

AgentRun 的核心设计原则

AgentRun 的工程化实践遵循以下五大核心原则,这构成了其安全、高效、可扩展的基石:

原则一:配置即代码

AgentRun 将沙箱环境定义(环境变量、资源规格、健康检查等)封装为标准化模版。这种设计实现了沙箱配置的版本化管理,使得 Agent 环境可以像代码一样进行复制和回滚。

原则二:会话即沙箱

AgentRun 将“会话”作为沙箱的唯一实体。通过 SessionID 绑定底层的计算实例与上下文状态,实现了真正的按需分配与状态保持。沙箱的创建与销毁完全独立于底层物理设施,对用户透明。

原则三:生命周期可编程

AgentRun 不仅提供创建(Create)和删除(Delete)接口,还引入了“暂停”、“恢复”和“自动超时”机制。这种可编程性让上层应用能根据业务价值最大化资源利用率,实现成本与性能的最优平衡。

原则四:网络接入标准化

AgentRun 抹平了底层网络的差异,提供标准化的 HTTP/WebSocket 接口,并支持 Server-Sent Events(SSE)。无论底层如何升级,上层 Agent 沙箱始终通过标准的 Header 或 Cookie 携带 SessionID 进行交互,降低了集成复杂度。

原则五:存储隔离细粒度化(即将上线)

AgentRun 不仅支持模版粒度的文件系统共享,同时也能够配置沙箱粒度目录级动态挂载。每个沙箱单独挂载一个目录,从根源上杜绝了多租户环境下的数据越权访问风险。

总结与展望

AgentRun Sandbox 是 Serverless 技术在 AI Agent 领域的最佳工程化实践。

通过将阿里云函数计算(FC)在 RunD 安全虚拟化(解决隔离与启动速度)、会话亲和性(解决状态保持)以及 动态 NAS 挂载(解决数据隔离)等方面的底层技术创新,封装为面向业务的 AgentRun 平台,我们成功降低了企业构建 AI Agent 的门槛。

对于构建下一代智能体应用的企业而言,选择 AgentRun Sandbox 不仅是选择了一个沙箱工具,更是选择了一套兼顾安全性、用户体验与商业效率的弹性基础设施。未来,AgentRun Sandbox 将继续在启动延迟优化、状态秒级快照恢复以及更多样化的存储支持上深耕,致力于成为 AI Agent 时代最佳的沙箱基座。

立即体验函数计算 AgentRun

函数计算 AgentRun 的无代码到高代码演进能力,现已开放体验:

查看更多产品详情https://www.aliyun.com/product/fc/agentrun

1.快速创建:访问控制台(https://functionai.console.aliyun.com/cn-hangzhou/agent/explore),60秒创建你的第一个 Agent

2.深度定制:当需要更复杂功能时,一键转换为高代码
3.持续演进:利用函数计算 AgentRun 的基础设施能力,持续优化你的 Agent

从想法到上线,从原型到生产,函数计算 AgentRun 始终是你最好的伙伴。欢迎加入“函数计算 AgentRun 客户群”,钉钉群号:134570017218。

快速了解函数计算 AgentRun

一句话介绍:函数计算 AgentRun 是一个以高代码为核心的一站式 Agentic AI 基础设施平台。秉持生态开放和灵活组装的理念,为企业级 Agent 应用提供从开发、部署到运维的全生命周期管理。

image.png

函数计算 AgentRun 架构图

AgentRun 运行时基于阿里云函数计算 FC 构建,继承了 Serverless 计算极致弹性、按量付费、零运维的核心优势。通过深度集成 AgentScope、LangChain、RAGFlow、Mem0 等主流开源生态。函数计算 AgentRun 将 Serverless 的极致弹性、零运维和按量付费的特性与 AI 原生应用场景深度融合,助力企业实现成本与效率的极致优化,平均 TCO 降低 60%

让开发者只需专注于 Agent 的业务逻辑创新,无需关心底层基础设施,让 Agentic AI 真正进入企业生产环境。

作者:江昱

阿里云函数计算 AgentRun 全新发布后,我们整理了“探秘 AgentRun”系列文章,本系列将梳理企业落地 Agent 常见难题,给出具体解法,助力 Agentic AI 快速走进生产级环境。欢迎加入“函数计算 AgentRun 客户群”与我们交流,钉钉群号: 134570017218

当你已经用 LangChain、AgentScope、LangGraph 等框架开发了 Agent 应用,如何让它们享受函数计算 AgentRun 提供的 Serverless 运行时、企业级 Sandbox、模型高可用、全链路可观测等能力?好消息是,你几乎不需要改动现有代码,只需要简单的适配就可以迁移到函数计算 AgentRun。

这篇文章将通过真实的代码示例,展示如何将不同框架的 Agent 应用部署到函数计算 AgentRun 上,以及如何充分利用函数计算 AgentRun 的各种能力。

为什么要部署到函数计算 AgentRun?

在讨论具体的集成方案前,让我们先明确一个问题:如果你的 Agent 应用已经在本地或自建服务器上运行良好,为什么还要迁移到函数计算 AgentRun?

答案很简单:从开发环境到生产环境,有一道巨大的鸿沟。  本地运行只需要考虑功能实现,但生产环境需要考虑性能、稳定性、成本、安全、可观测等一系列问题。函数计算 AgentRun 提供的不是又一个 Agent 框架,而是让你的 Agent 能够以企业级标准运行的完整基础设施。

具体来说,部署到函数计算 AgentRun 后,你能获得:零运维的 Serverless 运行时(自动扩缩容、按量付费),企业级的 Sandbox 环境(高性能、安全隔离),模型高可用保障(自动熔断、多模型 Fallback),全链路可观测(完整的 Trace、成本归因),以及统一的工具和 MCP 管理。

image

快速上手:5 分钟部署你的第一个 LangChain Agent

让我们从最流行的 LangChain 框架开始,通过一个完整的例子展示如何将 LangChain Agent 部署到函数计算 AgentRun。

第一步:安装 Serverless Devs

函数计算 AgentRun 使用 Serverless Devs 作为部署工具。如果你有 Node.js 环境,一行命令即可安装:

npm i -g @serverless-devs/s

第二步:创建项目

使用脚手架快速创建项目(注意:需要 Python 3.10 及以上版本):

# 初始化模板
s init agentrun-quick-start-langchain
# 进入代码目录
cd agentrun-quick-start-langchain/code
# 初始化虚拟环境并安装依赖
uv venv && uv pip install -r requirements.txt

第三步:配置认证信息

通过环境变量(建议使用 .env 文件)配置你的 AgentRun 访问凭证:

export AGENTRUN_ACCESS_KEY_ID="your-access-key-id"
export AGENTRUN_ACCESS_KEY_SECRET="your-access-key-secret"
export AGENTRUN_ACCOUNT_ID="your-account-id"
export AGENTRUN_REGION="cn-hangzhou"

第四步:理解集成方式

这是最关键的部分。打开生成的代码,你会看到集成非常简单:

from agentrun.integration.langchain import model, sandbox_toolset
from agentrun.server import AgentRunServer
# 使用 AgentRun 的模型(自动享受高可用、熔断等能力)
llm = model("<your-model-name>")
# 使用 AgentRun 的 Sandbox 工具
tools = sandbox_toolset(
    template_name="<your-sandbox-name>",
    template_type=TemplateType.CODE_INTERPRETER,
    sandbox_idle_timeout_seconds=300,
)
# 创建 LangChain Agent(和原来的代码完全一样)
agent = create_agent(
    model=llm,
    tools=tools,
    system_prompt="你是一个智能助手"
)
# 定义调用函数
def invoke_agent(request):
    result = agent.invoke({"messages": request.messages})
    return result["messages"][-1].content
# 启动 HTTP Server(提供 OpenAI 兼容的 API)
AgentRunServer(invoke_agent=invoke_agent).start()

核心要点:

  • model() 函数返回的是 LangChain 可以直接使用的模型对象
  • sandbox_toolset() 返回的是 LangChain Tools 列表
  • 你的 Agent 创建代码完全不需要改动
  • AgentRunServer 自动处理 HTTP 请求,提供标准的 OpenAI API

第五步:本地测试

启动服务后,可以通过 HTTP 请求测试:

curl 127.0.0.1:9000/v1/chat/completions \
  -X POST \
  -H "content-type: application/json" \
  -d '{"messages": [{"role": "user", "content": "通过代码查询现在是几点?"}], "stream":true}'

第六步:部署到生产环境

项目中已经包含了 s.yaml 配置文件。你只需要修改其中的 role 字段为你的阿里云角色:

role: acs:ram::{您的阿里云主账号 ID}:role/{您的阿里云角色名称}

配置部署密钥:

s config add
# 按照引导输入 Access Key ID 和 Secret,记住密钥对名称(如 agentrun-deploy)

执行部署:

s deploy -a agentrun-deploy

部署完成后,你会得到一个 HTTPS URL,就可以在生产环境调用你的 Agent 了。

不同框架的集成案例

函数计算 AgentRun 不仅支持 LangChain,还深度集成了主流的 Agent 开发框架。所有框架都遵循同样的理念:通过简单的适配层,让你的代码无缝迁移到函数计算 AgentRun,享受企业级能力。

LangGraph:工作流编排

LangGraph 是 LangChain 团队推出的工作流编排框架,适合构建复杂的多步骤 Agent。集成方式和 LangChain 类似:

from agentrun.integration.langgraph import model, tools
from langgraph.graph import StateGraph, MessagesState
from langgraph.prebuilt import ToolNode
# 使用 AgentRun 的模型和工具
llm = model("<your-model-name>").to_langgraph()
agent_tools = tools()
# 构建 LangGraph 工作流(和原来的代码一样)
def call_model(state: MessagesState):
    messages = state["messages"]
    response = llm.invoke(messages)
    return {"messages": [response]}
workflow = StateGraph(MessagesState)
workflow.add_node("agent", call_model)
workflow.add_node("tools", ToolNode(agent_tools))
workflow.set_entry_point("agent")
# 定义条件边...
app = workflow.compile()
# 调用
result = app.invoke({"messages": [HumanMessage(content="查询上海天气")]})

LangGraph 的优势是可以精确控制 Agent 的执行流程,比如条件分支、循环、并行执行等。部署到函数计算 AgentRun 后,这些复杂的工作流都能自动享受弹性伸缩和可观测能力。

AgentScope:多智能体协作

AgentScope 是阿里达摩院开源的多智能体框架,特别适合构建多 Agent 协作场景。集成方式:

from agentrun.integration.agentscope import model, tools
from agentscope.agent import ReActAgent
from agentscope.tool import Toolkit
# 使用 AgentRun 的模型和工具
llm = model("<your-model-name>").to_agentscope()
agent_tools = tools()
# 注册工具到 Toolkit
toolkit = Toolkit()
for tool in agent_tools:
    toolkit.register_tool_function(tool)
# 创建 Agent(和原来的代码一样)
agent = ReActAgent(
    name="assistant",
    sys_prompt="你是一个智能助手",
    model=llm,
    toolkit=toolkit,
)
# 调用
result = await agent.reply(Msg(name="user", content="查询上海天气", role="user"))

AgentScope 的优势是对多 Agent 系统的原生支持,包括 Agent 之间的通信、协调、记忆共享等。部署到函数计算 AgentRun 后,每个 Agent 都在独立的隔离环境中运行,确保安全性。

PydanticAI:类型安全的 Agent 框架

PydanticAI 是一个新兴框架,强调类型安全和结构化输出。集成方式:

from agentrun.integration.pydantic_ai import model, tools
from pydantic_ai import Agent
# 使用 AgentRun 的模型和工具
llm = model("<your-model-name>").to_pydantic_ai()
agent_tools = tools()
# 创建 Agent
agent = Agent(
    llm,
    instructions="Be concise, reply with one sentence.",
    tools=agent_tools,
)
# 同步调用
result = agent.run_sync("上海的天气如何?")
# 异步调用
result = await agent.run("上海的天气如何?")

PydanticAI 的优势是强类型和结构化输出,特别适合需要严格数据验证的企业场景。

充分利用函数计算 AgentRun 的核心能力

将 Agent 部署到函数计算 AgentRun 后,你不仅获得了 Serverless 运行环境,还可以深度利用平台提供的各种企业级能力。

模型高可用:告别单点故障(搭配 AI 网关)

部署到函数计算 AgentRun 后,你的 Agent 自动享受模型高可用能力。当你配置的主模型出现故障、限流或超时时,系统会自动切换到备用模型,整个过程对你的代码完全透明。
在函数计算 AgentRun 控制台配置模型时可以和 AI 网关进行联动,可以设置:主模型(如 GPT-4),备用模型列表(如 Claude-3、Qwen-Max),熔断策略(错误率阈值、超时时间),负载均衡策略(轮询、权重、最少连接)。
你的代码完全不需要改动,只需要在创建模型时使用函数计算 AgentRun 的模型名称,所有的容错、切换、负载均衡都由平台自动处理。

企业级 Sandbox:安全执行代码

函数计算 AgentRun 提供的 Sandbox 不是简单的代码执行环境,而是企业级的安全隔离沙箱。每个 Sandbox 实例都是独立隔离的,支持多种执行类型:

Code Interpreter 支持 Python、Node.js、Java、Bash 等语言,可以执行数据分析、文件处理等任务。Browser Tool 提供浏览器自动化能力,支持网页爬取、表单填写、截图等操作。All In One 集成了代码解释器和浏览器工具,提供更丰富的交互能力。

使用时,通过 sandbox_toolset() 函数就可以获取相应的工具集合,这些工具会自动转换为你使用的框架所需的格式。

工具和 MCP:标准化集成

函数计算 AgentRun 提供统一的工具管理和 MCP(Model Context Protocol)机制。你可以从工具市场选择现成的工具,也可以自定义工具并发布到市场。

更强大的是 MCP 的 Hook 机制。通过前置 Hook,可以在工具调用前自动注入用户凭证、记录请求日志、校验参数合法性。通过后置 Hook,可以对结果进行转换、记录审计日志、处理异常情况。这些通用逻辑不需要在每个工具中重复实现,大大提升了开发效率。

全链路可观测:不再是黑盒

这是函数计算 AgentRun 最强大的能力之一。你的代码不需要做任何改动,平台会自动记录 Agent 的完整执行链路

在可观测平台上,你可以看到:Agent 接收到用户请求的时间和内容,调用了哪个模型、使用了多少 Token、花费了多少钱,调用了哪些工具、每个工具的执行时间和结果,访问了哪些知识库、检索了多少数据,每个环节的耗时分布,完整的调用链 Trace。

这些能力都是平台自动提供的,通过探针注入实现,无论是高代码还是低代码创建的 Agent,都自动享受这些可观测能力。

记忆和知识库:数据不出域

函数计算 AgentRun 深度集成了 RAGFlow、Mem0 等开源项目,提供灵活的记忆和知识库管理。你可以选择一键托管模式,由平台统一管理部署运维,享受 Serverless 的弹性和按量付费优势。也可以选择绑定模式,将 Agent 连接到已经部署在企业 VPC 或 IDC 内的实例,数据完全不出企业内网

这种灵活性让你可以根据数据的敏感级别选择不同的策略:核心业务数据私有化部署,一般数据托管上云,在安全性和便利性之间找到最佳平衡。

立即体验函数计算 AgentRun

函数计算 AgentRun 的无代码到高代码演进能力,现已开放体验:

  1. 快速创建: 访问控制台( https://functionai.console.aliyun.com/cn-hangzhou/agent/explore ),60 秒创建你的第一个 Agent
  2. 深度定制: 当需要更复杂功能时,一键转换为高代码
  3. 持续演进: 利用函数计算 AgentRun 的基础设施能力,持续优化你的 Agent

从想法到上线,从原型到生产,函数计算 AgentRun 始终是你最好的伙伴。欢迎加入“函数计算 AgentRun 客户群”,钉钉群号:134570017218。

快速了解函数计算 AgentRun:

一句话介绍:函数计算 AgentRun 是一个以高代码为核心的一站式 Agentic AI 基础设施平台。秉持生态开放和灵活组装的理念,为企业级 Agent 应用提供从开发、部署到运维的全生命周期管理。

image

函数计算 AgentRun 架构图

AgentRun 运行时基于阿里云函数计算 FC 构建,继承了 Serverless 计算极致弹性、按量付费、零运维的核心优势。通过深度集成 AgentScope、LangChain、RAGFlow、Mem0 等主流开源生态。函数计算 AgentRun 将 Serverless 的极致弹性、零运维和按量付费的特性与 AI 原生应用场景深度融合,助力企业实现成本与效率的极致优化,平均 TCO 降低 60% 。 

开发者只需专注于 Agent 的业务逻辑创新,无需关心底层基础设施, 让 Agentic AI 真正进入企业生产环境。

本次更新主要是体验优化上,列一下更新内容:

代码高亮方案换为 ShiKi

新方案体验有问题希望可以及时反馈我做修正,旧方案比较老旧了所以用了新的。

介绍页内容变化

经验值与金币值的常量现在实时了,另外可以输入站内表情以及自动优化中英文空格。

评论列表性能优化

之前楼层数多了,尤其是楼中楼多的情况下,输入会出现卡顿,新版做了优化看体验是否更好一些。

浏览优化

现在滚动时在左侧上方会出现返回按钮,方便回到上一页。

输入优化

现在评论的编辑框增加了@当前楼层的所有人以及@所有人。目前@所有人只取当前评论列表的所有用户名,后续再看是否查询全部。

金币消耗变动

♥️与 👍 现在的消耗增加,让这两个表情的分量更加重一些,且获得会被系统扣除掉 10%。同时金币打赏的最低额度设置为 100 金币,最高 500 金币,各位现在不那么容易慷慨解囊了。

既然有用户慷慨的发现有些操作不消耗金币,我就勉强加入了:

  • 编辑评论、帖子、附言均需要消耗金币;
  • 新增附言需要消耗金币。

消息提醒优化

现在长连接通知收到后,会在浏览器的标题上显示未读计数。

还有不少优化

不列了,比较琐碎。sobbing

一、概述

近期,天穹沙箱团队在追踪银狐家族的攻击活动时,发现其最新样本采用了高度复杂且极具迷惑性的攻击链。该攻击链通过多阶段反调试检测、伪装合法软件安装、内存反射加载等技术,并结合隐蔽的进程注入与DLL侧载(DLL Side-Loading)等手段,以规避安全检测,实现持久驻留于受害者主机。

二、样本信息

  • 样本名: Rar0092_v3.53.278_2xdcey.exe
  • SHA1:50715a3abd66e17654255b7881b035d006dce605
  • 文件类型:EXE
  • 文件大小:127.03 MB
  • 家族归属:银狐家族
  • 报告链接:天穹沙箱分析报告

三、样本分析

该样本具备高度隐蔽性,在执行过程中反复侦测运行环境,其执行逻辑具有明显的多层次、复杂化特征。天穹智能化沙箱系统凭借其全链路行为深度建模与动态分析能力,成功完整捕获并解析了该样本从初始释放、伪装执行、多阶段内存加载到最终持久化与 C2 通信的全过程。系统不仅精准识别了其反调试、环境探测、权限提升等规避行为,还完整提取了各阶段解密后的恶意载荷。以下结合沙箱动态分析结果细致分析样本的恶意行径。

图1 攻击流程

1、反调试检测

首先,样本运行后先检测自身是否处于调试状态,通过检查 PEB->BeingDebugged 字段识别当前是否被用户态调试器附加调试。
接着,调用 NtQuerySystemInformation(SystemBasicInformation) 接口获取当前系统基本信息,检测 CPU 核心数量是否满足 >= 3 核,以及物理内存大小是否满足 >= 3G,样本依据上述硬件配置判断是否处于沙箱分析环境。

图2 反调试检测

当以上检测要求通过后,样本开启真正的恶意能力释放。为保护自身核心代码和逻辑不被轻易窥探,外部函数调用均通过手动查找 LDR 链表获取模块基址,再解析 PE 头获取函数地址,增加函数调用的隐蔽性。
这类多层环境感知检查被深度内嵌在代码执行流的关键节点上,形成贯穿始终的对抗屏障,阻碍安全人员的动态调试和静态分析。

2、伪装安装程序

环境检测通过后,样本再度检查自身是否具有管理员权限,权限满足后会在 C:\\ProgramData 目录下创建随机字符串的目录,并释放多个文件:

app.exe._ (MD5:f041793908111b5395226bc9ed5e6698)
README.md (MD5:daa5414f94d8f43925efffd79979cf75)
View.dat (MD5:c2db56df94b92d6370c87303d1506f54)
Web.dat (MD5:937ab7f863261a046ba3dd46df7cb270)
åº ç ¨å® .exe (MD5:34f435f15a846ae677f88ea412c074d1)
View.conf (MD5:85fac9d703132b9a28beb11d8ec3d181)
alt text
图3 创建目录释放文件

其中 åº ç ¨å® .exe (MD5:34f435f15a846ae677f88ea412c074d1) 为腾讯应用宝的可信安装程序,其余文件为样本后续阶段运行的加密 payload。
为掩盖程序真实意图,样本在释放恶意文件后,调用 WdcRunTaskAsInteractiveUser 接口运行腾讯应用宝安装程序,制造正常操作的假象,欺骗用户。随后,样本隐蔽地拉起 app.exe 进程,进入下一阶段的恶意操作。

图4 伪装程序

3、Payload 加载与执行

第一阶段: View.dat 文件 payload 为 raw 数据,样本通过 VirtualAlloc 分配内存,将 payload 解密后写入内存,并调用 CreateThread 函数创建线程执行该段 payload。
解密后的 payload 是一段具备内存反射加载 PE 文件功能的 shellcode,会加载 raw 数据中夹带的 DLL 文件,并调用其入口函数 DllEntryPoint 进入下一阶段逻辑。

图5 加载 payload

第二阶段: 内存加载的 DLL 文件注册服务并运行 svchost.exe 进程,并注入其他两个文件中包含的 payload (app.exe._ 和 View.dat)

图6 注入 payload

值得说明的是,在本阶段执行注入操作时样本会判断运行环境,高版本 Windows 系统将使用 PoolParty (泳池派对) 注入技术。
注入的恶意代码会在用户目录下释放两个文件:WebViewHelper.exe 和 libcef.dll,其中 WebViewHelper.exe 为具备合法签名的白文件,被用来加载黑文件 libcef.dll,达到混淆视听的目的。

图7 释放文件

svchost.exe 进程通过自启动服务方式运行重命名之后的 WebViewHelper 进程,进入下一阶段逻辑。

第三阶段: WebViewHelper 进程加载的恶意 DLL 文件 (libcef.dll) 会进行一系列的环境检测,包括判断运行环境、所属 session 以及管理员权限等,检测通过后与 C2 服务器建立通信。

图8 环境检测
图9 网络通信
图10 样本攻击链

整个攻击链逻辑错综复杂,层层递进,分析难度极大。同时,攻击者通过伪装合法安装程序、利用白文件加载黑文件等方式混淆视听,进一步干扰了用户和安全人员的判断。

四、IOC

恶意文件(MD5)

481577b35e4d09510c49d78f5c3fa98c    Rar0092_v3.53.278_2xdcey.exe
0c0d6806bb8caf68d4dfa5208db52a17    app.exe
f041793908111b5395226bc9ed5e6698    app.exe._
daa5414f94d8f43925efffd79979cf75    README.md
c2db56df94b92d6370c87303d1506f54    View.dat
937ab7f863261a046ba3dd46df7cb270    Web.dat
34f435f15a846ae677f88ea412c074d1    åº ç ¨å® .exe
85fac9d703132b9a28beb11d8ec3d181    View.conf
c154442ddf6363b6ac5822e47028d672    WebViewHelper.exe
74be16979710d4c4e7c6647856088456    libcef.dll

恶意IOC

192.238.201.32[:]30009              C2 地址

报告链接

分析报告:天穹沙箱分析报告

五、检出规则

天穹沙箱已针对该银狐变种样本编写如下YARA规则,供用户参考使用:

rule Trojan_SilverFox
{
    meta:
        description = "银狐变种的检测"
        date = "2026-01-04"
    strings:
        $seq1 = { 81 E2 FF 00 00 00 03 C2 25 FF 00 00 00 2B C2 88 04 24 48 63 44 24 04 48 8B 4C 24 20 8A 04 01 88 44 24 01 0F B6 04 24 48 63 4C 24 04 48 8B 54 24 20 4C 8B 44 24 20 41 8A 04 00 88 04 0A 0F B6 04 24 48 8B 4C 24 20 8A 54 24 01 88 14 01 }

        $seq2 = { 81 E2 FF 00 00 00 03 C2 25 FF 00 00 00 2B C2 48 8B 4C 24 20 88 81 01 01 00 00 48 8B 44 24 20 0F B6 80 00 01 00 00 48 8B 4C 24 20 8A 04 01 88 04 24 48 8B 44 24 20 0F B6 80 01 01 00 00 48 8B 4C 24 20 0F B6 89 00 01 00 00 48 8B 54 24 20 4C 8B 44 24 20 41 8A 04 00 88 04 0A 48 8B 44 24 20 0F B6 80 01 01 00 00 48 8B 4C 24 20 8A 14 24 88 14 01 48 8B 44 24 20 0F B6 80 00 01 00 00 48 8B 4C 24 20 0F B6 04 01 48 8B 4C 24 20 0F B6 89 01 01 00 00 48 8B 54 24 20 0F B6 0C 0A 33 C1 }

    condition:
        all of them
}

六、技术支持与反馈

星图实验室深耕沙箱分析技术多年,致力于让沙箱更好用、更智能。做地表最强的动态分析沙箱,为每个样本分析人员提供便捷易用的分析工具,始终是我们追求的目标。各位同学在使用过程中有任何问题,欢迎联系我们。

小T导读:京能集团在储能安全管理平台中采用 TDengine TSDB 作为底层时序数据库。依托 TDengine 企业版的零代码数据写入平台,来自全国 28 家电化学储能电站的数据能够按照统一编码规则高效接入 TDengine 时序数据库中,实现了稳定、高性能的数据采集与管理。在此基础上,借助 TDengine TSDB Flink Connector,系统可快速、稳定地从数据库中读取海量数据,开展实时分析与智能处理,充分释放数据的潜在价值。本文将结合该项目的实践过程,为大家带来深入分享与参考。

项目背景

京能集团储能安全管理平台共接入全国 28 家电化学储能电站,累计测点达 270 万个,由四个平台公司分别负责数据传输与汇聚。系统需要支撑大规模的数据统计分析、事件报警与安全预警,对底层数据库的性能与稳定性提出了极高要求。

鉴于电化学储能项目采集点数量庞大(270 万点)、锂电池热失控的超前预警技术复杂等因素,传统关系型数据库已无法满足高并发写入与海量数据存储的需求。由于这些数据具备时间序列写入、格式固定、写入量巨大等典型特征,我们最终选择采用时序数据库作为系统核心数据底座。

应用实际落地

在充分调研国内多款时序数据库产品后,我们发现,从国内目前的实际情况分析,TDengine TSDB 已成为众多企业在海量数据高速存储、处理与调用场景中的首选方案。基于其成熟的技术体系与稳定的性能表现,我们最终选定 TDengine TSDB 作为平台的底层时序数据库,并结合 Kafka 与 Flink 构建了完整的数据流处理体系,实现了数据的高效传输与实时计算,顺利达成项目预期目标。以下是架构简图:

TDengine TSDB 支持多种写入方式

  1. SQL 语言写入 :https://docs.taosdata.com/basic/insert/
  2. 无模式写入:https://docs.taosdata.com/develop/schemaless/
  3. 参数绑定方式:https://docs.taosdata.com/develop/stmt/
  4. 企业版的零代码数据写入— taosExplorer 数据接入功能:https://docs.taosdata.com/advanced/data-in/

项目中涉及多个 Kafka 集群、数十个需要接入的 topic。我们重点采用了 TDengine 企业版的零代码数据写入能力,实现了从 Kafka 到 TDengine TSDB 的高效对接。该功能支持灵活配置类似 ETL 的复杂自定义选项,极大简化了数据接入流程和时间,而且数据接入性能完全达到了项目要求。

为了保证数据的合理性,我们出台了《京能集团电化学储能电站安全管理平台和储能电站设备标识编码规则》,通过标准的 kks 编码在 taosX 对 Kafka 数据进行了有效过滤和清理,最终写入 TDengine TSDB。kks 部分编码实例如下:

下图为数据过滤、转换等规则设置:

此外,taosX 数据接入还支持多节点高可用配置。只需在多台 taosX 上部署相同的 Kafka 数据接入任务,并设置相同的 groupId,即可自动实现任务高可用,确保数据接入的连续性与稳定性。

同时,TDengine 还提供完善的 taosX 任务监控机制,可直接通过 Grafana 一键配置,快速生成可视化监控图表:

超级表 + 子表的使用

TDengine TSDB 结合“一个数据采集点一张表”的设计理念,引入了具有创新性的“超级表”机制,从根本上解决了大规模时序数据结构不统一、聚合困难、运维复杂等问题。每个采集点的数据独立存储,天然具备写入无锁、数据顺序追加、块状连续存储等优势。这种设计方式不仅提升了写入与查询性能,还带来了极高的数据压缩效率。

TDengine TSDB 支持对超级表标签进行动态的添加、修改与删除操作,满足设备属性变更、系统扩展等业务需求。

计算、分析处理

在 Flink 计算平台上,我们借助 TDengine TSDB 企业版提供的 Flink 连接器——TDengine TSDB Flink Connector(https://docs.taosdata.com/advanced/data-publisher/Flink/),实现了与 TDengine TSDB 的无缝集成。该连接器可高效、稳定地从 TDengine TSDB 中读取海量时序数据,并在此基础上进行全面、深入的分析处理,充分挖掘数据的潜在价值,极大地提升数据处理的效率和质量。

Flink CDC 主要用于提供数据订阅功能,能实时监控 TDengine TSDB 数据库的数据变化,并将这些变更以数据流形式传输到 Flink 中进行处理,同时确保数据的一致性和完整性。

落地效果

  1. 数据接入便利性:目前我们已接入 20 多个 kafka 数据,后期还会继续增加。得益于 TDengine 企业版零代码数据接入能力,新增任务仅需复制并做少量参数调整即可完成,操作简便高效,整体接入过程较传统方式节省约 90% 的时间成本
  2. 数据查询性能高:开启数据库缓存功能后,能够实时获取每个设备点位最新值,毫秒级别即可返回结果
  3. 数据存储成本低:TDengine TSDB 具备出色的数据压缩能力,其二级压缩技术将数据视作无差别的二进制块进行再次压缩。与一级压缩相比,二级压缩的侧重点在于消除数据块之间的信息冗余。目前我们提供的服务器存储远远满足我们项目规划的 5 年数据存储,存储成本估算节省至少 60-70%
  4. 实时订阅:通过 TDengine 提供的 Flink CDC 实时订阅功能,能方便、高效的进行分析、告警等处理,给我们后期分析带来了极大的便利性。

后期规划

目前,我们正在对京能集团储能安全管理平台已经接入的 28 场站数据进行分析和优化,提高数据采集的可靠性和鲁棒性。未来我们会针对 TDengine TSDB 新版本和新功能进行持续跟踪,进一步开发 TDengine TSDB 的内在潜力和各种有效的功能。

近期我们关注到 TDengine 发布了新产品 TDengine IDMP,通过经典的树状层次结构组织传感器、设备采集的数据,建立数据目录,对数据提供情境化、标准化的处理,并提供实时分析、可视化等功能,接下来我们会进一步了解此产品在我们业务中的使用可能。

关于京能集团

北京能源集团有限责任公司是北京市人民政府出资设立的国有独资公司,肩负着保障首都北京能源安全可靠供应的重任。京能集团成立于 2004 年,由原北京国际电力开发投资公司和原北京市综合投资公司合并而成,2011 年、2014 年先后又与北京市热力集团有限责任公司、北京京煤集团有限责任公司实施合并重组,实现了产业链条融合互补。经过多年的资源整合,集团由单一能源产业发展为热力、电力、煤炭、健康文旅等多业态产业格局。2024 年在中国企业 500 强排名第 247 位,中国服务企业 500 强排名第 87 位。

作者:张海增

服务器存储数据恢复环境:
某品牌服务器存储上有16块FC硬盘,存储设备前面板的10号硬盘指示灯和13号硬盘指示灯亮黄灯,存储设备映射到服务器redhat linux系统上的卷无法挂载,业务中断。

服务器存储数据恢复过程:
1、通过存储设备厂商的管理程序storage manager连接到服务器存储上查看当前存储状态,逻辑卷状态failed。查看物理磁盘状态,6号盘报告“警告”,10号和13号盘报告“失败”。
通过storage manager将故障存储的完整日志状态备份,解析备份出来的存储日志获取逻辑卷结构的部分信息。
2、北亚企安数据恢复工程师将故障存储中16块FC盘做好标记后,从存储设备中取出。使用专业镜像设备对16块FC盘进行初步测试。经过测试发现16块盘均能正常识别。分别检测16块盘的SMART状态,结果6号盘的SMART状态为“警告”,和storage manager中的报告一致。
3、北亚企安数据恢复工程师在windows环境下将识别出来的FC盘在磁盘管理器中标记为脱机状态,然后对原始磁盘进行扇区级别完整镜像。将原始磁盘中的所有物理扇区镜像到windows系统下的逻辑磁盘并以文件形式保存。
在镜像过程中服务器数据恢复工程师发现6号磁盘的镜像速度极慢,结合先前检测结果综合判断,6号盘应该存在大量损坏以及不稳定扇区,导致windows环境下的一些软件无法对其进行操作。
4、使用专业镜像设备对6号硬盘进行坏道镜像操作,在镜像过程中观察镜像的速度和稳定性。在镜像过程中发现6号盘上的坏道并不多,但是存在大量读取响应时间长的不稳定扇区。于是服务器数据恢复工程师调整6号盘的拷贝策略,将“遇到坏道跳过扇区数”和“响应等待时间”等参数作一些调整后继续对6号盘进行镜像操作。同时观察剩余盘在windows环境下镜像的情况。
5、镜像完成后查看日志,发现在storage manager和SMART状态中均没有报错的1号盘也存在坏道,10号和13号盘均存在大量不规则的坏道分布。
根据坏道列表使用工具定位到目标镜像文件进行分析后发现,ext3文件系统的一些关键源数据信息被坏道破坏。只能等6号盘镜像完毕后,通过同一条带进行xor以及根据文件系统上下文关系手动修复被损坏的文件系统。
6、6号盘镜像完成,但是为了最大限度做出有效扇区和保护磁头所设置的拷贝策略,会让这次完成的镜像在镜像过程中自动跳过一些不稳定扇区,所以现在的镜像是不完整的。于是服务器数据恢复工程师调整拷贝策略,继续镜像被跳过的扇区,直到6号盘所有扇区全部镜像完成。
7、所有硬盘镜像完成后,基于镜像文件分析所有硬盘底层数据。根据北亚企安数据恢复工程师对ext3文件系统的逆向研究和对日志文件的分析,获取到16块FC盘的盘序、RAID块大小、RAID的校验走向和方式等重组RAID的必要信息,根据获取到的信息虚拟重组RAID。RAID搭建完成后进一步解析ext3文件系统。
8、和用户方沟通后提取出一些oracle数据库的dmp文件,用户方尝试通过dmp文件恢复数据库。
在dmp恢复的过程中,oracle数据库报告imp-0008错误。北亚数据恢复中心的oracle数据库工程师分析导入dmp文件的日志文件后,发现恢复的dmp文件存在问题,从而导致dmp导入数据失败。
9、服务器数据恢复工程师重新分析raid结构,进一步确定ext3文件系统被破坏的程度,重新恢复dmp文件和dbf原始库文件。
10、将恢复出来的dmp文件移交给用户方进行数据导入测试,这次测试顺利,没有发现问题。对恢复出来的dbf原始库文件进行校验检测,所有文件均能通过测试。
11、数据库工程师到达现场,和用户沟通后决定使用恢复出来的dbf原始库文件进行操作,以确保把数据恢复到最佳状态。

oracle数据库恢复过程:
1、拷贝数据库文件到原数据库服务器作为备份,备份文件所在文件夹路径为/home/oracle/tmp/syntong。在根目录下创建一个名为“oradata”的目录,把syntong文件夹拷贝到oradata目录下。更改oradata文件夹及其所有文件的属组和权限。
2、备份原数据库环境,包括ORACLE_HOME下product文件夹下的相关文件。配置监听,使用原机中的splplus连接到数据库,尝试启动数据库到nomount状态。进行基本状态查询后,了解到环境和参数文件没有问题。 尝试启动数据库到mount状态,进行状态查询没有发现问题。当启动数据库到open状态,出现报错:
ORA-01122: database file 1 failed verification check
ORA-01110: data file 1: '/oradata/syntong/system01.dbf'
ORA-01207: file is more recent than control file - old control file
经过进一步的检测和分析,判断此故障为控制文件和数据文件信息不一致,这是一类常因断电或突然关机引发的故障。
3、对数据库文件进行逐个检测,检测到所有数据文件都不存在物理损毁的情况。
4、在mount状态下,对控制文件进行备份。alter database backup controlfile to trace as ' /backup/controlfile'。对备份的控制文件进行查看修改,取得其中的重建控制文件命令。把这些命令复制到一个新建脚本文件controlfile.sql中。
5、关闭数据库,删除/oradata/syntong/下的3个控制文件。 启动数据库到nomount状态,执行controlfile.sql 脚本。
SQL>startup nomount
SQL>@controlfile.sql
6、完成重建控制文件后,启动数据库报错,需要做进一步处理。
SQL> alter database open
alter database open
*
ERROR at line 1:
ORA-01113: file 1 needs media recovery
ORA-01110: data file 1: '/free/oracle/oradata/orcl/system01.dbf'
然后执行恢复命令:
recover database using backup controlfile until cancel
Recovery of Online Redo Log: Thread 1 Group 1 Seq 22 Reading mem 0
Mem# 0 errs 0: /free/oracle/oradata/orcl/redo01.log

做介质恢复,直到返回报告,恢复完成。
7、尝试open数据库。
SQL> alter database open resetlogs
8、成功启动数据库。把原来temp表空间的数据文件加入到对应的temp表空间中。
9、对数据库进行各种常规检查,没有发现任何错误。
10、进行emp备份。全库备份完成也没有报错。将应用程序连接到数据库,进行应用层面的数据验证。经过验证没有发现问题。本次数据恢复工作完成。

在企业数字化转型中,CRM 系统是连接“客户-销售-服务”的核心枢纽。从线索获取到商机转化,从自动化流程到数据决策,不同品牌的CRM在核心能力上的差异,直接决定了企业能否“用对工具、提效增收”。

本文基于超兔一体云、Salesforce、SuiteCRM、Freshsales、红圈 CRM 、六度人和( EC SCRM)的公开能力素材,从线索与商机管理、自动化能力、报表能力、审批能力、可配置性五大维度展开深度对比,结合表格、流程图、脑图、雷达图**直观呈现差异,为企业选型提供参考。

一、对比框架与核心逻辑

本次对比围绕“企业实际业务需求”设计维度,重点回答以下问题:

  • 能否覆盖从“线索→客户→商机→订单”的全流程?
  • 能否通过自动化减少重复劳动?
  • 能否通过数据报表支撑决策?
  • 能否适配企业的个性化流程(如审批、字段)?
  • 能否匹配企业的规模与行业特性?

二、核心能力横向对比

(一)维度1:线索与商机管理——从“获客”到“转化”的全流程覆盖

线索与商机是销售的“源头活水”,核心评价标准是流程完整性、AI辅助能力、自定义适配性

各品牌表现拆解

品牌核心优势具体能力
超兔一体云多渠道获客+“三一客”小单快转模型1. 覆盖百度、抖音、微信、地推等10+线索来源; 2. 三一客模型(定人、定时、定动作)推进小单转化; 3. 自动计算市场活动ROI(成本均摊到线索/签约)。
SalesforceAI预测+全流程自动化流转1. Einstein AI预测商机赢单概率(准确率达85%+); 2. Lead→Opportunity自动关联客户/联系人; 3. 产品/价格簿深度整合(支持复杂报价)。
SuiteCRM开源自定义流程1. 支持线索→客户→商机的全流程自定义(字段、布局、节点); 2. 适配企业独特业务逻辑(如制造业的“线索→经销商→商机”)。
FreshsalesAI线索评分+行为跟踪1. AI线索评分(基于邮件打开、页面访问等行为); 2. 自动触发邮件序列(如未打开邮件3天后重发); 3. 客户行为 timeline 可视化。
红圈 CRM全流程覆盖+公海池管理1. 覆盖“线索→客户→商机→回款”全链路; 2. 公海池解决线索分散问题(未跟进线索自动回收再分配); 3. 适配工程行业的“项目型商机”。
六度人和社交渠道整合+AI商机助手1. 整合微信、QQ、企业微信等社交线索(占比80%+); 2. AI商机助手自动总结客户需求(如微信聊天中的“价格咨询”); 3. 跟踪客户社交行为(如打开朋友圈链接)。

流程可视化:超兔一体云“线索→商机”时序图

sequenceDiagram
    participant 市场 as 市场渠道(百度/抖音/微信)
    participant 超兔 as 超兔一体云
    participant 销售 as 销售
    participant 客户 as 客户

    市场->>超兔: 推送线索(手机号/IP/行为)
    超兔->>超兔: 线索清洗(去重/归属地识别)
    超兔->>销售: 分配通知(短信/APP)
    销售->>超兔: 跟进记录(电话/拜访/微信)
    超兔->>超兔: 三一客模型判定(是否合格)
    alt 合格
        超兔->>超兔: 转化为商机(关联客户)
        销售->>客户: 报价/演示
        客户->>超兔: 确认订单
        超兔->>超兔: 计算ROI(市场成本/签约额)
    else 不合格
        超兔->>超兔: 移入线索池(需求培养)
        超兔->>销售: 定期提醒复访
    end

(二)维度2:自动化能力——从“人工重复”到“智能执行”的效率跃迁

自动化是CRM的“效率引擎”,核心评价标准是低代码 /无代码能力、AI 智能体 、跨系统协同

各品牌表现拆解

品牌核心优势具体能力
超兔一体云低代码工作流+AI智能体嵌入式应用1. 自然语言AI生成工作流(如“新线索自动分配给区域销售”); 2. AI智能体嵌入客户视图(自动生成跟单待办、日报); 3. 订单自动化(锁库、生成采购单)。
Salesforce低代码+AI代理+跨系统集成1. Lightning低代码平台(拖拽式配置工作流); 2. Agentforce AI代理(自动处理19万+潜在客户,节省50万+小时); 3. MuleSoft集成ERP/供应链系统。
SuiteCRM基础工作流引擎1. 新线索自动分配给区域销售; 2. 任务到期自动提醒; 3. 需技术团队二次开发复杂流程(如售后工单派工)。
FreshsalesAI助手+邮件序列自动化1. Freddy AI自动生成跟单待办(如“客户3天未回复,建议跟进”); 2. 邮件序列(未打开邮件3天后重发,打开后触发跟进); 3. 自动记录客户行为(如访问产品页面)。
红圈 CRMPaaS平台+行业定制流程1. PaaS平台配置自动化(如“工程商机达标自动触发合同审批”); 2. 适配工程行业的“项目进度→商机更新”流程; 3. 支持第三方系统集成(如ERP)。
六度人和社交行为触发自动化1. 客户打开微信链接→自动发跟进消息; 2. 客户未回复微信→3天后自动提醒销售; 3. 整合微信朋友圈广告线索→自动分配。

流程可视化:Salesforce“订单审批”自动化工作流

graph TD
    A[触发条件: 商机金额>10万] --> B{检查审批人权限}
    B -->|是| C[发送通知(邮件/Slack)]
    B -->|否| D[退回修改+原因提示]
    C --> E[审批人审批]
    E -->|通过| F[自动生成订单+锁库]
    E -->|驳回| G[通知销售修改]
    F --> H[同步至ERP]

(三)维度3:报表能力——从“数据”到“决策”的价值转化

报表是CRM的“大脑”,核心评价标准是可视化能力、自定义深度、实时性

各品牌表现拆解

品牌核心优势具体能力
超兔一体云多表聚合+实时工作台1. 工作台数字卡片(实时显示线索量、商机转化率); 2. 多表聚合分析(线索→商机→订单关联); 3. 单日KPI引擎(销售今日需完成的线索跟进量)。
Salesforce高级BI+权限管控1. Tableau集成(高级可视化,如销售漏斗趋势); 2. 动态仪表板(实时更新业绩、客户留存); 3. 权限精细管控(如销售仅能看自己的客户数据)。
SuiteCRM基础自定义报表1. 支持线索、客户、商机的基础统计; 2. 自定义字段过滤(如“区域=华北”的线索量); 3. 需二次开发复杂报表(如“项目成本分析”)。
Freshsales智能绩效仪表盘1. 团队业绩仪表盘(显示转化率、平均单客价); 2. 客户旅程可视化(如“线索→商机→成交”的步骤); 3. AI分析(如“高意向客户的共同特征”)。
红圈 CRM行业定制BI1. 工程行业成本分析(项目成本→商机利润); 2. 销售业绩对比(同比/环比); 3. 实时动态建模(如“本月新签项目的区域分布”)。
六度人和社交行为统计1. 销售微信互动次数统计; 2. 客户响应率分析(如“微信消息的回复率”); 3. 朋友圈广告线索转化率。

(四)维度4:审批能力——从“合规”到“高效”的流程管控

审批是企业的“风险闸门”,核心评价标准是流程自定义、触发条件、移动端支持

各品牌表现拆解

品牌核心优势具体能力
超兔一体云全局权限+移动端便捷审批1. 全局权限机制(上级管下级、助理跟主管、老板看全局); 2. 移动端审批(支持微信/APP); 3. 自动触发(如“费用报销>500元需经理审批”)。
Salesforce多节点+多渠道通知1. 自定义审批节点(如“订单→区域经理→财务→老板”); 2. 多渠道通知(邮件、Slack、手机); 3. 审批历史追溯(如“谁驳回了订单”)。
SuiteCRM需二次开发1. 基础审批功能(如请假); 2. 复杂审批(如合同)需技术团队修改代码; 3. 无移动端原生支持。
Freshsales第三方集成1. 通过Zapier集成审批工具(如ApprovalMax); 2. 无原生审批流程; 3. 移动端需跳转到第三方应用。
红圈 CRM行业定制流程1. 工程合同审批(项目经理→财务→老板); 2. 层级审批(如“金额>10万需总部审批”); 3. 移动端支持。
六度人和基础配置+第三方扩展1. 请假、报销等基础审批; 2. 复杂审批需集成钉钉/企业微信; 3. 微信小程序审批。

(五)维度5:可配置性——从“通用”到“个性”的适配能力

可配置性决定了CRM能否“贴合企业业务”,核心评价标准是低代码 工具、开源/闭源、集成能力

各品牌表现拆解

品牌核心优势具体能力
超兔一体云功能订阅+自定义工作台1. 功能白名单(仅订阅需要的模块,降低成本); 2. 自定义工作台(销售/市场/财务的专属数据大屏); 3. 自定义业务表(如客户字段、订单布局)。
Salesforce低代码+元数据驱动1. Lightning低代码平台(非技术人员可自定义模块); 2. 元数据驱动(升级不影响自定义功能); 3. Apex语言二次开发(深度定制业务逻辑)。
SuiteCRM开源深度定制1. 开源代码(可修改核心逻辑); 2. 集成第三方ERP(如SAP); 3. 自定义字段/布局/流程。
Freshsales企业版高级自定义1. 免费版:基础字段修改; 2. 企业版:自定义模块(如“项目”)、工作流; 3. 集成第三方工具(如Mailchimp)。
红圈 CRMAPI开放+行业适配1. 开放API接口(集成项目管理/ERP系统); 2. 适配130+行业(如工程、医药); 3. 自定义数据字典(如“工程阶段”字段)。
六度人和开箱即用+基础调整1. 无需配置,快速上线; 2. 基础调整(如客户字段、菜单); 3. 集成微信/企业微信。

三、综合能力雷达图——各品牌的“能力边界”

以下是各品牌在五大维度的1-5分评分(5分为满分),直观呈现“长板”与“短板”:

品牌线索与商机自动化报表审批可配置
超兔一体云4.54.34.04.24.4
Salesforce4.84.94.74.84.7
SuiteCRM4.03.03.52.54.5
Freshsales4.34.54.23.03.5
红圈 CRM4.54.04.34.54.2
六度人和4.23.83.53.03.2

四、选型建议——匹配“企业特性”的最优解

根据企业规模、行业、技术能力,推荐以下选型方向:

企业类型推荐品牌原因
中小企业(10-200人)超兔一体云全流程覆盖+高可配置+低成本(功能白名单),适配小单快转的业务需求。
中大型企业(200人以上)SalesforceAI+集成能力强,支持复杂销售流程(如多产品、跨区域)。
有技术团队的企业SuiteCRM开源深度定制,可整合自有ERP/项目管理系统。
成长型企业(注重效率)FreshsalesAI线索评分+自动待办,提升销售效率(适合电销/网销团队)。
复杂行业(如工程)红圈 CRM全流程覆盖+行业适配(如项目成本分析、合同审批)。
社交型销售(教育/金融)六度人和微信/企业微信整合,跟踪客户社交行为(如朋友圈互动)。

五、总结——CRM选型的“本质”

CRM的核心价值不是“功能多”,而是“匹配企业的业务阶段与需求”。中小企业需要“全流程、高可配置、低成本”;中大型企业需要“AI、集成、复杂流程”;行业型企业需要“定制化、行业适配”。

通过本文的对比,企业可以清晰看到:

  • 超兔一体云是中小企业的“全流程数字化工具”
  • Salesforce是中大型企业的“ AI+ 集成平台
  • 红圈CRM是复杂行业的“全流程管家”
  • 六度人和是社交型销售的“获客神器”

最终,选型的关键是“以业务为中心”——先明确自己的核心需求(如“要解决线索转化慢”还是“要做AI预测”),再匹配品牌的“长板”能力。

(注:文中功能相关描述均基于公开披露信息,具体功能服务与价格以厂商实际落地版本为准。)

作者:辰泉

前言

在 Agentic AI 时代,智能体需要与真实世界交互,而浏览器是连接虚拟世界与现实世界的重要桥梁。AgentRun Browser Sandbox 为智能体提供了安全、高性能、免运维的浏览器执行环境,让 AI Agent 真正具备“上网”的能力——从网页抓取、信息提取到表单填写、自动化操作,一切皆可实现。

AgentRun Browser Sandbox 介绍

什么是 Browser Sandbox?

Browser Sandbox 是 AgentRun 平台提供的云原生无头浏览器沙箱服务,基于阿里云函数计算(FC)构建。它为智能体提供了一个安全隔离的浏览器执行环境,支持通过标准的 Chrome DevTools Protocol (CDP) 远程控制浏览器实例。

核心特性

无头浏览器能力

  • 内置 Chromium/Chrome 浏览器,支持完整的 Web 标准
  • 原生兼容 Puppeteer、Playwright 等主流自动化框架
  • 支持通过 CDP 协议进行精细化控制

实时可视化

  • 内置 VNC 服务,支持实时查看浏览器界面
  • 提供操作录制功能,方便调试和回放
  • 支持通过 noVNC 客户端在网页中直接交互

安全与隔离

  • 每个沙箱实例运行在独立的容器环境中
  • 文件系统和进程空间完全隔离
  • 支持 WSS 加密传输,确保数据安全

Serverless 架构

  • 按需创建,按量付费,无需提前预置资源
  • 快速弹性伸缩,支持高并发场景
  • 零运维,无需管理服务器和浏览器依赖

主要应用场景

  • AI Agent 赋能: 为大模型提供“眼睛”和“手”,执行网页浏览、信息提取、在线操作等任务
  • 自动化测试: 在云端运行端到端(E2E)测试和视觉回归测试
  • 数据采集: 稳定、高效地进行网页抓取,应对动态加载和反爬虫挑战
  • 内容生成: 自动化生成网页截图或 PDF 文档

上手使用 AgentRun Browser Sandbox

AgentRun SDK 快速介绍

后续的内容将基于 AgentRun SDK 进行,因此我们先对 SDK 进行简要介绍。

Agentrun SDK 是一个开源的开发者工具包,本期介绍 Python 版本。其旨在简化智能体与 AgentRun 平台各种服务(包括 Browser Sandbox)的集成。它提供了统一的接口,让您可以用几行代码就将沙箱能力集成到现有的 Agent 框架中。SDK 的核心功能如下:

统一集成接口

  • 提供对 LangChain、AgentScope 等主流框架的开箱即用支持
  • 统一的模型代理接口,简化多模型管理
  • 标准化的工具注册机制

Sandbox 生命周期管理

  • 自动创建和销毁沙箱实例
  • 支持会话级别的状态保持
  • 灵活的资源配置和超时控制

安装 AgentRun SDK

pip install agentrun-sdk[playwright,server]

注意: 确保您的 Python 环境版本在 3.10 及以上。

基本使用示例

以下是使用 AgentRun SDK 创建和管理 Browser Sandbox 的核心代码:

from agentrun.sandbox import Sandbox, TemplateType
from playwright.sync_api import sync_playwright
# 创建 Browser Sandbox
sandbox = Sandbox.create(
    template_type=TemplateType.BROWSER,
    template_name="your-template-name",
    sandbox_idle_timeout_seconds=300
)
# 获取 CDP URL(用于 Playwright 连接)
cdp_url = sandbox.get_cdp_url()
# 使用 Playwright 连接并操作
with sync_playwright() as p:
    browser = p.chromium.connect_over_cdp(cdp_url)
    page = browser.contexts[0].pages[0]
    page.goto("https://www.example.com")
    page.screenshot(path="screenshot.png")
    browser.close()
# 销毁 Sandbox
sandbox.delete()

关键概念:

  • template_name: 控制台创建的浏览器环境模板
  • cdp_url: 用于 Playwright/Puppeteer 连接
  • vnc_url: 用于实时查看浏览器画面(可通过 sandbox.get_cdp_url() 获取)

注意: 由于所有浏览器操作都在云端进行,您无需在本地安装浏览器。Playwright 仅用于通过 CDP 协议连接到云端的浏览器实例。

如何创建 Sandbox 模板

使用 Browser Sandbox 需要新建 Sandbox 模板,您需要访问 AgentRun 控制台网站 [ 1] ,并按照如下步骤创建模板:

  1. 在顶部菜单栏选择“运行时与沙箱”;
  2. 在左侧边栏选择“Sandbox 沙箱”;
  3. 点击右上角“创建沙箱模板”;

image

  1. 选择“浏览器”;

image

  1. 在弹出的抽屉对话框中填写和选择您的模板的规格、网络等配置,并复制模板名称;

image

  1. 点击“创建浏览器”等待其就绪即可。

从零开始用 LangChain 创建 Browser Sandbox 智能体

本教程将指导您从零开始创建一个完整的 Browser Sandbox 智能体项目。

基于 LangChain 集成 Browser Sandbox

本教程将详细讲解如何使用 LangChain 创建 Browser Sandbox 相关的 Tools 并集成到 Agent 中。

项目结构

为了保持代码的内聚性和可维护性,我们将代码拆分为以下模块:

模块职责划分:

sandbox_manager.py:负责 Sandbox 的创建、管理和销毁,提供统一的接口
langchain_agent.py:负责创建 LangChain Tools 和 Agent,集成 VNC 信息
main.py:作为入口文件,演示如何使用上述模块

步骤 1:创建项目并安装依赖

首先创建项目目录(如果还没有):

mkdir -p langchain-demo
cd langchain-demo

创建 requirements.txt 文件,内容如下:

# LangChain 核心库
langchain>=0.1.0
langchain-openai>=0.0.5
langchain-community>=0.0.20
# AgentRun SDK
agentrun-sdk[playwright,server]>=0.0.8
# 浏览器自动化
playwright>=1.40.0
# 环境变量管理
python-dotenv>=1.0.0

然后安装依赖:

pip install -r requirements.txt

主要依赖说明:

  • langchain 和 langchain-openai:LangChain 核心库
  • agentrun-sdk[playwright,server]:AgentRun SDK,用于 Sandbox 管理
  • playwright:浏览器自动化库
  • python-dotenv:环境变量管理

步骤 2:配置环境变量

在项目根目录创建 .env 文件,配置以下环境变量:

# 阿里云百炼平台的 API Key,用于调用大模型能力
# 请前往 https://bailian.console.aliyun.com/?tab=app#/api-key 创建和查看
DASHSCOPE_API_KEY=sk-your-bailian-api-key
# 阿里云账号的访问密钥 ID 和访问密钥 Secret,用于 AgentRun SDK 鉴权
ALIBABA_CLOUD_ACCESS_KEY_ID=your-ak
ALIBABA_CLOUD_ACCESS_KEY_SECRET=your-sk
ALIBABA_CLOUD_ACCOUNT_ID=your-main-account-id
ALIBABA_CLOUD_REGION=cn-hangzhou
# browser sandbox 模板的名称,可以在 https://functionai.console.aliyun.com/cn-hangzhou/agent/runtime/sandbox 控制台创建
BROWSER_TEMPLATE_NAME=sandbox-your-template-name
# agentrun 的控制面和数据面的 API 端点请求地址,默认cn-hangzhou
AGENTRUN_CONTROL_ENDPOINT=agentrun.cn-hangzhou.aliyuncs.com
AGENTRUN_DATA_ENDPOINT=https://${your-main-account-id}.agentrun-data.cn-hangzhou.aliyuncs.com

步骤 3:创建 Sandbox 生命周期管理模块

创建 sandbox_manager.py 文件,负责 Sandbox 的创建、管理和销毁。核心代码如下:

"""
Sandbox 生命周期管理模块
负责 AgentRun Browser Sandbox 的创建、管理和销毁。
提供统一的接口供 LangChain Agent 使用。
"""
import os
from typing import Optional, Dict, Any
from dotenv import load_dotenv
# 加载环境变量
load_dotenv()
class SandboxManager:
    """Sandbox 生命周期管理器"""
    def __init__(self):
        self._sandbox: Optional[Any] = None
        self._sandbox_id: Optional[str] = None
        self._cdp_url: Optional[str] = None
        self._vnc_url: Optional[str] = None
    def create(
        self,
        template_name: Optional[str] = None,
        idle_timeout: int = 3000
    ) -> Dict[str, Any]:
        """
        创建或获取一个浏览器 sandbox 实例
        Args:
            template_name: Sandbox 模板名称,如果为 None 则从环境变量读取
            idle_timeout: 空闲超时时间(秒),默认 3000 秒
        Returns:
            dict: 包含 sandbox_id, cdp_url, vnc_url 的字典
        Raises:
            RuntimeError: 创建失败时抛出异常
        """
        try:
            from agentrun.sandbox import Sandbox, TemplateType
            # 如果已有 sandbox,直接返回
            if self._sandbox is not None:
                return self.get_info()
            # 从环境变量获取模板名称
            if template_name is None:
                template_name = os.getenv(
                    "BROWSER_TEMPLATE_NAME",
                    "sandbox-browser-demo"
                )
            # 创建 sandbox
            self._sandbox = Sandbox.create(
                template_type=TemplateType.BROWSER,
                template_name=template_name,
                sandbox_idle_timeout_seconds=idle_timeout
            )
            self._sandbox_id = self._sandbox.sandbox_id
            self._cdp_url = self._get_cdp_url()
            self._vnc_url = self._get_vnc_url()
            return self.get_info()
        except ImportError as e:
            print(e)
            raise RuntimeError(
                "agentrun-sdk 未安装,请运行: pip install agentrun-sdk[playwright,server]"
            )
        except Exception as e:
            raise RuntimeError(f"创建 Sandbox 失败: {str(e)}")
    def get_info(self) -> Dict[str, Any]:
        """
        获取当前 sandbox 的信息
        Returns:
            dict: 包含 sandbox_id, cdp_url, vnc_url 的字典
        Raises:
            RuntimeError: 如果没有活动的 sandbox
        """
        if self._sandbox is None:
            raise RuntimeError("没有活动的 sandbox,请先创建")
        return {
            "sandbox_id": self._sandbox_id,
            "cdp_url": self._cdp_url,
            "vnc_url": self._vnc_url,
        }
    def get_cdp_url(self) -> Optional[str]:
        """获取 CDP URL"""
        return self._sandbox.get_cdp_url()
    def get_vnc_url(self) -> Optional[str]:
        """获取 VNC URL"""
        return self._sandbox.get_vnc_url()
    def get_sandbox_id(self) -> Optional[str]:
        """获取 Sandbox ID"""
        return self._sandbox_id
    def destroy(self) -> str:
        """
        销毁当前的 sandbox 实例
        Returns:
            str: 操作结果描述
        """
        if self._sandbox is None:
            return "没有活动的 sandbox"
        try:
            sandbox_id = self._sandbox_id
            # 尝试销毁 sandbox
            if hasattr(self._sandbox, 'delete'):
                self._sandbox.delete()
            elif hasattr(self._sandbox, 'stop'):
                self._sandbox.stop()
            elif hasattr(self._sandbox, 'destroy'):
                self._sandbox.destroy()
            # 清理状态
            self._sandbox = None
            self._sandbox_id = None
            self._cdp_url = None
            self._vnc_url = None
            return f"Sandbox 已销毁: {sandbox_id}"
        except Exception as e:
            # 即使销毁失败,也清理本地状态
            self._sandbox = None
            self._sandbox_id = None
            self._cdp_url = None
            self._vnc_url = None
            return f"销毁 Sandbox 时出错: {str(e)}"
    def is_active(self) -> bool:
        """检查 sandbox 是否活跃"""
        return self._sandbox is not None
    def __enter__(self):
        """上下文管理器入口"""
        return self
    def __exit__(self, exc_type, exc_val, exc_tb):
        """上下文管理器退出,自动销毁"""
        self.destroy()
        return False
# 全局单例(可选,用于简单场景)
_global_manager: Optional[SandboxManager] = None
def get_global_manager() -> SandboxManager:
    """获取全局 SandboxManager 单例"""
    global _global_manager
    if _global_manager is None:
        _global_manager = SandboxManager()
    return _global_manager
def reset_global_manager():
    """重置全局 SandboxManager"""
    global _global_manager
    if _global_manager:
        _global_manager.destroy()
    _global_manager = None

关键功能:

  1. 创建 Sandbox: 使用 AgentRun SDK 创建浏览器 Sandbox
  2. 获取连接信息: 自动获取 CDP URL 和 VNC URL,支持多种属性名兼容
  3. 生命周期管理: 提供销毁方法,确保资源正确释放

步骤 4:创建 LangChain Tools 和 Agent

创建 langchain_agent.py 文件,定义 LangChain Tools 并创建 Agent。核心代码如下:

"""
LangChain Agent 和 Tools 注册模块
负责创建 LangChain Agent,注册 Sandbox 相关的 tools,并集成 VNC 可视化。
本模块使用 sandbox_manager.py 中封装的 SandboxManager 来管理 sandbox 生命周期。
"""
import os
from dotenv import load_dotenv
from langchain.tools import tool
from langchain_openai import ChatOpenAI
from langchain.agents import create_agent
from pydantic import BaseModel, Field
# 导入 sandbox 管理器
from sandbox_manager import SandboxManager
# 加载环境变量
load_dotenv()
# 全局 sandbox 管理器实例(单例模式)
_sandbox_manager: SandboxManager | None = None
def get_sandbox_manager() -> SandboxManager:
    """获取 sandbox 管理器实例(单例模式)"""
    global _sandbox_manager
    if _sandbox_manager is None:
        _sandbox_manager = SandboxManager()
    return _sandbox_manager
# ============ LangChain Tools 定义 ============
@tool
def create_browser_sandbox(
    template_name: str = None,
    idle_timeout: int = 3000
) -> str:
    """创建或获取一个浏览器 sandbox 实例。
    当需要访问网页、执行浏览器操作时,首先需要创建 sandbox。
    创建成功后,会返回 sandbox 信息,包括 VNC URL 用于可视化。
    Args:
        template_name: Sandbox 模板名称,如果不提供则从环境变量 BROWSER_TEMPLATE_NAME 读取
        idle_timeout: 空闲超时时间(秒),默认 3000 秒
    Returns:
        Sandbox 信息字符串,包括 ID、CDP URL、VNC URL
    """
    try:
        manager = get_sandbox_manager()
        # 如果 template_name 为空字符串,转换为 None 以便从环境变量读取
        if template_name == "":
            template_name = None
        info = manager.create(template_name=template_name, idle_timeout=idle_timeout)
        result = f"""✅ Sandbox 创建成功!
📋 Sandbox 信息:
- ID: {info['sandbox_id']}
- CDP URL: {info['cdp_url']}
"""
        vnc_url = info.get('vnc_url')
        if vnc_url:
            result += f"- VNC URL: {vnc_url}\n\n"
            result += "提示: VNC 查看器应该已自动打开,您可以在浏览器中实时查看浏览器操作。"
        else:
            result += "\n警告: 未获取到 VNC URL,可能无法使用可视化功能。"
        return result
    except Exception as e:
        return f" 创建 Sandbox 失败: {str(e)}"
@tool
def get_sandbox_info() -> str:
    """获取当前 sandbox 的详细信息,包括 ID、CDP URL、VNC URL 等。
    当需要查看当前 sandbox 状态或获取 VNC 连接信息时使用此工具。
    Returns:
        Sandbox 信息字符串
    """
    try:
        manager = get_sandbox_manager()
        info = manager.get_info()
        result = f"""📋 当前 Sandbox 信息:
- Sandbox ID: {info['sandbox_id']}
- CDP URL: {info['cdp_url']}
"""
        if info.get('vnc_url'):
            result += f"- VNC URL: {info['vnc_url']}\n\n"
            result += "您可以使用 VNC URL 在浏览器中实时查看操作过程。\n"
            result += "   推荐使用 vnc.html 文件或 noVNC 客户端。"
        return result
    except RuntimeError as e:
        return f" {str(e)}"
    except Exception as e:
        return f" 获取 Sandbox 信息失败: {str(e)}"
class NavigateInput(BaseModel):
    """浏览器导航输入参数"""
    url: str = Field(description="要访问的网页 URL,必须以 http:// 或 https:// 开头")
    wait_until: str = Field(
        default="load",
        description="等待页面加载的状态: load, domcontentloaded, networkidle"
    )
    timeout: int = Field(
        default=30000,
        description="超时时间(毫秒),默认 30000"
    )
@tool(args_schema=NavigateInput)
def navigate_to_url(url: str, wait_until: str = "load", timeout: int = 30000) -> str:
    """使用 sandbox 中的浏览器导航到指定 URL。
    当用户需要访问网页时使用此工具。导航后可以在 VNC 中实时查看页面。
    Args:
        url: 要访问的网页 URL
        wait_until: 等待页面加载的状态(load/domcontentloaded/networkidle)
        timeout: 超时时间(毫秒)
    Returns:
        导航结果描述
    """
    try:
        manager = get_sandbox_manager()
        if not manager.is_active():
            return " 错误: 请先创建 sandbox"
        # 验证 URL
        if not url.startswith(("http://", "https://")):
            return f" 错误: 无效的 URL 格式: {url}"
        cdp_url = manager.get_cdp_url()
        if not cdp_url:
            return " 错误: 无法获取 CDP URL"
        # 使用 Playwright 连接浏览器并导航
        try:
            from playwright.sync_api import sync_playwright
            with sync_playwright() as p:
                browser = p.chromium.connect_over_cdp(cdp_url)
                pages = browser.contexts[0].pages if browser.contexts else []
                if pages:
                    page = pages[0]
                else:
                    page = browser.new_page()
                page.goto(url, wait_until=wait_until, timeout=timeout)
                title = page.title()
                return f"已成功导航到: {url}\n📄 页面标题: {title}\n💡 您可以在 VNC 中查看页面内容。"
        except ImportError:
            return f"导航指令已发送: {url}\n💡 提示: 安装 playwright 以启用实际导航功能 (pip install playwright)"
        except Exception as e:
            return f" 导航失败: {str(e)}"
    except Exception as e:
        return f" 操作失败: {str(e)}"
@tool("browser_screenshot", description="在浏览器 sandbox 中截取当前页面截图")
def take_screenshot(filename: str = "screenshot.png") -> str:
    """截取浏览器当前页面的截图。
    Args:
        filename: 截图文件名,默认 "screenshot.png"
    Returns:
        操作结果
    """
    try:
        manager = get_sandbox_manager()
        if not manager.is_active():
            return " 错误: 请先创建 sandbox"
        cdp_url = manager.get_cdp_url()
        if not cdp_url:
            return " 错误: 无法获取 CDP URL"
        try:
            from playwright.sync_api import sync_playwright
            with sync_playwright() as p:
                browser = p.chromium.connect_over_cdp(cdp_url)
                pages = browser.contexts[0].pages if browser.contexts else []
                if pages:
                    page = pages[0]
                else:
                    return " 错误: 没有打开的页面"
                page.screenshot(path=filename)
                return f"截图已保存: {filename}"
        except ImportError:
            return " 错误: 需要安装 playwright (pip install playwright)"
        except Exception as e:
            return f" 截图失败: {str(e)}"
    except Exception as e:
        return f" 操作失败: {str(e)}"
@tool("destroy_sandbox", description="销毁当前的 sandbox 实例,释放资源。注意:仅在程序退出或明确需要释放资源时使用,不要在一轮对话后销毁。")
def destroy_sandbox() -> str:
    """销毁当前的 sandbox 实例。
    重要提示:此工具应该仅在以下情况使用:
    - 程序即将退出
    - 明确需要释放资源
    - 用户明确要求销毁
    不要在一轮对话完成后就销毁 sandbox,因为 sandbox 可以在多轮对话中复用。
    Returns:
        操作结果
    """
    try:
        manager = get_sandbox_manager()
        result = manager.destroy()
        return result
    except Exception as e:
        return f" 销毁失败: {str(e)}"
# ============ Agent 创建 ============
def create_browser_agent(system_prompt: str = None):
    """
    创建带有 sandbox 工具的 LangChain Agent
    Args:
        system_prompt: 自定义系统提示词,如果为 None 则使用默认提示词
    Returns:
        LangChain Agent 实例
    """
    # 配置 DashScope API
    api_key = os.getenv("DASHSCOPE_API_KEY")
    if not api_key:
        raise ValueError("请设置环境变量 DASHSCOPE_API_KEY")
    base_url = "https://dashscope.aliyuncs.com/compatible-mode/v1"
    model_name = os.getenv("QWEN_MODEL", "qwen-plus")
    # 创建 LLM
    model = ChatOpenAI(
        model=model_name,
        api_key=api_key,
        base_url=base_url,
        temperature=0.7,
    )
    # 创建工具列表
    tools = [
        create_browser_sandbox,
        get_sandbox_info,
        navigate_to_url,
        take_screenshot,
        destroy_sandbox,
    ]
    # 默认系统提示词
    if system_prompt is None:
        system_prompt = """你是一个浏览器自动化助手,可以使用 sandbox 来访问和操作网页。
当用户需要访问网页时,请按以下步骤操作:
1. 首先创建或获取 sandbox(如果还没有)
2. 使用 navigate_to_url 导航到目标网页
3. 执行用户请求的操作
4. 如果需要,可以截取截图
重要提示:
- 创建 sandbox 后,会返回 VNC URL,用户可以使用它实时查看浏览器操作
- 所有操作都会在 VNC 中实时显示,方便调试和监控
- sandbox 可以在多轮对话中复用,不要在一轮对话完成后就销毁
- 只有在用户明确要求销毁时才使用 destroy_sandbox 工具
- 不要主动建议用户销毁 sandbox,除非用户明确要求
- 请始终用中文回复,确保操作准确、高效。"""
    # 创建 Agent
    agent = create_agent(
        model=model,
        tools=tools,
        system_prompt=system_prompt,
    )
    return agent
def get_available_tools():
    """获取所有可用的工具列表"""
    return [
        create_browser_sandbox,
        get_sandbox_info,
        navigate_to_url,
        take_screenshot,
        destroy_sandbox,
    ]

关键要点:

  1. Tool 定义: 使用 @tool 装饰器定义 LangChain Tools
  2. 类型提示: 所有参数必须有类型提示,用于生成工具 schema
  3. 文档字符串: 详细的文档字符串帮助 LLM 理解何时使用工具**
  4. 单例模式: 使用全局管理器实例确保 Sandbox 在会话中复用**

步骤 5:创建主入口文件

创建 main.py 文件,作为程序入口。核心代码如下:

"""
LangChain + AgentRun Browser Sandbox 集成示例
主入口文件,演示如何使用 LangChain Agent 与 AgentRun Browser Sandbox 集成。
"""
import os
import sys
import signal
import webbrowser
import urllib.parse
import threading
import http.server
import socketserver
from pathlib import Path
from dotenv import load_dotenv
from langchain_agent import create_browser_agent, get_sandbox_manager
# 加载环境变量
load_dotenv()
# 全局 HTTP 服务器实例
_http_server = None
_http_port = 8080
# 全局清理标志,用于防止重复清理
_cleanup_done = False
def start_http_server():
    """启动一个简单的 HTTP 服务器来提供 vnc.html"""
    global _http_server
    if _http_server is not None:
        return _http_port
    try:
        current_dir = Path(__file__).parent.absolute()
        class VNCRequestHandler(http.server.SimpleHTTPRequestHandler):
            def __init__(self, *args, **kwargs):
                super().__init__(*args, directory=str(current_dir), **kwargs)
            def log_message(self, format, *args):
                # 静默日志,避免输出过多信息
                pass
        # 尝试启动服务器
        for port in range(_http_port, _http_port + 10):
            try:
                server = socketserver.TCPServer(("", port), VNCRequestHandler)
                server.allow_reuse_address = True
                # 在后台线程中运行服务器
                def run_server():
                    server.serve_forever()
                thread = threading.Thread(target=run_server, daemon=True)
                thread.start()
                _http_server = server
                return port
            except OSError:
                continue
        return None
    except Exception as e:
        print(f"启动 HTTP 服务器失败: {str(e)}")
        return None
def open_vnc_viewer(vnc_url: str):
    """
    自动打开 VNC 查看器并设置 VNC URL
    Args:
        vnc_url: VNC WebSocket URL
    """
    if not vnc_url:
        return
    try:
        # 获取当前文件所在目录
        current_dir = Path(__file__).parent.absolute()
        vnc_html_path = current_dir / "vnc.html"
        # 检查文件是否存在
        if not vnc_html_path.exists():
            print(f"警告: vnc.html 文件不存在: {vnc_html_path}")
            print_vnc_info(vnc_url)
            return
        # 启动 HTTP 服务器
        port = start_http_server()
        if port:
            # 编码 VNC URL 作为 URL 参数
            encoded_url = urllib.parse.quote(vnc_url, safe='')
            # 构建 HTTP URL
            http_url = f"http://localhost:{port}/vnc.html?url={encoded_url}"
            # 打开浏览器
            print(f"\n正在打开 VNC 查看器...")
            print(f"HTTP 服务器运行在: http://localhost:{port}")
            print(f"VNC URL: {vnc_url[:80]}...")
            print(f"完整 URL: {http_url[:100]}...")
            webbrowser.open(http_url)
            print(f"VNC 查看器已打开")
            print(f"VNC URL 已通过 URL 参数自动设置,页面加载后会自动连接")
        else:
            # 如果 HTTP 服务器启动失败,尝试使用 file:// 协议
            print(f"HTTP 服务器启动失败,尝试使用文件协议...")
            encoded_url = urllib.parse.quote(vnc_url, safe='')
            file_url = f"file://{vnc_html_path}?url={encoded_url}"
            webbrowser.open(file_url)
            print(f"VNC 查看器已打开(使用文件协议)")
            print(f"提示: 如果无法自动连接,请手动复制 VNC URL 到输入框")
    except Exception as e:
        print(f"自动打开 VNC 查看器失败: {str(e)}")
        print_vnc_info(vnc_url)
def print_vnc_info(vnc_url: str):
    """打印 VNC 连接信息"""
    if not vnc_url:
        return
    print("\n" + "=" * 60)
    print("VNC 可视化连接信息")
    print("=" * 60)
    print(f"\nVNC URL: {vnc_url}")
    print("\n使用方式:")
    print("   1. 使用 noVNC 客户端连接")
    print("   2. 或在浏览器中访问 VNC 查看器页面")
    print("   3. 实时查看浏览器操作过程")
    print("\n" + "=" * 60 + "\n")
def cleanup_sandbox():
    """
    清理 sandbox 资源
    这个函数可以被信号处理器、异常处理器和正常退出流程调用
    """
    global _cleanup_done
    # 防止重复清理
    if _cleanup_done:
        return
    _cleanup_done = True
    try:
        manager = get_sandbox_manager()
        if manager.is_active():
            print("\n" + "=" * 60)
            print("正在清理 sandbox...")
            print("=" * 60)
            result = manager.destroy()
            print(f"清理结果: {result}\n")
        else:
            print("\n没有活动的 sandbox 需要清理\n")
    except Exception as e:
        print(f"\n清理 sandbox 时出错: {str(e)}\n")
def signal_handler(signum, frame):
    """
    信号处理器,处理 Ctrl+C (SIGINT) 和其他信号
    Args:
        signum: 信号编号
        frame: 当前堆栈帧
    """
    print("\n\n收到中断信号,正在清理资源...")
    cleanup_sandbox()
    print("清理完成")
    sys.exit(0)
def main():
    """主函数"""
    global _cleanup_done
    # 重置清理标志
    _cleanup_done = False
    # 注册信号处理器,处理 Ctrl+C (SIGINT)
    signal.signal(signal.SIGINT, signal_handler)
    # 在 Windows 上,SIGBREAK 也可以处理
    if hasattr(signal, 'SIGBREAK'):
        signal.signal(signal.SIGBREAK, signal_handler)
    print("=" * 60)
    print("LangChain + AgentRun Browser Sandbox 集成示例")
    print("=" * 60)
    print()
    try:
        # 创建 Agent
        print("正在初始化 LangChain Agent...")
        agent = create_browser_agent()
        print("Agent 初始化完成\n")
        # 示例查询
        queries = [
            "创建一个浏览器 sandbox",
            "获取当前 sandbox 的信息,包括 VNC URL",
            "导航到 https://www.aliyun.com",
            "截取当前页面截图",
        ]
        # 执行查询
        for i, query in enumerate(queries, 1):
            print(f"\n{'=' * 60}")
            print(f"查询 {i}: {query}")
            print(f"{'=' * 60}\n")
            try:
                result = agent.invoke({
                    "messages": [{"role": "user", "content": query}]
                })
                # 提取最后一条消息的内容
                output = result.get("messages", [])[-1].content if isinstance(result.get("messages"), list) else result.get("output", str(result))
                print(f"\n结果:\n{output}\n")
                # 如果是创建 sandbox,自动打开 VNC 查看器
                if i == 1:
                    try:
                        # 等待一下确保 sandbox 完全创建
                        import time
                        time.sleep(1)
                        manager = get_sandbox_manager()
                        if manager.is_active():
                            info = manager.get_info()
                            vnc_url = info.get('vnc_url')
                            if vnc_url:
                                print(f"\n检测到 VNC URL: {vnc_url[:80]}...")
                                open_vnc_viewer(vnc_url)
                                print_vnc_info(vnc_url)
                            else:
                                print("\n警告: 未获取到 VNC URL,请检查 sandbox 创建是否成功")
                    except Exception as e:
                        print(f"打开 VNC 查看器时出错: {str(e)}")
                        import traceback
                        traceback.print_exc()
                # 如果是获取信息,显示 VNC 信息
                elif i == 2:
                    try:
                        manager = get_sandbox_manager()
                        if manager.is_active():
                            info = manager.get_info()
                            if info.get('vnc_url'):
                                print_vnc_info(info['vnc_url'])
                    except:
                        pass
            except Exception as e:
                print(f"查询失败: {str(e)}\n")
                import traceback
                traceback.print_exc()
        # 交互式查询
        print("\n" + "=" * 60)
        print("进入交互模式(输入 'quit' 或 'exit' 退出,Ctrl+C 或 Ctrl+D 中断)")
        print("=" * 60 + "\n")
        while True:
            try:
                user_input = input("请输入您的查询: ").strip()
            except EOFError:
                # 处理 Ctrl+D (EOF)
                print("\n\n检测到输入结束 (Ctrl+D),正在清理资源...")
                cleanup_sandbox()
                print("清理完成")
                break
            except KeyboardInterrupt:
                # 处理 Ctrl+C (在 input 调用期间)
                print("\n\n检测到中断信号 (Ctrl+C),正在清理资源...")
                cleanup_sandbox()
                print("清理完成")
                break
            if not user_input:
                continue
            if user_input.lower() in ['quit', 'exit', '退出']:
                print("\nBye")
                # 退出前清理 sandbox
                cleanup_sandbox()
                break
            try:
                result = agent.invoke({
                    "messages": [{"role": "user", "content": user_input}]
                })
                output = result.get("messages", [])[-1].content if isinstance(result.get("messages"), list) else result.get("output", str(result))
                print(f"\n结果:\n{output}\n")
                # 检查是否需要打开或显示 VNC 信息
                user_input_lower = user_input.lower()
                if "创建" in user_input_lower and "sandbox" in user_input_lower:
                    # 如果是创建 sandbox,自动打开 VNC 查看器
                    try:
                        # 等待一下确保 sandbox 完全创建
                        import time
                        time.sleep(1)
                        manager = get_sandbox_manager()
                        if manager.is_active():
                            info = manager.get_info()
                            vnc_url = info.get('vnc_url')
                            if vnc_url:
                                print(f"\n检测到 VNC URL: {vnc_url[:80]}...")
                                open_vnc_viewer(vnc_url)
                                print_vnc_info(vnc_url)
                            else:
                                print("\n警告: 未获取到 VNC URL,请检查 sandbox 创建是否成功")
                    except Exception as e:
                        print(f"打开 VNC 查看器时出错: {str(e)}")
                        import traceback
                        traceback.print_exc()
                elif "sandbox" in user_input_lower or "vnc" in user_input_lower:
                    # 其他情况只显示信息
                    try:
                        manager = get_sandbox_manager()
                        if manager.is_active():
                            info = manager.get_info()
                            if info.get('vnc_url'):
                                print_vnc_info(info['vnc_url'])
                    except:
                        pass
            except Exception as e:
                print(f"查询失败: {str(e)}\n")
                import traceback
                traceback.print_exc()
        # 清理资源(仅在程序正常退出时)
        cleanup_sandbox()
    except KeyboardInterrupt:
        # 处理顶层 KeyboardInterrupt (Ctrl+C)
        print("\n\n检测到中断信号 (Ctrl+C),正在清理资源...")
        cleanup_sandbox()
        print("清理完成")
        sys.exit(0)
    except EOFError:
        # 处理顶层 EOFError (Ctrl+D)
        print("\n\n检测到输入结束 (Ctrl+D),正在清理资源...")
        cleanup_sandbox()
        print("清理完成")
        sys.exit(0)
    except ValueError as e:
        print(f"配置错误: {str(e)}")
        print("\n提示: 请确保已设置以下环境变量:")
        print("   - DASHSCOPE_API_KEY: DashScope API Key")
        print("   - ALIBABA_CLOUD_ACCOUNT_ID: 阿里云账号 ID")
        print("   - ALIBABA_CLOUD_ACCESS_KEY_ID: 访问密钥 ID")
        print("   - ALIBABA_CLOUD_ACCESS_KEY_SECRET: 访问密钥 Secret")
        print("   - ALIBABA_CLOUD_REGION: 区域(默认: cn-hangzhou)")
    except Exception as e:
        print(f"发生错误: {str(e)}")
        import traceback
        traceback.print_exc()
        # 发生错误时也尝试清理
        cleanup_sandbox()
if __name__ == "__main__":
    main()

关键功能:

  1. VNC 自动打开: 创建 Sandbox 后自动打开 VNC 查看器
  2. 信号处理: 捕获 Ctrl+C,确保资源正确清理
  3. 交互模式: 支持持续对话,复用 Sandbox 实例

VNC 可视化集成

VNC(Virtual Network Computing)功能允许您实时查看和监控浏览器在 Sandbox 中的操作过程,这对于调试和监控 Agent 行为非常有用。

获取 VNC URL:

创建 Sandbox 后,可以通过 get_sandbox_info tool 获取 VNC URL:

# 通过 Agent 调用
result = agent.invoke({
    "messages": [{"role": "user", "content": "获取 sandbox 信息"}]
})
# 或直接通过管理器获取
manager = get_sandbox_manager()
info = manager.get_info()
vnc_url = info['vnc_url']

自动打开 VNC 查看器:

在 main.py 中,我们实现了自动打开 VNC 查看器的功能:

import webbrowser
import urllib.parse
from pathlib import Path
def open_vnc_viewer(vnc_url: str):
    """自动打开 VNC 查看器"""
    current_dir = Path(__file__).parent.absolute()
    vnc_html_path = current_dir / "vnc.html"
    if vnc_html_path.exists():
        # 通过 URL 参数传递 VNC URL
        encoded_url = urllib.parse.quote(vnc_url, safe='')
        file_url = f"file://{vnc_html_path}?url={encoded_url}"
        webbrowser.open(file_url)

VNC HTML 页面:

vnc.html 页面会从 URL 参数中读取 VNC URL,并自动连接到 VNC 服务器。页面包含以下核心功能:

  1. noVNC 库加载: 从 CDN 动态加载 noVNC 客户端库
  2. 自动连接: 读取 URL 参数中的 VNC URL 并自动连接
  3. 状态显示: 显示连接状态(连接中、已连接、已断开)
  4. 手动控制: 支持手动输入 VNC URL、断开重连等操作

核心 JavaScript 代码片段:

// 从 URL 参数获取 VNC URL
const urlParams = new URLSearchParams(window.location.search);
const vncUrl = urlParams.get('url');
// 加载 noVNC 库
async function loadNoVNC() {
    const module = await import('https://cdn.jsdelivr.net/gh/novnc/noVNC@v1.4.0/core/rfb.js');
    return module.default;
}
// 连接 VNC
async function connectVNC(url) {
    const RFB = await loadNoVNC();
    rfb = new RFB(vncScreen, url, {
        shared: true,
        credentials: { password: '' }
    });
    rfb.addEventListener('connect', () => {
        console.log('VNC 连接成功');
    });
}

完整的 vnc.html 文件可以在示例代码仓库中获取。

手动使用 VNC 查看器:

如果自动打开失败,您也可以手动使用 VNC 查看器:

1. 使用 noVNC 在线客户端:

  • 访问 noVNC 在线客户端 [ 2]
  • 在连接设置中填入 VNC URL
  • 点击连接

2. 使用本地 VNC HTML 页面:

  • 打开 vnc.html
  • 输入 VNC URL
  • 点击连接按钮

实时监控功能:

  • 所有浏览器操作都会在 VNC 中实时显示
  • 可以看到 Agent 的每一步操作(导航、点击、输入等)
  • 方便调试和监控 Agent 行为
  • 支持交互式操作(在 VNC 中直接操作浏览器)

运行和测试

python main.py

程序会自动:

  1. 创建 Browser Sandbox
  2. 打开 VNC 查看器(实时查看浏览器操作)
  3. 执行预设查询
  4. 进入交互模式

工作原理

为了更好地理解系统架构,我们将工作流程拆分为两个部分:LangChain Agent 工作流程和 SandboxManager 生命周期管理

1. LangChain Agent 工作流程

下图展示了 LangChain Agent 如何处理用户请求并调用相应的 Tools:

image

Agent 工作流程说明:

  1. 请求接收: 用户发起自然语言请求(如“访问淘宝首页并截图”)
  2. 意图分析: Agent 分析用户意图,决定需要调用哪些 Tools
  3. Tool 调用: 根据任务需求,顺序或组合调用多个 Tools
  4. Manager 交互: 所有 Tools 都通过 SandboxManager 单例实例操作 Sandbox
  5. 结果处理: Agent 将 Tool 返回的结果整合成用户友好的响应
  6. 多轮对话: Sandbox 在整个会话中保持活跃,支持多轮对话

5 个核心 Tools 的职责:

image

2. SandboxManager 生命周期管理

下图展示了 SandboxManager 如何管理 Sandbox 的完整生命周期:

image

SandboxManager 工作流程说明:

1. 单例管理:

  • 首次调用时创建 Manager 实例
  • 后续调用复用同一个实例
  • 确保整个会话只有一个 Sandbox

2. Sandbox 创建:

  • 调用 AgentRun SDK 的 Sandbox.create()
  • SDK 通过阿里云 API 与函数计算 FC 通信
  • FC 服务创建独立的容器实例,包含:
  • Chromium 浏览器 VNC 服务必要的运行环境

3. 连接信息获取:

  • CDP URL: WebSocket 地址,用于 Playwright/Puppeteer 远程控制浏览器
  • VNC URL: WebSocket 地址,用于实时查看浏览器画面**

4. 浏览器操作:

  • Playwright 通过 CDP URL 连接到远程浏览器
  • 执行各种浏览器操作(导航、点击、截图等)
  • VNC 同步显示操作过程,用户可实时监控

5. 资源清理:

  • 调用 destroy() 方法销毁 Sandbox
  • 清理 Manager 内部状态
  • 通过 SDK 释放云端资源

3. Agent 与 Manager 的协作关系

交互模式:

用户请求 → Agent → Tool → SandboxManager → AgentRun SDK → 云端 Sandbox
                                    ↓
用户响应 ← Agent ← Tool ← SandboxManager ← 操作结果

关键设计理念:

  1. 分层架构:
  • 用户层:自然语言交互
  • Agent 层:意图理解和任务分解
  • Tool 层:功能封装和参数验证
  • Manager 层:资源管理和状态维护
  • SDK 层:云服务通信
  • 云端层:实际的 Sandbox 环境
  1. 单例模式:
  • SandboxManager 使用单例模式
  • 保证整个会话中只有一个 Sandbox 实例
  • 避免资源浪费和状态冲突
  1. 状态复用:
  • Sandbox 在多轮对话中保持活跃
  • 减少创建和销毁的开销
  • 提供更流畅的用户体验
  1. 双通道设计:
  • CDP 通道:Agent 通过 Playwright 控制浏览器
  • VNC 通道:用户通过 VNC 查看器实时监控
  1. 解耦设计:
  • Tools 不直接操作 SDK,通过 Manager 统一管理
  • 便于扩展和维护
  • 统一的错误处理和资源管理

典型使用场景示例:

# 第 1 轮对话
用户: "创建一个 sandbox 并访问淘宝首页"
→ Agent 调用: create_browser_sandbox → navigate_to_url
→ Manager: 创建 Sandbox → Playwright 导航
→ 结果: "Sandbox 已创建,已访问淘宝首页"
# 第 2 轮对话(复用 Sandbox)
用户: "截取当前页面"
→ Agent 调用: take_screenshot
→ Manager: 使用现有 Sandbox → Playwright 截图
→ 结果: "截图已保存"
# 第 3 轮对话(复用 Sandbox)
用户: "访问京东首页"
→ Agent 调用: navigate_to_url
→ Manager: 使用现有 Sandbox → Playwright 导航
→ 结果: "已访问京东首页"

通过这种设计,Agent 专注于理解用户意图和任务编排,而 Manager 专注于 Sandbox 的生命周期管理,实现了清晰的职责分离。

工作原理总结:

  1. 工具注册:使用 @tool 装饰器将 Sandbox 功能封装为 LangChain Tools
  2. 生命周期管理: SandboxManager 负责 Sandbox 的创建、管理和销毁
  3. 状态保持:使用单例模式管理 Sandbox 实例,确保同一会话内复用
  4. VNC 集成:自动获取并返回 VNC URL,方便用户实时查看
  5. 错误处理:所有工具都包含完善的错误处理机制

扩展和定制

添加自定义 Tools:

@tool
def extract_table_data(url: str) -> str:
    """从网页中提取表格数据"""
    from playwright.sync_api import sync_playwright
    manager = get_sandbox_manager()
    cdp_url = manager.get_info()['cdp_url']
    with sync_playwright() as p:
        browser = p.chromium.connect_over_cdp(cdp_url)
        page = browser.contexts[0].pages[0]
        page.goto(url)
        tables = page.query_selector_all("table")
        return f"找到 {len(tables)} 个表格"

自定义提示词:

custom_prompt = """你是一个专业的网页数据提取助手。
在执行任务前,请先创建 sandbox,然后使用浏览器工具完成任务。"""
agent = create_browser_agent(system_prompt=custom_prompt)

最佳实践

  1. 模块化设计:将 Sandbox 管理和 Agent 创建分离,提高代码可维护性
  2. 错误处理:所有工具都应包含完善的错误处理
  3. 资源清理:使用信号处理器确保资源正确清理
  4. VNC 提示:在工具返回中包含 VNC URL,方便用户使用
  5. 单例模式:确保 Sandbox 实例在会话中复用,避免重复创建

前端集成可视化监控(VNC)

VNC 集成架构

下图展示了前端如何集成 VNC 实现实时监控:

image

轻量级 HTML 页面集成

创建一个简单的 vnc-viewer.html 文件:

<!DOCTYPE html>
<html>
<head>
    <title>Browser Sandbox VNC 查看器</title>
    <style>
        body { margin: 0; padding: 0; background: 
#000
; }
        
#vnc
-container { width: 100vw; height: 100vh; }
    </style>
</head>
<body>
    <div id="vnc-container"></div>
    <script type="module">
        const params = new URLSearchParams(window.location.search);
        const vncUrl = params.get('url');
        if (!vncUrl) {
            alert('请提供 VNC URL 参数');
        } else {
            const module = await import('https://cdn.jsdelivr.net/gh/novnc/noVNC@v1.4.0/core/rfb.js');
            const RFB = module.default;
            const rfb = new RFB(
                document.getElementById('vnc-container'),
                vncUrl,
                { shared: true, credentials: { password: '' } }
            );
            rfb.scaleViewport = true;
        }
    </script>
</body>
</html>

使用方式:

import webbrowser
import urllib.parse
vnc_url = sandbox.vnc_url
encoded_url = urllib.parse.quote(vnc_url, safe='')
viewer_url = f"file:///path/to/vnc-viewer.html?url={encoded_url}"
webbrowser.open(viewer_url)

React 应用集成

核心组件代码:

import React, { useEffect, useRef } from 'react';
interface VNCViewerProps {
  vncUrl: string;
  onConnect?: () => void;
  onDisconnect?: () => void;
}
export const VNCViewer: React.FC<VNCViewerProps> = ({ 
  vncUrl, 
  onConnect, 
  onDisconnect 
}) => {
  const containerRef = useRef<HTMLDivElement>(null);
  useEffect(() => {
    let rfb: any;
    const initVNC = async () => {
      if (!containerRef.current || !vncUrl) return;
      const { default: RFB } = await import('@novnc/novnc/core/rfb');
      rfb = new RFB(containerRef.current, vncUrl, {
        shared: true,
        credentials: { password: '' }
      });
      rfb.scaleViewport = true;
      rfb.addEventListener('connect', () => onConnect?.());
      rfb.addEventListener('disconnect', () => onDisconnect?.());
    };
    initVNC();
    return () => {
      if (rfb) rfb.disconnect();
    };
  }, [vncUrl, onConnect, onDisconnect]);
  return (
    <div 
      ref={containerRef} 
      style={{ width: '100%', height: '600px', background: '
#000
' }} 
    />
  );
};

使用示例:

import React, { useState, useEffect } from 'react';
import { VNCViewer } from './VNCViewer';
function App() {
  const [vncUrl, setVncUrl] = useState<string>('');
  useEffect(() => {
    fetch('/api/sandbox/create', { method: 'POST' })
      .then(res => res.json())
      .then(data => setVncUrl(data.vnc_url));
  }, []);
  return (
    <div>
      <h1>Browser Sandbox 实时监控</h1>
      {vncUrl ? (
        <VNCViewer 
          vncUrl={vncUrl}
          onConnect={() => console.log('已连接')}
          onDisconnect={() => console.log('已断开')}
        />
      ) : (
        <p>正在初始化...</p>
      )}
    </div>
  );
}

Puppeteer 和 Playwright 直接集成

如果您更熟悉传统的浏览器自动化库,也可以直接使用 Puppeteer 或 Playwright 连接到 Browser Sandbox。

使用 Playwright

from playwright.sync_api import sync_playwright
from agentrun.sandbox import Sandbox, TemplateType
# 创建 Sandbox
sandbox = Sandbox.create(
    template_type=TemplateType.BROWSER,
    template_name="your-template-name",
    sandbox_idle_timeout_seconds=3000
)
# 使用 Playwright 连接
with sync_playwright() as p:
    browser = p.chromium.connect_over_cdp(sandbox.cdp_url)
    page = browser.contexts[0].pages[0]
    # 执行操作
    page.goto("https://www.example.com")
    page.screenshot(path="screenshot.png")
    content = page.content()
    browser.close()
# 清理
sandbox.delete()

使用 Puppeteer(Node.js)

const puppeteer = require('puppeteer-core');
// CDP URL 从 Sandbox 获取
const cdpUrl = 'wss://your-account.funagent-data-pre.cn-hangzhou.aliyuncs.com/sandboxes/xxx/ws/automation';
(async () => {
  const browser = await puppeteer.connect({
    browserWSEndpoint: cdpUrl,
    defaultViewport: null
  });
  const page = (await browser.pages())[0];
  await page.goto('https://www.example.com');
  await page.screenshot({ path: 'screenshot.png' });
  await browser.close();
})();

总结

通过本教程,您已经学会了:

  1. AgentRun SDK 基础: 如何使用 SDK 创建和管理 Browser Sandbox
  2. LangChain 集成: 如何将 Sandbox 封装为 LangChain Tools
  3. VNC 可视化: 如何在前端集成 VNC 实现实时监控
  4. 直接集成: 如何使用 Puppeteer/Playwright 直接连接 Sandbox

相关链接:

[1] Agentrun 控制台网站

https://functionai.console.aliyun.com/cn-hangzhou/agent/runti...

[2] noVNC 在线客户端

https://novnc.com/noVNC/vnc.html

一、IP地址查询工具:安全隐患与隐私问题

IP地址查询工具广泛应用于各类行业,从网络安全到广告投放,它们都能提供精准的定位和风险识别。然而,使用这些工具时,很多人对隐私泄露存在担忧。实际上,IP查询过程中可能会涉及以下个人信息:

  • IP地址本身:作为查询的基础,IP地址是用户网络连接的唯一标识。通过IP查询工具,可能泄露用户的上网历史和地理位置。
  • 位置信息:根据IP地址查询,工具能够获取精确的地理位置,包括城市、国家、甚至街道位置,这些信息若被滥用,可能影响个人隐私。
  • 运营商信息:IP地址的查询还会揭示用户所在的网络运营商,尤其在某些情况下,能揭示用户所属的网络提供商与服务类型,进一步暴露用户的网络环境。
  • 潜在的恶意软件或钓鱼攻击:某些不可靠的查询工具可能隐藏恶意程序,盗取用户的设备信息或利用查询工具作为钓鱼攻击的媒介。

因此,在选择IP地址查询工具时,保护个人信息的安全是非常重要的。

二、如何选择安全可靠的IP查询工具

选择一个安全可靠的IP查询工具不仅要考虑其准确性,还要确保其保护用户隐私的能力。以下是一些选择标准:

  • 数据加密和隐私政策:优质的IP查询工具应提供数据加密,防止用户的IP查询记录被第三方截取或滥用。同时,工具需要有清晰且严格的隐私保护政策,承诺不会泄露用户数据。
  • 工具的声誉与市场评价:选择那些有良好市场口碑和用户评价的工具,尤其是业内推荐的服务商。
  • 查询结果的精确度:工具应能提供高精度的定位和数据,避免因错误的IP识别而引起不必要的风险。
  • 支持的功能与服务:除了基本的IP查询功能,安全的IP查询工具应提供更多增值服务,如风险评分、代理检测等,帮助用户更全面地分析数据。

接下来,我们将介绍几款常见的、安全可靠的IP地址查询工具。

三、安全可靠的IP查询工具推荐

1.IP数据云

简介:IP数据云是国内领先的高精度IP地理定位与风险识别服务商,支持全球范围内的IP查询。它拥有毫秒级响应速度,支持IPv4/IPv6信息查询,并提供20多维度的数据字段。特别适合金融反欺诈、政企安全审计、精准广告投放等对精度和安全性要求高的场景。

安全性:IP数据云严格遵守隐私保护政策,确保用户数据不会被滥用,同时为用户提供加密的查询服务,避免信息泄露。
image.png
 

2.IPnews

简介:IPnews是专注于IP地址深度分析的全球工具,支持精准定位和风险监控,广泛应用于网络安全和广告投放领域。它能提供多维度的威胁监控,识别代理、IP相关域名等信息,为用户提供安全且精确的查询结果。

安全性:IPnews注重数据保护与隐私安全,所有查询操作都通过加密处理,确保用户信息不被外泄。
image.png
 

3.IPinfo

简介:IPinfo是一个知名的IP查询工具,支持全球IP地址定位。它可以提供IP归属地、ISP(互联网服务提供商)、ASN等多维度数据,广泛应用于企业的安全审计与广告投放。

安全性:IPinfo提供良好的隐私保护措施,并严格遵守GDPR等数据保护法规,确保用户数据的安全性。
image.png
 

4.IPstack

简介:IPstack是另一款高精度IP定位工具,支持实时IP地址查询,提供详细的IP信息和精确的地理位置。它被广泛用于广告定向投放、跨国企业的IP监控等应用场景。

安全性:IPstack提供HTTPS加密服务,并承诺不会出售用户查询数据,是一款值得信赖的安全工具。
image.png
 

5.geoPlugin

简介:geoPlugin是一款轻量级IP查询工具,能够提供精确的地理位置、IP类型、时区信息等。它支持免费查询,并且API接口灵活,适用于各种开发者和小型企业。

安全性:geoPlugin采用标准的数据加密方式,确保查询数据的安全。
image.png
 

四、如何使用IP查询工具保护个人信息

在使用IP查询工具时,除了选择安全可靠的工具外,用户还可以采取一些额外的措施来保护自己的隐私:

  • 避免查询个人敏感信息:不要在查询过程中输入与自己相关的敏感信息,尽量避免输入与个人身份紧密相关的内容。
  • 定期清理查询记录:定期清理浏览器的查询历史记录,避免被不法分子利用。
  • 使用代理:通过代理隐藏真实IP地址,可以在查询时保护用户的真实身份。
     

    五、部署示例

{
  "code": 200,
  "data": {
    "location": {
      "area_code": "320311",
      "city": "徐州",
      "city_code": "0516",
      "continent": "亚洲",
      "country": "中国",
      "country_code": "CN",
      "district": "泉山",
      "elevation": "40",
      "ip": "180.124.68.28",
      "isp": "电信",
      "latitude": "34.214855",
      "longitude": "117.169163",
      "multi_street": [
        {
          "lng": "117.169163",
          "lat": "34.214855",
          "province": "江苏",
          "city": "徐州",
          "district": "泉山",
          "street": "双山路",
          "radius": "2.27",
          "zip_code": "221000"
        },
        {
          "lng": "117.191078",
          "lat": "34.224231",
          "province": "江苏",
          "city": "徐州",
          "district": "泉山",
          "street": "解放南路387号",
          "radius": "1.15",
          "zip_code": "221000"
        },
        {
          "lng": "117.180535",
          "lat": "34.218589",
          "province": "江苏",
          "city": "徐州",
          "district": "泉山",
          "street": "文华路",
          "radius": "2.73",
          "zip_code": "221000"
        }
      ],
      "province": "江苏",
      "street": "双山路",
      "time_zone": "Asia/Shanghai",
      "weather_station": "CHXX0437",
      "zip_code": "221000"
    }
  },
  "msg": "success"
}

六、总结

选择安全的IP查询工具不仅仅是为了获取准确的数据,更是为了保护个人信息的安全。通过选择可靠的工具如IP数据云、IPnews、IPinfo等,用户可以在享受高精度查询服务的同时,避免个人信息泄露的风险。

微软:2026 年 AI 发展的 7 个趋势

说实话,每次看到“AI 趋势预测”这类标题,我都会先深吸一口气。

不是因为害怕,而是因为这类文章太容易写成两种极端:

要么是“AI 要统治世界了快跑”的恐慌文,要么是“拥抱 AI 否则被淘汰”的焦虑营销。

最近读了微软发布的 2026 年 AI 趋势文章,里面有 7 个预测。

我不打算照搬原文,而是结合我自己的理解,和你讲下这 7 个趋势与我们有什么关系,看你是否能在这 7 个趋势中找到自己的机会。

趋势 1:AI 成为你的数字同事

AI 不是来抢你饭碗的,是来帮你“开挂”的。

想象一下,以前你开发一个页面要 3 天,现在 AI 帮你写代码,你只需要专注在业务需求、用户体验等事情上。

这就像以前洗衣服要手搓,现在有洗衣机了。洗衣机没有让“洗衣服”这件事消失,而是让你有时间去做更重要的事。

所以与其担心被 AI 取代,不如想想“我能用 AI 放大什么?”

趋势 2:AI 代理更安全

现在的 AI 有时候像个热心但冒失的实习生——你让它帮你写邮件,它可能把你的私人信息也一起发出去了……

2026 年的 AI 会更像一个训练有素的助理:知道什么该做,什么不该做,什么信息可以用,什么必须保密。

所以虽然 AI 能帮你处理各项事务,但也要有基本的安全意识,尤其不要让他删库跑路了。

趋势 3:AI 解决全球医疗危机

想象一下,当你走进医院,AI 系统能在几分钟内准确诊断你的病情,准确率高达 85.5%,而传统医生的平均准确率只有 20%。

这听起来像科幻电影,但微软最新的 AI 医疗诊断系统已经达到了这个水平。

这意味着 AI 将成为第一线的健康顾问,当然,这不是说 AI 要取代医生。而是说,AI 可以让医疗资源的分配更均衡一些。

所以新的一年,你可以关注 AI 在健康领域的应用,但看病还是要去正规医院,别指望 AI 给你开药方。

趋势 4:AI 成为科学研究的催化剂

以前做研究,光是文献综述就要花几个月。

现在 AI 可以帮你快速梳理几千篇论文,找出关键信息。

这就像以前考古要一铲子一铲子挖,现在有了探地雷达,能更快定位到有价值的区域。

所以如果你是学生或研究者,学会用 AI 辅助学习和研究,会是一个很大的竞争优势。

趋势 5:AI 基础设施会变得更智能、更高效

支撑 AI 运行的基础设施会持续优化,这意味着 AI 基础设施能够智能调度算力,确保每个任务都能在最佳时间、地点获得最优资源。

以后无论你在哪里,使用什么设备,都将获得一致且高效的 AI 服务。

云计算将变得像自来水一样普及和可靠。

趋势 6:AI 正在学习理解代码背后的“为什么”

AI 不只学习代码语言,还在理解代码背后的上下文。

这意味着以前的 AI 写代码就像个新手程序员——你说什么它写什么,但不理解你到底想解决什么问题。

现在的 AI 开始能理解“你为什么要这么做”,然后给出更合理的方案。

对我们程序员来说,AI 将能更好地协助你维护和改进现有系统。

趋势 7:量子计算的突破比想象中更近

专家预测,量子计算的重大突破将发生在“几年,而不是几十年”的时间框架内。

随着量子计算的出现,密码学、药物发现、气候模拟等领域将迎来革命性突破。

当然对我们来说,这暂时不需要操心,但可以保持关注。因为这是那种“一旦发生就会改变很多事”的技术。

普通人该怎么办?

这些趋势的共同点是:AI 正在从工具变成伙伴,从辅助变成合作伙伴,从后台变成前台

不过看完这 7 个趋势,你可能还是会问:所以我到底该做什么呢?

我的建议很简单,三句话:

第一,别焦虑,但要保持好奇

AI 发展很快,但天不会塌下来。与其焦虑“会不会被取代”,不如花点时间玩玩各种 AI 工具,看看它们能帮你做什么。

第二,找到你的“不可替代性”

AI 擅长的是“标准化”的事情。而你的独特经历、审美、判断力、人际关系——这些是 AI 很难复制的。想想你有什么是 AI 做不到的

第三,学会“和 AI 协作”

未来最吃香的不是“会用 AI 的人”,也不是“完全不用 AI 的人”,而是“知道什么时候用 AI、什么时候用自己”的人。

说到底,AI 是工具,不是对手。

就像汽车发明后,马车夫确实失业了,但司机、修车工、交通规划师这些新职业也出现了。

变化一直在发生,我们要做的,是在变化中找到自己的位置。

PS:岂可修,这让我想到了阿里的文化——拥抱变化

我是冴羽,10 年笔耕不辍,专注前端领域,更新了 10+ 系列、300+ 篇原创技术文章,翻译过 Svelte、Solid.js、TypeScript 文档,著有小册《Next.js 开发指南》、《Svelte 开发指南》、《Astro 实战指南》。

欢迎围观我的“网页版朋友圈”,关注我的公众号:冴羽(或搜索 yayujs),每天分享前端知识、AI 干货。

提示词供应链:从“一键 Reprompt”到“系统提示投毒”

2026 年 LLM 安全的三段式攻防

文章定位:偏工程落地 + 新视角总结
说明:本文只写可用于安全评估与防守的思路,不提供可直接复制用于攻击的载荷、脚本与绕过细节;示例均做“脱敏/占位符化”。

深度技术分析:从攻击面到实现机制

URL参数注入的技术实现链路

Copilot Reprompt 和 ChatGPT 的参数注入本质是前端输入验证缺失导致的上下文污染。这类漏洞的技术关键在于参数直接进入模型推理路径,绕过了常规的输入清洗流程。

前端路由层接收参数后,未进行上下文隔离就直接构造API请求。

这种实现让 URL 参数获得了与直接用户输入相同的上下文权重。攻击者可以通过精心构造的 URL,将恶意指令注入到系统提示之后、用户输入之前的位置,形成上下文劫持。

更危险的是某些实现中的自动提交机制。

这种机制下,用户访问恶意链接后,不需要任何交互就能触发 LLM 工具调用链。

从攻击链路看,URL 参数注入的成功依赖三个条件的叠加。前端未对参数来源进行可信度标记,后端未区分用户主动输入与被动接收的参数,且模型推理过程中将所有上下文视为同等权重。这三个条件构成了完整的攻击路径。

LangChain CVE-2025-68664 的攻击面展开

LangChain 序列化漏洞的核心危险在于将非结构化的 LLM 输出直接用于框架对象重构。其攻击路径通常涉及以下技术环节。

LLM 输出被解析器误认为 LangChain 特殊对象结构。

实际攻击中,这类漏洞利用了 LangChain 在处理历史对话、工具调用结果时的自动序列化机制。当 LLM 输出包含特殊格式的结构化数据时,反序列化器可能将其当作可信对象处理。

另一个关键攻击向量是通过工具返回值注入。

这种模式下,攻击者控制了外部 API 的返回内容,通过 LLM 工具调用链实现间接注入。

LangChain 框架中存在多个此类攻击面。对话历史存储时的序列化、工具调用结果的对象转换、以及 Prompt 模板的动态加载机制,都可能成为注入点。框架设计时假设 LLM 输出是安全的,但实际工程中这个假设经常不成立。

系统提示投毒的供应链特征

系统提示投毒区别于传统提示注入的核心在于其持久性和全局性。从技术实现角度看,这类攻击通常利用以下系统特性。

多租户环境中的提示词模板复用机制。

这种架构下,单一污染点可以影响整个用户群体。更危险的是当系统提示词存储在可被运营配置修改的数据库中时,所有使用该模板的后续对话都会被植入恶意指令。

企业级应用中常见的一种危险模式是通过管理后台动态编辑系统提示词。

当管理后台存在权限越权或会话劫持时,攻击者可以修改系统提示词模板。这种污染的持续性强于单次会话注入,因为所有新会话都会加载被污染的模板。

更隐蔽的投毒方式是通过外部数据源间接影响系统提示词。例如某些系统允许从知识库文档中提取规则动态追加到系统提示。

这种投毒方式难以检测,因为恶意指令被包装在正常文档内容中,且通过自动化规则提取机制进入系统提示。

间接注入在 RAG 系统中的放大效应

RAG 系统是最容易被忽视的间接注入攻击面。其危险在于检索到的文档内容被系统默认为可信上下文。

攻击者可以通过投递恶意文档到知识库,让检索过程返回带有嵌入指令的内容。

当用户的查询与该文档相似度匹配时,嵌入的指令就会被注入到上下文中。这种攻击方式的隐蔽性在于恶意内容被包装在正常文档内部,且通过语义相关性触发。

RAG 系统中存在多种文档投毒向量。用户上传的文件、网络爬虫获取的网页内容、第三方知识库同步的数据,都可能被注入恶意指令。这些内容在检索后直接进入模型上下文,且通常不会经过与用户输入相同的验证流程。

另一种危险的 RAG 注入方式是通过跨模态检索。

当 OCR 提取的图片文本中包含嵌入指令时,这类攻击尤其难以检测,因为图片内容的来源和真实性的验证成本较高。

工具调用链的权限边界消解

现代 Agent 系统中,工具调用是最危险的能力出口。其风险核心在于 LLM 可能被诱导执行超出用户意图的操作。

攻击者可以通过控制 context 中的外部内容,诱导 LLM 选择高风险工具。

这种攻击成功的关键在于系统没有区分工具调用权限的来源。当外部内容被允许影响工具调用决策时,整个权限边界就被消解了。

更复杂的工具链攻击涉及多步骤的权限提升。

当系统未对工具调用的来源进行追踪时,攻击者可以构造看似合理的多步骤任务链,逐步提升权限并最终执行高危操作。

记忆系统的双刃剑效应

记忆功能的开启让单次会话的攻击可以持续影响未来所有会话。从攻击者角度看,这相当于获得了一个持久化的配置修改接口。

一旦恶意内容被写入长期记忆,后续所有会话都会在上下文中包含这些内容。更危险的是,某些实现中记忆内容会被优先级处理,甚至可以覆盖系统提示词的某些部分。

多租户环境中的交叉污染风险

多租户 SaaS 应用中的提示词污染具有特殊的危险性。当多个用户共享同一套系统提示词模板或 RAG 知识库时,一个租户的恶意内容可能影响其他租户。

当系统未正确隔离租户间的模板更新权限时,恶意租户可能修改共享的基础模板,影响所有其他租户。

函数调用劫持的实现机制

函数调用劫持是比直接注入更危险的攻击形式。攻击者只需要在上下文中植入特定的触发模式,当模型遇到匹配的语义场景时会自动调用危险函数。

实际攻击场景中,函数调用劫持通常利用模型对上下文来源的误判。

当系统未实现上下文来源追踪时,攻击者可以通过在 RAG 检索结果中埋入函数调用触发器。

当用户的查询与这份恶意文档语义相近时,模型可能会误认为这是系统标准的应急流程,从而调用危险的函数。

多模态注入向量的隐蔽性

多模态 LLM 系统中的注入攻击具有更高的隐蔽性。攻击者可以将恶意指令编码在图片、音频甚至视频中,通过非文本通道绕过常规的内容过滤。

图片中的隐藏文字是最常见的多模态注入向量。

这种攻击方式之所以危险,是因为大多数系统的 OCR 提取内容不会经过与用户输入同等级别的安全检查。更隐蔽的做法是使用 Steganography 技术,将恶意指令隐藏在图片的像素数据中,只有特定的解码流程才能提取。

上下文污染的级联效应

上下文污染在多轮对话中会产生级联效应。一旦第一轮对话被成功注入,后续所有轮次都会受到污染上下文的影响。

实际系统中,上下文窗口的管理策略往往加剧了这种级联效应。

当 RAG 内容被标记为低优先级时,正常情况下会被优先清除。但攻击者可以通过在污染内容中添加重复性关键词,增加其在语义检索中的相关性得分,从而在多轮对话中反复被检索到。

只要用户的查询涉及这些话题,相关的恶意文档就会被检索出来并注入到上下文中。

模型输出污染的下游影响

模型输出不仅会直接被用户看到,在很多系统中还会被传递给下游服务。当输出被污染时,下游服务可能会执行非预期的操作。

一个典型的危险场景是将 LLM 输出直接用作 SQL 查询构造。

如果攻击者成功在上下文中注入了恶意指令,模型可能会生成包含 UNION SELECT 或其他注入技术的 SQL 语句。

更危险的场景是将 LLM 输出用于配置文件生成或脚本生成。

攻击者可以通过在 RAG 内容中植入恶意配置模板,让模型生成包含后门指令的配置文件。

工作流编排系统的注入风险

现代 LLM 应用通常不是单一的模型调用,而是包含多个步骤的工作流。工作流编排系统中的注入点更加隐蔽,因为恶意指令可以在工作流的任意环节被注入。

典型的工作流系统会包含任务分发、结果聚合、错误重试等环节。

当任务之间的数据传递没有进行来源标记和权限检查时,攻击者可以污染中间结果,影响后续任务的执行。

工作流系统中的另一个危险点是错误处理和重试逻辑。

攻击者可以通过故意触发特定的错误类型,然后在错误上下文中注入恶意指令,让系统在重试时执行攻击者指定的操作。

前言:Prompt Injection 不再是“聊天框里的几句话”

很多人还停留在“让模型忽略上一句指令”的阶段,但 2025 下半年到 2026 年初的几个热点事件,已经把问题推到了另一个层级:
Prompt 变成了一个可被传递、拼接、缓存、持久化、再利用的“供应链”对象。

你以为你在做“检索、总结、问答、自动化”,实际上你在做一件更危险的事:
把不可信数据,混入到一个会影响决策的上下文里;再把决策结果交给工具执行。

这条链路一旦跑通,攻击者不需要“破解模型”,只需要“投喂上下文”。

一、提示词供应链正在成型

1)Copilot 的 “Reprompt”:一次点击,任务自己跑完

2026 年 1 月,Varonis 披露 Microsoft Copilot 的 “Reprompt” 问题:核心是通过链接里的查询参数,把一段 prompt 直接塞进 Copilot 的输入路径,用户只要点一下,后续可能出现静默数据外泄等风险;媒体报道提到微软已在 2026 年 1 月 13 日左右完成修复。

它最值得记的点不是“又一个注入”,而是这种形态:

Prompt-as-URL:提示词从聊天框迁移到了 URL 参数;

低交互:一次点击即可触发;

隐蔽:用户甚至可能感知不到“有一段会话正在发生”。

这不是传统意义的“社会工程 + 账号接管”,更像是:
点击链接 = 触发一个 AI 工作流。

2)ChatGPT 的 ?q=:前端参数也能变成“执行入口”

Tenable 在 2025 年披露过 ChatGPT Web 前端 ?q= 参数可触发自动提示注入的风险:用户打开某个链接时,页面加载就可能把参数内容当成输入执行(文中包含示例)。

换句话说:
入口不只在“你输入了什么”,也在“你打开了什么”。

3)“Command Memories / 记忆注入”:把一次成功变成长期后门

更麻烦的是“持久化”。Tenable 还提出过通过间接注入引入“Command Memories”的思路,用来影响或利用用户记忆相关信息,扩大数据泄露面。

一旦产品开启“记忆/长期偏好”,安全问题会发生质变:

过去:一次会话被带偏

现在:把带偏写进配置,下次还跟着偏

4)LangChain CVE:当 LLM 输出进入序列化/反序列化,安全边界直接断裂

CVE-2025-68664 是一个很典型的“AI 工程踩进经典漏洞坑”的案例:在 LangChain 的序列化/反序列化链路里,用户可控数据可能被误识别为框架对象结构,带来敏感信息泄露等风险;国内多个通告与复现文章也提到了其严重性(CVSS 9.3)以及受影响版本与修复建议。

它提醒我们一件事:
LLM 输出永远是“不可信输入”。
把它直接喂给反序列化、模板渲染、动态加载这类机制,本质上是在给自己找“第二条 RCE 路径”。

5)系统提示投毒(System Prompt Poisoning):供应链的“上游污染”

2025 年的研究提出“系统提示投毒”:攻击者不是注入用户提示,而是让系统提示被污染,从而对后续任务产生持续影响。

这类风险一旦进入现实产品形态(比如系统提示由多个模块拼接、由运营后台配置、由某些外部内容间接影响),它的地位就像“配置中心被投毒”:
不是某次请求出错,而是全体请求慢性中毒。

二、“对抗样本输入”按攻击链拆成为三段:入口、滞留、出站

A. 入口(Ingress)——提示词从哪里进来?

除了聊天框,还有很多“隐形入口”:

1 URL 参数(Copilot Reprompt、ChatGPT ?q= 这类)

2RAG 文档块(用户上传、知识库、网页摘要、邮件内容)

3搜索结果摘要(Search 场景被投喂“带指令的网页内容”)

4工具返回(插件/API 的返回内容被当成“更可信的上下文”)

5运营配置(系统提示词/策略模板/提示词片段库)

入口越多,越像供应链。

B. 滞留(Persistence)——它能不能留下来?

滞留能力决定“事故是一次性的”还是“长期性的”:

写入 memory / 偏好 / 画像(记忆注入)

写入对话摘要(很多产品会把历史压缩成“摘要记忆”)

写入 RAG 缓存(命中缓存后反复触发)

写入系统提示拼接层(最危险)

C. 出站(Egress)——它最终能造成什么影响?

出站不是“模型说了什么”,而是“系统做了什么”:

泄露:把内部信息带到回复里 / 带到工具调用里

越权行动:诱导 Agent 调用工具(发请求、写数据、改配置)

结构化攻击:诱导输出“看似合法的结构”,再被系统解析执行(LangChain CVE 属于这类思路的延伸)

把这三段串起来,你会发现:
Reprompt 之所以吓人,是因为它几乎把“入口→出站”做成了一键工作流。

三、把 Prompt 当“依赖”,把工具当“权限”,才能真正落地

很多团队做防护,第一反应是“加几条拒答规则”“拦截敏感词”。但这条路会越来越痛苦:同义改写、跨语言、格式混淆都能绕,而且事件证明入口不止用户输入。

我更推荐一个能落地的框架:

“上下文溯源 + 权限票据”——用工程手段重建边界

1)上下文溯源:给每一段上下文打标签

不要再把 prompt 当一整段字符串拼来拼去,至少拆成五段:

SYSTEM:系统提示(只读、版本化)

USER:用户输入

EXTERNAL:外部内容(网页/文档/RAG chunk/搜索摘要)

TOOL:工具返回

MEMORY:长期记忆/画像

每段都带上元信息:来源、时间、信任级、是否允许影响工具调用。

这样做的意义是:
让“模型看不见的边界”,在系统层变得可审计、可限制。

2)权限票据:工具调用必须拿到“能力票”

把 Agent 能做的事分级,尤其是“写入型能力”:

L0(低风险):查询公开信息、总结文本

L1(中风险):读取内部知识库、读文件(只读)

L2(高风险):写入 memory、发送外联请求、创建/修改数据

L3(致命):改权限、改配置、执行脚本、触发支付/发信

然后规定:
EXTERNAL 段永远不能直接触发 L2/L3。
哪怕模型说“我需要写入记忆以便更好服务你”,也必须走策略门、走二次确认或人审。

这套思路能直接对齐三个热点:

URL 参数注入:入口更隐蔽 → 必须把它标成 EXTERNAL/UNTRUSTED

记忆注入:滞留能力强 → memory_write 必须是高风险能力

LangChain CVE:结构化输出有“执行风险” → 解析/反序列化必须有 allowlist 与安全默认值

四、对抗样本怎么写才“能用”:

1)一个合格的对抗样本用例 = 目标 + 约束 + 判定器

目标:诱导泄露 / 诱导调用工具 / 诱导写入 memory

约束:输入必须来自 EXTERNAL(模拟间接注入),不能由用户明说

判定器:是否出现 tool_call、是否触发 memory_write、是否输出敏感字段特征

判定器尽量“非 LLM 化”:用正则/结构校验/审计事件,而不是让模型自己说“我很安全”。

2)给你三类“可发布”的对抗样本模板(脱敏占位符版)

下面只给结构,不给可直接复用的攻击载荷:

模板 A:外部数据夹带“伪装指令”

测试点:模型是否把外部段当“指令源”。

模板 B:诱导触发工具调用

测试点:模型是否会把“外部理由”当授权。

模板 C:诱导持久化(记忆/画像)

测试点:是否出现 memory_write 意图或相关事件。

3)变异策略:打的就是“拦关键词”那套

语义变异:委婉说法、分步推理、反问句

结构变异:表格/代码块/引用层级嵌套

语言变异:中英混写、同音替换、符号插入

位置变异:把关键语义放在“你以为不会读”的地方(脚注、引用、括号)

高级攻击场景分析

分布式提示词注入网络

分布式提示词注入是一种新兴的攻击技术,攻击者通过在多个不同的数据源中分散植入恶意指令片段,这些片段单独看起来无害,但被系统组合后就会形成完整的攻击载荷。

这种攻击方式利用了现代 AI 系统中普遍存在的多源数据聚合特性。

每个注入点可能只是一小段看似无关的文本。

当这些片段被检索并在上下文中聚合时,它们就组合成了一个完整的恶意指令集。

对抗性样本的自动生成

攻击者正在开发自动化工具来生成对抗性提示词样本。这些工具利用遗传算法、强化学习等技术,自动寻找能够绕过安全防护的提示词变体。

这种自动化生成系统能够快速发现大量有效的对抗性样本,远远超过手工测试的效率。

跨模型迁移攻击

跨模型迁移攻击是指针对一个模型训练的对抗性提示词,在另一个完全不同的模型上仍然有效。这种现象的存在表明不同 LLM 的安全漏洞存在某种共性。

研究发现某些类型的提示词模式在不同模型间都有较高的迁移成功率。

持续学习系统的污染攻击

具备持续学习能力的 LLM 系统可能会从用户交互中不断学习和优化。攻击者可以通过精心设计的交互序列,将恶意模式注入到模型的学习数据中。

这种攻击的隐蔽性极高,因为恶意行为被包装在正常的性能优化建议中。

漏洞挖掘方法论

基于符号执行的提示词分析

符号执行技术可以应用于提示词分析,通过形式化方法探索所有可能的执行路径,发现潜在的注入点。

模糊测试在 LLM 系统中的应用

模糊测试技术可以大规模自动化地发现 LLM 系统中的安全漏洞。

动态污点分析框架

污点分析可以追踪不可信数据在系统中的流动路径,识别出所有可能被污染的执行点。

五、结语:别再问“能不能彻底防住”,先问“最坏情况下它能做多大”

这波事件给我的最大感受是:
LLM 安全不是“模型对不对”,而是“系统允许它做什么”。

如果你的产品具备以下任一条件——

可以浏览/搜索并总结

有 RAG 或会读取用户文档

有工具调用/Agent 自动化

开启记忆/长期偏好

系统提示词由多个模块拼接、可运营配置

那你就已经进入“提示词供应链时代”。

从工程角度,最实用的三句话是:

1所有外部内容默认不可信,只能影响“回答”,不能影响“权限”。

2写入型能力(memory/外联/改数据)必须是高风险能力,走策略门。

3 LLM 输出永远当不可信输入,尤其别让它直连反序列化/模板/执行链路。(LangChain CVE 就是活教材)

2026 年最真实的趋势:
Prompt 不是文本,是供应链;防御不是拒答,是权限设计。

参考阅读

Reprompt 一键外泄相关新闻与解读

Tenable:ChatGPT ?q= 参数触发 prompt injection

Tenable:Command Memories / SearchGPT prompt injection 风险

System Prompt Poisoning 研究论文

LangChain 序列化注入(CVE-2025-68664)通告/分析

“没有,从来都没有安心的时候。”

在 2026 年达沃斯世界经济论坛,DeepMind 创始人、Google DeepMind CEO 德米斯·哈萨比斯,用这句话形容过去三到四年的谷歌。

外界一度流行的“谷歌慢半拍”的言论,在他看来是一个彻底的误解。事实上,在这段时间里,谷歌的 AI 团队几乎一直处于红色警报状态。他本人长期保持着每周 100 小时、一年 50 周的工作强度,把一家万亿美元体量的科技巨头,硬生生拉回到创业公司的战时节奏。

也正是在这样的状态下,谷歌迎来了 Gemini 3 的发布,被哈萨比斯视为“重回行业最前沿”的关键节点。

在接受彭博社记者 Emily Chang 的专访时,他罕见地系统性拆解了当下几乎所有 AI 世界的核心争议:

  • 谷歌是否真的掉队?

  • 中国 AI 是否构成威胁?

  • Transformer 和大模型是否已经走到尽头?

  • AGI 会在什么时候到来?

  • 当工作不再必要,人类该如何寻找意义。

在哈萨比斯看来,过去十年,现代人工智能产业所依赖的关键突破,比如 Transformer 架构、深度强化学习、AlphaGo 背后的技术体系,几乎都诞生于谷歌与 DeepMind。他高度赞扬谷歌深厚的技术积累,他认为 谷歌是唯一真正具备 AI 全栈能力的公司,其真正的问题在于能否把研究、算力、数据、硬件和产品,整合成一个统一体系。

他还高度赞扬了谷歌的科学研究氛围,认为这正是他当初选择谷歌作为 Google DeepMind 归宿的原因。他还透露了他与拉里・佩奇、谢尔盖・布林如何高效分工。

在访谈中,哈萨比斯还反复提到一个关键词:物理 AI(Physical AI),他承认物理 AI 确实正处于突破的临界点。

在他的设想中,Gemini 从一开始就不是“聊天模型”,而是一个理解现实世界的多模态系统,是通往物理 AI 的入口。未来 Gemini 只会走向两个方向:

  • 随身的通用 AI 助手(眼镜、手机)

  • 真正能干活的机器人

当然,他也给出了冷静判断,距离物理 AI 跨过临界点还有 18 个月到两年的时间,在算法、数据、硬件等方面,都还差最后一段路。

谈到中国 AI,哈萨比斯的态度异常冷静。

他并不认为 DeepSeek 构成真正意义上的“危机”,也直言西方舆论夸大了其算力效率优势,这背后仍依赖西方模型蒸馏。在他看来,中国公司极其擅长追赶,但是否能率先打开下一代技术前沿,仍有待时间验证。而 现代人工智能行业所依赖的约 90% 的突破性技术,都是谷歌研发的。

但他特别表扬了 字节跳动,给出了一个极具分量的评价:字节跳动距离技术前沿,大约只差 6 个月,而不是 1–2 年。

这位把 AGI 当作毕生使命的科学家型 CEO,几乎反驳了 马斯克、杨立昆和伊利亚·苏茨克维的核心判断,同时给出了一个异常冷静 AGI 的时间表:2030 年,有 50% 的概率实现通用人工智能。

哈萨比斯对 AGI 有自己一套严格的标准,即必须具备完整的人类认知能力,尤其是科学创新能力,不仅能解决问题,还要能提出真正重要的问题  这其中还有不小的差距。

他认为距离 AGI,还需要一两项,最多不超过五项突破性技术,这可能体现在世界模型、持续学习的能力、稳定性表现、更强的推理能力或更长远的规划能力等方面。他高度认可现有的模型成就,认为在现有方法的基础上进行优化并扩大规模,或许就能实现 AGI。

在访谈的最后,话题不可避免地走向未来社会:人工智能是否会取代人类的工作?围绕这一问题,哈萨比斯提出了一个有趣的概念 “后稀缺时代”

在他看来,AI 带来的变革,无论规模还是速度,都会是工业革命的十倍,取代部分人类工作几乎是不可避免的结果。但他厘清一个概念,即人工智能本质上是一种终极的科学研究工具,就像更先进的望远镜和显微镜一样,是为科学服务的。

在哈萨比斯的设想中,真正重要的并不是“谁被取代”,而是人类将因此获得前所未有的自由,把注意力转向那些更根本的问题。例如能源危机,如何实现核聚变,如何发现全新的材料体系。这些长期困扰人类的难题,或许正是在人工智能的加持下,才第一次显露出被彻底解决的可能性。

这不仅是一场技术竞赛,更是一场文明级实验。真正的风险,在于当人类不再需要通过工作来定义自身价值时,我们是否已经准备好回答那个更深层的问题“为什么而活?”。

在那个时代,人类或许需要的不只是更强的工程师,而是伟大的哲学家,去重新书写意义的来源。

以下是哈萨比斯访谈实录,更多的谈话细节,欢迎来看:

谷歌的红色警报期与“王者归来”

主持人:和你上次来达沃斯相比,今年的感受有什么不同吗?Gemini 3 已经发布了,相关的消息我们也都听说了。我在内部甚至把这段时间称作“红色警报”。你觉得谷歌已经找回曾经的状态了吗?

哈萨比斯:我不太确定这是不是该由我来评价,但我确实认为,过去这一年我们做得非常出色。我们付出了极其艰苦的努力,几乎是全力以赴,才让我们的技术和模型重新回到行业最前沿

尤其是 Gemini 3,以及我们在视觉和成像系统方面取得的一些关键突破,都在这一过程中起到了决定性作用。同时,我们也逐渐适应了如今这种节奏极快、需要迅速将成果推向市场的行业环境,让整个团队重新焕发出一种更接近初创公司的活力。

主持人:你认为人们是否低估了谷歌,或是对谷歌有误解?

哈萨比斯:或许是吧,我不确定。我的意思是,我们一直都拥有站在这个领域前沿的所有必备条件,显然我们在这方面有着悠久的积淀。

我认为在过去十年里,谷歌和 Google DeepMind(谷歌深度思维)联手,创造出了现代人工智能行业所依赖的大部分突破性技术。比如 Transformer 架构,还有最知名的阿尔法狗背后的深度强化学习技术,这些都是我们的成果。

我们还有覆盖数十亿用户的优质产品矩阵,从搜索引擎、电子邮箱到谷歌浏览器,这些产品天生就适合融入人工智能技术。

问题只是如何将所有这些资源整合起来,以正确的方式统筹规划。 过去几年我们已经做到了这一点,当然还有大量工作要做,但我们已经开始看到努力带来的成果了。

主持人:如果你认为谷歌具备优势,你觉得这个优势有多大?能持续多久?

哈萨比斯:在我看来,一切都始于研究。尤其是模型,要在各类基准测试中都保持行业前沿水平。这也是我们整合谷歌和 Google DeepMind(谷歌深度思维)后,首要聚焦的工作。双子座系列模型的进展,我们感到非常满意,当然这方面还有很多工作要推进。

但我认为,我们是唯一一家拥有全栈能力的机构,从技术、战术、流程体系,到硬件、数据中心、云业务、前沿实验室,再到一众天生适配人工智能的优质产品,我们一应俱全。

所以从根本的结构层面来说,我们本就该有出色的表现,而且我认为我们未来还有很大的提升空间。

主持人:我想知道,作为前沿模型研发的负责人,日常工作状态是怎样的。我看到有报道说,你大多在凌晨一点到四点进行深度思考。确实是这样吧?谷歌内部的工作状态是否一直处于红色警报级别?你有没有感到安心的时候?

哈萨比斯:没有,从来都没有安心的时候。我们设定红色警报级别,本是针对特殊情况的,但过去三四年,工作强度一直大到难以想象。每周工作一百小时,一年工作五十周,这已经是常态。

在这个技术发展速度极快的领域,要想保持前沿,就必须这样做。行业的竞争异常激烈,可能是科技领域有史以来最白热化的阶段,而且背后的利害关系重大。通用人工智能的研发,无论从商业还是科学角度,都有着深远的意义。

再加上我们正做的事情本身就令人振奋,而我的热情就是用人工智能探索科学难题,推动科学发现的进程。这是我一直以来的梦想,我毕生都在为人工智能发展的这一刻而努力。所以常常会因为有太多工作要做而难以入眠,但同时,也有太多令人兴奋的事情值得我们去探索、去推进。

主持人:聊聊谷歌目前的内部文化吧,你们既要在这场竞争中取胜,又要保证研发的方向正确。拉里・佩奇和谢尔盖・布林 现在的参与度如何?你和他们沟通的频率高吗?他们现阶段的工作重点是什么?

哈萨比斯:他们的参与度非常高。

拉里・佩奇更多负责战略层面的工作,我会在董事会会议上见到他,去硅谷时也会和他碰面。

谢尔盖・布林则更多参与具体工作,他甚至会亲自参与双子座研发团队的编码工作,尤其专注于算法细节方面。

他们能对当下的人工智能研发充满热情,这对我们来说是好事,毕竟这是计算机科学发展史上一个无比重要的时刻,单从科学角度来看,这也是人类历史上的重要时刻,所以所有人都想亲身参与其中,这一点非常好。

而对于我来说,我正努力融合各方优势,既保留初创企业快速推出产品、敢于冒险的活力,这一点我们已经看到了成效;又充分利用大企业的资源优势,同时还为长期研究和探索性研究保留空间,而非只聚焦于三个月内就能落地的产品相关研究,我认为只做短期研究是不明智的。

我正努力平衡这些因素,过去一年,各项工作的推进都很顺利,而且我认为今年我们能做得更好。我对目前的发展态势非常满意,谷歌的技术提升和研发进展速度,在业内应该是最快的。

物理 AI 的奇点时刻,还有 18 个月到两年的时间

主持人:我知道你一直把重点放在推动科学进步上,比如发现新材料。我们也看到,现在 Gemini 已经被整合进人形机器人系统中。那么你觉得,人工智能在真实物理世界中的应用,是否即将迎来一个类似 AlphaFold 那样的突破性时刻?如果是的话,这个“突破”会以什么形式出现?

哈萨比斯:是的,过去一年我花了大量时间深入研究机器人技术。我确实认为,我们正处在物理 AI 取得突破性进展的临界点。

但我还是觉得,距离实现这一突破,我们还有 18 个月到两年的时间,还需要开展更多研究。

不过我认为,双子座这样的基础模型,为我们指明了方向。从一开始,我们就将双子座设计为多模态模型,让它能够理解物理世界,背后有多重原因。

其一,是为了打造通用智能助手,这种助手或许会搭载在 智能眼镜或手机 上,能够理解周边的现实世界。

其二,当然就是为了应用在 机器人领域。那么人工智能在物理世界的突破性时刻,究竟会是怎样的?我认为,那就是让机器人能在现实世界中稳定地完成各类有实际价值的任务。

目前,仍有一些因素制约着这一目标的实现。

一方面,算法还不够完善,需要提升鲁棒性,而且相较于实验室中仅处理数字信息的模型,机器人相关算法能依托的数据量更少,合成这类数据的难度也远高于数字数据

另一方面,硬件方面也仍有一些难题尚未解决,尤其是机械臂和机械手的研发。其实深入研究机器人技术后,你会对人类的手部结构产生全新的敬畏之心,至少我是这样。进化的设计精妙绝伦,人类的手在稳定性、力量和灵活性上的表现,很难被复刻。所以在我看来,要实现这一突破,还有不少环节需要完善,但目前已有很多令人振奋的进展。

我们刚刚宣布与 波士顿动力 展开深度合作,他们研发的机器人非常出色,我们正将人工智能技术应用到汽 车制造领域

接下来一年,我们会先推出 原型机 进行测试,或许一两年后,我们就能展示一些令人印象深刻的成果,并实现规模化应用。

DeepSeek 并不是重大危机,特别表扬字节跳动

主持人:一年前,DeepSeek 模型的发布在西方引发了不小的震动,很多人把它视为一场潜在的危机。但一年过去了,局势似乎逐渐平稳下来,中国方面的节奏看起来也有所放缓。你对中国人工智能领域整体竞争格局的看法,有没有发生变化?

哈萨比斯:没有,其实并没有改变。一开始我就不认为这是一场真正意义上的危机,我觉得西方当时的反应多少有些过度了。

DeepSeek 的确是一个令人印象深刻的模型,它清楚地展现了中国科技公司的实力。

如果看头部企业,比如字节跳动,我认为他们的能力非常强。在技术前沿的跟进速度上,他们可能只落后大约六个月,而不是一到两年。DeepSeek 正是这一点的体现。

当然,围绕它的一些说法也被夸大了。比如关于 算力使用效率的说法,并不完全准确,因为他们在研发过程中借鉴并依托了部分西方模型,也对顶尖模型的输出结果进行了微调,而不是完全从零开始独立训练。

另外,还有一个关键问题目前仍然没有答案:那就是中国公司是否能够在跟进前沿的基础上,真正实现原创性的突破并引领下一代技术。 他们在追赶方面确实非常擅长,而且能力正在快速提升,但到目前为止,还没有证明自己能够率先打开新的技术前沿。

AGI 的时间表:2030 年,有 50% 的可能实现 AGI

主持人:是你为通用人工智能给出了定义,你也曾说过,到 2030 年,我们有 50% 的可能实现通用人工智能。 这个时间规划是否依然不变?

哈萨比斯:不变。

主持人:通用人工智能对你而言,依然是一个有价值的研发目标吗?

哈萨比斯:我认为是的,这个时间规划在我看来很合理,而且相较于一些人的预期,这个时间其实更充裕。

但我对通用人工智能的评判标准非常高,它指的是一个具备人类所有认知能力的系统,显然我们目前离这个目标还有很大差距。 这意味着,这类系统需要拥有 科学创新能力不仅能解决科学领域的猜想和难题,更要能率先提出研究假设和问题。 任何一名科学家都清楚,找到正确的问题,往往比找到答案难得多。

目前的人工智能系统显然还不具备这种能力,未来能否拥有,还未可知,我们也仍未明确实现这一能力需要哪些技术突破。比如 持续学习能力,也就是在线学习能力,让系统能突破训练的局限,在现实世界中自主学习;还有 稳定性,目前的系统在不同领域的表现参差不齐,而通用智能系统不该有这样的短板。在我看来,要打造通用人工智能系统,还有不少关键能力亟待突破。

主持人:我们来聊聊技术和未来的发展趋势。Meta 首席科学家 杨立昆(Yann LeCun) 认为,仅凭 Transformer 架构和大模型,无法实现通用人工智能。你是否认同这一观点?如果这些技术走到了尽头,我们的研发方向会是什么?

哈萨比斯:我不认同,我认为说这些技术走到尽头的观点显然是错误的,因为它们目前已经展现出了巨大的实用价值。但在我看来,这是一个实证问题,也是一个科学问题,仅凭这些技术是否能实现通用人工智能,尚无定论。

我认为有 50% 的可能,只需在现有方法的基础上进行优化并扩大规模,就能实现通用人工智能, 这是有可能的,而且我们也必须这样做。在我看来,这项研究是有价值的,因为至少这些大模型会成为最终通用人工智能系统的核心组成部分,唯一的问题只是,它是否是唯一的组成部分。

我能想象,从现在到实现通用人工智能,我们还需要一两项,最多不超过五项突破性技术

比如 世界模型,这是我一直提及的,我们也正在研发,目前我们的 GENI 系统就是最先进的世界模型(GENI 是 DeepMind 、Google 内部正在研发的一类世界模型(World Model)系统),我也直接参与了这项研发,我认为它至关重要。

还有 持续学习能力,以及打造 性能稳定的系统,让系统不再出现这种领域间的表现失衡,真正的通用智能系统,不该有这样的问题。

所以在我看来,人工智能还缺乏更强的 推理能力更长远的规划能力 等多项关键能力。目前尚未确定的是,实现这些能力,是否需要新的架构或突破性技术,还是只需在现有基础上继续优化。而谷歌和 Google DeepMind(谷歌深度思维)的做法是,双管齐下,既全力研发新的技术,也持续优化并扩大现有技术的规模。

主持人:OpenAI 联合创始人兼前首席科学家伊利亚・苏茨克维(Ilya Sutskever)认为,依靠扩大模型规模实现技术提升的时代即将结束。你是否认同这一观点?

哈萨比斯:我不认同。他的原话大概是 “我们重回研究的时代”,我和伊利亚・苏茨克维是很好的朋友,我们在很多问题上的看法都一致,但在这一点上,我并不认同。

我的观点是,我们从未离开过研究的时代,至少谷歌和 Google DeepMind(谷歌深度思维)一直如此。 我们始终在研发领域投入巨资,而且我认为,整合后的谷歌和 Google DeepMind(谷歌深度思维),拥有业内最深厚、最广泛的研发团队。

过去十年,现代人工智能行业所依赖的约 90% 的突破性技术,都是我们研发的,当然最知名的是 Transformer 架构,还有深度强化学习、阿尔法狗背后的各类强化学习技术,这些都是我们开创的。所以如果未来实现通用人工智能需要新的突破性技术,我相信,就像过去一样,我们依然会是这些技术的研发者。

主持人:最后一个问题,埃隆・马斯克说我们已经进入了技术奇点,你是否认同?

哈萨比斯:不认同,我认为这一说法为时过早。在我看来,技术奇点其实就是实现完全的通用人工智能,而我之前已经解释过,我们目前离这个目标还相去甚远。我相信我们最终能实现这一目标还有五年的时间,从实现通用人工智能的角度来看,其实并不长,但在那之前,我们还有大量的工作要做。

人工智能就像更先进的望远镜和显微镜

主持人:你是诺贝尔奖得主,我知道你一心想让人工智能推动科学研究的发展。如果未来人工智能本身取得了足以获得诺贝尔奖的科研发现,这个奖项该颁给谁?

哈萨比斯:我认为还是该颁给人类。当然,这取决于人工智能是否是完全独立完成这项发现。

目前来看,人工智能依然只是工具,在我眼中,它是终极的科学研究工具,就像更先进的望远镜和显微镜。 人类一直都在制造工具,让自己能更好地探索自然世界,人类本质上就是会制造工具的物种,这也是人类与其他动物的区别,而工具也让人类拥有了超越自身的能力,计算机当然也属于这类工具,人工智能则是这种能力的终极体现。

所以在我看来,人工智能一直都是推动科学研究的终极工具,而且在可预见的未来,科学研究都将是顶尖科学家与人工智能的合作成果:科学家提出富有创意的想法和研究假设,而人工智能作为强大的工具,助力提升数据处理、模式识别的效率,推动科学探索的进程。

AI 是否会取代人?我们将迎来后稀缺时代

主持人:谷歌是 Anthropic 人工智能公司的主要投资方,Anthropic 联合创始人兼 CEO 达里奥・阿莫迪 (Dario Amodei) 今天早些时候也来到了达沃斯。他预测,未来五年内,人工智能会取代 50% 的初级白领岗位,你是否认同这一观点?

哈萨比斯:我不认同,我认为这一过程会耗时更久。今年,我们或许能看到这一趋势的初步显现,比如初级岗位和实习岗位可能会受到影响,但要实现大规模取代,我们还需要解决人工智能系统的稳定性问题。

我把目前人工智能的这种不均衡表现称为 “锯齿型智能”,在某些领域表现出色,在另一些领域却不尽如人意。如果想将一整项工作完全交由人工智能代理完成,而非像现在这样,仅让其作为辅助工具,就需要让系统在各方面都保持稳定的表现。如果一个系统完成一项工作的成功率只有 95%,那是远远不够的,必须能圆满完成整个任务,才能让人放心地将工作交托给它。

所以在出现这种大规模的岗位变革前,我们还有大量工作要做,但 这种变革最终一定会到来。当然,一旦实现通用人工智能,整个经济体系都会发生改变,这早已超出了岗位变革的范畴。如果我们能打造出真正的通用人工智能,而且方向正确,我们或许会进入一个后稀缺时代,解决世界上一些根本性的难题,比如能源问题。借助人工智能,研发出全新的清洁、可再生的近乎免费的能源,比如实现核聚变还有新材料的研发,我认为在实现通用人工智能后的五到十年,我们会进入一个彻底改变的世界。

主持人:不过,在进入后稀缺时代之前,人们对这一过渡阶段充满了焦虑。我是一位母亲,我知道你也有孩子。你最担心孩子们未来会面临什么?你会和他们聊些什么?会告诉他们未来即将到来的变化吗?我听到很多人说,大学毕业生未来的就业会非常困难。

哈萨比斯:我倒不这么认为。我觉得我们即将进入一个变革的时代,就像工业革命那样,或许变革的速度会是工业革命的十倍,甚至难以想象。准确来说,变革的规模和速度都会是工业革命的十倍,影响力会是百倍。

但我想对所有人说,变革的背后,蕴藏着巨大的机遇。而且我始终坚信人类的创造力,我们的适应能力极强,因为人类的思维具有极强的通用性。

人类的大脑无比强大,我们的祖先以狩猎采集为生,而我们凭借这样的大脑构建了现代文明,所以我相信我们能再次适应新的时代。当然,这次的变革是前所未有的,因为它的速度太快了。以往,这样的重大变革往往需要一两代人的时间才能完成,而这次人工智能技术的变革,规模和影响力都极为巨大。

但对于如今的孩子,我会鼓励他们熟练掌握这些新工具,像使用母语一样运用它们,这些工具几乎能赋予他们超能力。比如在创意艺术领域,借助人工智能,一个人或许能完成过去十个人的工作。这意味着,如果你富有创业精神,在游戏设计、电影制作等创意领域有想法,就能完成更多工作,也能比以往更容易地跻身这些行业,成为新锐人才。

主持人:一些人主张暂停人工智能的研发,让监管政策跟上技术发展的步伐,也让社会有时间适应这些变化。如果在理想情况下,所有企业、所有国家都同意暂停研发,你是否会支持这一做法?

哈萨比斯:我会支持。我也曾公开表达过我的期望,这也是我十五年来的梦想。我接触人工智能研究已有二十五年,我一直希望,当我们接近实现通用人工智能的这一关键节点时,全球的科研人员能展开科学层面的合作。

我有时会设想,成立一个类似欧洲核子研究中心的国际人工智能研究机构,让全球最顶尖的人才携手合作,以极为严谨的科学方式,推进通用人工智能研发的最后阶段,同时让全社会参与其中,不仅是技术人员,还有哲学家、社会科学家、经济学家,共同探讨我们希望从这项技术中获得什么,以及如何让它造福全人类。这才是我们当下的核心议题。

但显然,这需要国际社会的通力合作,因为即便只有一家企业、一个国家,甚至整个西方世界决定暂停研发,倘若没有全世界的共同参与,没有制定统一的最低标准,这一做法也毫无意义。而目前,国际合作面临着不小的阻碍,所以如果想以严谨的科学方式推进通用人工智能的最后研发,就必须改变当下的国际合作现状。

主持人:如果到 2030 年我们实现了通用人工智能,而相关的监管政策尚未出台,我们是否注定会面临困境?

哈萨比斯:我依然乐观地认为,全球顶尖的人工智能研发机构会充分沟通,至少在安全和安保协议等方面展开合作,目前这方面的合作已经有了不少进展。比如我们和人工智能公司 Anthropic 在这些领域的合作就十分紧密。

如果国际层面的合作难以推进,这种行业内的同行合作就尤为必要。我和其他顶尖人工智能实验室的负责人关系都很不错,我认为,当利害关系足够重大时,大家会意识到问题的严重性和潜在的风险,而在未来两到三年,这一点会变得更加清晰。

主持人:你当初本可以把 Google DeepMind(谷歌深度思维)卖给任何一家企业,而如今,这些研发人工智能的企业都在寻求大众的信任。尤其是在监管政策难以跟上技术发展速度的情况下,历史经验也证明了这一点。我们为什么该信任你?为什么你认为谷歌,也是你内心所认可的,是最值得我们信任的企业?毕竟人工智能的研发存在不小的风险。

哈萨比斯:我认为,评判一家企业,要看它的实际行动,也要看参与相关研发的领导者的初衷。

我选择谷歌作为 Google DeepMind(谷歌深度思维)的归宿,有多个原因,最主要的是,谷歌的创始人创立谷歌的初衷,是打造一家以科学研究为核心的企业。 很多人都忘了,谷歌最初其实是一个 博士研究项目,是拉里・佩奇和谢尔盖・布林 的研究成果。所以我和他们一见如故。

拉里・佩奇主导了 Google DeepMind(谷歌深度思维)的收购,而谷歌的董事会成员也都是各行各业的顶尖人才,比如董事会主席约翰・轩尼诗是图灵奖得主,弗朗西斯・阿诺德是诺贝尔奖得主,这样的阵容在企业董事会中并不多见。所以谷歌的整体环境充满了 科学氛围企业的发展以科学研究和工程技术为核心,这一文化早已根深蒂固。而追求最高水平的科学研究,就意味着 做事要严谨、深思熟虑,在所有领域都践行科学方法

我认为这不仅适用于技术研发,也适用于企业的运营管理。所以我们始终努力做到深思熟虑、负责任,尽可能掌控我们推向市场的技术。当然,我们不可能做到尽善尽美,因为人工智能是一项全新、复杂且具有变革性的技术,但如果出现问题,我们会尽快调整修正。

最后我想说,谷歌想要为世界做的事情,也是我当初选择谷歌的原因之一。 谷歌的使命是整合全球信息,让人人皆可访问并从中受益,我认为这是一个非常崇高的目标。而 Google DeepMind(谷歌深度思维)的使命是破解智能的奥秘,并利用智能解决其他所有问题,这两个使命高度契合。人工智能与整合全球信息的工作本就相辅相成,谷歌的各类产品,从谷歌地图、电子邮箱到搜索引擎,都是对世界有实际价值的产品,人工智能能很自然地融入这些产品,为所有人的日常生活提供助力,我认为这是一件造福世界的事,能为此贡献力量,我感到很荣幸。

主持人:试想一下,在后稀缺时代,人们不再需要工作,当你实现了所有的技术目标后,你个人打算如何度过时间?毕竟到那时,科研工作本身或许也能实现自动化了。

哈萨比斯:如果真的到了那个阶段,我想利用人工智能探索物理学的极限

上学时,我最感兴趣的就是那些终极问题:现实的本质是什么?意识的本质是什么?费米悖论的答案是什么?(费米悖论是宇宙学和天体生物学中最经典的未解之谜,由美籍意大利物理学家、1938 年诺贝尔物理学奖得主恩里科・费米(Enrico Fermi) 在 1950 年提出,核心是 “理论上的地外文明存在性” 与 “人类实际观测证据为零” 的尖锐矛盾 ,其最经典的表述就是费米的一句反问:“他们都在哪儿呢?”)时间是什么?引力是什么?

我很惊讶,很多人每天忙于生活,却从未思考过这些重大问题,而这些问题一直萦绕在我心头,迫切想要找到答案。我想借助人工智能,去探索所有这些问题,或许还能在人工智能的助力下,利用新的能源和材料技术,实现星际旅行。

主持人:如果人们不再需要工作,我们还能找到生活的意义和目标吗?

哈萨比斯:说实话,这一点比经济层面的问题更让我担忧。经济层面的问题,更多是一个政治问题:当人工智能为我们带来巨大的效益和生产力提升时,我们能否确保这些成果为全人类共享,这也是我一直坚信的理念。

但更核心的问题是,很多人从工作和科研中获得生活的意义和目标,在新的时代,我们该如何找到这些?我认为,我们需要 新一代伟大的哲学家,来帮助我们思考这个问题。或许未来,我们的艺术创作会更加精妙,我们的探索之旅会更加深远,就像如今我们所做的极限运动等非经济目的的事情一样,未来或许会有更多更小众、更有深度的这类活动。

主持人:在场的所有人都想知道,自己该如何应对人工智能带来的变革。比如现在坐在达沃斯的会场里,十年后该如何自处?你认为,在场的人在看待人工智能这件事上,最容易犯的重大错误是什么?

哈萨比斯:我想从两个方面来说。

第一,对于年轻人和我们的孩子而言,唯一可以确定的是,未来会发生巨大的变化。所以在学习技能方面,要做好持续学习的准备,学会学习,才是最重要的能力。要能快速适应新环境,利用现有工具吸收新信息。

第二,对于在场的企业首席执行官和商界人士而言,当下最重要的是,目前市场上有很多顶尖的人工智能模型和服务提供商,未来还会更多。要选择那些以正确方式研发人工智能的合作伙伴,与这些企业携手,共同打造我们所期望的人工智能未来。

亲爱的播客漫游者们,

很高兴能与大家分享这份关于「播播鸡」(Boboji.org)的“食用”指南。

播客的世界浩瀚如海,我们常常被算法和既有的兴趣圈所困。而「播播鸡」的诞生,正是为了打破这种惯性,为我们提供一个全新的、充满人味的发现场。它不只是一个工具,它是一种态度,一种对偶然性探索精神的致敬。

让我们一同走进这个精心搭建的“街角”,看看如何更好地“品尝”这只独一无二的“播播鸡”。


第一章:功能与界面——“转角遇到爱”的地图

「播播鸡」的界面简洁而高效,它将中文播客的生态浓缩为四张核心榜单,它们是您在播客海洋中漫游的四张“地图”。

核心功能:四张榜单,四种视角

榜单名称核心内容发现价值
热门节目过去一段时间内,收听量和热度最高的单集播客快速了解当下最热门的话题和事件,不错过任何一个“爆款”瞬间。
热门播客综合表现最稳定、听众基础最庞大的播客频道寻找值得长期订阅和信赖的“老朋友”,建立稳定的收听习惯。
新锐节目近期发布,但迅速获得关注和收听的新单集捕捉最新的声音和趋势,发现播客界冉冉升起的“新星”。
新锐播客刚刚起步,但内容质量高、潜力巨大的新频道成为“伯乐”,支持和陪伴最具创新精神的创作者共同成长。

食用方法:分类浏览,无目的漫游

「播播鸡」提供了丰富的分类筛选功能,从“喜剧”到“投资”,从“犯罪纪实”到“休闲”,几乎涵盖了中文播客的所有领域。

如何“食用”:

  1. 选择一个你“不常去”的街区: 不要只停留在你熟悉的领域。尝试点击一个你从未涉足的分类,比如“哲学”或“航空”。
  2. 让榜单说话: 在选定的分类下,浏览四张榜单。你会发现,即便是“热门”,在小众分类中也带着独特的味道。
  3. 随心所欲地点击: 看到一个有趣的标题、一张吸引人的封面,就大胆点进去。不必带着“我一定要听什么”的目的性,就像在街角闲逛,看到一家有趣的店就推门而入。

第二章:理念——“无目的”的漫游

这正是「播播鸡」最迷人,也最核心的哲学所在:它刻意削弱了听播客的“目的性”

核心理念:转角遇到他

在当今的信息洪流中,我们习惯了“搜索”——输入关键词,得到精准的结果。这高效,但也无趣。它让我们错失了许多意料之外的惊喜

「播播鸡」没有搜索功能,这并非技术上的缺失,而是一种设计上的坚持

“我们希望您在「播播鸡」的每一次停留,都像是一次没有目的地的城市漫游。您不是来找一个特定的播客,而是来发现一个您还不知道自己会喜欢的播客。”

这种“无目的”的漫游,带来了以下价值:

  1. 偶然的惊喜: 您可能会因为一个有趣的标题,点进一个您从未听过的播客,发现一片全新的精神领地。这就像在街角咖啡馆,偶然听到一段触动心弦的对话。
  2. 打破信息茧房: 算法总是推荐“你可能喜欢”的内容,而「播播鸡」的榜单,是基于大众热度新锐潜力的客观呈现。它将您带出舒适区,接触到更广阔的中文播客世界。
  3. 重拾探索的乐趣: 在这里,您是主动的探索者,而不是被动的接收者。每一次点击,都是一次小小的冒险。

我的期望:成为中文播客的“秘密基地“

我对「播播鸡」的期望,是它能成为中文播客界一个温暖的“秘密基地”。它不仅能让听众发现好内容,更能让那些默默耕耘的新锐创作者,有一个被看见、被认可的舞台。我希望它能:

  • 持续挖掘潜力: 成为新声音的孵化器,让优质但小众的播客能通过“新锐榜”脱颖而出。
  • 保持独立精神: 永远以数据和听众的真实反馈为基础,保持榜单的公正性和透明度。
  • 成为一种文化: 让“刷播播鸡”成为中文播客听众的一种习惯,一种发现美好、分享惊喜的文化。

备注:每天基本都会有新的节目(新锐节目板块),每日第一次更新会稍慢一点点,它会加载新的内容。


结语与征询:我们是否需要“导航”?

在享受这种“无目的漫游”的乐趣时,一个问题也随之而来:我们是否需要一个“搜索”功能?

我知道,对于一些有明确收听需求的听众来说,没有搜索会带来不便。但正如我们所坚持的理念,搜索的加入,可能会削弱「播播鸡」最宝贵的偶然性探索感

现在,我想真诚地征求您的意见:

您认为「播播鸡」是否应该加入搜索功能?

  1. 不应该: 保持现状,让偶然和探索成为核心体验。
  2. 应该: 增加基础搜索,以提高效率和实用性。
  3. 折衷方案: 仅提供播客频道名称的搜索,而不提供单集内容的搜索,以平衡目的性和探索性。

期待您的反馈,它将决定「播播鸡」未来的方向。让我们一起,让中文播客的世界更加精彩!

其实,我还在想是否加入”收藏的功能“,哈哈哈哈~~~