WEBVTT

00:00:00.000 --> 00:00:03.360
欢迎来到鼻涕和咳嗽的世界。

00:00:05.160 --> 00:00:11.640
对，Mario 和我现在刚好赶上了孩子们

00:00:11.640 --> 00:00:13.220
把各种病带回家的这一波。

00:00:13.220 --> 00:00:19.160
大家把孩子送去学校或幼儿园，一周后所有人都病了。

00:00:20.740 --> 00:00:22.600
说个小插曲。

00:00:22.600 --> 00:00:28.640
我开始在 Sentry 工作的时间，差不多正好

00:00:28.640 --> 00:00:31.120
和我们第一个孩子出生重合。

00:00:31.920 --> 00:00:36.100
我的朋友、Sentry 创始人 David，现在也有了第一个孩子。

00:00:36.100 --> 00:00:42.560
他现在才开始体会这些，然后在 Twitter 上分享。

00:00:42.640 --> 00:00:43.980
比如：有孩子以后到底怎么工作？

00:00:44.240 --> 00:00:45.320
能工作的。

00:00:47.600 --> 00:00:49.680
是啊，第一次嘛。

00:00:50.960 --> 00:00:52.140
就是需要适应。

00:00:52.600 --> 00:00:53.860
对。

00:00:54.880 --> 00:00:59.940
我们现在也在适应模型的变化。

00:01:00.320 --> 00:01:00.980
这转场真不错。

00:01:01.560 --> 00:01:02.340
真是个好转场。

00:01:03.420 --> 00:01:04.820
你现在越来越擅长这个了。

00:01:07.700 --> 00:01:13.920
所以我们想聊聊新模型的行为，

00:01:13.920 --> 00:01:18.660
这对 harness 有什么影响，以及我们可能会怎么应对，或者不应对。

00:01:20.320 --> 00:01:21.380
还有我们怎么看这件事。

00:01:21.380 --> 00:01:21.880
对。

00:01:21.880 --> 00:01:21.900
对。

00:01:22.040 --> 00:01:28.340
Armin 最近发现的问题是，Opus 5.5 发布后，

00:01:28.340 --> 00:01:31.280
它不再使用 edit 工具了，基本上什么事都用 Bash。

00:01:32.720 --> 00:01:35.600
对，或者说，通过 Bash 来运行 Python。

00:01:35.600 --> 00:01:39.200
这样可能比较省 token。

00:01:39.200 --> 00:01:43.320
但也可能存在你发现的那些正确性问题。

00:01:43.320 --> 00:01:49.620
比如，这些代码未必能让模型知道：这次编辑

00:01:49.620 --> 00:01:51.160
其实没有达到预期的效果。

00:01:51.160 --> 00:01:52.880
这就不好了。

00:01:52.880 --> 00:01:59.920
而从用户体验来说，你看着执行记录不断往下刷，

00:01:59.920 --> 00:02:05.840
未必还能看到清楚的 diff，而是一段极其复杂、节省 token 的

00:02:05.840 --> 00:02:08.120
Bash 调用，里面还混着 Python。

00:02:08.400 --> 00:02:09.700
这体验也不太好。

00:02:10.120 --> 00:02:12.560
所以问题来了，Armin，我们怎么办？

00:02:12.700 --> 00:02:13.280
怎么办呢？

00:02:13.280 --> 00:02:19.080
我觉得这里有两个

00:02:19.080 --> 00:02:22.540
大的趋势，

00:02:22.540 --> 00:02:24.600
它们也在影响我们。

00:02:24.680 --> 00:02:30.140
不过，对那些追求大量使用 token 的人来说，首先就是：为什么还要在意执行记录？

00:02:30.400 --> 00:02:32.400
只看最终结果不就好了。

00:02:32.400 --> 00:02:35.820
第二个我觉得

00:02:35.820 --> 00:02:39.480
值得讨论的问题是，并不是所有 agent 都是编程 agent。

00:02:40.680 --> 00:02:43.060
有些场景需要更强的控制。

00:02:43.380 --> 00:02:48.000
agent 越不愿意使用你希望它使用的工具，

00:02:48.000 --> 00:02:52.200
你就越是在以某种方式让出控制权。

00:02:54.300 --> 00:02:56.540
那我们先聊聊：执行记录到底有什么用？

00:02:56.540 --> 00:03:01.000
对我来说，

00:03:01.000 --> 00:03:07.480
如果执行记录的作用是看 diff 之类的东西，

00:03:07.480 --> 00:03:11.240
那在 99% 的时候，它对我都没意义。

