KEEL · 龙骨 · A CURRICULUM FOR THE AI ERA
02. 先让模型只做一件事:生成消息 — keel 龙骨
这一章的目标很窄:你只需要学会调用 Ollama,并知道一次调用返回了什么。暂时不引入 Agent loop、工具注册表或数据库。
这一章的目标很窄:你只需要学会调用 Ollama,并知道一次调用返回了什么。暂时不引入 Agent loop、工具注册表或数据库。
一次调用的输入和输出
from ollama import chat
response = chat(
model="qwen3:8b",
messages=[
{"role": "user", "content": "用一句话解释 INC-001。"}
],
)
print(response.message.content)
模型收到的是消息,不是 Python 函数。它返回的是供应商响应对象,不是已经通过业务校验的最终结果。
适配器为什么存在
不同模型供应商的字段、流式事件和错误类型可能不同。项目的 ollama_adapter.py 把供应商对象转换成内部对象,让 Harness 不必在每个模块里读取 response.message.content。
Ollama Response
-> Ollama Adapter
-> Internal ModelResponse
-> Harness
适配器只做协议转换,不应修改业务数据库,也不应决定是否执行工具。
运行示例并观察三类结果
ollama serve
ollama pull qwen3:8b
python courses/foundation/agent-harness/course/project/examples/01_chat.py
你需要把结果分成三类:
| 结果 | 发生在哪里 | 处理方式 |
|---|---|---|
| 模型服务不可达 | Model Adapter | 重试或返回基础设施错误 |
| 响应无法解析 | 协议层 | 记录原始响应,拒绝进入动作层 |
| 内容不符合业务要求 | 应用层 | 由业务校验决定是否接受 |
流畅的自然语言不代表业务结果正确。
先做一个确定性对照
在测试里不要依赖模型“这次说了什么”。项目测试会用固定的 fake response 验证 Adapter 能否把响应转换成内部对象。这样你可以单独测试:
合法响应 -> Internal ModelResponse
缺少 message -> protocol_error
服务异常 -> model_unavailable
真实 Ollama 用来观察供应商行为,fake response 用来验证 Harness 不变量。
模型名称和能力不是一回事
qwen3:8b 可以用于普通对话;thinking、structured outputs 和 tool calling 是否可用,需要按模型与 Ollama 能力验证。不要把“能生成文本”推断为“能完成所有 Agent 协议”。
本章自测
如果 Ollama 返回了一段看似合理、但 JSON 结构缺少必填字段的内容,应该由谁拒绝?答案不是模型自己,也不是工具函数,而是进入下一层前的协议校验。
下一章会处理这个问题:流式响应为什么要拆成事件,以及“看到文字”为什么不等于“运行完成”。