大模型智能体 (agent)简易流程介绍
下面是一个使用 Rig 构建的简单 Agent 示例。它定义了一个计算工具,并让 Agent 自主决定是否调用它。
为什么不用langChain? 这个问题放到最后说
1 核心代码示例
在 Cargo.toml 中,只需要 rig-core 和 tokio。
use rig::{completion::Prompt, providers::openai};
use serde::{Deserialize, Serialize};
// 1. 定义工具的输入参数(强类型,类似 Java 的 DTO)
#[derive(Deserialize, Serialize, JsonSchema)]
struct AddArgs {
x: i32,
y: i32,
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::pub_error::Error>> {
// 2. 初始化客户端 (这里以 OpenAI 为例,也支持 Gemini/Claude)
let client = openai::Client::from_env();
// 3. 定义一个工具 (Tool)
// 在 Rust 里,工具就是一个带有元数据的函数
let add_tool = rig::tool::Tool::new(
"add",
"Adds two numbers together",
|args: AddArgs| async move {
Ok(args.x + args.y)
},
);
// 4. 构建 Agent (典型的 Builder 模式)
let agent = client
.agent("gpt-4o")
.preamble("你是一个精通数学的助手。")
.tool(add_tool) // 注册工具
.build();
// 5. 提示并运行
let response = agent.prompt("请问 123 加上 456 等于多少?").await?;
println!("Agent 回复: {}", response);
Ok(())
}
简单不简单
-
JsonSchema派生宏: 在 Rust 里,通过#[derive(JsonSchema)],Rig 会自动生成 LLM 需要的 JSON 描述。这比 Python 里手动写描述字符串要安全得多,修改字段名时编译器会帮你检查。 -
异步原生 (Tokio):由于 Agent 往往需要等待网络 IO(模型响应、API 调用),Rig 基于
tokio构建,能完美集成到你的高性能后端服务中。 -
零碎抽象:Rig 不像 LangChain 那样强迫你学习 Chain、Memory、OutputParser 等几十个概念。它认为 Agent = Model + Prompt + Tools。这种扁平化设计让调试变得非常简单。
2 简易流程
既然第四步请求了gpt为什么第三步还要创建一个函数,难道gpt会使用这个函数吗?
当然!
这是非常关键的一个点,也是 Agent(智能体) 与普通 Chatbot(聊天机器人) 的本质区别。
答案是:GPT 可能会发出了一个“调用指令”。
这里把这个过程拆解为三个阶段(这在 Java 中类似于远程过程调用 RPC 或反射):
1. 宣告能力
在第 4 步 build() 时,Rig 会把第 3 步定义的工具元数据(函数名:add,描述:Adds two numbers together,参数结构:x, y)转换成一个 JSON Schema,并随问题一起发给 GPT。
发送给 GPT 的隐藏信息:
“用户问了:123+456 等于多少?另外,我这有一个工具叫 add(x, y),如果你觉得用得着,可以告诉我。”
2. 逻辑决策
GPT 接收到请求后,它不会直接回答“答案是 579”。它会分析语义,发现自己需要做数学运算,于是它不返回文本,而是返回一个 Function Call 请求。
GPT 返回给 Rig 的信号:
{ "call": "add", "arguments": { "x": 123, "y": 456 } }
3. 本地执行
这时候,Rig 框架(在你的 Rust 程序里)收到了这个信号。它会:
- 在本地查找到我们刚注册的那个
add_tool函数。 - 把 GPT 给出的 JSON 参数反序列化为 Rust 的
AddArgs结构体。 - 真正运行我们的 Rust 代码(执行
x + y)。 - 把结果
579再发回给 GPT。 - GPT 看到结果后,最后组织语言回答你:“123 加上 456 等于 579。”
这就是agent的过程。但是你应该会问:“为什么要这么麻烦?直接让 GPT 算不行吗?”
因为
-
GPT 并不擅长计算: 对于
12345 * 67890这种大数,GPT 经常会一本正经地胡说八道。 -
GPT 无法触达外部世界: 它不能直接查询你的 MySQL 数据库,不能调用你的 Java 微服务接口,也不能读写本地文件。
通过这种模式,你可以把 llm 当成一个“大脑”,而把你的 Rust 函数当成它的“手”:
-
大脑(GPT) 负责拆解任务、理解意图、决定什么时候该用什么工具。
-
手(Rust 函数) 负责精准执行、访问私有数据、处理重型计算。
或者你把它想象成一个数据库查询
findUserById(Long id), GPT 就能根据用户的聊天内容,自动调用我们本地的能力,好像是去数据库里查数据了。
3 为什么不用langChain?
LangChain 是目前生态最丰富、功能最完备的 Agent 框架,但它已经不再是唯一的选择。
现在不再把 LangChain 看作一个单一的库,而是一个全栈生态系统。
它之所以被认为“最完整”,是因为它覆盖了从原型开发、生产环境编排到后期监测的全生命周期。
有核心铁三角:LangChain + LangGraph + LangSmith。
Rig 呢
而Rig (rig-core) 代表了与 LangChain 完全不同的进化方向:极致的性能、类型安全以及底层掌控力。
-
Rust 原生: 享受 Rust 的内存安全和零成本抽象。这意味着在处理数千个并发 Agent 请求时,它的资源占用远低于 Python。
-
类型安全(Type Safety): 在 LangChain 里,你经常会遇到“运行时错误”(运行到一半才发现变量类型不对)。而在 Rig 中,依靠 Rust 强大的编译器,大部分逻辑错误在代码编译阶段就能被揪出来。
-
极简抽象: 相比于 LangChain 嵌套五六层的类继承,Rig 的设计非常扁平,代码读起来直观得多。
流程编排呢
Rig 并没有像 LangGraph 那样引入复杂的“图”概念。(现阶段)它倾向于让开发者通过 Traits 和 异步流 来处理逻辑。
-
Rig 的解决方式: 它提供了一套清晰的 Agent 和 Tool 定义规范。虽然它没有内置像 LangGraph 那样的“可视化状态机”,但通过 Rust 的枚举(Enums)和模式匹配(Pattern Matching),能写出比 Python 更加严密的状态转换逻辑。
-
RAG 支持: Rig 内置了非常轻量化的向量存储抽象,特别适合构建高性能的检索增强生成应用。
浙公网安备 33010602011771号