00:03:11.340 --> 00:03:15.060
如果我同时开着多个 agent，我不会盯着所有执行记录看。

00:03:15.300 --> 00:03:16.180
那是在浪费时间。

00:03:16.260 --> 00:03:22.060
我主要看结果，看它们自认为完成之后产出的东西和文件改动。

00:03:22.060 --> 00:03:28.200
而且我会在真正的 IDE 或编辑器里看，那里有好用的 diff 工具，

00:03:28.200 --> 00:03:31.860
能跳转代码，甚至能调试，比如 VS Code。

00:03:32.540 --> 00:03:38.940
相比盯着执行记录、看 edit 工具调用，

00:03:38.940 --> 00:03:44.620
一看到生成或修改了蠢东西就插手，我觉得这样更值得花时间。

00:03:46.200 --> 00:03:47.400
我也差不多。

00:03:47.400 --> 00:03:52.600
除了少数几种情况，我不会在它执行时盯着记录。

00:03:52.600 --> 00:03:58.840
一种情况是，我让它在计算机上做些操作。

00:03:59.140 --> 00:04:03.720
我不是指 computer use，而是比如说，

00:04:03.720 --> 00:04:10.040
配置 CI，或者搞清楚怎么访问

00:04:10.040 --> 00:04:11.780
远程服务，比如执行 Pulumi 的变更。

00:04:11.780 --> 00:04:13.220
这时候我就很关心它在做什么。

00:04:14.700 --> 00:04:21.340
但大多数时候，至少它在实现功能时，我并不太关心执行记录。

00:04:21.460 --> 00:04:28.700
不过，我会和 agent 讨论具体问题该怎么解决。

00:04:28.980 --> 00:04:34.620
为了让它更好地理解我们在做的事情，

00:04:34.620 --> 00:04:38.580
我会鼓励它读文件、理解代码库等等。

00:04:38.580 --> 00:04:45.400
于是过程就是：读一些东西，也许做个概念验证，然后我们继续讨论。

00:04:46.120 --> 00:04:52.160
现在这些记录在 Pi 里不像以前那样能很好地折叠了，

00:04:52.160 --> 00:04:57.560
虽然以前也有不少 Bash 命令，本来就不太好折叠。

00:04:57.780 --> 00:05:04.200
但现在这些工具调用的输入特别大，因为所有写入操作都放进去了，而且不会折叠。

00:05:04.200 --> 00:05:09.740
所以在我确实想读记录的时候，它反而更难读了，

00:05:09.740 --> 00:05:13.780
因为里面的工具调用又冗长又难看。

00:05:14.420 --> 00:05:14.540
是的。

00:05:14.920 --> 00:05:21.180
我理解，如果操作涉及生产环境，甚至预发布环境，你确实会想看每条

00:05:21.180 --> 00:05:26.840
命令，判断它是不是马上就要搞砸。

00:05:26.840 --> 00:05:28.440
这很合理。

00:05:29.100 --> 00:05:32.920
我不知道有没有好的解决办法。

00:05:33.020 --> 00:05:37.500
我们看过 Codex、Claude Code 等其他 harness 的做法。

00:05:37.740 --> 00:05:39.600
你应该研究过 Claude Code。

00:05:39.780 --> 00:05:41.160
它们是怎么解决的？

00:05:41.160 --> 00:05:45.240
Claude Code 对所有新模型，

00:05:45.240 --> 00:05:49.120
包括 Fable 5、5.1 和 Opus 5.5，都用了一个模式。

00:05:49.120 --> 00:05:53.880
名字我忘了，那个名字挺有意思的，但本质上它做两件事。

00:05:54.060 --> 00:05:59.240
第一，通过提示词指令，推动 agent 直接使用 Bash。

00:05:59.240 --> 00:06:03.800
也就是说，模型本来默认就会这么做，它们还进一步强化了这种行为。

00:06:04.520 --> 00:06:11.380
第二，它会把你正在处理的文件写入一个单独的 Git 工作树，保存快照。

00:06:11.580 --> 00:06:17.620
在原有 Git 状态之外，它并不是传统意义上的用户工作树，

00:06:17.620 --> 00:06:19.140
而是写入一个单独的索引。

00:06:19.240 --> 00:06:24.000
所以，对每个仓库，它都会为一次 agent 执行维护单独的索引。

00:06:24.000 --> 00:06:27.240
然后在每次工具调用前后，

00:06:27.240 --> 00:06:32.260
它会比较当前本地检出的状态和之前保存的工作树状态。

