Agentic AI 基础 · 我的智能助手L3Grade 10

Python 文件读写
让 AI 长出手脚

数据从文件里来、到文件里去 · 程序怎么和模型对话 · 模型怎么用你的函数

自备电脑Jupyter + WorkBuddy本课件的代码可以直接运行

本节课内容

今天的路线

  1. 1文件操作基础:路径 · open · 读写(含 6 个常见坑)
  2. 2LLM API 调用:程序怎么和 AI 对话
  3. 3Tool Use:Function Calling——AI 怎么用你的函数
  4. 4接口约定:把工具说明写清楚
  5. 5设计你自己的一个工具
学完这节课,你应该能

· 读一个 txt、把结果写回一个文件
· 说清一次 API 调用的四个要素
· 讲清 AI 调用工具的完整过程

上半场 Python:数据从文件里来、到文件里去;下半场 AI:程序怎么和模型对话、怎么把工具交给它。

上节课回顾这些都练过了

今天只换一个数据来源

函数与 return

把结果交回去,不是只 print

筛选四步

空列表 + 循环 + 条件 + append

GCCD 四项

目标 · 背景 · 限制 · 怎样算完

MEMORY.md

给 WorkBuddy 的长期说明书

nums = [59, 60, 85]            # 数据在列表里
result = []
for x in nums:
    if x >= 60:
        result.append(x)
result = []
with open("scores.txt", encoding="utf-8") as f:
    for line in f:              # 数据在文件里
        if line.strip() != "":
            result.append(line.strip())

数据来源从「列表」换成「文件」——形状全是熟悉的筛选四步。

环境检查这页可以直接动手

这份课件里的代码,点 ▶ 就能跑

它是怎么做到的

页面里装了一个真正的 Python(Pyodide,跑在浏览器里)。不用装软件,也不用服务器。

操作

Shift+Enter 运行 · 同一页上面定义的变量下面能用 · 改坏了点「↺ 还原」

但是

作业还是在你自己电脑的 Jupyter 里做:打开 L3_homework.ipynb,能跑出 print 的举手。

上半场 · 文件读写

数据,不只活在代码里。

成绩在 txt / CSV 里——程序要能读进来、写出去,才能干真活。

文件放在哪路径

同一行 open("scores.txt"),文件放哪儿很要紧

推荐:把数据文件和 notebook 放在同一个文件夹,用相对路径。路径写错,程序就找不到文件。

open三个参数

open:文件名 · 模式 · 编码

# 三个参数,各管一件事
open("scores.txt",       # ① 文件名(或路径)
     "r",                # ② 模式:读 / 写 / 追加
     encoding="utf-8")   # ③ 编码:防中文乱码
模式含义
"r"只读(默认);文件不存在 → FileNotFoundError
"w"只写;会清空原内容;不存在则新建
"a"追加;写到末尾,不清空

encoding="utf-8":不写它,中文容易报错或乱码。

open动画 · 三种模式

同一个文件,三种打开方式

with open自动关文件

with:缩进里文件开着,缩进一退就关

1 with … as f: 打开,f 就是这个文件

2 缩进里就是「文件打开着」的范围

3 中途出错也会关——本课统一用 with

动手读 scores.txt

跑一下:一行一行读出来

左边是这个网页里的「虚拟文件夹」,每次运行后会刷新;新文件、改过的文件会闪一下。

读的三种方式只推荐第三种

read · readlines · for line in f

写法得到什么什么时候用
f.read()整个文件 → 一个字符串整段文本要一起处理时
f.readlines()每行一个元素 → 列表(带 \n)想先拿到一整个列表时
for line in f:一行一行拿,边读边处理✅ 推荐:正好接上循环
行尾的换行符strip()

"85\n" ≠ "85"

文件里每行末尾都藏着 \n;不 strip 掉,比较永远失败。line.strip() 去掉首尾的空白和换行。

写文件换行要自己写

write() 不会自动换行

