包含关键字 typecho 的文章

图片云上传 IMG-CLOUD-UPDATE

项目介绍

在写博客的场景下,不可避免上传一些图片。作为博客文章插图。

我都是直接上传到我阿里云的 oss 里面。但是阿里云自带的工具太重了,每次打开等半天,而且复制 url 还得点好几下。

我花了一周做了一个快速上传图片到阿里云 OSS ,并且直接生成 makedown 格式的图片链接,方便你写博客或文章的时候快速上传并插入。

下面是正经的介绍:


图片云上传是一款前端使用 vue3+element-plus ,后端使用 go+gin+bbolt 的图片上传项目。使用该项目可以让你更快的把本地图片传到远程图片云仓库。当前版本支持阿里云 oss 。不用担心你的 access_key_id 会泄露,本系统保存到本地二进制数据库,不做任何远程传输。

本项目也适合初学者学习参考,内有大量的注释,对于学习 golang 和 VUE 都有比较大的帮助。

已支持:

  • 阿里云 oss
  • 自定义路径
  • 自定义/自动修改名称
  • 自动添加 markdown 格式
  • 支持设置密码/默认安装页面

未支持

  • 显示多层文件列表
  • aws/腾讯云/七牛等更多远程仓库

截图


https://imgur.com/1kA2Bav

https://imgur.com/gIbloDS

依赖组件:

1. 前端:

  1. vue3
  2. element-plus
  3. pinia
  4. axios
  5. vue-router

2. 后端:

  1. go
  2. gin
  3. bbolt

安装

  1. docker 编译安装

直接执行 make 即可,会先编译 web 端,再编译 server 端。再打包容器镜像。最后 docker 运行镜像。

参考项目:

在这里插入图片描述

摘要

随着鸿蒙系统在手机、平板、穿戴设备以及多终端场景中的应用越来越多,UI 流畅度已经成为用户最直观、最容易感知的问题之一。
在实际开发中,很多页面逻辑并不复杂,但依然会出现掉帧、滑动卡顿、动画不顺畅等情况,问题往往不在 CPU,而是出在 GPU 渲染压力过大 上。

本文结合 ArkUI 实际开发经验,从页面结构、状态管理、动画、图片、列表等多个角度,系统性地讲一讲 鸿蒙系统中 GPU 渲染性能该怎么优化,并给出可以直接运行的 Demo 示例代码,帮助你在真实项目中快速落地。

引言

在 HarmonyOS / OpenHarmony 体系下,UI 渲染主要由 ArkUI + 系统渲染管线 + GPU 协同完成。
理想情况下,每一帧的渲染时间要控制在 16ms 以内(60fps),一旦 GPU 在某一帧中承担了过多工作,就会直接表现为:

  • 页面滑动一卡一卡的
  • 动画有明显掉帧
  • 列表滚动不跟手
  • 设备发热、功耗升高

尤其是在 列表页、图片多的页面、复杂动画页面 中,这些问题非常常见。

所以,GPU 优化不是“锦上添花”,而是必须要做的基础工作

减少无效重绘是第一优先级

状态放对位置,比任何技巧都重要

在 ArkUI 中,只要 @State 发生变化,就会触发组件重新构建和重新渲染。
如果状态放得不合理,GPU 就会被迫做很多“没必要的活”。

错误示例:一个状态刷新整个页面

@Entry
@Component
struct BadPage {
  @State count: number = 0

  build() {
    Column() {
      Text('当前数值:' + this.count)
      Button('点击 +1')
        .onClick(() => {
          this.count++
        })
    }
  }
}

这里的问题是:
整个 Page 都会随着 count 改变而刷新

推荐做法:把状态下沉到最小组件

@Component
struct Counter {
  @State count: number = 0

  build() {
    Column() {
      Text('当前数值:' + this.count)
      Button('点击 +1')
        .onClick(() => {
          this.count++
        })
    }
  }
}

@Entry
@Component
struct GoodPage {
  build() {
    Column() {
      Counter()
    }
  }
}

这样 GPU 只需要重绘 Counter 这块区域,页面其它部分完全不受影响

实际场景:仪表盘 / 实时数据页面

比如你在做一个设备状态监控页面

  • 电量实时变化
  • 网络状态刷新
  • 温度数值更新

如果所有数据都放在一个 Page 的 State 中,那 GPU 每秒都在全量刷新页面。

更好的做法是:

  • 每一个数据块独立成组件
  • 各自维护自己的 State

这样就能明显降低 GPU 的渲染负载。

减少透明度和层级嵌套(Overdraw)

opacity 是 GPU 的“隐形杀手”

很多开发者喜欢用 opacity 做视觉效果,但实际上它非常容易触发 离屏渲染

不推荐的写法

Column() {
  Text('Hello HarmonyOS')
}
.opacity(0.5)

推荐写法:直接用半透明颜色

Column() {
  Text('Hello HarmonyOS')
}
.backgroundColor('#80FFFFFF')

原因很简单
opacity 会让 GPU 先在缓存中绘制,再合成到屏幕上,步骤变多了,性能自然下降。

实际场景:弹窗、蒙层页面

常见的弹窗结构是:

  • 半透明遮罩
  • 中间卡片

推荐做法:

  • 遮罩用半透明色值
  • 卡片背景保持不透明
  • 避免多层 Stack 嵌套

这样在低端设备上也能保证弹窗动画顺畅。

图片与纹理优化

图片尺寸不匹配,会让 GPU 白干活

GPU 很不喜欢加载大图再缩小显示

错误示例

Image($r('app.media.big_image'))
  .width(100)
  .height(100)

正确做法:准备合适尺寸资源

Image($r('app.media.image_100'))
  .width(100)
  .height(100)

使用缓存,避免反复解码

Image($r('app.media.avatar'))
  .cache(true)

这在 列表头像、商品图片 这种场景下,效果非常明显。

实际场景:商品列表 / 相册页面

  • 列表中每一项都有图片
  • 滑动过程中频繁创建 Image

如果没有缓存和尺寸控制,很容易出现:

  • 滑动掉帧
  • 页面发热

动画优化:只动 transform,不动布局

动布局动画成本非常高

不推荐

.animate({ duration: 300 })
.width(this.size)

这里会触发布局重新计算,GPU 和 CPU 都要加班。

推荐:使用 transform

.animate({ duration: 300 })
.transform({
  translateX: this.offset
})

transform 只影响最终绘制阶段,对 GPU 更友好。

实际场景:侧滑菜单 / 卡片动画

  • 菜单滑入滑出
  • 卡片弹出收起

这些动画如果全用 transform,基本可以做到低端机也不卡

列表必须使用 LazyForEach

普通 ForEach 的问题

ForEach(this.list, item => {
  Text(item.name)
})

数据一多,GPU 会直接爆炸。

正确姿势:LazyForEach

LazyForEach(this.list, (item) => {
  Text(item.name)
}, item => item.id)

只有屏幕可见的部分才会真正创建和渲染。

实际场景:设备列表 / 日志列表

比如:

  • 智能设备列表
  • 升级日志
  • 消息列表

LazyForEach 基本是必选项

完整可运行 Demo:高性能列表页面

@Entry
@Component
struct GpuOptimizeDemo {
  private data: Array<{ id: number; name: string }> = []

  aboutToAppear() {
    for (let i = 0; i < 1000; i++) {
      this.data.push({ id: i, name: '设备 ' + i })
    }
  }

  build() {
    List() {
      LazyForEach(this.data, (item) => {
        ListItem() {
          Row() {
            Text(item.name)
              .fontSize(16)
          }
          .padding(12)
        }
      }, item => item.id)
    }
  }
}

这个 Demo 在真机上滑动时,GPU 占用非常稳定。

QA 环节

Q1:GPU 优化是不是只针对低端设备?

不是。
高端设备只是“扛得住”,但功耗和发热依然会变高。

Q2:opacity 一点都不能用吗?

不是不能用,而是少用、慎用,尤其避免大面积使用。

Q3:怎么快速定位 GPU 问题?

  • DevEco Studio 的布局和性能分析
  • 看是否有掉帧
  • 看是否存在大面积 Overdraw

总结

在鸿蒙系统中,GPU 渲染优化的核心思路其实很简单:

  • 状态尽量小、尽量局部
  • 少透明、少嵌套
  • 图片尺寸要对、缓存要开
  • 动画只动 transform
  • 列表一定懒加载

这些优化手段单独看都不复杂,但一旦组合起来,页面流畅度会有非常明显的提升。

在这里插入图片描述

摘要

在鸿蒙(HarmonyOS / OpenHarmony)应用和系统开发中,IO 操作几乎无处不在,比如文件读写、配置加载、日志输出、数据库访问以及 OTA 升级等。很多性能问题表面上看是应用卡顿、启动慢、耗电高,实际上根源都指向 IO 使用不当。本文结合当前鸿蒙系统的实际开发现状,从应用层和系统层两个角度,系统梳理 IO 性能优化的常见思路,并通过可运行的 Demo 代码,讲清楚这些优化在真实项目中该怎么落地。

文章整体偏向实战,语言尽量贴近日常开发交流,适合正在做鸿蒙应用、系统服务或设备升级相关开发的同学参考。

引言

随着鸿蒙生态逐渐完善,应用形态从早期的简单页面,发展到现在的多端协同、分布式能力、设备级应用,IO 压力明显变大。一方面,应用启动阶段要加载更多配置和资源;另一方面,系统服务、后台任务、设备升级都会产生大量读写操作。

在实际项目中,经常能看到下面这些情况:

  • 页面一打开就卡,结果发现主线程在读文件
  • 日志一多,设备开始明显发热
  • OTA 升级时间很长,写盘阶段占了一大半
  • 分布式数据一同步,前台体验明显下降

这些问题并不是鸿蒙系统本身性能不行,而是 IO 的使用方式不够合理。下面我们就从最常见、也最容易优化的地方开始讲。

鸿蒙 IO 性能瓶颈从哪来

在多数项目中,IO 性能问题通常集中在下面几个点:

  • 频繁进行小文件读写
  • 同步 IO 放在主线程执行
  • 每次用文件都重新 open 和 close
  • 没有任何缓存策略
  • 用文件存 KV 数据
  • 日志输出不受控制

只要命中其中一两条,性能基本都会出问题。

应用层 IO 优化(最常用)

IO 一定不要放在主线程

这是最基础,也是最容易踩坑的一点。ArkTS 中如果直接使用同步文件接口,UI 线程就会被直接卡住。

错误示例

import fs from '@ohos.file.fs';

let text = fs.readTextSync('/data/storage/test.txt');

这种写法在数据量稍微大一点时,页面就会出现明显卡顿。

推荐写法(异步 IO Demo)

import fs from '@ohos.file.fs';

export async function readFileAsync(path: string): Promise<string> {
  let file = await fs.open(path, fs.OpenMode.READ_ONLY);
  let buffer = new ArrayBuffer(4096);
  let result = '';

  let readLen = await fs.read(file.fd, buffer);
  if (readLen > 0) {
    result = String.fromCharCode(...new Uint8Array(buffer, 0, readLen));
  }

  await fs.close(file);
  return result;
}

代码说明

  • 使用 async/await,把 IO 操作放到异步任务中
  • 读取完成后再返回结果,不阻塞 UI
  • 真实项目中可以配合 taskpool 使用

合并小 IO,减少系统调用

很多性能问题不是数据量大,而是 IO 次数太多。

不推荐的写法

for (let i = 0; i < list.length; i++) {
  fs.writeSync(fd, list[i]);
}

推荐写法

let content = list.join('');
fs.writeSync(fd, content);

实际效果

  • 系统调用次数明显减少
  • 写盘效率更高
  • 对 Flash 存储更友好

引入内存缓存,避免重复读文件

配置文件、初始化数据非常适合放进内存缓存。

let configCache: string | null = null;

export async function getConfig(path: string): Promise<string> {
  if (configCache !== null) {
    return configCache;
  }
  configCache = await readFileAsync(path);
  return configCache;
}

使用场景

  • 应用启动配置
  • JSON 静态数据
  • 权限或状态信息

能用 Preferences 就别用文件

对于少量 KV 数据,文件 IO 的性价比非常低。

Preferences Demo

import preferences from '@ohos.data.preferences';

export async function saveUserInfo(context, userId: string) {
  let pref = await preferences.getPreferences(context, 'user_config');
  await pref.put('userId', userId);
  await pref.flush();
}

优点

  • 内部自带缓存
  • 自动批量落盘
  • 使用简单,性能稳定

系统层 IO 优化(Native / 服务侧)

使用缓冲 IO

在系统服务或 Native 模块中,直接写裸 IO 往往效率不高。

#include <stdio.h>

void writeFile(const char* path, const char* data, size_t len) {
    FILE* fp = fopen(path, "w");
    if (!fp) return;

    setvbuf(fp, nullptr, _IOFBF, 8 * 1024);
    fwrite(data, 1, len, fp);
    fclose(fp);
}

说明

  • 设置 8KB 缓冲区
  • 减少实际写盘次数
  • 适合大量顺序写场景

顺序 IO 优于随机 IO

off_t offset = 0;
pread(fd, buffer, size, offset);
offset += size;

尽量避免频繁 seek 和交叉读写多个文件。

控制日志 IO

日志在调试阶段很有用,但在正式环境中是 IO 隐形杀手。

if (__DEV__) {
  console.info('debug log');
}

建议:

  • 发布版本关闭 debug 和 info
  • 避免循环内打印日志
  • 合并日志输出

典型应用场景分析

场景一:应用启动阶段加载配置

问题

启动慢,页面白屏时间长。

解决方案

  • 异步读取配置
  • 内存缓存
await getConfig('/data/storage/app_config.json');

场景二:OTA 升级文件写入

问题

升级包大,写盘耗时长。

优化思路

  • 分块下载
  • 分块写入
  • 写完再统一校验
async function writeChunk(fd: number, data: Uint8Array) {
  await fs.write(fd, data.buffer);
}

场景三:日志过多导致设备发热

问题

设备运行一段时间后发热、掉帧。

解决方案

  • 控制日志级别
  • 关闭非必要日志

