OpenCode 学习笔记 01:核心架构 - Tool + Provider + Agent Loop

Phase 1 完整实现:理解 AI Agent 的三大支柱

January 19, 2026·5 min read·Yimin
#AI#Agent#OpenCode#TypeScript#Tool#ReAct

一个 AI Agent 的核心只有三件事:定义工具、调用 LLM、循环执行。

本篇目标

理解 AI Agent 的核心架构,并在 tiny-agent 中实现:

  • Config:依赖注入风格的配置管理,支持 proxy
  • Tool:定义 AI 可以使用的工具
  • Provider:统一调用多个 LLM
  • Agent Loop:ReAct 循环执行

一、AI Agent 的本质

1.1 从 ChatBot 到 Agent

ChatBot 只能聊天:

用户: 帮我看看 package.json
AI: 我无法访问你的文件系统...

Agent 可以行动:

用户: 帮我看看 package.json
AI: [调用 read 工具] → 读取文件 → 这是一个 TypeScript 项目...

关键区别:Agent 有工具,能做事

1.2 ReAct 模式

AI Agent 的思考方式叫 ReAct(Reasoning + Acting):

┌─────────────────────────────────────────────────────────┐
│                    ReAct 循环                           │
│                                                         │
│   用户输入 → LLM 思考 → 需要工具?                       │
│                            │                            │
│              ┌─────────────┴─────────────┐              │
│              ↓ 是                        ↓ 否           │
│         执行工具                      输出回答           │
│              ↓                                          │
│        返回结果给 LLM                                    │
│              ↓                                          │
│         继续思考... ─────────────────────→              │
│                                                         │
└─────────────────────────────────────────────────────────┘

核心思想:边想边做,做完再想,循环往复。

1.3 四个核心模块

模块职责类比
Config管理配置(API Key、proxy...)大脑的设置
Tool定义 AI 可以使用的工具AI 的手脚
Provider调用 LLM(GPT/Claude...)AI 的大脑
Agent Loop循环执行直到完成AI 的思考方式

二、配置系统(依赖注入)

2.1 为什么需要配置系统?

参考 planning-apiSettings 设计,我们需要:

  • 集中管理:API Key、Base URL 统一配置
  • 支持 Proxy:公司内网可能需要代理访问 LLM API
  • 方便切换:开发用便宜模型,生产用强模型

2.2 设计要点

环境变量驱动

环境变量说明示例
OPENAI_API_KEYOpenAI API 密钥sk-xxx 或 proxy key
OPENAI_BASE_URLOpenAI 代理地址https://proxy.example.com/v1
ANTHROPIC_API_KEYAnthropic API 密钥
ANTHROPIC_BASE_URLAnthropic 代理地址
DEFAULT_PROVIDER默认使用的 Provideropenai / anthropic / cerebras

Proxy 模式:如果公司有统一的 AI 网关,只需配置 BASE_URL 指向网关即可。

2.3 OpenCode 对应

OpenCode 的配置在 config/config.ts,支持:

  • 多 Provider 配置
  • 模型别名映射
  • 自定义 headers

三、Tool 系统

3.1 Tool 是什么?

Tool 是 AI 可以调用的能力。每个 Tool 包含:

属性说明示例
name工具名称read
description给 LLM 看的说明"读取文件内容"
parameters参数定义(JSON Schema){ path: string, limit?: number }
execute实际执行的函数读取文件并返回内容

3.2 为什么用 Zod?

Zod 是 TypeScript 的 schema 验证库,作用:

  1. 定义参数类型:LLM 返回的参数会被验证
  2. 自动生成描述.describe() 告诉 LLM 参数含义
  3. 类型推导:TypeScript 自动推导参数类型

OpenCode 的所有工具参数都用 Zod 定义。

3.3 Tool 工作流程

LLM 决定调用工具
        ↓
生成 JSON 参数 { "path": "package.json" }
        ↓
Zod 验证参数 ✓
        ↓
执行 execute 函数
        ↓
返回结果给 LLM

3.4 OpenCode 的工具列表

OpenCode 有 20+ 个工具,主要分类:

