实测 Doubao-Seed-Evolving:把 Windows 桌面图标做成一个会自己运转的小世界

豆包 Seed 又更新了:一张永远"最新"的模型卡

这次豆包推出的不是一个过段时间就会落后的固定版本,而是 Doubao-Seed-Evolving:一个专门面向 Coding 和 Agent 场景的 latest 分支。Evolving 的核心就是按周持续更新。开发者不用隔一段时间追一次新模型,使用同一个模型入口,背后的能力会随着每周迭代继续增强。可以把它理解成一张永远保持"最新"的模型卡。

这次升级最直观的两个点,是 1M 上下文和更强的长程任务能力。1M 上下文让模型一次能接住更大的代码仓库、更长的需求和更多历史信息;长程能力则让它在多轮规划、工具调用、代码修改和测试验证中不容易中途丢掉目标。对于 Codex 这类 Coding Agent 来说,能把一个复杂任务持续做下去,比只写好某一段代码更重要。

好的,今天我们就用 Codex 配置好这个模型,实测一下模型效果如何。

怎么接入和配置模型,我不在这里重复贴命令。火山引擎已经整理了 Codex CLI、Codex 桌面客户端等配置步骤,需要的同学直接按照https://console.volcengine.com/ark/region:cn-beijing/docs/82379/2556054?lang=zh 操作即可。

图中红框是官方教程的章节目录,按照自己使用的客户端选择对应部分即可,本文不再重复配置过程。

桌面脑洞

每天开机以后,Chrome、Edge、微信、VS Code 这些软件图标都安安静静地待在 Windows 桌面上。它们的工作只有一个:等我双击。

我突然想到一个有点无聊、但越想越有画面的事情:如果我下班了,桌面图标也下班了,它们会不会自己出来活动?浏览器之间可能互相看不顺眼,聊天软件可能凑在一起说悄悄话,开发工具也许会组队踢球。

后来,这个脑洞真的变成了一个 Windows 小工具------《桌面下班后》。有的图标长出手脚满桌散步,有的躲到一边聊天,两个图标还会突然打起来。过一会儿,整桌软件又会自动分成两队踢球。整个过程不用我操作,我最多在打架时点一下"劝架"。

下面是它实际运行时的画面:左边是真实桌面快捷方式,一枚都没动;右边那些长出手脚、满桌跑的,才是程序画出来的角色分身。

这个点子最开始,我确实只说了一句话。模型先判断它可以实现,再给出了"不要移动原生图标,改画角色分身"的关键方案。下面保留的是当时的对话原文节选:

红色标签标出了我的最初想法和模型给出的关键方案:原生桌面图标不动,另外生成角色分身。

这个点子差点又被我做复杂

"会打架、会踢球",听起来很像游戏。第一轮方案里自然出现了点击角色、拖动角色、指定聊天对象、主动发起足球比赛这些玩法。

但我看完就觉得不对。我要看的是软件图标趁我不操作电脑时自己活动,不是再给自己加一个需要操作和输赢的小游戏。

所以我又把边界说死了:

红色标签分别标出了我重新划定的产品边界,以及模型根据这条要求给出的调整结果。

这句话后来几乎决定了整个产品:

  • 不能点角色,不能拖角色;
  • 不能指定谁聊天、谁打架;
  • 不能手动开球,也不能控制任何一队;
  • 没有积分、成就和输赢;
  • 桌面舞台永远鼠标穿透;
  • 能做的只有换上、换下图标,以及打架时劝一下。

如果不劝,冲突过几秒也会自己结束。劝架只是留了一个很轻的入口,不是必须完成的玩法。

这个项目从这里开始才顺了。它不是"把小游戏盖在桌面上",更像一个会自己变化的桌面鱼缸。

先别写代码,先把三个方案砍一遍

图标动起来有三种做法,我先把风险摊开,不急着开项目。

方案 看起来怎么样 实际问题 结论
直接移动 Windows 原生图标 最像真的,图标确实离开原位 会破坏用户桌面布局,还带着双击、拖动、右键等系统行为 不做
做普通桌宠,内置一套软件图标 安全,动画也好做 不是用户电脑里的图标,少了最关键的代入感 不做
读取 .lnk 图标,再画一份角色分身 真实图标不动,又能使用本机图标 要处理透明窗口、穿透和桌面层级 就选这个

