跳到主要内容

Rig — 架构与原理

30 秒导读: Rig 是一个 Rust 库,用一套统一抽象把「20+ 个 LLM 供应商 + 10+ 个向量库」包在同一个接口后面,让你用最少的样板代码搭出从「一句话问答」到「带工具、带知识库的多轮 agent」的应用。它最出彩的一手,是把 agent 的多轮循环抽成一台完全不做 IO、可以序列化到磁盘再换个进程恢复的状态机。

本页是整套文档的入口:先讲清「Rig 是什么」(零基础),再给一张顶层全景图看懂大盘,最后给一张阅读地图告诉你哪一章讲什么、按什么顺序读。


1. 这是什么(零基础也能懂)

一句话定义

Rig 是一个 Rust 语言的 LLM 应用框架:你写业务逻辑,它负责把「调用哪个大模型、怎么发请求、怎么解析回复、怎么循环调用工具、怎么查知识库」这些脏活标准化。

解决什么问题 / 给谁用

假设你要用 Rust 写一个「会查资料、会调用工具的 AI 助手」,不用 Rig 你会遇到三件麻烦事:

  • 每个供应商 API 都不一样。 OpenAI 的请求体、Anthropic 的请求体、Cohere 的请求体字段全不同;换个模型就得重写一遍。
  • 工具调用要手写循环。 模型说「我要调 search 工具」,你得解析出来、真的去执行、把结果塞回对话、再问一次模型……这个循环容易写错。
  • 接向量库做 RAG 又是一套。 MongoDB、Qdrant、Postgres 的向量检索 API 各不相同。

Rig 把这三件事分别用**三个统一特征(trait)**盖住,你只依赖抽象,不依赖具体供应商。给谁用:Rust 后端 / agent / RAG 系统的开发者

它能做什么(功能)

  • 一套接口调 20+ 供应商的 completion(文本生成)和 embedding(向量化)模型。
  • 高层 Agent 类型:系统提示 + 上下文文档 + 工具 + 多轮循环,开箱即用。
  • 一套接口接 10+ 向量库,直接当 agent 的知识库(RAG)。
  • 结构化输出(让模型返回能反序列化成 Rust 结构体的 JSON)。
  • 流式输出、多轮流式、对话记忆、生命周期 hooks、OpenTelemetry 遥测。
  • 转录、音频生成、图像生成等多模态能力。核心库还能编译到 WASM。

用起来什么样

最小示例——三行核心逻辑就能问一次模型(源码地图见 crates/rig-core/src/lib.rs 顶部文档注释):

// 示意,改编自 crates/rig-core/src/lib.rs 顶部文档示例
use rig_core::{client::ProviderClient, completion::Prompt, providers::openai};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let openai = openai::Client::from_env()?; // 从环境变量读 API key
let agent = openai.agent(openai::GPT_5_2).build(); // 造一个 agent
let answer = agent.prompt("Who are you?").await?; // 问一句,拿到字符串
println!("{answer}");
Ok(())
}

注意最后一行 .prompt("...").await?:从「一句话」到「一个 String」,中间那套「发请求 / 解析 / 可能还要循环调工具」全被 Rig 藏起来了。

一句话直觉 / 类比

把 Rig 想成 LLM 世界的 ORM + 连接池:ORM 让你不管底层是 MySQL 还是 Postgres 都用同一套查询接口;Rig 让你不管底层是 OpenAI 还是 Anthropic 都用同一套 agent.prompt(...)。你换供应商,只改一行 Client

本节到此不碰任何底层代码。你只要记住:Rig = 「LLM / 工具 / 向量库」三件事的统一抽象层 + 一个能自己跑多轮循环的 agent。


2. 顶层全景(它大概怎么转)

怎么读这张图

从上到下是「你的代码 → 高层抽象 → 三大统一特征 → 具体后端」。中间那层的三个特征是整个库的承重墙;换后端只换最底下那层。

你的应用代码 (agent.prompt / extractor.extract / index.top_n)

┌──────────────────────────┼───────────────────────────┐
▼ ▼ ▼
┌─────────┐ ┌──────────────┐ ┌──────────────┐
│ Agent │ 多轮循环 │ Extractor │ 结构化抽取 │ EmbeddingsBuilder │
│ (高层封装)│─────┐ │ (结构化输出) │ │ (批量向量化) │
└─────────┘ │ └──────────────┘ └──────────────┘
│ │ 都往下落到 ↓ │
┌────┴──────────┴────────────────┐ ┌──────────────┐ ┌──┴───────────────┐
│ CompletionModel (特征) │ │ Tool (特征) │ │ EmbeddingModel/ │
│ 统一的「请求→回复」接口 │ │ 统一的工具接口 │ │ VectorStoreIndex │
└────────────────┬────────────────┘ └──────┬───────┘ └──────┬───────────┘
▼ ▼ ▼
OpenAI / Anthropic / Gemini / 你的 Rust 函数 / MongoDB / Qdrant /
Cohere / Ollama … 20+ 供应商 MCP server Postgres … 10+ 向量库