常见问题 QA

Q:异步 IO 一定比同步快吗?
A:不一定,但一定不会卡 UI。

Q:缓存会不会导致数据不一致?
A:需要设计好更新策略,配置类数据问题不大。

Q:文件和 RDB 怎么选?
A:结构化数据选 RDB,大文件选文件。

总结

IO 性能优化并不复杂,关键在于使用方式是否合理。大多数性能问题,并不是因为设备性能不足,而是 IO 用得太随意。

简单总结几句话:

  • IO 不要放主线程
  • 少做小 IO,多做批量 IO
  • 能缓存就缓存
  • 能不用文件就不用文件
  • 日志一定要克制

这些原则在应用层、系统层、OTA 场景中都是通用的。如果你正在做鸿蒙系统相关开发,把 IO 优化当成基本功,会少踩很多坑。

在这里插入图片描述

摘要

在 HarmonyOS 的 ArkUI 开发中,经常会遇到这样一种交互需求:
用户按下某个组件,拖动它,然后在松手的一瞬间触发一个“释放”动作,比如飞出去、回弹、投放到某个区域,或者触发业务逻辑。

很多同学在一开始都会问一个问题:
ArkUI 里有没有现成的“施放 API”?

答案是:没有。
但 ArkUI 提供的 手势系统、状态管理和动画能力,已经足够我们组合出各种“施放效果”。

这篇文章就从一个最基础的拖拽开始,一步一步讲清楚:
ArkUI 中的“施放功能”到底是怎么实现的,以及在真实项目中该怎么用。

引言

随着 HarmonyOS 应用交互越来越偏向“自然操作”,像拖拽、投放、抛出这类交互,在实际项目中出现得非常多,比如:

  • 卡片拖到指定区域触发操作
  • 图标长按后丢进回收区
  • 功能模块拖拽排序
  • 智能设备管理中,把设备“丢”进分组

在 ArkUI 里,这些效果并不是某一个组件单独完成的,而是多种能力的组合
理解这一点之后,你会发现实现起来并不复杂,而且扩展性非常强。

ArkUI 中“施放”的本质是什么

从技术角度来看,所谓“施放”,本质就是三步:

  1. 用手势感知用户操作
  2. 用状态驱动组件位置变化
  3. 在松手时,通过动画完成“释放效果”

换句话说就是:
手势负责输入,状态负责位置,动画负责感觉。

最基础的施放实现:拖拽 + 松手回弹

实现思路

这个 Demo 不考虑目标区域,只关注三件事:

  • 手指拖动时,组件跟着动
  • 松手后触发动画
  • 动画结束后回到原位

可运行 Demo 示例

@Entry
@Component
struct CastBasicDemo {
  @State offsetX: number = 0
  @State offsetY: number = 0

  build() {
    Column() {
      Text('拖拽组件,松手后施放')
        .fontSize(18)
        .margin(20)

      Box()
        .width(80)
        .height(80)
        .backgroundColor(Color.Blue)
        .translate({ x: this.offsetX, y: this.offsetY })
        .gesture(
          PanGesture()
            .onUpdate((event) => {
              // 拖动过程中,组件位置实时更新
              this.offsetX = event.offsetX
              this.offsetY = event.offsetY
            })
            .onEnd(() => {
              // 松手瞬间,触发“施放”动画
              animateTo({
                duration: 300,
                curve: Curve.EaseOut
              }, () => {
                this.offsetX = 0
                this.offsetY = 0
              })
            })
        )
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }
}

代码讲解(重点)

这里其实就三行是核心:

this.offsetX = event.offsetX
this.offsetY = event.offsetY

组件的位置完全由 @State 控制,手势只是不断修改状态。

而“施放”的感觉来自这里:

animateTo({}, () => {
  this.offsetX = 0
  this.offsetY = 0
})

只要状态变化发生在动画作用域内,就会自动过渡。

带目标区域的“施放”:成功 or 回弹

在真实项目中,施放通常不是随便松手就算成功,而是:

  • 拖到某个区域才成功
  • 没拖到就回弹

思路拆解

  • 拖拽过程中,持续记录位移
  • 松手时判断最终位置
  • 根据结果执行不同动画

示例代码

@Entry
@Component
struct CastTargetDemo {
  @State offsetX: number = 0
  @State offsetY: number = 0

  build() {
    Stack() {
      // 目标区域
      Box()
        .width(120)
        .height(120)
        .backgroundColor(Color.Grey)
        .position({ x: 200, y: 300 })

      // 可施放组件
      Box()
        .width(80)
        .height(80)
        .backgroundColor(Color.Green)
        .translate({ x: this.offsetX, y: this.offsetY })
        .gesture(
          PanGesture()
            .onUpdate((event) => {
              this.offsetX = event.offsetX
              this.offsetY = event.offsetY
            })
            .onEnd(() => {
              if (this.offsetX > 150 && this.offsetY > 250) {
                // 施放成功,吸附到目标
                animateTo({ duration: 200 }, () => {
                  this.offsetX = 200
                  this.offsetY = 300
                })
              } else {
                // 失败,回弹
                animateTo({ duration: 300 }, () => {
                  this.offsetX = 0
                  this.offsetY = 0
                })
              }
            })
        )
    }
    .width('100%')
    .height('100%')
  }
}

这里在做什么判断

if (this.offsetX > 150 && this.offsetY > 250)

这本质上是一个区域命中判断
在正式项目中,你可以:

  • 根据组件尺寸动态计算
  • 封装成工具函数
  • 甚至引入碰撞检测逻辑

真实应用场景示例

场景一:卡片拖拽投放到功能区

典型应用
首页卡片管理、模块编辑模式。

示例核心代码

.onEnd(() => {
  if (this.offsetX > 180) {
    animateTo({ duration: 200 }, () => {
      this.offsetX = 220
      this.offsetY = 0
    })
    // 这里可以触发业务逻辑,比如加入列表
  } else {
    animateTo({ duration: 300 }, () => {
      this.offsetX = 0
      this.offsetY = 0
    })
  }
})

逻辑上非常清晰:
UI 动画和业务逻辑是分开的,不会互相影响。

场景二:图标拖进回收站

这种交互非常常见,关键点是:

  • 松手瞬间让组件消失
  • 而不是回弹
.onEnd(() => {
  if (this.offsetY > 400) {
    animateTo({ duration: 200 }, () => {
      this.offsetY = 600
    })
  } else {
    animateTo({ duration: 300 }, () => {
      this.offsetX = 0
      this.offsetY = 0
    })
  }
})

你也可以配合透明度一起做:

.opacity(this.isRemoved ? 0 : 1)

场景三:设备管理中的“拖拽分组”

结合你后续可能做的鸿蒙设备管理场景:

  • 左侧设备列表
  • 右侧分组区域
  • 拖拽设备到分组完成绑定

这时就可以升级到 Drag & Drop,实现跨组件投放。

Box()
  .draggable(true)
  .onDragStart(() => {
    return { data: 'device-id-001' }
  })

目标区域:

Column()
  .onDrop((event) => {
    console.log('接收到设备:', event.data)
  })

这种方式更适合复杂业务。

QA 常见问题

Q1:为什么不用绝对定位?

绝对定位是死的,而 translate 是基于状态的,动画过渡更自然,也更安全。

Q2:施放动画卡顿怎么办?

  • 确保只操作必要的状态
  • 避免在 onUpdate 里写复杂逻辑
  • 动画时间不要太长

Q3:PanGesture 和 Drag 怎么选?

  • 单组件内部效果:PanGesture
  • 跨组件、跨区域:Drag & Drop

总结

在 ArkUI 中,“施放功能”并不是某一个 API,而是一种交互设计模式

  • 手势负责感知用户行为
  • 状态决定组件位置
  • 动画塑造最终体验

只要你理解了这个组合思路,就可以根据项目需求,灵活实现各种拖拽、投放、释放效果,而且代码非常干净、可维护性也很好。

我的工作流是一个围绕 superpowers 插件Loop,superpowers 的理念是:先思考再动手。当你提出一个需求,不会急于写代码,而是先退一步问你"你真正想要实现什么",通过对话梳理出完整的设计方案,再分步执行。

核心设计是 masterworker 分离。

  • 脑暴会话 (master):专注于思考和设计,输出高质量的设计文档和执行计划
  • 执行会话 (worker):专注于代码实现,执行详细的计划

1、需求录入 - 首先我会在 Zed 上进行需求录入,采用 md 格式。这一步非常重要,我大概有 30% 的时间花在需求录入上,我会把能想到的关于此需求的背景、最终目标、可行的技术方案、风险点、外部 API 文档等等一切资源,都在需求文档中说明。对于需求文档,我不会太在意格式,会有比较多口语化的表达。

2、脑暴阶段 - 把需求 MD 喂给 Claude,调用 /superpowers:brainstorm 和 claude 进行思维碰撞。这个阶段不写任何代码,只讨论设计方案和实现细节,最终输出 design.mdimplement.md,保证最终的实现方案是完美符合我的预期的。

3、 执行阶段 - 这里我会选择新起一个 ClaudeCode 会话,而不是在脑暴会话中进行代码实现。新会话的好处:一、原先脑暴会话已经经过多轮对话了,一般情况下上下文会比较满,新会话响应更快,并且不会“犯傻”;二、implement.md 足够详细,无需额外上下文

4、 CodeReview - 在 Zed 中进行代码审查和功能验收。关于代码审查,对于一些代码细节和实现原理,这里我会使用 zed-agent 来辅助我进行代码 review,当然,你也可以在终端新建一个 ClaudeCode 会话或者使用 Zed 的 Claude Agent。原则是尽量不在脑暴和执行会话中引入太多不必要的问题,保持这两个会话的「干净」。发现问题后,将改进项写入新的需求 MD

5、 LOOP - 改进项 MD 喂回脑暴会话,开始下一轮脑暴迭代

非常简单,但是效果超群。充分的前期设计可以提升 AI 的效率和质量,避免多次的来回拉扯。

举个真实案例:我用这套工作流将个人博客从 Quarz 框架迁移到 Astro 框架。脑暴阶段确认好设计方案后,我让 Claude 执行计划,然后就去睡午觉了。醒来发现 Claude Code 已经完美完成任务——中间零中断,一次成功,共计 5000+ 行代码变更。

时间序列无处不在,心电图上的心跳、股票价格、家庭智能电表读数,甚至句子中词语——这些都是时间序列。它们的特殊之处在于顺序:过去影响未来,相邻的数据点往往高度相关。

现代预测和分类模型很少直接处理原始时间序列值。它们依赖的是特征:用来描述序列形状、变异性、趋势和模式的摘要信息。好的特征能把困难的预测问题转化为更简单的回归或分类任务。

当前有两大趋势,一是 AutoML(自动机器学习),像 auto-sklearn 这样的系统能自动搜索模型族、超参数和预处理步骤。二是自动化时间序列特征提取,像 tsfresh 这样的库可以从每个序列生成数百个特征,涵盖统计量、自相关、频谱内容、熵等各个维度。

最近的研究表明,将 AutoML 与丰富的时间序列特征结合,在许多预测任务上能超越复杂的深度神经网络。更有意思的是这种方法甚至可以通过"语言时间序列"来提升文本分类的性能。

本文将介绍多步时间序列预测的构建方式、auto-sklearn 如何扩展用于时间序列、tsfresh 的工作原理和使用方法,以及两个案例研究:数值预测和文本作为时间序列。文末还有一些可以直接应用到项目中的实用技巧。

多步预测:不仅预测下一步,还要预测接下来的 k 步

多步超前预测的目标不是预测下一个值,而是预测一整个序列的未来值:

$$
x_{i+1}, x_{i+2}, \dots, x_{i+k}
$$

比如预测未来 24 小时的电力负荷、未来 10 天的原油价格,或者提前几个时间步预测洪水水位。

两种主要策略被广泛使用。

递归策略

首先训练一个模型只预测下一个时间步:

$$
\hat{x}_{i+1} = f(x_{i-w+1}, \dots, x_i)
$$

然后把这个预测值作为输入反馈进去,得到下一个预测:

$$
\hat{x}_{i+2} = f(x_{i-w+2}, \dots, x_i, \hat{x}_{i+1})
$$

如此重复直到达到 x_{i+k}。

这种方法只需训练一个模型,计算成本较低。但问题在于早期步骤的任何误差都会在后续预测中传播和放大,这就是我们常说的自回归预测。

直接多输出策略

另一种思路是训练一个模型一次预测所有未来步骤:

$$
[\hat{x}_{i+1}, \dots, \hat{x}_{i+k}] = f(x_{i-w+1}, \dots, x_i)
$$

这样做的好处是跨预测范围没有误差累积,在固定计算预算下通常准确性更好。缺点是模型更复杂,数据有限时可能更难拟合。

实践中两种策略都有用武之地。关键点在于:无论选择哪种策略,输入窗口大小 w 的选择以及从该窗口计算的特征都会显著影响性能。

时间序列的 AutoML:扩展 auto-sklearn

AutoML 的目标是自动化机器学习流水线的设计,包括数据清洗、特征预处理、模型选择和超参数调优。像 auto-sklearn 这样的系统把这当作搜索问题来处理:用贝叶斯优化和元学习探索不同的流水线,构建优秀候选者的集成。

典型的 auto-sklearn 流水线包含预处理器(缩放、填充等)、特征预处理器(PCA、核近似等)、模型(SVM、随机森林、梯度提升等)以及集成构建组件。

不过原始的 auto-sklearn 是为通用表格数据设计的。开箱即用时它不包含专门的时间序列特征提取器,像自相关峰值、频谱熵或季节性统计量这些。

有人对 auto-sklearn 做了修改,让特征预处理阶段可以包含时间序列特征提取(特别是使用 tsfresh),并且把窗口大小 w 本身作为超参数来搜索。扩展后的 AutoML 系统会搜索算法 A(SVM、GBM 等)、超参数 λ 和窗口大小 w,以最小化验证数据上的损失函数(如 RMSE)。

tsfresh

tsfresh(Time Series Feature Extraction based on Scalable Hypothesis tests,基于可扩展假设检验的时间序列特征提取)是一个 Python 库。它能自动从每个时间序列计算数百个特征:"综合"特征集大约有每个序列 794 个特征。

这些特征涵盖的类别相当广:基本统计量(均值、方差、分位数)、形状描述符(偏度、峰度、绝对能量)、自相关和偏自相关、频域度量(傅里叶系数、频谱能量、熵)、非线性时间序列特征(排列熵、小波系数等)。tsfresh 还会用假设检验来判断哪些特征与目标相关,配合多重检验校正来避免错误发现。

这种方式把工作重心从手动发明特征("要不要试试滚动均值、滞后差分,或许再加个 FFT?")转移到系统地探索一个丰富的特征库,让统计学和模型性能来决定什么才是重要的。

数据格式化

tsfresh 期望长格式的 DataFrame:一列用于 id(标识这行属于哪个时间序列)、一列用于 time(或排序索引)、一列或多列包含观测值。

示例结构大致如下:

特征提取

通常会调用类似这样的代码:

 from tsfresh import extract_features
from tsfresh.feature_extraction import ComprehensiveFCParameters

features = extract_features(
    df,
    column_id="id",
    column_sort="time",
    default_fc_parameters=ComprehensiveFCParameters()
 )

这会产生一个宽表,每行对应一个时间序列(一个 id),每列是一个特征,比如 valuemean、valueabs_energy、valueautocorrelationlag_1、valuefourier_entropybins_5 等等。

处理缺失值

对于很短或退化的序列,某些特征是未定义的(比如长度为 1 的序列没法计算 FFT)。tsfresh 提供了工具来填充或删除包含太多 NaN 的列:

 from tsfresh.utilities.dataframe_functions import impute
 
 impute(features)  # 用合理的默认值替换 NaN / inf

或者简单地删除全是 NaN 的列:

 features = features.dropna(axis=1)

特征相关性和选择

对于监督任务,tsfresh 还能基于假设检验进行特征选择,将每个特征与目标关联起来。这通常通过 extract_relevant_features 等函数完成,或者通过集成 tsfresh 的 AutoML 框架来应用其自身的选择逻辑。

用于预测的滚动特征提取

做预测时通常希望在滑动窗口上计算特征。先选择窗口大小(比如 24 小时),对每个时间窗口计算 tsfresh 特征,然后用这些特征行作为输入,将未来目标值作为标签。

案例研究 1:AutoML + tsfresh 用于多步预测

Wang 等人对 AutoML 和时间序列特征工程在多步预测任务上的相互作用进行了系统研究。

问题设置

给定单变量时间序列 (x_1, x_2, \dots, x_i),目标是仅使用最后 w 个观测值来预测接下来的 k 个值:

$$
x_{i+1}, \dots, x_{i+k}
$$

窗口大小 w 至关重要。太小会错过慢速模式;太大模型会看到嘈杂或不相关的历史。作者之前的工作已经表明,即使在单步任务中调整 w 也能显著影响预测性能,所以他们在这里把自动窗口大小选择扩展到了多步设置。

扩展 auto-sklearn

他们对 auto-sklearn 做了两处主要调整。第一是添加基于 tsfresh 的时间序列特征提取器作为候选特征预处理器。第二是把窗口大小 w 作为 AutoML 可以搜索的超参数,而不是固定的手动选择常数。

扩展后的 AutoML 系统会搜索模型族(SVM、GBM 等)、超参数(C、学习率、树深度等)和窗口大小 w(考虑 50–200 点等范围)。

三种 AutoML 变体

他们提出了三种专门用于时间序列预测的 auto-sklearn 变体。

W 变体(带自动窗口大小选择的 Auto-sklearn)使用窗口中的原始滞后值作为特征,让 AutoML 在 50–200 的范围内选择最佳窗口大小。

T 变体(带 tsfresh 特征的 Auto-sklearn)使用固定窗口大小(比如 w = 100),应用 tsfresh 从每个窗口段提取数百个特征,用 Benjamini-Hochberg 程序为每个预测步骤选择统计显著的特征,然后取跨预测范围的并集。

WT 变体结合了两个想法:AutoML 同时调整窗口大小 w 并使用从每个候选窗口提取的 tsfresh 特征。

基线和数据

为了对这些变体进行基准测试,他们与多种基线进行了比较。传统机器学习基线包括 SVM(递归和多输出两种形式)和 GBM(同样有递归和多输出两种)。神经网络和 AutoML 基线包括 N-BEATS(一个很强的单变量预测深度学习模型)、Auto-Keras(配置了 LSTM/GRU 循环块和手动选择的窗口大小)以及原始 auto-sklearn(固定窗口大小,无时间序列特定特征)。

数据集来自 CompEngine,一个大型时间序列数据仓库。他们从不同类别选择了 20 个数据集:音频(动物声音、语音、音乐)、生态数据、宏观和微观经济、金融(原油、汇率、天然气价格)、医学数据(ECG)、动力系统(受驱摆、Duffing 振荡器等)和随机过程(自回归、随机游走等)。每个数据集按时间分为 67% 训练集和 33% 测试集。

关键发现

几个最有意思的结果值得一提。

多输出模型在相同计算预算下通常优于递归模型,大概是因为避免了跨预测范围的误差累积。原始 auto-sklearn(固定窗口大小)已经在 20 个数据集中的 8 个上击败了所有传统机器学习基线。

专门的 AutoML 变体进一步提升了性能。W 变体(自动窗口大小,无 tsfresh)在 20 个数据集中的 14 个上优于最佳传统机器学习基线(SVM 多输出)。W、T 和 WT 分别在 10、5 和 5 个数据集上显示出比所有传统基线更低的误差。

与深度学习模型 N-BEATS 相比,最佳 AutoML 变体 W 在 20 个数据集中的 14 个上胜出。其他 AutoML 系统(Auto-Keras、原始 auto-sklearn、T、WT)也在许多数据集上击败 N-BEATS,有时差距相当大。

要点总结

这项研究有几个关键发现。AutoML 配合经典模型与深度模型具有极强的竞争力,特别是结合良好的特征工程和窗口大小调整时。窗口大小是一等超参数——即使没有花哨的特征,调整它也能带来很大收益。tsfresh 特征有帮助,但不一定以预期的方式:总体来看,纯窗口大小变体 W 是最强的,而基于 tsfresh 的变体可能在特定领域或评估指标上更有优势。多输出策略是有限预算下多步预测的可靠默认选择。

案例研究 2:将文本作为时间序列处理

时间序列特征工程不只适用于传感器读数或金融数据。在 2020 年的 EPJ Data Science 文章中,Tang 等人把短文本样本重新解释为时间序列,然后应用 tsfresh 风格的特征提取来改进作者归属任务。

从文本到"语言时间序列"

先对每个文本样本分词,然后把每个 token 映射到一个数值度量——可以是它在语料库中的频率、按频率的排名、字符长度,或者对词计数向量的贡献等。按 token 在句子中的位置排列这些数值,就形成了"语言时间序列"。

他们实验了五种功能性语言序列映射,包括 token 频率序列、token 排名序列、token 长度序列,以及基于分布的序列(如 token 长度分布和 token 排名分布)。每个结果序列都像普通时间序列一样处理。

文本上的时间序列特征提取

对于这五种映射中的每一种,他们用 tsfresh(ComprehensiveFCParameters)每个序列提取 794 个时间序列特征,最终得到每个文本样本 3970 个风格计量特征(794 × 5 种映射)。用 tsfresh 的 impute 函数处理缺失值和无穷值,用 10 折交叉验证评估模型,以 log loss 作为主要指标。

这些时间序列特征然后与标准 NLP 基线(朴素贝叶斯和最近质心分类器)的预测结合,用 XGBoost 构建混合分类器。

结果和见解

他们在两个数据集上进行了测试:Spooky Books(平衡类别,恐怖小说)和联邦党人文集(不平衡,历史上很重要的论文)。

在 Spooky Books 案例中,语言时间序列特征持续改进了基线 NLP 模型。对于联邦党人文集,将这些特征加到强 NLP 基线中带来了较小但仍有希望的改进。

一些特定的 tsfresh 特征在语言学上具有很好的可解释性。平均 token 长度特征能区分倾向于使用长词还是短词的作者。token 长度序列上的 c3 非线性统计量捕捉了词长波动的微妙模式。token 长度分布上的线性趋势特征(截距和斜率)能反映作者是倾向于使用均匀范围的词长还是集中于较短的词。

作者的结论是,时间序列特征提取提供了新颖的风格计量信号,可以增强传统 NLP 特征,这个功能性语言分析框架在更广泛的作者归属和风格分析任务中有潜力。

实用工作流程

整合前面的内容,这里给出一个可以用于时间序列项目(数值或文本)的具体流程。

首先要清楚定义预测任务:是单步还是多步预测?分类还是回归?

然后选择窗口策略。从 w 的合理范围开始(小时数据可以从 24–168 开始),如果可能的话把 w 作为可调超参数处理。

接着为 tsfresh 格式化数据。数值时间序列用 (id, time, value) 格式。文本的话,像 Tang 等人那样把句子转换为功能性语言序列(token 长度、频率、排名等)。

用 tsfresh 提取特征时,从 ComprehensiveFCParameters 开始探索完整的特征库,用 impute() 清理 NaN 和无穷值。

特征选择有几种方式:用 tsfresh 自带的相关性检验,或应用 Benjamini-Hochberg 这样的多重检验控制,或在模型中用正则化/特征重要性方法(基于树的模型、L1 正则化线性模型等)。

模型方面,如果做结构化实验,auto-sklearn 或 Auto-Keras 这样的框架可以搜索模型族和超参数。否则从梯度提升、随机森林或调优良好的神经网络这些强基线开始。

评估要充分。预测任务考虑 RMSE、MAE 和特定预测范围的误差。分类任务(包括文本)用准确率、log loss 和校准指标,最好配合交叉验证。

最后是解释关键特征。用特征重要性图或 SHAP 值看哪些 tsfresh 特征重要,把它们与领域知识联系起来:是否捕捉了季节性、波动性、体制变化或风格模式?是否揭示了不同组之间的差异(作者、患者类型、设备状态等)?

总结

从数值到文本领域,这些工作传达的信息很明确。

时间序列的特征工程远未过时——它只是变得更系统化和自动化了。AutoML 系统可以把 tsfresh 这样的时间序列特定组件纳入进来,效果很好,通常能在许多任务上与最先进的神经模型匹敌甚至超越。把文本这样的非传统数据当作时间序列处理,开启了一个全新的特征和分析工具空间。

如果正在构建预测或序列分类流水线,值得尝试 tsfresh 或类似的特征库、能同时调整模型和窗口大小的 AutoML 框架,以及"语言时间序列"这样的跨领域思路。工程特征带来可解释性,AutoML 提供灵活性,而如果这些研究有任何指示意义的话——实现最先进性能的机会相当不错。

引用:

https://avoid.overfit.cn/post/a96a4522adbf4d82a3b02b8c328b2306

作者:QuarkAndCode

引言

在上一篇文章中,我们探讨了 AI 绘画看似神奇的“魔法”背后的真相:它并非凭空创造,而是一个从混沌的噪点中,通过无数次“观察-脑补-修正”的循环,逐步建立秩序、生成图像的过程。理解了这一核心原理,一个自然的问题随之产生:我们该如何操控这个过程?是需要编写晦涩难懂的代码,还是有更直观、更易上手的方法?

答案是肯定的。今天,我们将介绍一位强大的幕后英雄——ComfyUI。作为一款基于节点流程的 Stable Diffusion 用户界面,ComfyUI 就像是一个透明的 AI 魔法工坊。它将复杂的 AI 生成过程拆解为一个个独立的模块,让使用者能够像搭积木一样,直观地构建和掌控自己的 AI 绘画工作流。本文将带领读者走进这个工坊,通过拆解一个最基础的文生图工作流,揭示每一个“积木”是如何分工协作,最终完成那场精彩的“脑补”大戏的。

第一部分:初识 ComfyUI —— AI 的可视化乐高

如果将传统的、集成度高的 AI 绘画 WebUI 比作一个功能齐全的“黑盒子”微波炉,用户只需放入食材、按下按钮即可得到成品,那么 ComfyUI 就更像是一套透明的乐高积木,或者一个开放式的中央厨房。

ComfyUI 的核心特点在于其“节点化 (Node-based)”的设计理念。在这里,每一个功能——无论是加载模型、处理文本,还是执行采样、解码图像——都被封装成了一个个独立的方块,称为“节点”。用户通过线缆将这些节点连接起来,定义数据的流向。

这种可视化流向的设计,使得 AI 的工作过程不再神秘。使用者看到了什么连接,AI 后台就执行了什么操作。数据从哪里来,到哪里去,经过了怎样的处理,一切都一目了然。更重要的是,这种极致的灵活性赋予了用户无限的创造空间。使用者可以根据自己的需求,像搭积木一样自由组合各种节点,构建出从简单到无比复杂的个性化创意工作流。

第二部分:解剖一只麻雀 —— 最基础的文生图工作流拆解

面对 ComfyUI 的界面,初学者可能会对满屏的节点和连线感到困惑。但无需担心,万丈高楼平地起。理解了最基础的工作流,就掌握了通往复杂应用的钥匙。下面展示的是一个最典型的 ComfyUI 文生图(Text-to-Image)工作流界面,我们将逐一拆解其中的核心角色。

1. 大管家:加载器 (Checkpoint Loader Simple)

一切工作的起点,是这个被称为“加载器”的节点。它就像是整个魔法工坊的物料仓库大管家。

它的作用是加载预先训练好的模型文件,通常称为 Checkpoint。这个文件至关重要,因为它打包了 AI 的核心能力:负责图像生成的“大脑”(UNet 网络)、负责理解文本的“眼睛”(CLIP 模型)以及负责图像数据转换的“翻译器”(VAE)。选择不同的 Checkpoint 文件,就决定了 AI 的“阅历”和基础“画风”,是擅长二次元动漫,还是写实摄影,全赖于此。它是所有后续工作的基石。

2. 翻译官与指挥棒:CLIP 文本编码器 (CLIP Text Encode)

人类使用自然语言描述画面,而 AI 的核心模型只能理解数学化的向量。这就需要“CLIP 文本编码器”充当人类与 AI 之间的沟通桥梁。

这个节点的作用是将用户输入的文本提示词(Prompt),“翻译”成 AI 能懂的数学指令,在技术上称为“条件 (Conditioning)”

在基础工作流中,通常会看到两个这样的节点。一个负责翻译正向提示词,生成“正向条件”,告诉 AI “画面里必须出现什么”(如:一只猫、高质量、阳光);另一个负责翻译反向提示词,生成“反向条件”,告诉 AI “画面里绝对不能出现什么”(如:低质量、变形、水印)。这两个条件就像是两根指挥棒,将在后续的生成过程中,严格引导和约束 AI 的创作方向。

3. 魔术师与沙盘:K 采样器 (KSampler)

“K 采样器”是整个工坊的核心车间,是奇迹真正发生的地方。它负责执行我们之前提到的“从噪点到清晰图像”的去噪循环。

为了高效地处理图像生成这一庞大的计算工程,AI 极其聪明地选择了一个策略:不在巨大的像素级画布上直接作画,而是在一个被称为“潜在空间 (Latent Space)”的沙盘上搭建一个精巧的“小模型”(潜在图像)。KSampler 就是在这个沙盘上进行精细化作业的魔术师。因为它处理的是高度浓缩的信息,而非海量的像素数据,所以效率极高。

这位魔术师在沙盘上工作时,并非随心所欲。它需要三种原料:从加载器获取的“模型”能力、一个初始的“空白画布”(通常是一个纯噪声的潜在图像),以及最重要的——从文本编码器传来的两根“指挥棒”。

在设定的步数内,KSampler 执行着“观察-脑补-修正”的循环。在每一步操作中,它都会严格参照“正向条件”的指南和“反向条件”的禁令,努力将沙盘上混沌的噪声,逐步转化为符合人类要求的、有意义的“小模型”。

4. 神奇打印机:VAE 解码 (VAE Decode)

当 KSampler 在沙盘上完成了创作,我们得到的是一个“潜在图像”。它虽然包含了画面的所有核心信息,但却是一团人类肉眼无法辨识的压缩数据。

这时就需要“VAE 解码”节点出场了。它就像是一台神奇的建筑打印机。它接过沙盘上那个抽象的“小模型”,利用大管家提供的 VAE 工具(图像数据转换的翻译器),按照特定的规则将这份压缩数据“解压”,并最终“打印”成我们眼前这座宏伟、清晰、色彩斑斓的像素大图。

5. 展示台:保存/预览图像 (Save/Preview Image)

工作流的终点是“保存/预览图像”节点。它的任务非常直观:将 VAE 解码器输出的最终像素图像展示在界面上供用户检阅,并将其保存到计算机的硬盘中,完成整个创作流程。

第三部分:连线——让数据流动起来

在 ComfyUI 中,节点之间的连线不仅仅是视觉上的连接,它们代表了数据显性的流动路径。理解了连线,就理解了 AI 工作的逻辑。

就像不同形状的积木插口一样,ComfyUI 中只有相同类型的数据端口才能连接,这保证了流程的正确性。