第一种最有噱头,我也最先想到它。但只要坐标、DPI 或 Explorer 状态出一次问题,用户排好的桌面就会被弄乱。更别说一个正在踢球的 Chrome 图标突然触发双击,把浏览器打开了。

所以项目第一条规矩不是"动画要好看",而是:

不移动、不删除、不改名、不执行任何真实快捷方式。

程序只扫描当前用户桌面和公共桌面的顶层 .lnk,拿到名称和图标以后,在透明窗口里画一份。截图里红框已经能看出来:真实快捷方式一直留在左侧,带手脚的角色在另一层里活动。退出工具,这一层消失,桌面原样不动。

第一脚先踢到 Windows 的铁板

透明舞台不能挡住鼠标

让一张图片在 WPF 里移动不难,难的是让一整个窗口看起来像不存在。

最简单的透明窗口虽然看不到背景,却仍然会吃掉鼠标。图标在桌面上跑了,用户也点不了真正的桌面。把窗口设成一直置顶更不行,浏览器和 IDE 上面也会飘着一群角色。

最后我先停下事件开发,只做一个透明舞台原型。窗口需要同时满足三件事:不接收点击、不抢焦点、不出现在 Alt + Tab 里。核心就是下面这几个 Win32 样式:

csharp 复制代码
var current = GetWindowLongPtr(handle, GwlExStyle).ToInt64();
SetWindowLongPtr(
    handle,
    GwlExStyle,
    new IntPtr(current | WsExTransparent | WsExToolWindow | WsExNoActivate));

鼠标会穿过舞台,继续落到 Windows 桌面;角色不会抢键盘焦点;切换窗口时也不会多出一块透明窗口。

还有一条:只有桌面在前台时才显示角色。打开浏览器、IDE 或其他普通软件,舞台隐藏,事件计时也暂停;回到桌面,它们接着活动。这样它才像桌面的一部分,而不是一直压在所有窗口上面的悬浮广告。

一点"隐藏面板",图标也全没了

原型通过以后,我以为最麻烦的部分结束了。结果第一版刚跑起来就出了一个很直白的问题:点击"开始演出",控制面板隐藏了,桌面角色也跟着没了。

不用看日志都知道这不对。

查下来不是 WPF 把舞台关了,而是"桌面是否在前台"的判断写得太死。我的电脑上还开着 SpeedBall,它属于桌面伴随程序。控制面板一隐藏,SpeedBall 短暂成为前台,程序就把它当成浏览器一类的普通窗口,把整个舞台暂停了。

修复以后,前台窗口分成三类:

  • Explorer 桌面:显示;
  • 本工具和已识别的桌面伴随程序:显示;
  • 浏览器、IDE 等普通应用:隐藏并暂停。

这个问题很小,却比"模型一次写了多少行代码"更能说明实际开发过程。Doubao-Seed-Evolving 给出的第一版也会漏场景,还是得把程序真的跑起来,照着眼前的错误继续改。

38 个图标一起上,我自己都看不下去

舞台不再消失后,我又遇到一个不算 Bug、但体验很差的问题:程序把扫描到的 38 个有效快捷方式几乎全放上去了。

截图确实热闹,实际看起来就是桌面春运。角色名字互相压住,聊天看不出是谁和谁,想找到某个图标也很费劲。

我给的修改很直接。连同"隐藏面板后图标也没了"的问题,我在同一条消息里一起反馈给了模型:

红色标签分别标出了实际运行反馈,以及模型完成修改、测试和重新打包后的结果。

于是首次阵容改成了前 10 个有效快捷方式。左侧保留其他可选图标,想换谁上场再由用户决定。已经用过旧版本的人也不能一刀切:只有旧存档接近"全部图标都上场"时,升级后才自动缩回 10 个;如果原来就是用户自己挑的阵容,则原样保留。

csharp 复制代码
public const int DefaultInitialCount = 10;

return valid
    .Take(Math.Min(limit, DefaultInitialCount))
    .ToArray();

为了给这篇文章补控制面板截图,我还抓到一个漏网问题:功能早就改成默认 10 个了,面板标题竟然还写着"默认显示全部"。代码是新的,文案还停在旧版本。这个我也一起改掉、重新打包,又把 25 项测试跑了一遍。

这张图比单独写一句"支持自定义阵容"更清楚:右边是首次上场的 10 个,左边是剩余图标,中间只有换上、换下和角色属性。顶部除了开始、暂停、隐藏面板,唯一和事件有关的按钮就是"劝架"。