00:06:32.420 --> 00:06:37.960
再在界面里合成一个 diff，看起来像是发生了一次 edit 工具调用。

00:06:38.760 --> 00:06:41.660
这样你就能看到当时发生的变化。

00:06:43.580 --> 00:06:50.740
我觉得这里有两点挺有意思。

00:06:50.740 --> 00:06:55.620
首先，我有时确实会从另一个工作目录修改文件。

00:06:56.340 --> 00:06:58.640
比如我们有 Pi，也有 Radius。

00:06:59.000 --> 00:07:02.500
偶尔我需要同时处理两个项目，而且会让它向另一个项目提交。

00:07:02.900 --> 00:07:05.280
这种工作树方案就处理不了这种情况。

00:07:05.380 --> 00:07:09.140
只要越出了当前这个目录范围，就不管用了。

00:07:09.460 --> 00:07:13.680
另一个问题是，它也不算特别快，因为里面可能有很多文件，

00:07:14.480 --> 00:07:20.440
Git 对这些文件的跟踪情况，并不足以让这件事轻易完成。

00:07:20.740 --> 00:07:24.300
所以我不确定这个取舍是否划算。

00:07:26.320 --> 00:07:33.140
而且你通常理解的 diff，是相对于自己的提交来说的；

00:07:33.900 --> 00:07:37.620
编程 agent 理解的 diff，却是相对于另一个索引。

00:07:38.080 --> 00:07:39.840
这又多了一层间接关系。

00:07:40.260 --> 00:07:44.860
我不太相信这是一项特别有必要的取舍。

00:07:44.860 --> 00:07:52.140
到了这一步，我觉得还不如直接提交到 Git，把相对于 Git 检出状态的 diff 体验做好。

00:07:54.040 --> 00:07:54.780
所以，我也说不好。

00:07:55.320 --> 00:07:57.960
我觉得还有个小问题，

00:07:58.000 --> 00:08:00.800
就是假如你确实想看执行记录，

00:08:01.140 --> 00:08:04.440
我们就假设你有这样的使用场景，

00:08:04.780 --> 00:08:08.060
它执行时你其实也来不及读那些内容。

00:08:08.060 --> 00:08:13.420
你只能等它做完再读，这本身也有点奇怪。

00:08:14.360 --> 00:08:18.200
所以，如果你真的想看执行记录，

00:08:18.340 --> 00:08:20.060
你可能更想要的是：它接下来准备做什么的简短说明。

00:08:22.700 --> 00:08:23.440
我想是这样。

00:08:24.060 --> 00:08:27.260
最大的结论可能是：我们需要更好的 diff 工具。

00:08:27.260 --> 00:08:27.700
对。

00:08:29.700 --> 00:08:30.020
对。

00:08:30.200 --> 00:08:37.620
我现在试过很多 diff 工具，也试过集成 agent 的 diff 工具，

00:08:37.760 --> 00:08:43.240
比如我们朋友做的那个工具［名称转写不清，待核］，我觉得挺不错。

00:08:43.620 --> 00:08:48.100
但它似乎也还不是我真正想要的。

00:08:50.420 --> 00:08:56.860
所以，至少对编程场景来说，diff 确实需要做得更好。

00:08:57.260 --> 00:09:02.020
它还需要支持多阶段提交，比如一个 PR 中的多个阶段。

00:09:02.420 --> 00:09:06.480
也不一定是多阶段提交，而是在正式提交之前，

00:09:06.740 --> 00:09:11.320
你就想在特定时刻给文件保存快照。

00:09:12.200 --> 00:09:16.900
我的自定义 Pi review 扩展就有这个功能，

00:09:17.360 --> 00:09:22.800
它是一个用 Daniel 的 Glimpse 框架做的桌面界面。

00:09:23.860 --> 00:09:26.400
我已经用了好几个月了。

00:09:26.400 --> 00:09:30.480
但我发现，现在自己甚至不需要它了。

00:09:30.660 --> 00:09:33.780
我不需要在提交之前保存这些快照。

00:09:34.180 --> 00:09:35.840
已经没那么在意了，

00:09:36.000 --> 00:09:42.220
主要是因为我会把工作拆成非常小的提交，

00:09:42.220 --> 00:09:43.680
按代码行数来说是这样。

00:09:44.040 --> 00:09:49.800
但这恐怕不是适用于所有情况的办法，因为有些工作流就是会产生很大的 diff，

00:09:49.880 --> 00:09:51.540
那你可能还是需要快照。

00:09:51.540 --> 00:09:52.660
是啊，很难。