  • 模型连模型 (MODEL):将加载器中的绘画能力传递给采样器。
  • 条件连条件 (CONDITIONING):将文本编码器生成的“指挥棒”传递给采样器,指引创作方向。
  • 潜在图像连潜在图像 (LATENT):在采样器和解码器之间传递那个核心的沙盘“小模型”。
  • VAE 连 VAE (VAE):将加载器中的翻译规则传递给解码器,用于最终图像的还原。

整个流程可以总结为一条清晰的主线:加载模型备物料 -> 输入文字变指挥棒 -> 准备沙盘造噪声 -> 采样核心搞创作(受指挥棒引导) -> VAE 解码打印出图像。

结语

ComfyUI 以其独特的节点化设计,看似复杂,实则提供了一种最直观、最透彻的方式来理解和掌控 AI 绘画。它将深奥的 AI 生成原理拆解为一个个清晰可见的步骤,让我们不仅能“知其然”(看到最终的精美图像),更能“知其所以然”(理解图像是如何一步步生成的)。

通过理解“潜在空间”这个高效运作的沙盘,以及“条件”这两根强有力的指挥棒,我们揭开了 AI 绘画魔法的一角。掌握基础工作流只是第一步,ComfyUI 的魅力在于其无限的扩展性。鼓励每一位使用者去探索更多的高级节点,如 ControlNet、LoRA 等,搭建属于自己的、独一无二的 AI 绘画流水线,释放无限的创造潜能。

本文由mdnice多平台发布

本人 C 开发,工作主要使用 C 写一些 dpdk vpp 插件和一些 Shell 、python 脚本,公司安排了 AI agent 开发培训,所以搞了一个 Cursor vibe 了一个塞尔达传说旷野之息的交互式地图。前端在大学玩过 jQuery, 没有开发经验。

https://i.imgur.com/X6dCUM4.jpeg

  • 虽然是 Vibe 的,但是我还是花了一天学习了一下 Reactleaflet L.CRS.Simple模式;最后也把所有代码都看懂了;

预览:https://echoechoin.github.io

RT,Microsoft365 的 copilot 大部分情况下都是大幅度降智的,见我的上个帖子
经过研究,Microsoft365 其实可以用上满血 GPT 5.2 Thinking,经过对比和官网智力没有区别,而且基本不会触发降智,用过官网的都知道官网经常降智。
好像还可以用 5.1,能用 5.2 应该没人会去用 5.1 吧,所以就没加到脚本里。

此外,如果账号本来就有切换模型的权限,请本脚本设置默认模型,并使用官方功能切换模型,可以用本脚本去除无关的数据源,以提升模型能力。

使用链接 https://m365.cloud.microsoft/
油猴脚本如下,为了能活的久一点,没有上传到 github 并给帖子设了权限,所以不建议转发该帖子内容

// ==UserScript==
// @name         M365 GPT 优化工具
// @namespace    https://linux.do/u/fatekey/summary
// @version      1.3
// @description  Modify M365 chat websocket messages
// @author       fatekey
// @match        https://m365.cloud.microsoft/*
// @grant        GM_addStyle
// @run-at       document-start
// ==/UserScript==

(function() {
    'use strict';

    // ================= 配置与状态管理 =================
    const STORAGE_KEY = 'm365_mod_config_v2';
    const DEFAULT_CONFIG = {
        mode: 'default', // default, reasoning, chat
        cleanData: false
    };

    function getConfig() {
        try {
            const saved = localStorage.getItem(STORAGE_KEY);
            return saved ? JSON.parse(saved) : DEFAULT_CONFIG;
        } catch (e) {
            return DEFAULT_CONFIG;
        }
    }

    function saveConfig(config) {
        localStorage.setItem(STORAGE_KEY, JSON.stringify(config));
    }

    let currentConfig = getConfig();

    // ================= WebSocket 拦截逻辑 =================
    const originalSend = WebSocket.prototype.send;

    WebSocket.prototype.send = function(data) {
        let modifiedData = data;

        if (typeof data === 'string') {
            // 1. 处理模式替换
            if (currentConfig.mode !== 'default') {
                const target = '"isSbsSupported":true';
                let replacement = target;

                if (currentConfig.mode === 'reasoning') {
                    replacement = '"isSbsSupported":true,"tone":"Gpt_5_2_Reasoning"';
                } else if (currentConfig.mode === 'chat') {
                    replacement = '"isSbsSupported":true,"tone":"Gpt_5_2_Chat"';
                }

                if (data.includes(target)) {
                    modifiedData = modifiedData.replace(target, replacement);
                }
            }

            // 2. 处理数据净化
            if (currentConfig.cleanData) {
                const keywordsPattern = '"People","File","Event","Email","TeamsMessage"';
                modifiedData = modifiedData.replace(keywordsPattern, '');
            }
        }

        return originalSend.apply(this, [modifiedData]);
    };

    // ================= UI 界面逻辑 =================

    const css = `
        #m365-mod-btn {
            position: fixed;
            top: 12px;
            right: 160px;
            z-index: 99999;
            background: #252525;
            color: #fff;
            border: 1px solid #444;
            border-radius: 4px;
            padding: 6px 12px;
            font-family: 'Segoe UI', sans-serif;
            font-size: 12px;
            cursor: pointer;
            box-shadow: 0 2px 5px rgba(0,0,0,0.2);
            transition: background 0.2s;
            user-select: none;
        }
        #m365-mod-btn:hover {
            background: #3a3a3a;
        }

        #m365-mod-modal-overlay {
            display: none;
            position: fixed;
            top: 0; left: 0; width: 100%; height: 100%;
            background: rgba(0,0,0,0.5);
            z-index: 100000;
            justify-content: center;
            align-items: center;
            backdrop-filter: blur(2px);
        }

        #m365-mod-modal {
            background: #1e1e1e;
            color: #fff;
            padding: 20px;
            border-radius: 8px;
            width: 300px;
            box-shadow: 0 10px 25px rgba(0,0,0,0.5);
            border: 1px solid #444;
            font-family: 'Segoe UI', sans-serif;
        }

        .mod-row { margin-bottom: 15px; }
        .mod-title { font-size: 16px; font-weight: bold; margin-bottom: 15px; display: flex; justify-content: space-between; align-items: center; }
        .mod-close { cursor: pointer; color: #aaa; font-size: 24px; line-height: 20px; padding: 0 5px; }
        .mod-close:hover { color: #fff; }

        .mod-select { width: 100%; padding: 6px; background: #333; color: white; border: 1px solid #555; border-radius: 4px; outline: none; }
        .mod-label { display: block; margin-bottom: 5px; font-size: 13px; color: #ccc; }

        .mod-checkbox-container { display: flex; align-items: center; cursor: pointer; user-select: none; }
        .mod-checkbox { margin-right: 10px; transform: scale(1.2); }

        .mod-status { font-size: 12px; color: #88ff88; min-height: 18px; margin-top: 10px; text-align: right;}
    `;

    if (typeof GM_addStyle !== 'undefined') {
        GM_addStyle(css);
    } else {
        const style = document.createElement('style');
        style.innerText = css;
        document.head.appendChild(style);
    }

    function createUI() {
        // 1. 创建触发按钮
        const btn = document.createElement('div');
        btn.id = 'm365-mod-btn';
        btn.innerText = '⚙️ 设置模型';
        // 直接绑定 JS 函数,而非 innerHTML 字符串
        btn.onclick = openModal;
        document.body.appendChild(btn);

        // 2. 创建模态框容器
        const overlay = document.createElement('div');
        overlay.id = 'm365-mod-modal-overlay';
        // 点击遮罩层关闭
        overlay.onclick = (e) => {
            if (e.target === overlay) closeModal();
        };

        const modal = document.createElement('div');
        modal.id = 'm365-mod-modal';

        // --- 标题栏 ---
        const header = document.createElement('div');
        header.className = 'mod-title';

        const titleText = document.createElement('span');
        titleText.innerText = 'M365 GPT 优化工具';

        const closeBtn = document.createElement('span');
        closeBtn.className = 'mod-close';
        closeBtn.innerHTML = '&times;';
        // 修复点:使用 onclick 属性直接绑定函数,避开 CSP 限制
        closeBtn.onclick = closeModal;

        header.appendChild(titleText);
        header.appendChild(closeBtn);
        modal.appendChild(header);

        // --- 选项 1: 模式 ---
        const row1 = document.createElement('div');
        row1.className = 'mod-row';
        row1.innerHTML = `<label class="mod-label">AI 模型</label>`;

        const select = document.createElement('select');
        select.className = 'mod-select';
        const modes = [
            { val: 'default', text: '默认' },
            { val: 'reasoning', text: 'GPT 5.2 Thinking' },
            { val: 'chat', text: 'GPT 5.2 Quick' }
        ];
        modes.forEach(m => {
            const opt = document.createElement('option');
            opt.value = m.val;
            opt.innerText = m.text;
            if (currentConfig.mode === m.val) opt.selected = true;
            select.appendChild(opt);
        });
        select.onchange = (e) => {
            currentConfig.mode = e.target.value;
            saveConfig(currentConfig);
            showStatus('修改生效');
        };
        row1.appendChild(select);
        modal.appendChild(row1);

        // --- 选项 2: 清理数据 ---
        const row2 = document.createElement('div');
        row2.className = 'mod-row';

        const labelClean = document.createElement('label');
        labelClean.className = 'mod-checkbox-container';

        const check = document.createElement('input');
        check.type = 'checkbox';
        check.className = 'mod-checkbox';
        check.checked = currentConfig.cleanData;
        check.onchange = (e) => {
            currentConfig.cleanData = e.target.checked;
            saveConfig(currentConfig);
            showStatus('Clean Setting Saved');
        };

        labelClean.appendChild(check);
        labelClean.appendChild(document.createTextNode('移除无关数据源(邮件、联系人、云文档等)'));
        row2.appendChild(labelClean);
        modal.appendChild(row2);

        // --- 状态栏 ---
        const status = document.createElement('div');
        status.id = 'mod-status-text';
        status.className = 'mod-status';
        modal.appendChild(status);

        overlay.appendChild(modal);
        document.body.appendChild(overlay);
    }

    // 打开弹窗函数
    function openModal() {
        const overlay = document.getElementById('m365-mod-modal-overlay');
        if (overlay) overlay.style.display = 'flex';
    }

    // 关闭弹窗函数
    function closeModal() {
        const overlay = document.getElementById('m365-mod-modal-overlay');
        if (overlay) overlay.style.display = 'none';
    }

    function showStatus(msg) {
        const el = document.getElementById('mod-status-text');
        if (el) {
            el.innerText = msg;
            setTimeout(() => { el.innerText = ''; }, 2000);
        }
    }

    // 延迟加载确保不被框架覆盖
    const waitLoad = setInterval(() => {
        if (document.body) {
            clearInterval(waitLoad);
            createUI();
        }
    }, 500);

})();


📌 转载信息
原作者:
fatekey
转载时间:
2026/1/20 19:19:50

就在明天!大家别忘了领哦!


📌 转载信息
转载时间:
2026/1/20 19:17:05

skill 搜索安装的 skill

搜索 skill 的 skill ,内置数万 skill 的链接,一键搜索安装

skill 管理客户端,