类别工具功能
文件操作read, write, edit, glob读写搜索文件
代码理解grep, codesearch搜索代码
命令执行bash执行 shell 命令
网络websearch, webfetch搜索和获取网页
交互question向用户提问
任务task, todo子任务管理

我们从最简单的 read 开始实现。


四、Provider 抽象

4.1 为什么需要 Provider?

不同 LLM 有不同的 API:

ProviderSDK调用方式
OpenAIopenaichat.completions.create()
Anthropic@anthropic-ai/sdkmessages.create()
其他各种 SDK各种方式

Provider 层统一这些差异,让上层代码不关心具体用哪个模型。

4.2 Vercel AI SDK

OpenCode 使用 Vercel AI SDKai 库)来统一 LLM 调用:

  • 统一接口generateText() / streamText() 适用所有模型
  • 工具支持:内置 Tool 调用支持
  • 流式输出:支持流式响应

我们也使用这个库。

4.3 模型选择

tiny-agent 支持的模型:

Provider模型特点
OpenAIgpt-4o, gpt-4o-mini全能,速度快
Anthropicclaude-3-5-sonnet代码能力强
Cerebrasllama-3.3-70b开源,便宜

通过 provider:model 格式指定,如 openai:gpt-4o-mini


五、Agent Loop

5.1 核心逻辑

Agent Loop 的本质是一个循环:

  1. 发送消息给 LLM
  2. LLM 返回文本或工具调用
  3. 如果是工具调用,执行工具,把结果加入消息
  4. 重复 1-3,直到 LLM 不再调用工具

5.2 maxSteps 防护

为防止无限循环,设置最大步骤数:

  • 默认值:10 步
  • 超过后:强制停止,返回当前结果

OpenCode 的 Agent 也有类似机制。

5.3 一次完整的执行

用户: "读取 package.json 并告诉我项目名称"

Step 1:
  LLM 思考 → 需要 read 工具
  调用 read({ path: "package.json" })
  返回文件内容

Step 2:
  LLM 看到文件内容
  思考 → 已经有了需要的信息
  输出 "这个项目叫 tiny-agent"

完成(2 步)

六、实现总结

6.1 目录结构

tiny-agent/src/
├── config/
│   └── index.ts       # 配置管理(依赖注入)
├── tool/
│   ├── tool.ts        # Tool 抽象定义
│   └── read.ts        # read 工具
├── provider/
│   └── index.ts       # Provider 抽象(支持 proxy)
├── agent/
│   └── loop.ts        # Agent Loop
└── index.ts           # 入口

6.2 核心函数

模块核心函数功能
ConfigSettings.get()获取配置
ToolTool.define()定义工具
ProviderProvider.getModel()获取模型实例
AgentAgentLoop.run()执行 Agent 循环

6.3 运行

cd external/tiny-agent

# 配置(直连或 proxy)
export OPENAI_API_KEY=your-key
export OPENAI_BASE_URL=https://your-proxy.com/v1  # 可选

# 运行
bun dev

七、与 OpenCode 对比

方面tiny-agentOpenCode
Config简单环境变量完整配置文件 + CLI
Tool简化版含权限、元数据、截断
ProviderAI SDK 直接使用自己封装转换层
Agent Loop单循环支持多 Agent 切换

OpenCode 额外功能(后续篇章讲解):

  • 工具权限控制(permission/
  • 输出截断(防止 token 爆炸)
  • 多 Agent 模式(build/plan/explore)
  • 会话持久化
  • Snapshot 回滚

八、关键理解

  1. Config 是依赖注入

    • 集中管理,支持 proxy
    • 方便切换不同环境
  2. Tool 是 AI 的手脚

    • 让 AI 能做事,而不只是聊天
    • Zod 保证参数正确
  3. Provider 是 AI 的大脑

    • 不同模型,统一接口
    • 支持 proxy 访问
  4. Agent Loop 是 AI 的思考方式

    • ReAct:边想边做
    • maxSteps 防止失控

下一步

Phase 2 将实现更多工具:

工具功能学习重点
write写入文件如何安全写文件
edit编辑文件模糊匹配如何工作
bash执行命令如何处理危险命令
grep搜索代码正则匹配

让 Agent 真正能写代码!


代码仓库

完整代码:external/tiny-agent/

cd external/tiny-agent
make dev   # 运行