会走了,不代表有东西可看

自动事件怎么选

最早的角色只是顶着图标随机移动。技术上算"动起来了",但看两分钟就没了。谁和谁都没关系,聊天像两张图片碰巧撞到一起,打架周围还挤着一圈路人。

后面才逐步加上状态、体力、性格、关系和事件冷却。平时角色会散步、休息;调度器到时间后,从空闲角色里自己找人聊天或冲突。同一个组合刚聊过,不会马上再聊;刚打完也有冷静时间;一次只能发生一个多人事件。

自动事件不是每一帧随便抽一个。调度器先看功能是否开启,再检查打架、足球和集体活动各自的冷却时间。一次随机结果会依次落到聊天、打架、足球、集体舞或巡游:

csharp 复制代码
var roll = _random.Next(0, 100);
if (roll < 42 && _options.EnableChat && TryStartChat(ignoreRelationship: false))
{
    return true;
}

if (roll < 58 && _options.EnableFight && _fightCooldownSeconds <= 0 && TryStartFight(ignoreRelationship: false))
{
    return true;
}

if (roll < 74 && _options.EnableFootball && _footballCooldownSeconds <= 0 && TryStartFootball())
{
    return true;
}

if (_options.EnableGroupActivities && _groupActivityCooldownSeconds <= 0)
{
    return roll < 87 ? TryStartDance() : TryStartParade();
}

这样既保留随机感,又不会刚打完架马上再打一次,或者让足球和集体舞同时发生。

光有规则还不够,得让人一眼看懂发生了什么:

  • 聊天双方会靠近,中间显示关系线,其他角色自动让出一块区域;
  • 打架最多只留 6 个围观者,而且只能站在外圈;
  • "走、聊、打、球"等状态直接写在角色上方,不靠 Emoji 猜;
  • 图标本身当身体,再加四条会弯的手脚,不同事件使用不同动作。

下面是自动演示里抓到的一次冲突。谁打架由程序自己选,旁边最多留 6 个围观角色,其他图标不会全挤到冲突中心。

我没有给每个软件画一套专属角色。微信还是微信的图标,Edge 还是 Edge 的图标。手脚只是让它们更像在活动,又不会认不出原来的软件。

足球也改过,最早并不是全员参加

全员参加,奇数也不落单

需求文档最初写的是自动选 4、6、8 个角色踢球,人数相等,逻辑很标准。真正跑起来以后却有点怪:几个人在球场里踢,剩下的人站在旁边发呆,甚至还想继续散步。

我后来把规则改成了"当前阵容全员参加"。偶数就平均分,奇数也不把谁丢在场外,两队人数最多差 1。足球开始后,所有角色都被锁进比赛状态,不能同时聊天、打架或换人。

代码里先确认当前所有角色都能参加,再按照总人数直接计算两队人数。奇数时左队只会比右队多 1 个,不会把最后一个角色留在场外:

csharp 复制代码
var selected = _characters
    .Where(item => item.State != CharacterStateKind.Leaving)
    .ToArray();
if (selected.Length < 4 || selected.Length != _characters.Count)
{
    return false;
}

Shuffle(selected);
selected = selected.OrderByDescending(FootballStrength).ToArray();
var leftTeamSize = (selected.Length + 1) / 2;
var rightTeamSize = selected.Length / 2;

图里那 38 个角色是我手动全部加上去做的压力测试,不是默认画面。顶部比分、两队颜色、倒计时和角色上方的"球"字都由程序自动控制。人只看,不负责开球、移动和射门。

足球跑通以后,我又加了集体舞和桌面巡游。规则没另起炉灶,仍然是整支阵容一起进入群体事件,结束后统一恢复普通状态。

人数一多,60 FPS 持续创建画刷、变换和线条对象太浪费。最后把渲染降到 24 FPS,并复用这些视觉对象。桌面小动画不需要游戏级帧率,24 FPS 看起来已经够用,普通应用切到前台后还会彻底暂停。

Doubao-Seed-Evolving 在这个项目里到底做了什么