  • 内置 skill 市场,数万 skill 可供选
  • 管理本地 skill,一键安装、更新、卸载
  • 支持多种 agent,




📌 转载信息
原作者:
zhangsaner
转载时间:
2026/1/20 19:15:33

作者: 闵加坤 | 淘天集团价格平台开发工程师

业务介绍

淘天价格力团队作为平台价格治理的核心部门,承载着淘宝天猫全域商品价格管理的重要职责。团队掌握着淘内外所有商品的全量价格信息,包括商品原价、券后价等多维度价格数据,每日增量数据规模达亿级以上。

在电商大促上下线时(如618、双11),价格变动频率会呈现数倍增长,这些海量数据不仅体量大,而且具有高时效性、强关联性和复杂变化特征。在大促常态化的现状下,行业运营急需高时效性的数据看板以便及时发现问题,并且需要商品维度、店铺维度等多维圈选能力,及时圈选出符合要求的数据并进行处理或分析。Hologres Dynamic Table完美契合业务需求。

Hologres Dynamic Table介绍

视图是基于表的虚拟表,不存储数据只存储查询逻辑,每次访问时动态执行SQL,返回最新结果,主要帮助我们简化复杂查询。如果没有视图,那么对于以下查询,需要我们自己保存到一个地方,查询时执行完整SQL。

SELECT region, SUM(amount) as total_sales 
FROM orders 
WHERE status = 'completed';

如果有视图,我们可以把查询托管给视图,直接查询视图,可以简化使用。

-- 创建视图
CREATE VIEW sales_summary AS 
SELECT region, SUM(amount) as total_sales 
FROM orders 
WHERE status = 'completed';

-- 查询视图
SELECT * FROM sales_summary;

视图虽然帮我们管理了SQL的定义,但是复杂逻辑SQL的执行通常很耗费时间。将视图的查询结果实际保存下来就是物化视图。物化视图的结果需要定期更新以保证数据新鲜度。所以物化视图就是预定义SQL + 物化结果 + 周期更新

Hologres Dynamic Table与物化视图类似,架构如下,提供全量刷新与增量刷新两种刷新模式。

全量刷新就是在周期到来时进行一次全量刷新覆盖,相当于Insert Overwrite。

增量刷新每次只处理增量数据,原理为在底层创建一个列存state表,存储中间状态(类似Flink state)。增量数据先以微批次方式做内存态聚合,再与state表合并,最后提交时以BulkLoad写入动态表。

在 Hologres V3.1 中 Dynamic Table 的能力如下。
image.png

业务实践

数据圈选

业务背景

价格力团队需要为多个业务场景如商品价格回滚、全网比价等提供灵活的数据圈选能力,要求支持动态的指标组合和筛选条件配置。圈选集创建后,圈选结果也需要随底表数据的变化而变动,不同业务场景可接受的数据变化时间间隔也有所不同。

解决方案

Dynamic Table完美符合场景要求:工程基于不同的筛选规则翻译成相应的DQL,并根据业务场景的需求灵活设置数据新鲜度等配置参数,最终生成完整的Dynamic Table DDL。

指标系统: 指标系统中将表列配置为实体指标。业务指标提供高阶能力如级联指标、聚合、召回计算。

筛选组件: 提供通用筛选配置组件,根据业务场景展示相应指标

业务场景默认配置:Diamond中保存不同业务场景默认配置,包括刷新周期、刷新模式、默认召回条件、默认Join条件等

DDL生成: 将筛选条件与默认条件通过DSL翻译为Hologres Dynamic Table DDL

状态监控: 实现刷新状态检查机制,定期检查动态表刷新状态,区分未完成刷新刷新后无数据两种情况

数据供给:动态表第一次刷新完成后,提供Flink分页查询两种数据供给方式。若选择Flink,在动态表创建完成后会自动根据默认条件创建Flink任务,通常把数据变更作为消息发送给MetaQ。

应用效果

该方案可在秒级亿级数据基表中完成Dynamic Table创建及初次数据刷新,已在价格力团队多个业务场景中部署应用,显著提升了数据圈选的灵活性和效率。


近实时报表构建

业务背景

数据看板的时效性越高,越能帮助运营及时发现问题,快速进行决策和业务调整。价格力团队内部分场景的报表数据原通过ODPS离线调度实现更新,但运营期望能有近实时分钟级数据。

解决方案

数据分层构建: 基于Hologres Dynamic Table实现ODS → DWD → DWS → ADS数据架构的近实时化改造

增量刷新策略: 采用动态表增量刷新机制,设置分钟级刷新间隔,实现近实时数据更新,并分钟级保存历史数据

资源隔离保障: 通过使用Hologres Serverless资源减少与其他任务的资源竞争。

应用效果

应用效果: 成功解决了数据看板的时效性痛点,亿级底表数据,输入RPS 1W的处理时延从小时级降低至分钟级,可以灵活比对任意分钟数据的同比,双十一期间为运营团队提供了及时可靠的数据支撑。

时隔近三年,马斯克再次开源 X 推荐算法

 

刚刚,X 工程团队在 X 上发帖宣布,正式开源 X 推荐算法,据介绍,这个开源库包含为 X 上的“为你推荐”信息流提供支持的核心推荐系统,它将网络内内容(来自用户关注的帐户)与网络外内容(通过基于机器学习的检索发现)相结合,并使用基于 Grok 的 Transformer 模型对所有内容进行排名,也就是说,该算法采用了与 Grok 相同的 Transformer 架构。

 

开源地址:https://x.com/XEng/status/2013471689087086804

 

X 的推荐算法负责生成用户在主界面看到的“为你推荐”(For You Feed)内容。它从两个主要来源获取候选帖子:

 

  1. 你关注的账号(In-Network / Thunder)

  2. 平台上发现的其他帖子(Out-of-Network / Phoenix)

 

这些候选内容随后被统一处理、过滤然后按相关性排序。

 

那么,算法核心架构与运行逻辑是怎样的?

 

算法先从两类来源抓取候选内容:

 

  • 关注内的内容:来自你主动关注的账号发布的帖子。

  • 非关注内容:由系统在整个内容库中检索出的、可能你感兴趣的帖子。

 

这一阶段的目标是“把可能相关的帖子找出来。

 

系统自动去除低质量、重复、违规或不合适的内容。例如:

  • 已屏蔽账号的内容

  • 与用户明确不感兴趣的主题

  • 非法、过时或无效帖子

 

这样确保最终排序时只处理有价值的候选内容。

 

此次开源的算法的核心是系统使用一个 Grok-based Transformer 模型(类似大型语言模型/深度学习网络)对每条候选帖子进行评分。Transformer 模型根据用户的历史行为(点赞、回复、转发、点击等)预测每种行为的概率。最后,将这些行为概率加权组合成一个综合得分,得分越高的帖子越有可能被推荐给用户

 

这一设计把传统手工提取特征的做法基本废除,改用端到端的学习方式预测用户兴趣。

 

 

这不是马斯克第一次开源 X 推荐算法。

 

早在 2023 年 3 月 31 日,正如马斯克收购 Twitter 时承诺的那样,他已将 Twitter 部分源代码正式开源,其中包括在用户时间线中推荐推文的算法。开源当天,该项目在 GitHub 已收获 10k+ 颗 Star。

 

当时,马斯克在 Twitter 上表示此次发布的是“大部分推荐算法”,其余的算法也将陆续开放。他还提到,希望“独立的第三方能够以合理的准确性确定 Twitter 可能向用户展示的内容”。

 

在关于算法发布的 Space 讨论中,他说此次开源计划是想让 Twitter 成为“互联网上最透明的系统”,并让它像最知名也最成功的开源项目 Linux 一样健壮。“总体目标,就是让继续支持 Twitter 的用户们最大程度享受这里。”

如今距离马斯克初次开源 X 算法,过去了近三年的时间。而作为技术圈的超级 KOL,马斯克早已为此次开源做足了的宣传。

 

1 月 11 日,马斯克在 X 上发帖称,将于 7 天内将新的 X 算法(包括用于确定向用户推荐哪些自然搜索内容和广告内容的所有代码)开源。

 

此流程将每 4 周重复一次,并附有详细的开发者说明,以帮助用户了解发生了哪些变化。

 

今天,他的承诺再次兑现了。

马斯克为什么要开源?

 

当埃隆·马斯克再次提到“开源”时,外界的第一反应并非技术理想主义,而是现实压力。

 

过去一年里,X 因其内容分发机制屡次陷入争议。该平台被广泛批评在算法层面偏袒和助长右翼观点,这种倾向并非零星个案,而被认为具有系统性特征。去年发布的一份研究报告就指出,X 的推荐系统在政治内容传播上出现了明显的新偏见。

 

与此同时,一些极端案例进一步放大了外界的质疑。去年,一段涉及美国右翼活动人士查理·柯克遇刺的未经审查视频在 X 平台迅速传播,引发舆论震动。批评者认为,这不仅暴露了平台审核机制的失效,也再次凸显了算法在“放大什么、不放大什么”上的隐性权力

 

在这样的背景下,马斯克突然强调算法透明性,很难被简单解读为一次纯粹的技术决策。

 

 

网友怎么看?

 

X 推荐算法开源后,在 X 平台,有用户对推荐算法机制做了以下 5 点总结:

 

1. 回复你的评论。算法对“回复+作者回应”的权重是点赞的 75 倍。不回复评论会严重影响曝光率。

2. 链接会降低曝光率。应该把链接放在个人简介或置顶帖里,千万不要放在帖子正文中。

3. 观看时长至关重要。如果他们滑动屏幕略过,你就不会吸引他们。视频/帖子之所以能获得高关注,是因为它们能让用户停下来。

4. 坚守你的领域。“模拟集群”是真实存在的。如果你偏离了你的细分领域(加密货币、科技等),你将无法获得任何分销渠道。

5. 屏蔽/默不作声会大幅降低你的分数。要有争议性,但不要令人讨厌。

 

简而言之:与你的受众沟通,建立关系,让用户留在应用内。其实很简单。

 

也有网友发现,虽然架构是开源的,但还有些内容仍未开源。该网友表示,此次发布本质上是一个框架,没有引擎。具体少了啥?

 

  • 缺少权重参数 - 代码确认“积极行为加分”和“消极行为扣分”,但与 2023 年版本不同的是,具体的数值被删除了。

  • 隐藏模型权重 - 不包含模型本身的内部参数和计算。

