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 结构缺少必填字段的内容,应该由谁拒绝?答案不是模型自己,也不是工具函数,而是进入下一层前的协议校验。

下一章会处理这个问题:流式响应为什么要拆成事件,以及“看到文字”为什么不等于“运行完成”。

下一章:屏幕上的字为什么不等于运行完成?

进入 keel 阅读