write() 不会自动加换行,要自己写 "\n";writelines(list) 逐条写,也不加换行。

常见坑 6 条点卡片看报错 · 今天大概率会中一条

报错先对照这 6 条

1 "w" 一开就把原文件清空
不报错,数据就没了! → 输出文件换个名字:result.txt
2 忘了 \n,全挤一行
Alice PASSBob FAIL → f.write(row + "\n")
3 忘了 encoding,中文乱码
UnicodeDecodeError: 'gbk' codec… → encoding="utf-8"
4 忘了 strip,比较总失败
"85\n" == "85" → False → line = line.strip()
5 "r" 打开不存在的文件
FileNotFoundError: [Errno 2] No such file or directory: 'score.txt' → 检查文件名拼写
6 文件不在同目录、路径写错
FileNotFoundError(同上) → 放进 notebook 所在文件夹

FileNotFoundError 找第 5 / 6 条,中文乱码找第 3 条。

文件读写四步范式逐行追踪 · 按 ▶ 一步一步看

打开 → 读 → 处理 → 自动关

动手练作业 ① 的课堂版

清洗 scores.txt → result.txt

验收还没有 result.txt

通过后挑战 L1 的 B4:把它写成函数 process_scores(input_path, output_path),每行写「姓名 PASS/FAIL」,返回有效条数。

下半场 · LLM API

程序怎么和 AI 对话

你和 AI 的每一次聊天,
背后都是一次 API 调用。

什么是 LLM API模型不在你的电脑上

API 就是约定好的「点餐窗口」

发出去什么、收回来什么,都有固定格式

模型跑在服务商的机房里

你的程序只负责发请求、接回答

一次 API 调用四个要素

地址 · 凭证 · 模型 · 消息

要素是什么打个比方
base_url请求发到哪;每家服务商一个去哪家店
api_key证明你是谁;像密码,别外传会员卡
model用哪个模型,如 deepseek-flash点哪个厨子
messages对话内容,一个列表你的菜单
最小的一次调用四要素都在这几行里

四行 setup + 一次 create

这个网页里的模型

默认是离线模拟模型:不联网、不花钱、结果固定。右上角可以换成真实模型。

跑通它

输出里有「20」——你的程序第一次直接和模型对话。

Key 是密码,谁拿到谁花钱。别写进要提交的作业,别发到群里。

messages对话的三种角色

多轮对话 = 这个列表越来越长


      
system设定:AI 是谁、按什么风格回答
user你说的话:问题、要求
assistantAI 的回答:上一轮说过什么
回答在哪儿response 的结构

一层一层取到底

temperature回答的随机程度

temperature:0 = 每次尽量一样

模型其实在「抽签」

它给每个候选词一个概率,再按概率抽一个。

低 temperature

高分词几乎必中 → 回答稳定。本课演示统一用 0。

高 temperature

冷门词也有机会 → 更有创意,也更容易跑偏。

关键模型没有记忆

每次调用都是全新的一单

想让 AI「接着聊」,就把之前的问答都放进 messages 一起发过去。这不是缺陷,是设计。

动手验证「没有记忆」

同一个问题,带不带历史

② 用的是 ① 里创建的 client——先跑 ①。

Tool Use · Function Calling

AI 只会说文字。

想让它干活?
把工具挂到这条对话通道上——工具,就是你定义的函数。

AI 的边界只会说,不会做

会聊天 ≠ 会干活

AI 能做的

理解你的问题,给出回答
写出一段 Python 代码
决定「这件事该怎么做」

AI 做不到的

读你电脑里的 scores.txt
自己运行一段代码
把结果写进一个新文件
精确地算大数

模型是「猜下一个词」猜出答案的,大数心算常常差几位。要让它干真活,得把「手脚」借给它——这就是 Tool Use。

一次工具调用的完整过程Function Calling 五步

AI 只点菜,你的程序来做菜

五步对照代码

每一步都是一行代码

