CMU AI AGENTS / 中文直观学习 / 第 01 课

模型只会输出文字,
怎么真的读到文件?

从一次库存查询开始。我们不急着背架构名词,先亲眼看见:一句请求怎样变成动作,动作的结果又怎样回到模型手里。

约 15–20 分钟前置:会比较大小、做简单乘法原课:Lecture 1 · 第 9–15 页

01 / 先给它一个必须查数据的任务

你问一个模型:“我需要 3 盒红笔。库存够吗?如果够,一共多少钱?”

这不是在考它会不会乘法。它首先缺少两个事实:现在有多少盒,每盒多少钱。 这两个数在库存文件里,而你发给模型的那句话没有包含它们。

模型现在收到的

“我需要 3 盒红笔。库存够吗?如果够,一共多少钱?”

只有任务,没有库存内容。

文件里实际保存的 · stock.csv
红笔库存5 盒
每盒单价12 元

我们把文件内容画在右边,是为了让你看清整个过程。模型并不会因为这份文件存在,就自动读到它。它能依据什么回答,取决于程序实际发给它的输入。

先预测,再展开

如果模型此时就回答“够,一共 36 元”,它已经完成查询了吗?

看看原因

没有。它可能猜对,但这次输入没有库存和价格,答案缺少查询依据。问题不是“36 算错了”,而是“5 和 12 从哪来”。接下来要建立一条取得证据的路径。

02 / 把三个不同的东西分开

让模型接触文件,需要一个包在它外面的程序。这个程序把任务发给模型,也接收模型的输出;当输出中包含一个合适的工具请求时,程序负责执行。

模型负责生成“接下来做什么”的请求。真正打开文件的是程序调用的读取函数。 库存文件提供本次任务所需的数据。

比如模型输出“读取 stock.csv”。把这句话打印在聊天窗口,只会多出一行文字;只有程序识别它并调用读取函数,文件才真的被访问。现实系统通常使用结构化请求,后续工具课再解释它怎样避免歧义。

这里可以先记住一个准确的区别:提出动作与执行动作,是两件事。 你稍后看到的 tool call,指的是前者,不是“模型自己进入文件系统”。

官方原课件 · Lecture 1 · PDF 第 13 页原课把模型与运行程序分开
官方第一讲PDF第13页:语言模型预测动作token,Harness解析校验执行调用,再返回观察token。

按箭头逐步看:左侧模型产生 read_file 请求,右侧 Harness 才执行并取得文件内容,再把结果变成观察。我们用库存文件替换了原图的 test.py,但没有改变职责边界:模型提出动作,外部程序执行动作。图里的 Reasoning 不代表我们可以检查模型所有内部计算。

03 / 一步一步看,信息到底走到哪了

下面两个面板一直保留:左边是模型输入,右边是文件和程序手里的结果(手机上依次上下排列)。每点一次“下一步”,只推进一个时刻。最值得留意的是第 3 步到第 4 步:读取已经成功,模型却还没看到结果。

实验 01

文件里有,不等于模型看到了

教学构造场景 · 数字按规则实算 · 未调用真实模型。先点「下一步」,观察信息怎样移动。

① 收到任务:模型还没有库存数据

你把任务发给了模型。右边文件里的内容尚未放进模型输入,所以现在不能据此判断够不够。

模型这次实际收到的内容

简化消息视图,省略系统说明与工具清单;不是完整 API 请求。

  1. 用户任务:我需要 3 盒红笔。库存够吗?如果够,一共多少钱?
等待第一次模型生成

尚未生成输出。

程序与文件

stock.csv · 教学数据
红笔库存5 盒
每盒单价12 元
读取函数返回给程序

还没有执行读取。

未回填
1 / 5
走完一次,再改变一个条件

改变条件后会回到第一步。先猜结论,再逐步验证。

这里的回答遵循「没有证据就说明未知」的教学规则。真实模型可能猜错、选错工具;这正是后续需要评测与校验的原因。

不操作也可以沿着下面五步走完同一个例子:

  1. 收到任务

    程序把“需要 3 盒,库存够吗”发给模型。输入中还没有库存数和单价。

  2. 提出动作

    模型生成“读取库存文件”的请求。到这里,它输出了文字或结构化数据,还没有发生文件读取。

  3. 程序执行

    程序调用读取函数,得到“库存 5 盒,单价 12 元”。结果先到程序手中;模型不会自动感知这个变化。

  4. 结果回填

    程序把这次动作与结果加入消息,连同原任务再次发给模型。第二次输入比第一次多了可核对的事实。

  5. 再次回答

    模型可以依据新输入判断数量、计算价格,并生成最终回答。程序将它展示给你,这次查询结束。

现在把最后一步真正算一遍:

库存 5 ≥ 需要 3 → 够
3 盒 × 12 元 / 盒 = 36 元

其中 3 来自你的任务,5 和 12 来自工具读取结果。每个数都找得到来源。“36 元”只是最后的计算;前面的读取与回填,让这个计算有了依据。

04 / 只改一件事,看看哪里会变

理解流程最好的办法,是让它在一个地方发生变化。回到实验的条件栏,分别试这三种情况。

情况一:库存从 5 盒变成 2 盒