00:09:53.120 --> 00:09:56.060
当然，目标应该是把 PR 做得很小。

00:09:56.380 --> 00:10:00.000
我觉得无论有没有 agent，这一点一直都成立。

00:10:00.000 --> 00:10:06.420
但有些情况不完全适用，因为除了

00:10:06.420 --> 00:10:08.840
PR 的大小之外，

00:10:09.480 --> 00:10:15.100
还要考虑你对上线的信心，以及测试的复杂程度。

00:10:15.180 --> 00:10:20.160
所以，即便加了功能开关，有些提交你还是不愿意立即合并，

00:10:20.160 --> 00:10:21.500
因为你想先充分测试。

00:10:21.500 --> 00:10:24.400
这样一来，它们就容易越变越大。

00:10:26.140 --> 00:10:28.700
你可能就会想在中间保存一些检查点。

00:10:29.000 --> 00:10:32.380
但和 agent 一起审查时，你看的其实又是相对于主分支的变化。

00:10:36.260 --> 00:10:37.460
对，我想是这样。

00:10:37.880 --> 00:10:39.200
我刚开始做 Pi 的时候，

00:10:39.340 --> 00:10:43.940
发现那时所有模型似乎都在非常相似的轨迹上接受强化学习训练，

00:10:43.940 --> 00:10:45.940
因为它们都预期会有一组基础工具。

00:10:46.120 --> 00:10:49.360
有了这些就能很好地工作，也就是 read、write、edit、Bash。

00:10:49.360 --> 00:10:51.720
现在时代可能变了。

00:10:52.080 --> 00:10:55.480
强化学习正在朝“只需要 Bash”这个方向发展。

00:10:55.940 --> 00:10:59.680
我记得 GPT 模型去年就开始这样了，

00:11:00.100 --> 00:11:02.640
大概是第一个 5 点几版本出来的时候。

00:11:03.900 --> 00:11:05.040
现在 Claude 也一样。

00:11:05.120 --> 00:11:07.140
其他模型也这么做，是很合理的推测。

00:11:07.320 --> 00:11:09.480
这些强化学习方式的变化，

00:11:09.960 --> 00:11:14.920
很有意思的一点是，它们对 agent 工程的用户体验影响很大。

00:11:16.220 --> 00:11:18.980
我们只能适应，兄弟。

00:11:19.360 --> 00:11:22.080
让强化学习的浪潮从你身上流过去吧。

00:11:22.940 --> 00:11:24.500
是啊，我觉得……

00:11:24.500 --> 00:11:27.320
我们一直比较擅长不去对抗强化学习的方向。

00:11:28.420 --> 00:11:30.500
至少也比较擅长判断它会往哪里走。

00:11:30.640 --> 00:11:35.460
但围绕它设计什么样的用户体验，我们还不够有创造力。

00:11:36.280 --> 00:11:40.500
Pi 的用户体验基本上只是覆盖在模型行为之上的薄薄一层。

00:11:40.500 --> 00:11:45.420
这种做法可能也有它的有效期。

00:11:45.640 --> 00:11:47.100
我们正在接近那个期限。

00:11:47.100 --> 00:11:53.320
这里我觉得有两件有意思的事。

00:11:53.380 --> 00:11:55.860
假如你能控制底层的大语言模型，

00:11:56.240 --> 00:12:00.000
比如你就是 OpenAI、Anthropic，或者自己运行模型，

00:12:01.160 --> 00:12:05.040
你就会越来越多地同时运行不止一个模型。

00:12:05.040 --> 00:12:07.140
先运行一个大模型来做事，

00:12:07.240 --> 00:12:09.500
再运行一个小模型，可能是为了预测式解码，

00:12:09.500 --> 00:12:14.280
也可能是为了提前截断推理输出。

00:12:14.620 --> 00:12:17.040
它们内部已经在这么做了。

00:12:18.500 --> 00:12:25.520
所以现在有个几乎顺理成章的想法：

00:12:25.660 --> 00:12:28.920
在工具调用之外，再给出一些过程说明。

00:12:29.640 --> 00:12:31.480
现在这方面做得还很少。

00:12:31.720 --> 00:12:35.100
一些 ChatGPT 模型开始出现一点这样的功能。

00:12:35.100 --> 00:12:36.420
它们有一个 commentary 通道。

00:12:37.060 --> 00:12:40.440
我觉得目前主要是用来

00:12:40.880 --> 00:12:43.800
区分最终给出的助手消息

00:12:43.860 --> 00:12:45.220
和执行过程中给出的助手消息。