我没有只给它一句提示词,然后等一个完整软件从天上掉下来。实际顺序更像这样:

  1. 我先说脑洞,它帮我拆产品形态和风险;
  2. 我否掉游戏化操作,要求改成纯观看工具;
  3. 先写需求计划和开发计划,再把两份文档放到一起挑错;
  4. 透明舞台先做最小原型,确认穿透和窗口切换能跑;
  5. 再实现桌面扫描、角色状态和自动事件;
  6. 每次在真实 Windows 上运行、截图,发现问题就继续改;
  7. 最后补测试、说明文档、自包含发布包和 SHA-256。

需求阶段我也没有让模型直接开写代码,而是先要求它产出需求计划、开发计划,再把两份文档放在一起复读找错。图中的红色标签分别标出了我的要求和模型交付。

技术栈最后只有 C#、.NET 10、WPF、Win32/Shell COM、JSON 和 xUnit,没有 Unity、Electron,也没有模型 SDK。

项目也只拆了两个主要部分:Core 管角色、关系、冷却和事件规则,App 管 WPF、桌面扫描、透明舞台、托盘和本地存档。这样足球是不是全员参加、劝架会不会重复结算,可以直接写单元测试,不用每次盯着桌面等事件发生。

Doubao-Seed-Evolving 的第一版实现也不会自动覆盖所有真实场景。隐藏面板后图标消失、默认全量上场、旧文案没更新,这些都不是"代码能编译"就能发现的,只能靠实际运行和复查抓出来,再把结果继续交给模型修改。

现在这版能做到什么

当前版本已经可以完整走一遍:

  • 扫描当前用户和公共桌面的顶层 .lnk
  • 首次默认 10 个角色,之后自己换上、换下;
  • 角色自动散步、休息、聊天和发生卡通冲突;
  • 全员自动踢球、跳集体舞、绕桌面巡游;
  • 打架可以从控制面板或托盘劝开,也可以不管;
  • 隐藏控制面板后舞台继续运行;
  • 打开普通软件时舞台自动隐藏,回到桌面再继续;
  • Ctrl + Alt + Esc 可以紧急退出。

所有设置、阵容、关系和最近的桌面纪事都只保存在 %LocalAppData%\DesktopAfterHours。程序不读取聊天记录、浏览记录和文档内容,也不会把快捷方式信息发出去。

最后

做完以后回头看,这个项目最有意思的地方,不是简单地让 AI 多写了多少代码,而是一个很模糊的脑洞被一步步收成了能运行的东西:不碰真实图标,不要求用户玩,默认只出现 10 个角色,出问题还能继续顺着现场结果修改。

这次用下来,我觉得 Doubao-Seed-Evolving 很适合这种"先有一句想法,再边做边改"的项目。它能先把脑洞拆成需求和风险,再继续写计划、搭项目、跨文件改代码、补测试和打包。前面的产品边界也能接到后面的实现里,不用每一轮都从头解释。

它并不是第一次就全对。隐藏面板、默认阵容和旧文案这些问题,都是我把程序真正跑起来以后才发现的。但模型能接着这些具体反馈继续查原因、改代码、跑验证,这比一次生成一个看起来完整的 Demo 更有用。

现在我回到桌面,偶尔会看到浏览器和开发工具排成两队踢球,也会看到两个图标躲到一边聊天。我一般看几秒,然后继续干自己的事。这个小工具有这几秒,就够了。

相关推荐
法雅特吉他8 小时前
吉他弦寿命模型与更换判定
经验分享·新媒体运营·学习方法·材质·内容运营
haolly10 小时前
「主流网页高亮插件横评」—— Acorny 事实卡 + 完整正文
经验分享·程序人生·学习方法
八十天环游世界11 小时前
企业AI智能体建设费用明细:2026 透明报价清单(附估价逻辑)
经验分享
香辣牛肉饭1 天前
【算法】动态规划 最长公共子序列(LCS)
经验分享·笔记·算法·动态规划
维克兜率天1 天前
【维克】概率论入门:从“抛硬币“到理解金融市场的不确定性
经验分享·学习·概率论
怀旧诚子1 天前
Fedora 创建个人的应用启动器(GNOME)
经验分享
Rain的Java大神实战圈1 天前
线上慢SQL的排查思路
经验分享·架构设计·场景设计题
法雅特吉他1 天前
吉他日常保养完全指南:从环境参数到部位养护的系统化方案
大数据·经验分享·新媒体运营·学习方法·材质
tinygone2 天前
在Windows上部署Unlimited-ocr并提供给大模型使用
人工智能·windows·经验分享