部件一句话职责

部件干什么在哪
Agent<M>把模型 + 系统提示 + 上下文 + 工具 + 多轮循环打包成一个可反复调用的对象crates/rig-core/src/agent/completion.rsAgent
AgentRunagent 多轮循环的「大脑」:一台不做 IO 的可序列化状态机,只决策不执行crates/rig-core/src/agent/run/mod.rsAgentRun
CompletionModel所有 completion 模型的统一特征:把 Rig 的规范请求变成回复crates/rig-core/src/completion/request.rs:613CompletionModel
CompletionRequestRig 的规范请求表示,provider 负责翻译成自家请求体crates/rig-core/src/completion/request.rs:668CompletionRequest
Messageprovider 无关的消息模型(System/User/Assistant + 多模态内容)crates/rig-core/src/completion/message.rs:22Message
Tool所有工具的统一特征:名字 + JSON schema + 执行函数crates/rig-core/src/tool/mod.rs:116Tool
VectorStoreIndex向量检索的统一特征:top_n 查最相近的 N 条crates/rig-core/src/vector_store/mod.rs:84VectorStoreIndex
providers::*每个供应商一个模块,实现上面几个特征crates/rig-core/src/providers/(约 25 个)

主线走一遍(高层,不进代码)

agent.prompt("查一下天气然后总结") 为例,端到端是这样一条链:

输入 prompt


Agent 组装规范请求 CompletionRequest(塞进 preamble / 工具定义 / 上下文文档)


AgentRun 状态机说:"下一步该调模型" (CallModel)


选中的 provider 把 CompletionRequest 翻译成自家 HTTP 请求,发出、收回、翻译回 Message


模型回复里有工具调用?
├─ 有 → 状态机说 "下一步该执行工具" (CallTools) → 执行 → 结果塞回对话 → 回到调模型
└─ 没有 → 状态机说 "完成" (Done) → 返回最终文本

关键点:「决策」和「执行 IO」是分开的。 AgentRun 只吐出「下一步该干嘛」,真正发 HTTP、跑工具由外层驱动器(driver)做。这条设计线是第 2 章的主角,也是 Rig 最值得学的地方。


3. 阅读地图(各章讲什么,建议顺序)

建议按顺序读,每章都建立在前一章的抽象上:

顺序章节讲什么读完你能
101-completion-providers.md最底层的统一抽象:CompletionModel 特征、Message 数据模型、CompletionRequest 规范请求、provider 怎么实现说清「一次 completion 从 Rig 请求到 provider 回复」怎么走
202-agent-loop.mdAgent 类型 + AgentRun 无 IO 状态机 + 「决策/执行分离」的驱动循环说清 Rig 的多轮 agent 循环为什么能序列化、能换进程恢复
303-tools.mdTool 特征、ToolDyn 动态分发、ToolSet、非法工具调用的 Fail/Retry/Repair/Skip 恢复、MCP 接入自己写一个工具,理解模型「乱调工具」时框架怎么兜底
404-rag-embeddings.mdEmbed 特征、EmbeddingsBuilderVectorStoreIndex、动态上下文/动态工具(RAG)、Extractor 结构化抽取搭一个带知识库的 RAG agent,让模型返回结构化数据
505-advanced-and-map.mdhooks 生命周期、流式与多轮流式、对话记忆、OutputMode(issue #1928)、边界局限、横向对比、代码地图掌控高级特性并知道 Rig 的取舍与边界

如果你只想快速定位

  • 想知道「怎么换供应商」 → 第 1 章(CompletionModel + providers)。
  • 想知道「多轮循环怎么实现的、能不能持久化」 → 第 2 章(AgentRun),这是全库最精华的一章。
  • 想知道「工具乱调怎么办」 → 第 3 章(非法工具调用恢复)。
  • 想搭 RAG → 第 4 章。
  • 想接遥测 / 流式 / 记忆 → 第 5 章。

说明:本文档只解剖 rig-core(核心库)。仓库里另有 rig-mongodbrig-qdrantrig-bedrock 等约 18 个伴生 crate,它们只是针对具体后端实现核心库定义的特征,原理在核心库里都讲清楚了。