0-qwen3-chat-demo.ipynb 代码说明这份 notebook 是一个最小文本对话 demo。
它的目标不是训练模型,而是让学生先看到:
如果你把它和 5/2-prog/0-qwen3-vl-demo.ipynb 对照着看,会发现:
contentcontent 之外多了 images所以这份 notebook 可以看成视觉 notebook 的更简单基础版。
这份 notebook 的流程非常短:
这一格说明:
qwen3.5:0.8b它帮助学生先建立一个边界:
这一格是提示说明,不执行代码。
它的作用是让学生知道:
代码是:
import json
import os
import urllib.request
import urllib.error逐个解释:
import json 作用:把 Python 字典转成 JSON 字符串。import os 作用:后面清理代理环境变量。import urllib.request 作用:发 HTTP 请求。import urllib.error 作用:捕获请求错误。和前面的视觉版本相比,这里没有:
base64mimetypesPath因为文本对话不需要读图片,也不需要处理文件。
这一格告诉学生:
prompt = '请用三句话解释什么是预训练,以及它为什么改变了 NLP。'
prompt逐行解释:
prompt = '...' 把一个中文问题存进变量里。prompt 直接显示变量内容,方便确认自己写的是什么。为什么要先用变量,而不是直接把文本写死在下面的请求里?
因为这样更方便:
这一格的意义是让学生知道:
代码是:
payload = {
'model': 'qwen3.5:0.8b',
'stream': False,
'messages': [
{
'role': 'user',
'content': prompt,
}
],
}
payload逐项解释:
'model': 'qwen3.5:0.8b' 指定本次调用哪个本地模型。'stream': False 表示不要流式返回。 对课堂展示更简单。'messages': [...] 表示这是一个对话输入。'role': 'user' 表示消息来自用户。'content': prompt 把刚才定义的 prompt 作为用户问题塞进去。为什么 messages 是列表?
因为对话可能有多轮:
这里只做最简单的一轮,所以列表里只有一条用户消息。
这一步帮助学生切换思路:
代码是:
request = urllib.request.Request(
'http://localhost:11434/api/chat',
data=json.dumps(payload).encode('utf-8'),
headers={'Content-Type': 'application/json'},
method='POST',
)逐行解释:
'http://localhost:11434/api/chat' 是本地 Ollama 的聊天接口。json.dumps(payload) 把 Python 字典转成 JSON 字符串。.encode('utf-8') 再把字符串转成字节,方便发送。headers={'Content-Type': 'application/json'} 告诉服务端:这次发的是 JSON。method='POST' 说明这是一次提交数据的请求。接下来:
for key in [
'http_proxy',
'https_proxy',
'HTTP_PROXY',
'HTTPS_PROXY',
'all_proxy',
'ALL_PROXY',
]:
os.environ.pop(key, None)
opener = urllib.request.build_opener(urllib.request.ProxyHandler({}))这一段的作用是:
为什么要这么做?
因为很多同学电脑里会有:
这些配置有时会把本地 localhost 请求也一起带偏。
os.environ.pop(key, None) 的意思是:
然后:
urllib.request.ProxyHandler({})表示:
最后:
with opener.open(request) as response:
result = json.loads(response.read().decode('utf-8'))这一段表示:
这一格是过渡说明。
它的意义是告诉学生:
result['message']['content']这里是最简单、但最值得学生记住的一格。
它说明:
message -> content这一格告诉学生:
看输出会怎样变化
代码是:
payload['messages'][0]['content'] = '请比较 GPT、BERT、T5 三条路线的主要差别。'这一句的作用是:
这是一种很适合教学的写法,因为它能让学生看到:
后面这段请求代码和前面几乎一样:
requestopener.open(...)最后:
result['message']['content']直接显示新的回答。
payload 里最核心的三个字段是:model、stream、messages。现象:
URLError说明:
现象:
model not found说明:
现象:
localhost说明:
这也是为什么这里专门清理代理配置。