00:12:46.500 --> 00:12:49.720
但如果你自己运行推理系统，

00:12:49.840 --> 00:12:51.400
理论上你就能做到：

00:12:51.660 --> 00:12:54.020
这里是一段简短的操作说明。

00:12:54.440 --> 00:12:56.400
你可以多花一些 token 来概括它。

00:12:56.480 --> 00:12:57.980
不过，在流式输出过程中这么做会比较棘手。

00:12:58.600 --> 00:13:00.080
也可以让 Jev 来处理［原文名称转写待核］，

00:13:00.160 --> 00:13:01.860
对正在发生的事情做分类。

00:13:02.480 --> 00:13:03.520
所以我也不知道。

00:13:03.520 --> 00:13:04.360
这个……

00:13:05.100 --> 00:13:08.180
可能会有人想做一些实验，

00:13:08.180 --> 00:13:10.260
试试看

00:13:10.780 --> 00:13:13.220
该如何在执行记录中展示这些工具调用。

00:13:15.260 --> 00:13:15.980
对。

00:13:16.060 --> 00:13:16.420
我也说不好。

00:13:16.920 --> 00:13:19.520
我觉得现在最简单的办法，

00:13:19.620 --> 00:13:21.200
而且对很多模型都管用，就是：

00:13:21.660 --> 00:13:23.540
在工具定义里，

00:13:24.060 --> 00:13:26.420
加上 description、summary，

00:13:26.540 --> 00:13:28.720
或者类似的、要求模型填写的字段。

00:13:29.460 --> 00:13:30.920
把它放在第一个参数，

00:13:31.240 --> 00:13:33.820
也就是工具调用参数对象的第一个字段。

00:13:33.820 --> 00:13:36.840
通常你就会最先收到它。

00:13:38.240 --> 00:13:39.880
我们应该试试。

00:13:39.980 --> 00:13:41.580
我觉得这能临时补一下。

00:13:42.260 --> 00:13:45.520
但最终，我们可能得放弃逐个展示工具调用。

00:13:45.520 --> 00:13:49.220
这就引出了另一个问题：

00:13:49.220 --> 00:13:52.740
最初为什么要把工具调用分成不同类型？

00:13:52.740 --> 00:13:56.240
一个重要原因是审批关卡。

00:13:56.240 --> 00:13:57.980
Pi 显然从来就没有真正做过这套。

00:13:58.180 --> 00:14:03.240
但比如 Claude，会用它来……

00:14:03.240 --> 00:14:05.740
你可以设置默认允许编辑，

00:14:05.900 --> 00:14:07.920
前提是它使用 edit 工具。

00:14:07.920 --> 00:14:10.480
其他操作则都要询问。

00:14:10.640 --> 00:14:14.400
但现在要么大家已经根本不在乎了，

00:14:14.400 --> 00:14:19.020
要么就再运行一个大模型来做审批，

00:14:22.020 --> 00:14:23.800
判断这个操作该不该执行。

00:14:23.860 --> 00:14:24.980
也就是所谓的 auto mode。

00:14:26.520 --> 00:14:29.000
你怎么看这个？

00:14:29.000 --> 00:14:35.240
就是再运行一个分类器或模型，

00:14:35.240 --> 00:14:36.920
来做这些判断。

00:14:37.500 --> 00:14:39.840
首先，审批关卡一直就很扯。

00:14:40.780 --> 00:14:44.660
我不认识任何真正会用它的工程师。

00:14:44.920 --> 00:14:49.000
它就像是 harness 为了标榜“企业级可用”而必须勾选的一个功能。

00:14:49.100 --> 00:14:50.360
但其实没人在用。

00:14:52.020 --> 00:14:54.740
所以无论如何，这些东西都在消失。

00:14:54.740 --> 00:14:59.900
因为即便让第二个模型判断工具调用好不好，

00:14:59.900 --> 00:15:01.920
仍然存在很大的问题。

00:15:02.700 --> 00:15:03.840
至少我还是这么认为。

00:15:04.780 --> 00:15:07.960
要做这个判断，模型通常不能只看工具调用本身，

00:15:08.160 --> 00:15:09.680
还得看完整上下文，

00:15:11.260 --> 00:15:13.020
判断才有意义。

00:15:13.340 --> 00:15:17.800
我总不能随便让一个 Haiku、Terra 或 Luna 模型，

00:15:18.460 --> 00:15:21.400
只看一条 Bash 调用，就说“没事，不危险”，