  • 未公开的训练数据 - 对于训练模型的数据、用户行为的采样方式,以及如何构建“好”样本与“坏”样本,我们一无所知。

 

对于普通 X 用户而言,X 的算法开源并不会造成太大影响。但更高的透明度可以解释为什么有些帖子能获得曝光而另一些则无人问津,并使研究人员能够研究平台如何对内容进行排名。 

为什么推荐系统是必争之地?

 

在大多数技术讨论中,推荐系统往往被视为后台工程的一部分,低调、复杂,却很少站在聚光灯下。但如果真正拆解互联网巨头的商业运转方式,会发现推荐系统并不是边缘模块,而是支撑整个商业模式的“基础设施级存在”。正因如此,它可以被称为互联网行业的“沉默巨兽”。

 

公开数据已经反复印证了这一点。亚马逊曾披露,其平台约 35% 的购买行为直接来自推荐系统;Netflix 更为激进,约 80% 的观看时长由推荐算法驱动;YouTube 的情况同样类似,大约 70% 的观看来自推荐系统,尤其是信息流(feed)。至于 Meta,虽然从未给出明确比例,但其技术团队曾提到,公司内部计算集群中约 80% 的算力周期都用于服务推荐相关任务。

 

这些数字意味着什么?如果将推荐系统从这些产品中移除,几乎等同于抽掉地基。就拿 Meta 来说,广告投放、用户停留时长、商业转化,几乎都建立在推荐系统之上。推荐系统不仅决定用户“看什么”,更直接决定平台“如何赚钱”。

 

然而,正是这样一个决定生死的系统,长期面临着工程复杂度极高的问题。

 

在传统推荐系统架构中,很难用一个统一模型覆盖所有场景。现实中的生产系统往往高度碎片化。以 Meta、LinkedIn、Netflix 这类公司为例,一个完整的推荐链路背后,通常同时运行着 30 个甚至更多专用模型:召回模型、粗排模型、精排模型、重排模型,各自针对不同目标函数和业务指标进行优化。每个模型背后,往往对应一个甚至多个团队,负责特征工程、训练、调参、上线与持续迭代。

 

这种模式的代价是显而易见的:工程复杂、维护成本高、跨任务协同困难。一旦有人提出“是否可以用一个模型解决多个推荐问题”,对整个系统而言,意味着复杂度的数量级下降。这正是行业长期渴望却难以实现的目标。

 

大型语言模型的出现,给推荐系统提供了一条新的可能路径。

 

LLM 已经在实践中证明,它可以成为极其强大的通用模型:在不同任务之间迁移能力强,随着数据规模和算力的扩展,性能还能持续提升。相比之下,传统推荐模型往往是“任务定制型”的,很难在多个场景之间共享能力。

 

更重要的是,单一大模型带来的不仅是工程简化,还包括“交叉学习”的潜力。当同一个模型同时处理多个推荐任务时,不同任务之间的信号可以相互补充,随着数据规模增长,模型更容易整体进化。这正是推荐系统长期渴望、却很难通过传统方式实现的特性。

 

LLM 改变了什么?其实是改变了从特征工程到理解能力。

 

从方法论层面看,LLM 对推荐系统最大的改变,发生在“特征工程”这一核心环节。

 

在传统推荐系统中,工程师需要先人为构造大量信号:用户点击历史、停留时长、相似用户偏好、内容标签等,然后明确告诉模型“请基于这些特征做判断”。模型本身并不理解这些信号的语义,只是在数值空间中学习映射关系。

 

而引入语言模型后,这一流程被高度抽象。你不再需要逐条指定“看这个信号、忽略那个信号”,而是可以直接向模型描述问题本身:这是一个用户,这是一个内容;这个用户过去喜欢过类似内容,其他用户也对这个内容有正反馈——现在请判断,这条内容是否应该推荐给这个用户。

 

语言模型本身已经具备理解能力,它可以自行判断哪些信息是重要信号,如何综合这些信号做出决策。在某种意义上,它不只是执行推荐规则,而是在“理解推荐这件事”。

 

这种能力的来源,在于 LLM 在训练阶段接触过海量、多样化的数据,使其更容易捕捉细微但重要的模式。相比之下,传统推荐系统必须依赖工程师显式枚举这些模式,一旦遗漏,模型就无法感知。

 

从后端视角看,这种变化并不陌生。就像你向 GPT 提问,它会基于上下文信息生成回答;同样地,当你问它“我是否会对这条内容感兴趣”,它也可以基于已有信息做出判断。某种程度上,语言模型本身已经天然具备“推荐”的能力。

专家解读:工业界可参考,对学术价值不大

 

如果 X 的方向真是“让 Grok 成为算法本身”,那么这次开源事件的意义就不止是透明度提升,更像是把一场大模型化推荐的系统级改造公开摆到台前,接受开发者与行业的持续检视与解读。

 

借此机会,我们邀请到了搜推广资深算法专家,生成式推荐模型 OnePiece 作者,《业务驱动的推荐系统:方法与实践》作者傅聪,为大家解读这次开源事件。

 

InfoQ:从代码层面看,X 这套推荐系统中,大模型是否是已经进入核心决策环节?这与传统“LLM + 规则 / 特征管道”的推荐系统相比,最大的结构性变化是什么?是否只是替换了部分模块?

 

傅聪:从系统整体设计层面看,开源的代码依然遵从 recall -> rank 这样的多阶段漏斗筛选架构。新的 post 推送会从数亿 候选集合中 以传统的 双塔 向量召回,合并排序、去重等等环节,最后送给用户。grok 没有参与中间过程,只是给 post 做排序的模型采用了类似 grok 的模型架构,但远小于 grok 的参数量。

 

最大的结构变化在于他们用了一种纯 transformer(类 grok)的模型结构去做排序,其它差异不大。

 

InfoQ:从能力边界看,该如何看待“每日处理上亿条内容、并进行实时多模态理解”这一目标所带来的系统挑战?

 

傅聪:需要极其充足的 GPU 算力以及高并发的处理引擎,尤其是视频内容,其 token 消耗量巨大,因此计算量巨大。此外,模型还需要一个可以高速访问的大型文件系统,保证大量视频可以暂存、传递给 Grok 模型。而实际上 x 并没有真的让 grok 来做这个事情,应该是处于成本考虑。

 

InfoQ:传统推荐系统采用轻量级启发式算法,成本效益高,而 Grok 方法需要大量计算资源,那么您怎么看待成本和用户体验提升之间的收益比?在算力、成本和基础设施约束下,这种方式是否注定只属于极少数平台?

 

傅聪:Grok 消耗的算力是数千倍于传统的推荐系统的,这部分成本往往不能被平台的收益覆盖。尤其是 X 这样的平台,其收入核心来源是广告。只有做到延迟、体验都能对标原有系统,其广告收入才可以持平。但因为投入成本过高,这个 ROI 过低,目前来看只 X 自己也没有真的以这种规模使用 grok。

 

InfoQ:如果 Grok 真要“把帖子都读一遍、把视频都看一遍”再来做匹配,这是不是相当于把推荐系统推到了更强的“内容级监控”?平台不只是记你点过什么,还能在语义层面猜到你可能会被什么吸引,是否会带来新的以前没有的问题?

 

傅聪:Grok 读过并不一定会记忆。很多数据并不一定会被 Grok 用来训练

 

InfoQ:另外,传统推荐系统的信息茧房问题,语义理解方式是否能解决?是否更“中立”?(此前的争议有一部分在于认为 X 平台偏向马斯克个人账号和一些党派言论)。从系统机制上看,它最可能在哪些环节反而更容易固化偏好、放大偏差?

 

傅聪:大语言模型有它自己的 bias,以大语言模型为核心的推荐系统会根据它的语言偏好构建新的信息茧房。

 

InfoQ:从开源意义看,在推荐系统这种高度复杂、长期被视为“黑箱”的领域,这种“持续、周期性开源”代码的方式,实现起来的难度在哪里?

 

傅聪:难度在于只开源代码,不开源所有配套的系统和训练数据,就无法复现它的效果。这种开源,对学术研究价值不大,对工业交流有一定参考意义。但目前其架构来看,可参考的新东西不多。

 

InfoQ:您如何看待这次开源的影响?如果 Grok 这套思路跑通,这次开源是否会迫使其他内容平台跟进,从而引发推荐系统的一轮“范式迁移”?在这种趋势下,行业会不会弱化对行为数据(包括历史数据)的依赖,甚至调整数据收集与画像方式,进而重塑整个推荐系统生态?对广告行为的影响会是什么样的?

 

傅聪:即使 Grok 跑通,其它平台也不一定会跟进。第一其他平台没有属于自己的 Grok,第二,其它大部分平台不会在这里投入这么多算力。

 

行业也不会弱化对用户行为和画像的依赖,经验证明,用户历史行为才是实现个性化的数据根基,缺少这部分信息输入的推荐系统很难千人千面,而容易做成千篇一律。从开源代码看,ranking 模型依然在使用用户行为历史进行预测,这一点也符合预期。

 

嘉宾简介:

 

傅聪,搜推广资深算法专家、生成式推荐模型 OnePiece 作者,《业务驱动的推荐系统:方法与实践》作者,《生成式推荐系统算法与实践》作者。

 

参考链接:

https://github.com/xai-org/x-algorithm

https://x.com/XEng/status/2013471689087086804

https://x.com/BlockFlow_News/status/2013510113873813781

2026 势不可挡!融云开年便在产业、技术与生态多维度收获多重认可。

前沿科技媒体的专业背书、开发者社区的口碑选择、全球生态伙伴的战略肯定,共同印证了融云的智能通信云服务已获得产业界、开发者与商业生态的全面肯定。

行业媒体 | 2025 年度灯塔产品榜
图片

领先科技媒体“雷科技”发布 2025 年度灯塔产品榜,融云对话 Agent 登上“年度杰出产品榜单”。

该榜单自 2017 年创办以来,始终坚持“专业编辑提报+千万粉丝投票”的评选制度,致力于记录时代创新。本次评选涵盖消费电子、家电、汽车出行及 AI 等四大领域,融云对话 Agent 与 Google、Kimi、快手、百度等科技大厂产品共同入选 AI 领域榜单。

开发者社区 | 年度科技创新突破奖

图片

在硬核技术开发者聚集的领域,融云也赢得了关键认可。近日,国内领先的大数据与人工智能开发者社区 DataFun 揭晓“星空奖”年度榜单,融云对话 Agent 获评“年度科技创新突破奖”。

作为行业权威的技术社区,DataFun 设置该榜单旨在表彰具备实质性突破与行业影响力的工程实践。融云此次获奖,核心在于其对话 Agent 实现了从技术到场景的工程化创新落地:通过深度意图识别能力,将 AI 对话转化为可触发业务逻辑、联动外部系统的自动化任务闭环。目前,这一方案已在社交、电商等场景中高效应用,实现了从技术创新到产业价值的转化。

数字商业生态 | 最具行业影响力品牌

图片

在更广阔的商业生态维度中,融云同样展现了深远的品牌影响力,获评 360 智慧商业颁发的“2025 年最具行业影响力品牌”。该奖项重点关注品牌在所属行业内推动进步、建立标准及引领方向的能力。

融云此次入选,标志着其“全球智能通信云”的专业地位以及“通信+AI”的战略布局,获得了数字商业生态的广泛认同。

全球化生态 | 智创未来领军人物

图片

在全球化生态协作维度,融云 CEO 董晗获评数美科技“星辰奖·智创未来领军人物”。“星辰奖”旨在表彰在 AI 浪潮中通过技术创新驱动行业变革的领航者。
融云此次获评,彰显了融云与全球化生态伙伴在技术互补与商业共建方面的深度互信,折射出共同推进全球数字化转型的生态力量。
秉持“赋能千行百业智能化升级”的初衷,融云致力于打造全球化的智能通信云底座。我们正将硬核的技术能力转化为驱动商业模式重塑的工程化力量,协助开发者高效构建智能互动能力,将技术创新转化为实际的业务增长与运营效率。

近年来,随着AI大模型、传感器技术和机器人硬件的进步,具身智能(Embodied AI)逐步从理论探索迈向实际部署。2025年后,行业进入“生态构建”关键期,企业与政府开始联合推进标准化、平台化和开放化发展 。2026年被视为具身智能实现多场景渗透与产业闭环验证的重要节点。OpenAtom openKylin(简称“openKylin”)社区作为以技术创新为目标的根社区也已经着眼布局此领域。

在 Community SIG 的协调组织下,openKylin 社区 ROS SIG、OpenLoong SIG、RISC-V SIG、Release SIG 四大 SIG 凝心聚力、分工协作,正式启动 RISC-V 架构具身智能人形机器人适配计划,此次计划填补了社区在具身智能人行机器人领域的生态空白。
联合SIG工作计划
01openKylin适配运行
在2026年2月上旬,基于openKylin桌面版本完成ros2 jazzy core/base/desktop 在超睿物理硬件平台上的可运行验证。确保核心包可以正常安装卸载,模拟程序(如 turtlesim)可以正常运行。
02测试验证ROS软件包
在2026年3月中旬,开始基于机器人真机和openKylin系统测试验证 ROS 软件包。并在3月下旬基于人形机器人进行功能演示。
03贡献ROS代码和补丁
完成所有功能测试和演示后按照社区规范向 openKylin 社区贡献 ROS相关代码和补丁。目前该计划聚集上海苦芽科技有限公司、先进计算与关键软件海河实验室、麒麟软件有限公司、OpenLoong社区、超睿科技(上海)有限公司。

openKylin社区也欢迎更多对此计划感兴趣的组织加入,共同推动RISC-V架构具身智能人形机器人的生态繁荣!

近日,OpenAI 在其官方网站及官方社交媒体公告中表示,公司计划在“未来几周内”开始在 ChatGPT 对话界面中测试广告投放,这些广告将首先面向美国地区的免费版用户以及新推出的低价订阅层级“ChatGPT Go”用户。

 

广告内容的展示形式预计主要是在 ChatGPT 生成的回答底部以清晰标注的独立模块形式出现,与 AI 生成内容严格区分。

OpenAI 强调,广告不会影响 ChatGPT 的回答逻辑,也不会向广告商分享用户对话内容。付费订阅用户(如 Plus、Pro、Business 及 Enterprise 层级)仍将享受无广告体验。

 

据官方发布内容及多家外媒消息,OpenAI 此举是为了进一步拓展营收来源,以缓解高昂的研发与基础设施支出压力,同时扩大服务的可持续性。

 

公司管理层表示,即便公司业务规模庞大,依靠订阅收入仍难覆盖巨额算力成本,而广告收入是补充营收的一种必要尝试。OpenAI 同时承诺,广告不会改变 AI 应答过程,并且将在敏感话题如健康、政治等领域避免投放广告。

 

OpenAI 此举引发了社区热议,但批评声音居多。

 

在 Hacker News 上,有用户表示,由于他们加了广告,很多用户已经转向了 Gemini,所以长远来看这种行为是得不偿失。

 

“OpenAI 广告的一个问题是,用户已经开始转向 Gemeni,而 Gemeni 并不投放广告。

 

ChatGPT 大多数情况下也比 Gemeni 差(或许如此),而且没有像 Gemeni 那样严格的速率限制。因此,他们已经开始流失用户,并且产品体验也比竞争对手更糟糕。

 

OpenAI 当然能从广告中赚到一些钱,但这能弥补他们巨额的亏损吗?我觉得不太可能。他们真的需要像微软那样,被一位财力雄厚的“金主”收购,才能玩转这种游戏。”

 

还有用户表示即使他们加入了广告,也不会向谷歌和 Facebook 那样赚大钱,只是赚一些小钱罢了。该用户评价道:

 

“就我所了解的广告市场而言,像谷歌和 Facebook 这样的公司之所以能赚得盆满钵满,主要是因为它们在广告市场的垂直整合中占据了绝对优势。而 OpenAI 整合广告的方式在我看来,似乎只是想分得蛋糕里最小的一块——一个投放广告的地方——这意味着,我估计他们的用户收入更接近于报纸网站,而不是最大的社交媒体网站,或者更接近于推特或 Tumblr 这类从未实现过巨额盈利的公司。”

 

明知加广告会被骂,OpenAI 为什么还要这么做?那就要从 OpenAI 的财务状况说起。 

营收增长 10 倍,但算力投入扩大 9.5 倍

 

OpenAI 的财务状况与算力投入呈现出高度协同的增长态势,过去三年,二者均实现了累计十倍左右的扩张,印证了“算力决定营收上限”的核心逻辑。这种强关联不仅是业务发展的结果,更成为 OpenAI 规划未来投入、平衡供需关系的重要依据。

 

在 OpenAI 最新一期博客中,公司首席财务官 Sarah Friar 透露了 OpenAI 的财务细节。

 

从算力投入来看,OpenAI 的扩张速度堪称惊人。

 

  • 2023 年,其算力规模为 0.2 吉瓦(GW);

  • 2024 年,迅速提升至 0.6 吉瓦;

