13 个版本
0.1.32 | 2024 年 6 月 11 日 |
---|---|
0.1.31 | 2024 年 6 月 5 日 |
0.1.30 | 2024 年 5 月 24 日 |
0.1.25 | 2024 年 4 月 9 日 |
0.1.0 | 2024 年 1 月 14 日 |
#138 in 机器学习
1,026 每月下载量
760KB
3K SLoC
简化 Rust 中的 AI 代理 🕵🏼
espionox
是尝试使在 Rust 中构建 AI 应用程序与使用 LangChain 等其他库一样易于接近。
为什么我会使用 Espionox?
- 在 Rust 中制作 LLM 应用程序
- 实验复杂的 '提示流程',如链/思维树
入门
首先,您需要初始化一个 Agent
,Agent::new
接受两个参数
- 系统提示的可选内容,如果留空
None
,则您的代理将没有系统提示 - 一个
CompletionModel
,您希望使用哪个提供者(截至写作时,仅支持 OpenAi 和 Anthropic 提供者)。
use espionox::prelude::*;
let api_key = std::env::var("OPENAI_KEY").unwrap();
let agent = Agent::new(Some("This is the system message"), CompletionModel::default_openai(api_key));
现在,为了提示您的代理,您将调用其上的 do_action
let response: String = agent
.do_action(io_completion, (), Option::<ListenerTrigger>::None)
.await
.unwrap();
一开始这可能看起来很可怕,但让我们看看 do_action
的签名
pub async fn do_action<'a, F, Args, Fut, R>(
&'a mut self,
f: F,
args: Args,
trigger: Option<impl Into<ListenerTrigger>>,
) -> AgentResult<R>
where
F: for<'l> FnOnce(&'a mut Agent, Args) -> Fut,
Fut: Future<Output = AgentResult<R>>
do_action
接受 4 个参数
- 调用方法的
Agent
- 一个异步函数,它修改代理并返回一个
AgentResult
,它可以从anyhow::Result
强制转换。因此,只要函数签名返回任何AgentResult<T>
,只需确保在任何错误返回上调用.into()
即可,它应该是有效的。 - 可选的上述函数的参数
- 一个可选的监听器触发器(我们将讨论它)
因此,在我们之前的对 do_action
的调用中,我们传递了函数 io_completion
,一个空参数和 None。 espionox
提供以下辅助函数来获取补全或嵌入
io_completion
stream_completion
function_completion
我们使用了这些函数之一,但我们可以轻松地定义自己的 io_completion
函数,并在调用 do_action
时传递它
监听器
Espionox 最好的功能之一是 AgentListener
特性
pub trait AgentListener: std::fmt::Debug + Send + Sync + 'static {
fn trigger<'l>(&self) -> ListenerTrigger;
fn async_method<'l>(&'l mut self, _a: &'l mut Agent) -> ListenerCallReturn<'l> {
Box::pin(async move { Err(ListenerError::NoMethod.into()) })
}
fn sync_method<'l>(&'l mut self, _a: &'l mut Agent) -> AgentResult<()> {
Err(ListenerError::NoMethod.into())
}
}
您会注意到 3 个方法
trigger
:这是定义监听器何时被触发的方式。想想看就像一个 ID。ListenerTrigger
有两种变体ListenerTrigger::String(String)
ListenerTrigger::Int(i64)
记住trigger
参数到do_action
?确保在调用do_action
时通过传递匹配的ListenerTrigger
来触发监听器。
async_method
。如果实现了,函数体必须被包装在Box::pin(async move {})
sync_method
每个 async_method
和 sync_method
都是您定义监听器在触发时实际要做什么的地方。这些都是互斥的,只应实现其中一个方法。如果两个都实现了,则同步方法将是唯一触发的方法。任何实现此特性的结构都可以使用 Agent::insert_listener
插入到代理中。
您如何使用监听器呢??
监听器的用途可能一开始并不明显,但它可以用来创建自洽机制、提示链或甚至 RAG 管道。请参阅示例目录以获取有关 AgentListener
的更多信息
espionox 还处于早期开发阶段,API 中的所有内容都可能发生变化。请随时提问、建议、问题或其他任何事情 :)
依赖关系
~12–31MB
~516K SLoC