为什么我们把 Agent 当工程对待与共处:一个真正的文件系统、一个 Workspace 而非单文档、逐字节对齐 Claude Code 的工具方言,以及 —— 像 Claude Code 一样,用 grep 而不是向量化。
Why we treat Agents like engineers: a real file system, a Workspace rather than a single document, bit-exact parity with Claude Code’s tool dialect, and — like Claude Code — grep instead of vector search.
给 Agent 做工具这件事,很容易走错方向。最常见的错误是:把 Agent 当成一个初级产品运营,给它一堆听起来像产品功能的 API—— create_document、summarize_file、search_memory—— 看起来很「智能」,但每一个 API 都是一个新语汇、一个新心智模型、一次新的提示工程。
huozi 走的是相反的方向。我们认为,Agent 应该被当成工程师对待: 给它工程师用的东西——一个文件系统、一个 workspace、一套 Unix 风格的原语工具。这篇文章写我们五个核心设计原则,以及背后的推理。
我们没有造「文档 API」。我们造的是一个真正的文件系统,以路径寻址:
huozi_read({ file_path: "notes/2026/w17-review.md" })
huozi_edit({
file_path: "data/roadmap.csv",
old_string: "Q2,Planning",
new_string: "Q2,Shipping",
})
huozi_glob({ pattern: "drafts/**/*.md" })
为什么用文件系统?因为文件系统是过去五十年人类最成功的工程抽象之一—— 每一个工程师都会用,每一个大语言模型都在训练语料里见过几百万次 ls、cat、grep、sed。我们不需要再教 Agent 一套新语法。
文件系统还给我们几个「免费」的好处:
projects/2026/q2/roadmap.md 比一个叫 doc_7f3a8b 的 ID 能告诉 Agent 多得多,而且只要几个 token。做完一个文件系统,下一个陷阱是把它当成「许多孤立文档的集合」。但 Agent 做任何真实任务时,它关心的都是上下文: 这个项目的目录结构长什么样?README 里写了什么约定?有没有类似的现有文件可以参照?提交历史告诉我最近发生了什么?
所以 huozi 的最小单位不是「文档」,是 Workspace: 一整棵版本化的文件树,所有写入都落在同一个提交图里,Agent 可以把整个树当一个项目来推理。
# Agent 的一次真实对话:
> 我想在 analytics 目录下加一个新指标
# Agent 不会凭空写。它会先:
huozi_glob({ pattern: "analytics/**" }) # 看现有结构
huozi_read({ file_path: "analytics/README.md" }) # 读约定
huozi_grep({ pattern: "defineMetric" }) # 找类似写法
huozi_history({ file_path: "analytics/retention.ts" }) # 最近谁改过
# ——然后才 huozi_write 新文件。
这是工程师的工作流。如果接口只给它一个 create_document,它会失去所有这些上下文,只能盲写。Workspace 的存在,就是让 Agent 能像人一样,先看再做。
提交(commit)也是 Workspace 级的,不是单文件级的。huozi_batch_edit 可以在一次提交里跨多个文件原子性地改——这对需要跨文件保持一致性的重构非常关键。
huozi 的 MCP 工具——huozi_read、huozi_edit、huozi_write、huozi_glob、huozi_grep、huozi_batch_edit、huozi_history—— 在 schema、错误码、行号分页、edit 的字符串唯一性规则上,与 Claude Code 内置的文件工具逐字节一致。
这不是偶然。我们是刻意把 Claude Code 的工具语义移植过来: 同样的 old_string → new_string 替换契约、同样的 replace_all 标志、同样的 file_unchanged 缓存响应、同样的 cat-n 风格行号输出。
为什么?三个原因:
cd 了一下。这是最常被挑战的一条,也是我们最确信的一条。
很多「Agent 知识库」产品的第一反应是:把所有文件 chunk、embed、存进向量库,让 Agent 用语义搜索找相关内容。huozi 不这么做。我们跟 Claude Code 一样——用 grep 和 glob,按需扫描,返回事实。
原因不是偷懒,是深思熟虑:
huozi_grep("defineMetric") 告诉你这个标识符在哪几个文件的哪几行。Agent 能去读上下文、理解为什么匹配、作出判断。向量搜索告诉你「这五个文件可能相关,相似度 0.87」—— Agent 拿到的是一个它无法质疑的黑盒分数。getUserById 还是 get_user_by_id,向量嵌入会把它们聚到一起,而 grep 告诉你精确的区别。对工程任务,精确比「相近」重要一万倍。工程上,我们用 D1 的 FTS5 trigram 索引给 grep 做预过滤——跟本地 ripgrep 的体验一致,但规模化到 Workspace 的整棵树,通常比遍历树快 50 倍。依然是 grep,依然是事实,只是更快。
一句话:代码和文档应该用读代码和文档的方式来用,不是用搜论文的方式。
Agent 的运行成本是 token。每一个工具调用的返回,都在消耗 Agent 的上下文预算。所以 huozi 每一个工具,都是围绕「让 Agent 能以最少 token 拿到正确答案」设计的:
huozi_read 返回 file_unchanged——零字节。offset: 200, limit: 50,不必每次把整个文件拖回来。huozi 的核心假设是:Agent 不是需要被包装好的用户,而是一个能用 Unix 工具的工程师。所以我们不造新抽象,我们把 Agent 已经会的东西—— 文件系统、路径、grep、commit、patch—— 完整地给它。Workspace 住在 Agent 之外,Agent 只是来操作它的 CPU。
文件为器,Agent 为工。
Building tools for Agents is easy to get wrong. The most common failure mode is treating the Agent like a junior product operator and handing it a pile of API endpoints that sound product-shaped — create_document, summarize_file, search_memory. It looks smart, but every endpoint is a new vocabulary, a new mental model, a new round of prompt engineering.
Huozi goes the opposite way. We believe Agents should be treated like engineers — so we hand them the things engineers use: a file system, a workspace, a set of Unix-flavoured primitive tools. This post lays out the five principles we designed around, and the reasoning behind each.
We didn’t build a “document API.” We built a real file system, addressed by paths:
huozi_read({ file_path: "notes/2026/w17-review.md" })
huozi_edit({
file_path: "data/roadmap.csv",
old_string: "Q2,Planning",
new_string: "Q2,Shipping",
})
huozi_glob({ pattern: "drafts/**/*.md" })
Why the file system? Because it is one of the most successful engineering abstractions of the last fifty years. Every engineer knows it. Every LLM has seen millions of examples of ls, cat, grep, and sed in its training corpus. There is no new grammar to teach.
The file system gives us three things for free:
projects/2026/q2/roadmap.md tells the Agent far more than an opaque doc_7f3a8b ever could — and in a handful of tokens.Once you have a file system, the next trap is treating it as “a collection of isolated documents.” But any realistic Agent task is about context: what does the project’s directory structure look like? What conventions does the README spell out? Is there a similar existing file I can model mine on? What do recent commits tell me about what’s going on?
So Huozi’s unit of addressability is not a document. It is a Workspace: a full, versioned file tree, every write landing in the same commit graph, the whole thing reasonable-about as a single project.
# A real Agent turn:
> I want to add a new metric under analytics/
# The Agent won't just write blindly. It first:
huozi_glob({ pattern: "analytics/**" }) # see the shape
huozi_read({ file_path: "analytics/README.md" }) # read conventions
huozi_grep({ pattern: "defineMetric" }) # find prior art
huozi_history({ file_path: "analytics/retention.ts" }) # who changed this?
# — then, and only then, huozi_write the new file.
That is an engineer’s workflow. If we only gave the Agent a create_document, it would lose all of that context and have to write blind. The Workspace exists precisely so the Agent can look before it leaps.
Commits are workspace-level, not file-level. huozi_batch_edit performs N changes across any number of files atomically, in one commit — essential for refactors that need cross-file consistency.
Huozi’s MCP tools — huozi_read, huozi_edit, huozi_write, huozi_glob, huozi_grep, huozi_batch_edit, huozi_history — are bit-exact with Claude Code’s built-in file tools. Same schemas, same error codes, same line-offset pagination, same string-uniqueness contract on edit.
This is not an accident. We deliberately ported the semantics of Claude Code’s toolbox across: the same old_string → new_string replacement contract, the same replace_all flag, the same file_unchanged cache response, the same cat-n-style line numbers.
Three reasons:
cd.This is the principle we get challenged on the most, and also the one we’re most certain about.
The reflex reaction for most “Agent knowledge base” products is to chunk everything, embed it, shove it into a vector store, and let the Agent do semantic search. Huozi refuses. Like Claude Code, we grep and glob on demand, returning ground truth.
This is not laziness; it’s deliberate:
huozi_grep("defineMetric") tells you exactly which files, which lines. The Agent can go read the context, decide why it matched, and make a judgement. Vector search hands the Agent a black-box number it can’t audit — “these five files look related, similarity 0.87.”getUserById or get_user_by_id matters, and matters precisely. Embeddings blur that distinction away; grep preserves it. For engineering work, precision beats “nearby” by a huge margin.Operationally, we use D1’s FTS5 trigram index as a pre-filter for grep — same experience as local ripgrep, scaled across the whole Workspace tree, typically 50× faster than a tree walk. Still grep. Still ground truth. Just faster.
In one line: code and documents deserve to be used the way code and documents are used — not the way you search a pile of research papers.
The running cost of an Agent is tokens. Every tool result spends some of the Agent’s context budget. So every Huozi tool is designed to let the Agent get the right answer with the fewest tokens:
huozi_read returns file_unchanged — zero bytes.offset: 200, limit: 50 and skip pulling the whole file back.Huozi’s core assumption is that an Agent is not a user who needs to be wrapped in product-shaped APIs — it is an engineer who can use Unix tools. So we don’t invent new abstractions. We hand the Agent exactly what it already knows how to use — a file system, paths, grep, commits, patches — in full. The Workspace lives outside the Agent; the Agent is just the CPU operating on it.
Files as the vessel. Agents as the craft.