大模型时代的基础设施:从 Framework 到 Harness
你买过一块没有操作系统的 CPU 吗?
插上电,它什么也干不了。不是算力不够,是没人告诉它算什么、数据从哪来、结果往哪去、出了错怎么办。
今天很多人用大模型的方式,就像在裸机上写汇编------直接调 API,手动拼 prompt,自己管上下文,自己写重试逻辑。能跑,但累。
LangChain、LlamaIndex 这些 Framework 解了一部分问题。 它们像 C 标准库,把常用操作封装成函数,你不用从零写起。但你仍然是那个写主循环的人------调用什么、什么时候调用、失败了怎么办,全靠你自己。
Harness 是另一回事。 它是大模型的操作系统。
Framework ≈ 标准库
写 C 程序,你不会手写 printf。你 #include <stdio.h>,调标准库。标准库帮你处理缓冲区、格式化、系统调用,但主函数是你的:
c
int main() {
printf("Hello"); // 标准库提供封装
scanf("%s", buf); // 你决定什么时候读
printf(buf); // 你决定什么时候写
return 0; // 你控制流程
}
传统 AI Framework 干的是一样的事:
python
from langchain.chains import RetrievalQA
chain = RetrievalQA.from_chain_type(
llm=ChatOpenAI(model="gpt-4"), # 选模型
retriever=vectorstore.as_retriever(), # 配检索
)
result = chain.run("什么是 harness?") # 你决定什么时候调
Framework 提供了封装------Chain、Agent、Tool、Retriever------但流程由你定义。你决定调哪个模型、什么时候检索、输出怎么解析。模型只是你代码里的一个函数调用。
这没什么问题。很多场景下你本来就想精细控制每一步。就像写嵌入式程序,你不需要 Linux,一个裸机循环就够了。
问题是:当任务变复杂、步骤变多、Agent 需要自主决策的时候,你发现自己写了越来越多的调度逻辑、错误处理、上下文管理......你在手写一个操作系统。
Harness ≈ 操作系统
操作系统的职责是什么?不是替你算,而是管好算力周围的一切:
| OS 组件 | 职责 |
|---|---|
| 进程调度器 | 决定下一个执行什么 |
| 内存管理 | 分配、回收、虚拟内存换页 |
| 系统调用 | CPU 访问外设的统一接口 |
| 权限控制 | 进程不能越界 |
| 文件系统 | 持久化存储 |
| 日志 | 记录发生了什么 |
Harness 对大模型做的事一模一样:
| Harness 组件 | 对应 OS | 职责 |
|---|---|---|
| Orchestration Loop | 进程调度器 | 模型思考 → 行动 → 观察 → 再思考(ReAct 循环) |
| Context Engineering | 内存管理 | 上下文窗口有限,需要压缩、检索、换页 |
| Tools / MCP | 系统调用 | 模型访问外部能力的统一接口(文件读写、搜索、代码执行) |
| Guardrails | 权限控制 | 过滤危险输入输出,限制操作范围 |
| Memory System | 文件系统 / 存储 | 短期对话记忆 + 长期知识持久化 |
| Sandbox | 容器 / VM | 隔离执行环境,防止模型"炸机" |
| Observability | syslog / 监控 | 追踪每一步决策,调试用 |
| Prompt / Instructions | 可执行程序 | 告诉模型该干什么、怎么干 |
关键区别:谁主控?
在 Framework 里,你的代码是操作系统,模型是被调度的进程。你写 if/else、for 循环,模型只是被你调用的函数。
在 Harness 里,模型是 init 进程。它决定下一步做什么。Harness 是它脚下的操作系统,提供工具(系统调用)、管理上下文(内存)、限制权限(guardrails),但不规定它该走哪条路。
python
# Framework 思路:你写调度逻辑
def handle_query(query):
context = retriever.search(query) # 第1步:检索
prompt = build_prompt(query, context) # 第2步:拼提示词
answer = llm.chat(prompt) # 第3步:调模型
if needs_tool(answer): # 第4步:你判断
result = call_tool(answer.tool_call) # 第5步:你执行
answer = llm.chat(prompt + result) # 第6步:再调模型
return answer
python
# Harness 思路:你定义环境和工具,模型自己调度
agent = Agent(
model="claude-sonnet-4-6",
tools=[file_read, file_write, bash_run, web_search], # 系统调用
instructions="你是一个代码助手,只能操作项目目录", # 可执行程序
guardrails=[output_filter, file_scope_limit], # 权限控制
memory=ConversationMemory(max_tokens=200000), # 内存管理
)
result = agent.run("修复这个项目的 lint 错误")
# 模型自己决定:先看哪些文件、改哪里、跑什么测试、失败了怎么办
在 Harness 模式下,你没有写 if needs_tool() ------ 模型自己判断要不要调工具、调哪个、调几次。就像你写用户态程序,你不需要告诉内核什么时候调度下一个进程。
对照表:Framework vs Harness
| Framework | Harness | |
|---|---|---|
| 类比 | 标准库(glibc) | 操作系统(Linux) |
| 谁控制流程 | 你的代码(if/else/for) | 模型自主推理 |
| 模型角色 | 被调用的函数 | init 进程(第一个用户进程) |
| 工具 | 你定义、你调用 | 你定义,模型自己调用 |
| 上下文管理 | 你手动拼接 | Harness 自动工程化 |
| 失败处理 | try/catch + 重试 N 次 | 模型自己判断重试策略 |
| 安全 | 靠你写校验 | 内置权限系统 |
| 可观测性 | 你自己加 log | 内置追踪和调试 |
| 上手成本 | 低,装个库就行 | 中,需要理解系统设计 |
| 适合场景 | 固定工作流、简单链式调用 | 开放任务、长时间运行、需要自主决策 |
从裸机到操作系统:一个演进路径
不是每个项目都需要 Day 1 就装操作系统。演进路径很自然:
css
阶段 1:裸机调用(raw API)
直接 HTTP 请求,手写 prompt。就像写裸机汇编。
适合:简单的问答、翻译、摘要。
阶段 2:装个标准库(Framework)
引入 LangChain / LlamaIndex,用 Chain 和 Agent 封装。
适合:固定工作流,步骤已知。
阶段 3:装操作系统(Harness)
用 Claude Code、Agent SDK 等搭建完整运行环境。
适合:开放任务,Agent 需要自主决策。
阶段 4:多操作系统协作(Multi-Agent Harness)
多个 Agent 各自有独立的 Harness,通过消息通信。
适合:复杂系统,需要专业化分工。
转折点在阶段 2 → 3。当你在 Framework 里写的调度逻辑、错误处理、上下文管理代码加起来超过 500 行的时候,你就该考虑 Harness 了------你已经写了一半的操作系统,不如用一个现成的。
一个例子:修复代码
同样一个任务------"修复这个项目的 lint 错误"。
Framework 思路:
python
# 你需要预判所有步骤
files = list_source_files() # 你知道要先列文件
for f in files:
lint_result = run_lint(f) # 你知道要跑 lint
if lint_result.has_errors:
prompt = f"修复这些错误:{lint_result}"
fix = llm.chat(prompt) # 调模型修
apply_fix(f, fix) # 你应用修改
run_lint(f) # 你验证结果
如果中间某步失败了?你写 try/catch。如果模型修了反而引入新问题?你写回滚。如果文件之间有关联?你写依赖分析。代码越写越多。
Harness 思路:
python
agent = Agent(
model="claude-sonnet-4-6",
tools=[read_file, write_file, run_bash],
instructions="修复 lint 错误,每个文件修完要验证",
sandbox="./project", # 只能操作这个目录
)
result = agent.run("修复所有 lint 错误")
模型自己看文件、跑 lint、修代码、验证、遇到问题自己调整策略。Harness 提供工具和安全边界,但不规定步骤。
一句话
Framework 是库,你调它;Harness 是操作系统,它托着你和模型。 模型越强,你越不该用代码限制它的行为,而是该为它搭一个可靠的运行环境。
就像没人会抱怨 Linux 限制了 CPU 的发挥------恰恰相反,没有操作系统,CPU 就是一块发热的硅片。