00:15:21.400 --> 00:15:24.700
或者“它不会造成我们不希望出现的破坏”。

00:15:25.880 --> 00:15:26.880
我也不知道，兄弟。

00:15:27.100 --> 00:15:29.360
直接把你的 agent 关进沙箱就行了。

00:15:29.900 --> 00:15:30.480
事情就解决了。

00:15:31.960 --> 00:15:32.360
对。

00:15:32.940 --> 00:15:39.300
我觉得，我们很可能正在走到这样一个节点：编程 agent

00:15:39.300 --> 00:15:43.220
已经完全涵盖了其他所有形式的 agent。

00:15:43.220 --> 00:15:48.360
所以，就算你想在非编程环境里使用它，

00:15:49.400 --> 00:15:52.440
你大概也会给它一门编程语言。

00:15:52.700 --> 00:15:53.780
而它是图灵完备的。

00:15:53.980 --> 00:15:54.600
那就祝你好运了。

00:15:55.800 --> 00:16:00.560
所以，你得约束它周围的所有东西。

00:16:02.440 --> 00:16:09.220
你是不是说过，有个 harness 的 code mode 实现，还给了模型完全不受保护的 Bash？

00:16:09.220 --> 00:16:15.540
基本上，现在大多数 code mode 都会把 agent 拥有的所有工具暴露出来。

00:16:15.660 --> 00:16:15.760
对。

00:16:15.940 --> 00:16:21.860
所以，code mode 本身可能被严格限制在沙箱里，但你又能

00:16:21.860 --> 00:16:25.260
通过 code mode 调用 Codex 的 Bash。

00:16:25.260 --> 00:16:28.240
那你还是得另外把整个环境放进沙箱。

00:16:28.240 --> 00:16:34.540
于是就成了一个沙箱加另一个沙箱。我想这也有道理，因为 code mode 理论上运行在 harness

00:16:34.540 --> 00:16:35.720
所在的、更加可信的环境里。

00:16:36.560 --> 00:16:42.920
而 Bash 则运行在 exe.dev，或另一个 worker 平台［名称转写不清］，

00:16:42.920 --> 00:16:44.880
或者 Cloudflare Durable Object 的沙箱环境里。

00:16:44.880 --> 00:16:50.140
但从某种意义上说，这一切就是：

00:16:50.140 --> 00:16:53.340
我们已经全面投入了以代码来完成任务这条路。

00:16:53.460 --> 00:16:53.600
对。

00:16:53.700 --> 00:16:59.900
所以现在我们最好把这些沙箱控制好。但在沙箱

00:16:59.900 --> 00:17:02.000
允许的能力范围内，

00:17:03.280 --> 00:17:05.780
harness 基本上已经不起什么作用了。

00:17:05.780 --> 00:17:10.660
或者至少，它的控制能力非常有限，因为模型已经如此深地

00:17:10.660 --> 00:17:14.260
接受了编程语言和 Bash 方面的训练。

00:17:15.940 --> 00:17:22.160
我觉得对 Pi 来说，主要问题就是：如何让人们

00:17:22.160 --> 00:17:24.840
自由尝试自己想要的执行记录展示方式？

00:17:25.020 --> 00:17:29.220
我们现在提供了足够的基础能力，让大家去折腾吗？

00:17:29.220 --> 00:17:36.140
还有，如果有人要做一个自行运行的 agent，比如放在 Durable Object 里，

00:17:36.140 --> 00:17:40.160
应该怎样组织它？

00:17:40.380 --> 00:17:44.280
Pi 里的基础能力够不够，让这种做法可行？

00:17:46.720 --> 00:17:49.440
我觉得这里会有很多有趣的东西。

00:17:49.700 --> 00:17:53.080
如果有人有想法，我们很想听听。

00:17:53.080 --> 00:17:59.840
但某种意义上说，很多自定义工具可能要走到尽头了。

00:18:00.440 --> 00:18:00.620
对。

00:18:01.800 --> 00:18:07.660
我得说，至少对我的工作流，自定义工具历来都没有特别大的帮助。

00:18:07.940 --> 00:18:14.140
我最近做了一个新工具，叫 Pi History Handoff，

00:18:14.140 --> 00:18:18.120
有点像 Codex 新出的实验功能。

00:18:18.120 --> 00:18:25.300
由模型自己决定清空上下文，只给自己留下一份摘要。

00:18:25.480 --> 00:18:33.080
它相当于更精致的上下文压缩，再加一个让模型搜索已压缩历史的工具。

00:18:34.340 --> 00:18:38.800
这是我最近唯一做出来、确实适合自己工作流的工具。

