【手写一个能日常使用的 Agent】 实现Chatbot

项目初始化:手写一个能日常使用的 Agent

随着 AI 发展越来越快,模型能力也越来越强,Agent 已经越来越频繁地参与到日常开发流程里。

我平时用得最多的是 Codex 和 Claude Code。虽然大概知道它们背后的工作原理,比如对话循环、工具调用、上下文管理、文件编辑、命令执行等,但很多细节仍然停留在"知道概念"的层面,并没有真正拆开理解。

想把这些细节弄清楚,最直接的办法有两个:一个是读源码,另一个是自己实现一遍。现在 Codex 有开源实现,Claude Code 也可以通过反编译和行为观察去研究,但只读源码很容易停留在旁观者视角。相比之下,自己手搓一个能真正用于日常开发的 mini-agent,可以在实现过程中逐步理解 Agent 的关键机制。

所以,我决定从零开始写一个自己的 mini-agent

为什么选择 Rust

技术选型上,我选择用 Rust 来实现这个项目。

原因很简单:我刚学完 Rust 语法,还谈不上非常熟练。如果只是看书或者写一些小 demo,很多知识点很快就会忘。用 Rust 完成一个真实的 Agent 项目,可以把所有权、生命周期、异步、错误处理、模块组织、trait 抽象这些内容都串起来。

当然,说通过这个项目就能"精通 Rust"有点夸张,但至少它会逼着我在真实场景里反复使用 Rust,而不是只停留在语法练习阶段。

项目定位

这个项目的目标不是复刻一个完整的 Claude Code 或 Codex。

主流编码 Agent 已经非常成熟,功能也很完整。我的目标更现实:先做一个自己能日常编码使用的 mini-agent,然后在使用过程中不断迭代它。

初始版本会比较简单,但后续会逐步实现这些能力:

  • TUI 交互界面
  • 多轮对话
  • 流式输出
  • Tool use
  • MCP 支持
  • Plan 模式
  • Memory
  • Skill
  • Subagent
  • mini-agent 迭代 mini-agent

最后一点是我最期待的:当基础能力足够之后,就用它来继续开发它自己。这样既能验证 Agent 的可用性,也能更深入地理解一个编码 Agent 在真实开发中的能力边界。

架构图先行

目前先按最小可运行版本来设计,后续边做边调整。很多架构细节不需要一开始就定死,先让核心 loop 跑起来,再逐步补齐能力。

第一阶段:先实现一个 Chatbot

第一阶段的目标很简单:实现一个基础的对话 loop,支持流式输出和多轮对话。

这其实是 Agent 的前身:Chatbot。

它只能聊天,还不能真正帮我们干活。没有工具调用,就不能读文件、改代码、执行命令;没有上下文压缩和状态管理,长对话也很快会失控。但所有 Agent 的核心都离不开这个最基础的循环:

  1. 接收用户输入
  2. 构造 messages
  3. 调用模型
  4. 流式输出回复
  5. 把 assistant response 写回上下文
  6. 等待下一轮用户输入

这个 loop 跑通之后,再往上叠加工具调用、Plan 模式、Memory、Skill、Subagent,整个 Agent 的形状才会慢慢清晰起来。

项目初始化

先把 workspace 和三个核心 crate 建起来:

sql 复制代码
cargo new mini-agent
cd mini-agent
mkdir crates

cargo new crates/agent-cli --bin
cargo new crates/agent-core --lib
cargo new crates/provider --lib

然后在根目录的 Cargo.toml 里配置 workspace:

ini 复制代码
[workspace]
resolver = "2"

members = [
    "crates/agent-cli",
    "crates/agent-core",
    "crates/provider",
]

目前项目结构大概是这样:

bash 复制代码
crates/
  agent-cli/    # CLI / TUI 入口,负责用户交互
  agent-core/   # Agent 核心逻辑:对话、消息、loop、工具调度等
  provider/     # 模型 provider 抽象:OpenAI-compatible、Claude API 等

这个拆分的思路是:

  • agent-cli 只负责交互入口,不直接关心模型调用细节。
  • agent-core 放 Agent 的核心行为,包括 message 管理、会话循环、上下文维护等。
  • provider 抽象不同模型供应商,避免核心逻辑和某个 API 绑定太死。

这样做的好处是后续扩展会更自然。比如先接入 OpenAI-compatible API,之后再接 Claude API、Gemini 或本地模型时,只需要实现新的 provider,而不是改动整个 Agent 核心。

API 设计

第一阶段的 API 不需要设计得太复杂,先把最小对话链路跑通。

当前代码里的核心骨架大概是这样:

实际调用流程可以理解成这样:

这里最关键的是 Agent 不直接关心具体 API 怎么调用,它只依赖 Provider trait。现在的 OpenAIProvider 只是其中一个实现,内部再根据 ApiType 分成 completionsresponses 两条路径。

第一版先保证这些能力稳定:

  • 初始化一个 Agent
  • 接收用户输入
  • 保存多轮上下文
  • 通过 Provider 发起流式请求
  • 在 CLI 里流式输出模型回复
  • 输出完成后,把 assistant response 写回历史记录

后面真正加入 tool use 时,再扩展 tool_usetool_result 和 tool dispatch loop。

测试

简单测试一下在终端中是可以跑通的!

代码

github.com/Groos-dev/m...

小结

这篇文章算是 mini-agent 的开篇记录。

我想通过这个项目把 Agent 的核心机制拆开:先从最简单的多轮对话开始,然后一步步加入工具调用、计划模式、记忆系统、MCP 和子 Agent。最终目标是写一个自己真的会用、并且能持续迭代的编码 Agent。

下一步,先把最基础的 loop 跑起来。

相关推荐
chaowwwww1 小时前
从0开始实现个人最简harness项目
人工智能·agent
付玉祥1 小时前
给 Agent 加一个 Approval Gate
agent
程序猿小卡2 小时前
模型越来越便宜之后,AI 应用团队要重算的不是 token 价格
agent·ai编程
songrongzhen2 小时前
easy-agent:面向 Spring Boot 的轻量级 Agent 能力组件
agent
星航夜空的帆舟5 小时前
ADK 模型抽象与多模型集成:从 Gemini 到 Ollama
go·agent
前端一小卒13 小时前
我用 TypeScript 从零手写了一个 Claude Code,然后发现它的核心只有 30 行
前端·agent
云烟成雨TD15 小时前
LangFlow 1.x 系列【5】可视化编辑页面功能说明
人工智能·python·agent
阿拉斯攀登16 小时前
Agent 核心架构:思考-行动-观察循环(ReAct)
人工智能·ai·agent·react
8Qi817 小时前
HelloAgents:RAG——让 Agent 学会检索知识
人工智能·llm·agent·ai编程·vibecoding