  • 2025 年,进一步增至约 1.9 吉瓦,三年累计扩大约 9.5 倍。

 

为保障未来算力供应,Sarah Friar 称 OpenAI 已与微软、英伟达、AMD、甲骨文等企业签署数千亿美元的合作协议,同时从单一供应商转向多云、多芯片的多元化布局,在高端训练任务中采用最新硬件,在大规模推理场景中使用低成本基础设施,平衡效率与开支。

 

值得注意的是,算力投入存在显著的时间差,当前的投入需提前规划至 2028~2030 年的需求,这也意味着 OpenAI 需要稳定的长期收入来覆盖前置成本。

 

营收方面,OpenAI 同步实现了三倍速年度增长,与算力扩张节奏高度匹配。

 

2023 年,其收入达到 20 亿美元,2024 年增至 60 亿美元,2025 年预计突破 200 亿美元,三年累计增长约十倍。

 

这种增长并非依赖单一业务,而是构建了多元化的收入结构:一是订阅收入,涵盖个人用户的 ChatGPT Go、Plus、Pro 档位及企业订阅服务,满足不同层级用户需求;二是 API 服务收入,为开发者和企业提供模型调用能力,支出与交付成果直接挂钩;三是广告与电商收入,依托免费用户流量开辟新增长曲线;未来还将探索授权许可、知识产权合作、结果导向定价等模式,进一步丰富收入来源。

 

从运营效率看,OpenAI 的算力投入与营收的强相关性,验证了其商业模式的可行性。但当前仍面临算力缺口的核心挑战——由于算力不足,诸多潜在产品与功能无法落地,尚未充分释放价格弹性杠杆

 

这也解释了为何 OpenAI 持续加码算力投资,同时通过广告等业务拓宽收入渠道,本质上是为了打破算力瓶颈,释放更多商业价值。

加入广告,也会坚守三大原则

 

从成本端看,算力是 OpenAI 发展的核心命脉,且需求近乎无限。但 Sarah Friar 在博客中表示,即便在模型中加入广告,也会“死守”三大底线。他表示:

 

“大家普遍会疑惑,广告会对产品本身和公司运营产生怎样的影响?要回答这个问题,我们可以从当前的用户结构说起:如今,我们消费端平台上 95% 的用户都在使用免费版本。这恰恰契合了我们的使命 —— 研发通用人工智能是为了造福全人类,而非仅仅服务于有能力付费的群体。因此,保障用户的访问权至关重要。

 

从广告业务的角度出发,我认为有三点原则必须坚守。第一,我们要让所有人都清楚:模型给出的永远是它能提供的最佳答案,而非付费推广的结果。很多其他平台正是在这一点上栽了跟头,导致用户无法判断看到的内容是付费广告还是真实的最优推荐。而我们的核心准则就是,模型始终以提供最优答案为导向。

 

第二,广告本身可以具备很高的实用价值我们会明确标注广告内容,让用户一目了然。举个例子,如果用户搜索 “圣地亚哥周末短途旅行”,那么一条爱彼迎的广告可能会非常有帮助。用户甚至可能愿意在 ChatGPT 的对话场景中,与广告商展开深度交流 —— 前提是他们清楚这是广告环节。这正是我们需要创新的方向,要打造出与平台生态深度融合的广告形式,而非简单地把传统的横幅广告生搬硬套过来。

 

第三,也是最后一点,我们必须保留无广告的服务层级,让用户拥有选择权和控制权。同时,我们对用户数据的保护始终保持高度谨慎。此前推出医疗健康功能时,我们就明确告知用户,相关数据会被隔离存储,不会用于模型训练。信任是 OpenAI 的立足之本,即便在广告业务上,我们也会坚守这些原则。”

 

Sarah Friar 还表示,其实不只是 OpenAI,未来,消费者很可能会订阅多款人工智能服务,就像现在大多数人都会订阅不止一个流媒体平台一样,这一消费行为模式可以作为很好的参考。不同的人会根据自身需求做出不同选择,包括免费选项 —— 毕竟也有广告支持的免费流媒体服务。

 

而且即便是同一项服务,也会同时提供付费版和免费版两种选择,未来的市场格局会呈现出丰富的多样性。不过,用户切换不同平台时也会面临一个问题 —— 迁移成本。

 

Sarah Friar 还表示模型的记忆功能也是值得探讨的问题。他还进一步表示 OpenAI 不会垄断整个市场:

 

“未来的模型是会实现跨平台统一记忆,还是会分平台独立记忆?其实即便是基于同一个模型,不同服务商也会推出各具特色的服务,在功能取舍上各有侧重。哪怕是依托 OpenAI 模型的服务,也有很多不同的开发者在提供差异化产品,这也是我所理解的 ‘多平台使用’ 的含义。当然,我并不认为 OpenAI 会垄断整个市场。”

 

为维持算力与营收的同步增长,OpenAI 需要持续投入数千亿美元用于基础设施建设与合作伙伴拓展,而单一的订阅制模式难以支撑如此庞大的资金需求。

 

广告业务的引入,能够借助免费用户的流量规模,开辟新的收入来源,为算力投入提供稳定的资金补充,形成“算力支撑业务、业务反哺算力”的循环。

 

此外,广告业务的布局也与 OpenAI 的长期战略相契合。在 ChatGPT 月活用户突破 8 亿且仍有巨大增长空间的背景下,广告成为连接免费用户与商业价值的桥梁。

 

据业内消息,OpenAI 预计 2026 年通过广告获得数十亿美元级收入,未来将逐步放大这一收入来源,与订阅、API 服务等形成互补,降低单一模式的经营风险。

OpenAI 缺钱了?

 

既有巨额的算力成本支出,又有逐年翻倍的营收进账,那 OpenAI 到底是不是真的缺钱了?

 

近日,《纽约时报》的一位专栏作家却做出了一个明确的预测:OpenAI 将在 18 个月内因其在人工智能领域的投入而破产。

 

该作家表示,根据去年的一份外部报告,OpenAI 预计在 2025 年将烧掉 80 亿美元,到 2028 年将烧掉 400 亿美元。鉴于该公司据报道预计到 2030 年实现盈利,不难计算出其中的利害关系。

 

Altman 的风险投资计划在数据中心领域投入 1.4万亿 美元。正如外交关系委员会经济学家 Mallaby 所指出的,即便 OpenAI 重新考虑那些受盲目乐观影响的承诺,并“用其估值过高的股票为其他投资买单”,仍然存在巨大的资金缺口。

 

Mallaby 并非唯一持此观点的人,贝恩公司去年发布的报告显示,即便在最乐观的预期下,该行业也至少存在 8000 亿美元的资金缺口。

 

这位金融专家巧妙地分析了这种情况,他概括地指出,问题的关键不在于终端用户人工智能是否会在技术上得到普及,而在于开发人工智能在中长期内是否具有经济意义。

 

分析师指出,理论上,投资者应该“弥合一项伟大技术出现与最终盈利之间的差距”,但实际上,许多人工智能公司烧钱的速度似乎远远超过了其盈利能力。Mallaby 指出,鉴于微软或 Meta 等“传统”公司在人工智能出现之前就已经拥有盈利业务,并且(实际上)有能力等待必要的时期,直到人工智能最终带来收益,因此,这些新来者的处境比它们要糟糕得多

 

据他所说,大多数人都在使用免费服务,一旦他们常用的 AI 模型添加了广告或使用限制,他们就会毫不犹豫地转向竞争对手。目前各种任务都有无数的选择,也证实了这一点。

 

不过,他认为这对人工智能提供商来说只是暂时的难题,随着智能人工智能越来越深入人们的日常生活,转换将会变得更加困难,因为 AI 模型最终应该能够掌握你所有的购物偏好、愿望和情感特征——甚至可能比你本人做得更好。

 

Mallaby 确实赞扬了 OpenAI 首席执行官 Sam Altman 的“吸金能力”,他成功筹集了 400 亿美元的投资,超过了历史上任何一轮私募融资的规模——甚至超过了沙特阿美 300 亿美元的融资额。不同之处在于,沙特阿美和其他一些上市企业拥有成熟的商业模式和盈利能力,而 OpenAI 目前这两点都不具备。

 

人工智能金融这条衔尾蛇看起来确实像是要吞噬自己的尾巴,但也有人认为它只会失去较新的部分。如果人工智能市场失去一个或多个开创者,那将颇具讽刺意味。

参考链接:

https://www.tomshardware.com/tech-industry/big-tech/openai-could-reportedly-run-out-of-cash-by-mid-2027-nyt-analyst-paints-grim-picture-after-examining-companys-finances

https://news.ycombinator.com/item?id=46663341

OpenCode + SVG:一套省心可控的 AI PPT 生成方案

前两天接到个活儿,要做个项目方案演示 PPT。

打开 PowerPoint 的那一刻,我盯着空白页面发了五分钟呆。

说实话,作为一个产品,PPT 能力属实一般 —— 内容我能写,但怎么让它好看有重点一眼能抓住人 ,这事儿我真不太行。

正好最近 OpenCode 特别火,号称是 Claude Code 的平替。最关键的是,它支持接入 GitHub Copilot 作为模型能力。

巧了,公司正好给订阅了 Copilot 企业版

也就是说,我现在直接实现了 API 自由 —— 装个 OpenCode,切到 Copilot,然后猛猛造就完事儿了。

于是就有了这篇:用 OpenCode 无痛生成可编辑 PPT 的完整流程


预期管理

先说清楚,咱们今天分享的这套方案,主打三个字:

  • 简单实用 (不需要 mcp、skills)
  • 复用性强 (掌握方法后可在多种 PPT 场景下使用)
  • 可控性高 (支持持续性的调整和二次修改)

最关键的是 —— 输出的内容可以在 PPT 里二次编辑 ,不像 NotebookLM 那种,生成出来是张图片,改都没法改。

但有一点要提前说:这次主打实用,美观性这种主观因素先不深究。不过可以保证,出来的效果直接拿去用是没问题的。

还有,我下面描述的操作流程更多是提供一种思路 ,很多步骤不是固定的,也没有所谓「一键出成果」的操作。希望大伙儿按这个思路多试试,换不同风格玩玩看。


省流总结

凡是需要把复杂信息结构化呈现、用图形辅助理解的场景,都很契合这套流程。

熟悉 Vibe Coding 的小伙伴,看完这个流程估计不用看细节就能直接上手了:

  1. 安装 OpenCode
  2. 安装官方插件 oh-my-opencode
  3. 创建项目文件夹,准备好 PPT 文稿内容
  4. 用 OpenCode 打开项目文件夹,切换到 Plan 模式,输入 ulw 进入 Ultrawork 模式
  5. 输入下文准备好的 Prompt,选择 PPT 风格,输出为 SVG 格式
  6. 在 PPT 中导入 SVG 文件,点击「转换为形状」
  7. 微调一下文本排列和字号,搞定!

效果展示

正好这两天国外 X 上有位大佬发了篇长文特别火:「如何在一天内彻底修复你的人生」,我就拿这篇文章来做流程演示。

这是从一篇 4000 字的长文,到一套可编辑的 PPT 录屏效果。

全程用 OpenCode 生成,导入后可以直接在 PPT 里改,先瞅瞅看效果如何

原文链接:https://x.com/thedankoe/status/2010751592346030461?s=20

如何在一天内彻底修复你的人生.pdf
想上传视频的,没找到咋搞,大伙儿打开 PDF 看看也行。

前期准备

1. 安装 OpenCode

打开官网,安装指引很详细。支持三种方式:终端、客户端、IDE 插件。

个人推荐直接选客户端 —— 方便查看历史记录,使用门槛也低。

官方安装链接:OpenCode | Download


2. 添加模型提供商

安装完成后,打开终端输入以下命令,选择 Agent 执行任务时用哪个模型提供商:

opencode auth login

我这里直接选了 GitHub Copilot。

没有提前准备 API 也没关系 —— 官方很贴心地内置了几个免费模型,终端里选第一项,或者客户端里选置顶的几个大模型,就能直接免费用。

备注:以下所有效果均通过 GitHub Copilot 的 Claude Opus 4.5 模型生成。



3. 安装 oh-my-opencode 插件

这一步很关键。

oh-my-opencode 是官方插件,一个强大的 OpenCode 扩展集合。简单说,开启后会进入火力全开模式 ,自动根据任务情况安排最合适的工作 Agent。

安装很简单,直接在对话框输入:

"Install and configure by following the instructions here https://raw.githubusercontent.com/code-yeongyu/oh-my-opencode/refs/heads/master/README.md" 

参考文档:🔥 Oh My OpenCode (Oh My OpenCode) - OpenCode 中文文档


4. 准备项目文件

新建一个文件夹作为项目文件夹,把 PPT 文稿内容存成 .md 格式放进去,然后用 OpenCode 客户端打开这个文件夹。

到这里,所有前置准备就完成了。接下来进入 PPT 生成的具体步骤

PPT 生成操作流程

1. 进入 Ultrawork 模式

打开项目文件后,在输入框直接输入 ulw,让 OpenCode 进入「燃起来」的 Ultrawork 模式

输入后,会先告知该模式的一些事项和规则。官方给出了详细的 Prompt,最下方也有使用场景说明:

  • 探索代理(背景)— 代码库结构、文件模式、内部实现
  • 图书管理员代理(背景)— 外部文档、API 参考、开源示例
  • 计划代理 — 详细工作分解和策略
  • 数据库代理 — 架构决策、代码审查、高智商推理
  • 前端 UI/UX 工程师 — 视觉设计和实现
  • 文档编写者 — 技术文档


2. 分析 PPT 内容

接着,把工作模式切换成 Planner-Sisyphus—— 这是 OpenCode 的计划只读模式 ,专门用于自我演进、迭代优化和处理高复杂度任务的规划模式。

然后通过 @ 符号引用 PPT 文案的 md 文件,在输入框输入:

请作为一名资深 PPT 设计师,帮我处理这份文档: 

1. **拆解**:提炼文档精华,产出结构化的 PPT 页面清单(包含页数、内容、重点)。 

2. **渲染**:利用 SVG 矢量代码输出每一页的视觉雏形。要求:图文分离、层级分明,代码需兼容 PPT 的"转换为形状"功能,以便我进行后期可编辑式的二次调整。  

基于这些诉求,给出方案。

这一步其实不需要什么精妙的提示词。项目初期,每次对话更多是想法碰撞和方案定位 ,不是一开始就用提示词框死大模型的想象空间。

直接在 Plan 模式下抛出核心诉求:一是 拆解,二是 渲染。然后让大模型输出方案,根据提示不断调整方向,最终达到效果即可。

只要能出满意的效果,那这个提示词就是合理且有效的。

按这个思路,大模型输出的方案大概率包括:

  • 拆解后每页 PPT 的内容(标题、内容、重点…)
  • PPT 输出模式确认(分页生成 / 全部生成)
  • 设计规范确认(尺寸、配色、字体、风格…)
  • SVG 输出格式要求(代码规范、组件规范…)

如果觉得拆解不合适,可以在 Planner 模式下持续对话,不断提要求,直到满意为止。


3. PPT 风格确认

这一步,建议只给定 尺寸要求、配色要求、主题色要求,剩下的布局排列和组件样式,推荐先让大模型自由发挥 —— 体验一下抽盲盒的快乐。

可以参考我的输入试试,这里的配色是直接从公司 PPT 模板里扣的,大伙儿可以替换成自己的要求:

尺寸要求:16:9
主题风格:浅色风格
配色要求:
| 颜色用途 | RGB 值 | 说明 |
|---------|--------|------|
| 主色 | `rgb(1,107,255)` | 品牌蓝 |
| 次色 | `rgb(86,91,255)` | 紫蓝 |
| 辅助色 | `rgb(46,204,247)` | 青蓝 |
| 背景色 | `rgb(246,246,246)` | 浅灰 |
| 文字色 | `rgb(0,0,0)` | 黑色 |

先让大模型输出前三页看看效果。下面是第二、三页的效果 —— 会发现实在太寡淡、太平面化了,不是不能用,就是一眼看上去没有记忆点。

这时我想到:好的 PPT 绝不是套用模板,而是要根据内容进行「适配性设计」,才能真正突出重点、制造记忆点。

既然如此,能不能让大模型先理解文本,由它来构思最契合的风格和布局方案?

于是直接输入了一个简单的要求:

基于这篇文章的内容,和品牌配色,还可以有怎样的风格和布局推荐?

结果很 amazing!

OpenCode 内置的 Agent 能力非常强大 —— 不仅分析出这篇文章的主题与「成长」「身份重塑」「行为心理学」「自我发展」等关键词相关,还会根据这些关键词在网上搜索相关的 PPT 设计方案,最终给出一个非常详细的每页风格推荐。

根据新的设计方案,第三页推荐使用「冰山隐喻」风格,效果如下 —— 确实比第一版好太多了!

接着,只需要根据设计方案,对剩下的页面做批量生成即可。


4. PPT 内容编辑

SVG 批量生成后,难免有些文本内容或布局效果不符合预期。怎么办?

最简单的办法:直接在对话框描述问题,还可以通过 辅助说明需要调整的地方。

如果只是文本内容的问题,也可以用 VSCode 打开 SVG 文件,直接手动改。


5. PPT 文件导入

最后一步。

检查所有 SVG 效果图都满足要求后,把 SVG 文件导入 PPT,点击「转换为形状」,就能把 SVG 一键转成 PPT 支持的组件样式,对所有元素进行编辑和调整。

这样再也不用担心大模型生成的 PPT 是一次性的 —— 上下文丢了,都不知道怎么改。

具体的导入和转化操作可以参考我往期的内容:

实际操作中,转化后的效果还是会遇到不少问题:字号错乱、布局偏移、组件变形…

这里简单总结了一些优化方案,只需要在输出 SVG 前,把要求全部告知大模型即可:

1️⃣ **圆角矩形优化**:使用 `<path>` + 贝塞尔曲线 `C` 命令绘制,避免 `<rect rx="24">` 在 PPT 中丢失圆角

2️⃣ **字体优化**:Windows 字体优先排列 `Microsoft YaHei, SimHei, PingFang SC, sans-serif`,避免 PingFang SC 在 Windows 上不存在导致布局变化

3️⃣ **文字定位优化**:使用 `style` 属性整合样式,手动计算居中位置,避免 `text-anchor``dominant-baseline` 属性支持不完善

4️⃣ **颜色格式优化**:使用 `#RRGGBB` + `fill-opacity` 分离透明度,避免 `rgba()` 和带透明度的十六进制颜色支持不佳

5️⃣ **阴影效果**:移除 `filter="drop-shadow(...)"` 属性,在 PPT 中转换后手动添加阴影

后续优化

这一套操作下来,熟悉大模型的伙伴可能会觉得:就这?连 MCP 和 Skills 都没用上,没啥新意。

但对于一些小白 —— 比如连 OpenCode 或终端是什么都不知道的小伙伴 —— 操作过程中还是会遇到不少问题的。

不过我觉得,AI 时代,只要能说得清楚、有明确报错信息的问题,丢给 AI 都能解决。所以还是希望能引导更多人去动手试试看。

后续计划研究一下 Skills,正好扣子 skills 不是也出了吗,打算把这些流程固化进去,尽可能实现一次生成就能满足效果 的情况。

最后

PPT 这件事,难的从来不是内容,而是怎么让内容被看见。

现在有了 OpenCode + SVG 这条路,至少「呈现」这一步,可以交给 AI 先跑一版了。

剩下的,就是你来把控方向。


有问题欢迎留言,一起交流


📌 转载信息
原作者:
Vigorxu
转载时间:
2026/1/20 18:06:18

你会不会有过这些疑问:

为什么有的企业总能快速响应市场需求,有的企业却总是“慢半拍”?

为什么有的企业成本控制得心应手,有的企业却被成本压得喘不过气?

为什么有的企业能保证客户满意度,有的企业却老收到投诉?

这些情况,其实是我从业十几年观察到的部分现象。

自从对企业的供应链管理进行学习后,我就发现:

不管是大企业还是小公司,是制造业、零售业,还是电子商务行业,想要解决上面的问题,都离不开供应链的高效管理。那么,供应链究竟是什么?数字化供应链又是什么?为什么说它对企业经营很重要?

一、供应链究竟是什么?

实际上,供应链就是产品从无到有的过程。

说白了就是由“从供应商购买原材料 --> 工厂加工生产 --> 分销商销售 --> 消费者购买”构成的整个链条。

举个例子:

一盒阿莫西林胶囊:“药厂采购原材料 --> 制药厂的生产车间去加工 --> 药品通过医药物流公司配送到医院药房 --> 药房给到患者”的过程,就叫做医药供应链。

image.png

供应链的特点主要有以下几点:

流程化:从原材料到最终用户,一系列相互关联的活动构成了一个完整的流程。

整体性:供应链中的各个企业相互协作,共同满足最终用户的需求。

信息与物流结合:信息在供应链中起着很重要的作用,它指导着物流的方向和效率。

全球化:现在国内有很多供应链已经涉及了多个国家和地区的供应商、制造商和分销商。

二、供应链的构成有哪些?

如果要从“供应链”这个词里面,找出一个最重要的字,你会选哪个?

相信大多数朋友跟我一样,会选“链”这个字。

这其实也说明了,供应链是由多个部分串联起来的一条长链。在这个过程中,供应链由五要素组成,同时三大流贯穿始终,从而保证整个链条的有序运作。

1、五大要素

分别是供应商、制造商、分销商、零售商和用户。

供应商。是供应链的起点,主要是向制造商提供所需材料和零部件的企业。优质的供应商能够保证物资的质量、按时交付,对企业的生产运营至关重要。

所以,要做好供应商管理,很多企业都会配置供应商管理系统(SCM),通过系统:

从多方面考察供应商的实力和绩效,使供应商不断改进

供应商与制造商之间获得一个沟通和解决问题的平台,保证了信息的一致性和准确性,提高双方效率。

制造商。负责将原材料加工成成品,通过生产制造过程,实现产品的增值。在开头提到的咖啡例子中,制造商就是那些将咖啡豆烘焙、研磨并冲泡成咖啡的企业。

分销商。在制造商和零售商之间起到桥梁作用的企业。他们可能负责物流、仓储和分销等任务。

零售商。直接面向消费者,负责将产品卖出去,超市就是咱们最熟悉的零售商之一。他们的主要任务是了解消费者需求、提供优质的购物体验。

最终用户。也就是消费者,他们是供应链的最终环节,也是整条供应链的唯一收入来源。

2、三大流

分别是信息流、物流、资金流。

信息流。在商品流通中,所有信息的流动过程,简称信息流。它贯穿于商品交易过程的始终,是分析物流、导向资金流、进行经营决策的重要依据。常见的信息流包括生产能力信息、促销计划和交付时间表等以及销售情况、库存信息等等。

物流。物流主要关注的是如何用最短的时间、最低成本对原材料、中间品和成品进行交付。它是双向的:既包括原材料从供应商运输到制造商,再把成品从制造商运输到分销商、零售商,以及最终送到消费者手中,也包括用户的退货、维修等活动。

资金流。在商品流通中,信用证、汇票、现金等,在各个交易方之间的流动,就是资金流。从消费者支付货款给零售商开始,资金会沿着供应链反向依次流转,涉及采购付款、货款结算、信贷融资等方面。

image.png

三、再来说说,什么是数字化供应链?

数字化供应链是通过数字技术(物联网、大数据、人工智能等技术)对传统供应链进行全方位改造,以实现供应链的数字化、智能化、协同化的管理模式。主要目的是提升效率、降低成本、增强灵活性和抗风险能力。

那么,数字化供应链到底是“供应链的数字化”,还是“数据化的供应链”呢?

这两者有什么区别呢?

简单来讲,前者指的是,将数字技术应用到供应链各个环节的过程,更关注工具的实施。比如过去供应链上各个环节用手工,现在都用系统。

后者是前者的结果。各环节都用系统后,一定会逐渐沉淀出更多的电子化数据。也就是说,“数据化的供应链”是“供应链数字化”的直接结果。

而本文一开始提到的“数字化供应链”,是在“数据化了的供应链”的基础上,更进一步的结果。

比如,我们使用云计算、低代码、大数据、人工智能等数字技术,对沉淀的数据进行深入分析,来进行用户需求预测、库存优化、科学排产等动作,让数据驱动决策,发挥出数据的价值。

这才是数字化供应链的终点。

下面以疫苗生产为例,说明这三个阶段。

1、供应链的数字化

过去药厂采购员用用excel记录原材料采购;生产车间的温湿度靠手工抄表;物流温度靠司机纸质记录;疾控中心靠经验估算各社区医院的疫苗需求量。

现在全环节部署数字系统(比如上海一家从事医疗行业的集团型公司,他们采用织信低代码,耗时5个月构建了8套业务管理系统),采购用SRM系统,生产用MES系统,仓库用WMS系统,质量管理用QMS系统,物流用车载物联网设备,疾控中心用疫苗信息管理系统等等。

这一切是“数字化”的过程。

2、数据化的供应链

现在,每一支疫苗从原料批号、生产时间、生产线、检验数据,到出库后的实时位置、冷链车温度,再到进入省-市-区疾控中心冷库的入库时间、库存数量、库内温度,最后到接种门诊的接收记录、冰箱温度、每日接种数量……所有这些信息都被自动采集,并以结构化的数据形式沉淀在各自的系统中。

3、数字化供应链

系统自动接入并分析多种数据:过去三年的各地接种数据、今年各地区的儿科门诊流感样病例监测数据、人口流动数据、天气预测数据。

系统智能决策:AI模型预测出,A市新区由于年轻家庭多、儿童人口激增,今年需求将比往年增长40%,系统自动向生产环节发出动态生产计划。

四、数字化供应链促发新的商业模式

1、制造服务化

随着数字化时代的快速发展,越来越多的企业尝试将服务融入产品业务,由以前基于产品销售的单一模式逐渐演变成提供连续服务的模式,这种新的商业模式被称为制造服务化。制造服务化模式不仅使信息共享变得更为便捷,同时提高了供应链的整体效率。制造商不再仅仅提供产品,而是将服务与产品相结合,为客户提供综合解决方案。这为制造业数字化转型提供了明确的方向。如英伟达公司从一个主要服务于个人计算机游戏市场的显卡生产商,成功地转变成一个提供从硬件到软件,再到云服务的全方位解决方案科技巨头。这就是制造服务化的典型案例。

2、数据驱动的快速直销

数据驱动快速直销模式是指企业运用大数据、人工智能及其他创新技术,迅速识别用户行为、消费模式和市场动向,从而迅速生产市场高需求度产品,确保在短时间内实现有效的销售。这种模式已经司空见惯,相信大家都不陌生。中国最具代表性的企业就是跨境服装企业SHEIN.目前估值已超过H&M和ZARA的市值之和。在欧美国家已经跻身快消品牌前三。SHEIN在全球没有自己的实体店,完全是通过深入分析用户行为、搜索动态以及社交媒体的反馈,迅速洞察最新的时尚潮流,并根据这些数据进行产品设计。而且SHEIN主打的是小批量生产模式,特定款式只有50-100件服装,小批量向消费者销售经过算法筛选的商品,常常导致产品短缺,较好地发挥了饥饿营销的作用,最终实现了巨大的成功。

数据驱动快速直销模式一方面简化了供应链,允许制造商直接与消费者互动,绕过了传统的零售中介,不但降低了成本,还为制造商提供了更直接的客户反馈渠道。另一方面该模式极大地依赖强大的数据分析技能、高效的生产和供应链管理技能,以及与消费者直接互动的能力。通过分析消费者的购买历史、浏览行为和偏好,企业可以为消费者提供个性化的产品推荐和营销信息,从而提高购买转化率和客户满意度。而基于真实的消费者数据和需求预测,企业可以更准确地管理库存,减少过度库存的风险,确保热销产品始终有货。

3、平台经济

平台经济指的是基于技术平台建立的商业模式,使得其中两个或者更多的用户群体可以直接互动、交换价值。平台经济的关键在于利用技术把人们联系在一起,不同的参与方提供提供连接,一起创造价值和进行交流。这种经济模式常常通过网络效应产生更好的价值,平台上的每一个新用户都可能为其他用户增加价值。

目前,全球大型平台经济企业大部分集中在美国和中国。常见的有阿里巴巴、腾讯、字节跳动、美团、拼多多等,还有国外的苹果、微软、亚马逊、Meta等等。

以上就是今天介绍的全部内容。希望对大家有所帮助。