00:18:38.960 --> 00:18:42.020
除此之外，我没有多少自定义工具。

00:18:42.020 --> 00:18:48.120
现在特别有意思的一点是，我们一方面看到大家全面转向 Bash，

00:18:48.940 --> 00:18:51.580
另一方面，MCP 又全面回潮了。

00:18:53.260 --> 00:18:59.540
我还没完全想明白，这两件事该怎么结合，因为我觉得 MCP

00:18:59.540 --> 00:19:02.440
解决了鉴权问题，这很重要。

00:19:02.440 --> 00:19:06.660
它也对工具执行设置了一些约束，

00:19:06.660 --> 00:19:10.080
但我们把它们连接起来的方式，又是 code mode。

00:19:11.060 --> 00:19:14.040
所以这很有意思。

00:19:14.220 --> 00:19:16.120
这些东西如今会落在哪里？

00:19:16.620 --> 00:19:16.760
是啊。

00:19:17.360 --> 00:19:20.600
你最近应该又深入研究了一些 MCP。

00:19:20.600 --> 00:19:27.080
我的理解是，MCP 工具必须定义输入 schema，

00:19:27.080 --> 00:19:33.920
但输出 schema 可以定义，也可以不定义。

00:19:34.380 --> 00:19:37.620
而多数情况下，你其实需要两个通道，对吧？

00:19:37.660 --> 00:19:42.720
一个给大模型看，为了节省 token，可能是非结构化的。

00:19:42.720 --> 00:19:49.200
另一个则需要结构化，比如让 MCP 工具能被 code mode 调用。

00:19:49.720 --> 00:19:50.580
现在这方面是什么情况？

00:19:50.900 --> 00:19:54.120
我们到底有这两个输出通道，还是只有一个？

00:19:56.020 --> 00:19:58.080
大多数情况下，只有一个通道。

00:19:59.280 --> 00:20:02.920
有意思的是，我们在做 Radius 的时候，

00:20:02.920 --> 00:20:07.300
希望你能和 agent 对话，让它重新配置 Radius。

00:20:07.580 --> 00:20:08.840
我们尝试了很多方案。

00:20:08.840 --> 00:20:13.700
实际发现，对现在这些模型最有效的是 OpenAPI。

00:20:14.480 --> 00:20:21.700
所以我们加了一个端点，你可以描述任务，返回的是经过检索筛选的结果：

00:20:22.280 --> 00:20:24.860
这些是你可能想使用的端点，以及对应的 OpenAPI schema。

00:20:25.340 --> 00:20:27.480
你也可以通过 MCP 暴露它。

00:20:27.640 --> 00:20:31.240
所以，这种模式完全可以套到 MCP 上。

00:20:32.240 --> 00:20:37.420
唯一的问题是，这时候 MCP 实际上只负责鉴权。

00:20:37.420 --> 00:20:42.540
相当于 RPC 加鉴权，这是对 MCP 非常狭窄的一种用法。

00:20:43.140 --> 00:20:46.980
如果你按这种方式构建服务器，

00:20:46.980 --> 00:20:51.260
它只会输出结构化数据，而 MCP 通常不是这样用的。

00:20:51.840 --> 00:20:58.280
如果你把它放进传统 MCP 用法中，把所有输出直接塞进上下文，

00:20:58.280 --> 00:21:00.680
那就不太行。

00:21:00.680 --> 00:21:06.780
所以现在出现了一个中间地带：你几乎可以把 MCP 当成 RPC

00:21:06.780 --> 00:21:10.080
系统，只输出结构化数据。

00:21:10.920 --> 00:21:17.100
然后希望 code mode 有足够的辅助能力，完成筛选、

00:21:17.100 --> 00:21:18.320
后处理之类的工作。

00:21:19.440 --> 00:21:21.580
但目前大多数 MCP 服务器不是这样工作的。

00:21:21.700 --> 00:21:24.680
它们大多输出各种压缩过的 Markdown。

00:21:25.300 --> 00:21:26.260
或者纯文本，诸如此类。

00:21:26.260 --> 00:21:29.060
所以这个协议现在确实很有用。

00:21:29.300 --> 00:21:33.420
但服务器还不太确定应该面向哪一种用法。

00:21:35.420 --> 00:21:36.700
对，很有意思。

00:21:37.120 --> 00:21:42.820
所以，对未来的 MCP 服务器作者和现有维护者来说，结论可能就是：

00:21:42.820 --> 00:21:46.300
请提供结构化输出，因为我们正在全面走向 code mode。