保持任务和单价不变,走到最后。现在比较的是 2 < 3,还差 3 − 2 = 1 盒。回答应该说明数量不足,不能把“3 盒共 36 元”当作已经可以满足的订单。

改变的是环境提供的数据,不是模型凭空学会了新知识。 这个例子演示的是把新事实放进输入;我们没有更新模型权重。

情况二:程序读到了,但没有把结果回填

勾选“读到结果,但不回填”,再走到最后。右边仍能显示库存 5 盒,左边却没有这条消息。

不能因为你在屏幕上看见“读取成功”,就认为模型已经知道库存。需要核对的是:下一次发给模型的输入里,究竟有没有读取结果? 在本回放中,缺少结果就回答无法确认。

情况三:文件读取失败

取消上一项,勾选“文件读取失败”。这次回填的是一条错误,不是库存数据。模型可以据此解释失败、建议重试或请求帮助,但不能把“没读到”解释成“库存为 0”。

检查一个容易混淆的边界

“库存为 0”和“库存文件读不到”,下一步应该一样吗?

展开解释

不同。库存为 0 是已经得到的数据,可以判断没有货;文件读不到说明库存仍然未知,需要恢复读取或寻找其他可靠来源。这也是为什么工具结果要保留错误状态,而不能只返回一个空白值。

05 / 原来 Agent 的“循环”就在这里

刚才我们请求了模型两次。第一次,它提出读取请求;第二次,它看见读取结果后作答。

如果第二次还需要别的信息,比如另一个仓库的库存,它可以继续提出动作。程序执行后,再把结果送回。于是同一段过程可以重复:

看当前输入 → 提出动作 → 执行 → 得到新观察 → 再决定下一步。

这条反馈路径就是 Agent 循环的核心。现实里不一定只有一个工具,也不一定每次都成功;但每一步都可以用刚才的问题来检查:模型拿到了什么,输出了什么,程序实际做了什么,新结果有没有回来。

现在再把几个术语放回你已经看过的过程:

Agent 不是仅指那一个模型。 在这类系统中,模型、运行程序、工具和环境共同形成行动过程。模型再强,如果没有可用工具或执行程序,这个查询也不会自动触及你的本地文件。

它怎样停下来?

本例拿到足够的信息后,模型输出最终答案,程序结束查询。实际系统还会设置次数或费用限制、错误处理和人工中止等条件。模型给出结束信号,只是停止的一个依据,不等于外部任务已经被证明成功。我们会在评测课继续检查这一点。

一个小循环,怎样变成编码或研究 Agent?

读代码 → 改文件 → 跑测试,新的观察是测试结果;搜索资料 → 阅读来源 → 核对说法,新的观察是文章或证据。任务变了,工具变了,动作后的结果再影响下一步这条关系仍然存在。第一讲介绍这些应用,是为了说明同一套分工可以连接到不同环境。

让系统变好也有两条常见路径:改进运行程序,例如更可靠地保存结果;或者训练模型,让它更会选择动作。今天改善的是我们对运行过程的理解,SFT 和 RL 将在后面的训练单元展开。

06 / 合上图,用自己的话走一遍

下面不考术语背诵。先在心里回答,再展开核对。

问题 1 · 谁执行

模型输出了“读取库存文件”,文件却没有被访问。你先检查哪里?

核对思路

先检查宿主程序有没有识别动作请求、有没有调用读取函数,以及执行是否被权限或错误阻止。模型输出请求,并不能证明读取已经发生。

问题 2 · 信息在哪里

日志显示读取成功,但模型仍说不知道库存。要检查哪一份内容?

核对思路

检查下一次真正发给模型的输入。读取结果可能只存在于程序日志中,尚未回填;也可能被截断、格式错误或被后续上下文处理丢失。看“执行过”与看“模型收到了”是不同的检查。

问题 3 · 换一个数字

需要 3 盒,每盒 12 元。工具读回库存 3 盒。它应该怎样回答?如果只想知道 2 盒的价格,哪个输入要改变?

核对思路

3 ≥ 3,库存刚好够,总价 36 元。若需求改为 2 盒,应改变用户任务中的数量,价格计算为 2 × 12 = 24 元。库存记录不需要为了配合需求而改变。本页交互固定需求为 3 盒,这个问题请自己算。

能解释这三题,就已经抓住本课的主线:模型提出动作,程序执行;执行结果要进入新的输入,才会成为下一步判断的依据。

回看原课:每个机制都有原始位置

本课是对 CMU 第一讲中“动作如何发生”这一主题的中文改编。库存例子与实验由本项目自编,不是讲师的原案例,也不是一次真实模型实测。第一讲其余内容将按问题链继续展开。

来源核对:2026-10-25,官方课件与官方视频自动生成的英文字幕。时间定位依据字幕,自动字幕可能有识别误差,应以视频实际讲述和课件为准。

下一个问题 · 可直接阅读

工具跑完了,为什么模型还要再调用一次?

下一课把这五步对应到两次模型调用的消息数组,亲自检查原任务、动作和结果怎样拼进下一次输入,以及循环什么时候该停。你现在已经知道这条反馈路径为什么必要。

进入第二课:展开两次调用 →