发生了什么代码
1带上工具清单,发起提问llm_with_tools.invoke([HumanMessage("...")])
2AI 返回「调用请求」:工具名 + 参数ai_msg.tool_calls
3你的程序执行函数calculate.invoke(tool_call)
4执行结果加回对话历史messages.append(tool_msg)
5再问一次,AI 给出最终回答llm_with_tools.invoke(messages)

全程 AI 只做两件事:决定调什么、消化结果。真正执行函数的,是你的 Python 程序。

绑定把工具说明变成 AI 能读的格式

@tool:AI 读的是三样东西

没绑定的工具,AI 完全不知道它存在——你写的 process_scores 也一样,绑了才能用。

演示 ①现场跑 · 先看它给什么

AI 返回的是「调用请求」

它返回了一张「点菜单」

没有自己算,也没有瞎编答案:调哪个工具、参数是什么。菜,得你的程序来做。

试试

① 跑完后,把最后一行换成 calculate.schema(),看模型读到的说明书。
② 把 query 改成 "(3+4)*5 是多少"。

演示 ②把菜做完,端回去

执行 → 回传 → 最终回答

第二次 invoke

AI 看到的是完整历史:问题、点菜单、执行结果——消化了结果,才给出最终回答。

先跑上一页

这一格接着用上一页的 messages、ai_msg、calculate。

AI 用工具的三种常见翻车都怪说明书没写清

编造工具 · 参数给错 · 无视返回值

编造工具

清单里没有的工具,它可能自己「发明」一个,还说调用成功了。

→ 绑定的工具清单要写全

参数给错

args 格式不对,函数当场报错。

→ 参数的类型和说明要写清

无视返回值

返回明明是 "Error: Invalid expression",它却说算好了。

→ 返回值的含义要写明

接口约定表绑定说明的完整形态

先约好接口,再各写各的

工具名输入输出出错时
calculate(expression)expression: str,数学表达式结果的字符串返回 "Error: Invalid expression"
process_scores(in, out)输入文件路径、输出文件路径结果文件 + 有效条数文件不存在 → 报错,提醒用户
查单词(word, word_list)一个单词、一个单词列表位置(从 0 起)或 -1查不到 → 返回 -1,不报错
你的新工具…???

@tool 定义里的每一行——名字、参数、说明、返回值——填进这张表就是一格。
L7 分组以后,你们要一起把这张表填起来。

课堂练习个人 4 分钟 + 邻座互看 2 分钟

设计一个工具,画盒子图

改上面的格子,下面的代码和约定表跟着变。互看只查两件事:输入输出是否清晰?能不能单独测试?

挑战把你的工具绑上模型

写好说明书,模型才会选对工具

步骤

① 改写 grade 或换成你自己的工具
② 先单独测试函数(不用模型)
③ 再绑定,看模型会不会点它

观察

把 docstring 删掉再跑——离线模拟模型是按 docstring 找工具的,真模型也一样依赖它。

今天带走的三句话

三句话

  1. 1文件——打开 → 读写 → 处理 →(with 自动)关闭
  2. 2API——地址、凭证、模型、消息;每次调用带全历史
  3. 3工具——AI 只点菜不执行;绑定就是把说明书写清楚
作业清单可拍照 · 交 Classroom

作业

做什么交什么
作业 ①文件读写:读 scores.txt → 扔掉空行和 # 行 → 写入 result.txt,最后一行「共 N 条有效成绩」L3_homework.ipynb,result.txt 正好 6 行
作业 ②为学习场景设计 2 个工具每个:盒子图 + 按 @tool 格式写说明(工具名 / 参数及类型 / docstring);写得清楚的下节课现场绑上演示
选读L1_补充_Python数据结构.ipynb不计考核;给 L4 铺路

交作业前对照六坑自查一遍。别把 API Key 写进要提交的作业。

下次课 · L4

列表与字典
让 AI 自我检查(Reflection)

数据会放进文件了,下一步是把它处理得更聪明。