00:21:47.080 --> 00:21:47.660
我想是这样。

00:21:47.660 --> 00:21:50.540
我觉得很可能会这样发展。

00:21:52.640 --> 00:21:53.120
对。

00:21:53.180 --> 00:21:53.860
是的，这说得通。

00:21:53.920 --> 00:22:00.180
我还是想说，在 Pi 里，模型看到的内容和 harness、

00:22:00.180 --> 00:22:05.160
或者事件消费者看到的内容，基本上一直是有区别的。

00:22:06.640 --> 00:22:11.240
工具以及执行记录里的条目都是如此。

00:22:11.240 --> 00:22:11.280
对。

00:22:12.060 --> 00:22:12.440
我觉得这……

00:22:12.440 --> 00:22:15.960
不过也得说，如果只有 Bash，那就只有一个输出，对吧？

00:22:16.080 --> 00:22:16.320
当然。

00:22:16.720 --> 00:22:16.960
当然。

00:22:17.040 --> 00:22:20.520
如果只有 Bash，那你就……［此处表达转写不清，待回听］。

00:22:20.680 --> 00:22:25.360
但我觉得未来会通过 MCP 加 code mode 来组合这些能力。

00:22:25.560 --> 00:22:26.620
这挺合理。

00:22:26.980 --> 00:22:30.060
不过我担心，目前模型在这方面的训练还不够充分。

00:22:31.340 --> 00:22:34.240
我分析过很多 Codex 的执行记录。

00:22:34.240 --> 00:22:40.680
Astra 发布时，我专门在 Codex harness 里做了不少工作，

00:22:40.680 --> 00:22:42.540
就是为了观察它的行为。

00:22:43.460 --> 00:22:50.460
我发现 Astra 很喜欢用 code mode，哪怕有些场景根本不需要。

00:22:50.520 --> 00:22:55.380
比如我见过它用 code mode 来调用 apply_patch，你为什么要这么做呢？

00:22:55.500 --> 00:22:58.140
这只是多了一层没什么必要的间接调用。

00:22:58.140 --> 00:23:03.920
而且，不同模型使用 code mode 的方式也有差异。

00:23:04.280 --> 00:23:04.440
对。

00:23:04.580 --> 00:23:10.860
code mode 暴露的能力范围，显然比

00:23:10.860 --> 00:23:12.600
普通的工具调用通道大得多。

00:23:13.700 --> 00:23:19.100
所以我觉得，这需要大量测试和评估，

00:23:19.100 --> 00:23:22.000
未来会怎么走还不清楚。

00:23:22.000 --> 00:23:27.840
它和本地模型之间也有些矛盾，因为我敢保证，本地模型

00:23:27.840 --> 00:23:29.120
在 code mode 上会表现得很差。

00:23:29.460 --> 00:23:31.560
所以，是啊。

00:23:32.320 --> 00:23:37.660
我很想把 code mode 加进 Pi，最感兴趣的用途其实还不是 MCP。

00:23:37.900 --> 00:23:41.880
而是 Jev。要让 Jev 发挥作用，

00:23:41.880 --> 00:23:47.320
第一步得先生成一些代码，然后 Jev 才能反复对它进行评估。

00:23:47.320 --> 00:23:52.040
也就是说，你基本上是在创建一个状态机或工作流，每次迭代时，

00:23:52.040 --> 00:23:54.820
由 Jev 决定该沿着哪条路径继续。

00:23:54.820 --> 00:24:00.440
所以，它会成为 Pi harness 里非常有用的一项基础能力。

00:24:03.080 --> 00:24:09.560
相比用于 MCP，我现在更相信它对 Jev 有用，除非 MCP 服务器也发生变化。

00:24:10.160 --> 00:24:11.460
不过，拭目以待吧。

00:24:12.140 --> 00:24:12.520
不错。

00:24:13.680 --> 00:24:15.160
真是有意思的时代。

00:24:15.160 --> 00:24:17.900
我们是不是该回床上，被这场“男人流感”打倒了？

00:24:18.720 --> 00:24:19.560
像两个大宝宝一样？

00:24:19.560 --> 00:24:20.100
我想是的。

00:24:20.380 --> 00:24:20.700
好。

00:24:20.960 --> 00:24:21.320
行。

00:24:22.040 --> 00:24:22.860
周一快乐。

00:24:23.220 --> 00:24:23.800
周一快乐。

00:24:23.800 --> 00:24:23.960
好。

00:24:24.820 --> 00:24:25.820
周一快乐。
