15个版本
新 0.2.3 | 2024年8月21日 |
---|---|
0.2.2 | 2024年7月27日 |
0.2.1 | 2024年6月6日 |
0.0.8 | 2024年3月22日 |
0.0.0 | 2023年9月19日 |
#12 in 机器人
每月352次下载
190KB
5.5K SLoC
dimas
DiMAS - 构建分布式多智能体系统的框架
⚠️ 警告 ⚠️ : DiMAS正在积极开发中,因此文档和实现之间存在差距。
分布式多智能体系统是一组广泛分布但某种程度相连的独立智能体。它们被设计成可以通过协同工作来解决复杂任务。
该系统具有以下特点
- 一个相对较大且复杂的环境
- 包含一组(非智能体)对象,智能体可以感知、创建、移动、修改或销毁这些对象
- 由于外部规则而随时间变化
有多个智能体在该环境中运行,它们
- 可以在一定程度上感知环境
- 可以与一些或所有其他智能体进行通信
- 具有影响环境的一定能力
此crate可在crates.io上找到。
DiMAS遵循语义版本控制原则,增强之处在于,直到版本1.0.0,每个新次要版本都有破坏性更改,而补丁是非破坏性更改,但可能包括增强。
用法
DiMAS需要一个async
运行时。您必须将您的main
函数定义为async
函数。
因此,在您的Cargo.toml
的依赖项部分中包含dimas
以及一个异步运行时。由于DiMAS使用tokio
作为异步运行时,因此最好使用tokio
来构建您的应用程序。请确保您使用了一个多线程运行时,否则DiMAS将会崩溃。
您的Cargo.toml
应包括
[dependencies]
dimas = "0.2"
tokio = { version = "1", features = ["macros"] }
返回一个 Result
也是有道理的,因为一些函数可能会返回一个。DiMAS 错误始终是类型 Box<dyn std::error::Error>
,并且应该是线程安全的。DiMAS 提供了一个类型定义 Result<T>
,以便使生活更加简单
合适的主程序骨架可能看起来像
use dimas::prelude::*;
#[tokio::main]
async fn main() -> Result<()> {
// your code
// ...
Ok(())
}
示例
一个非常简单的示例至少包括两个代理,一个 publisher
发布消息,一个 subscriber
监听这些消息。
此发布/订阅示例的 Cargo.toml
应包括
[dependencies]
dimas = version = "0.2"
tokio = { version = "1",features = ["macros"] }
发布者
的 publisher.rs
应看起来像这样
use dimas::prelude::*;
use std::time::Duration;
/// The Agent's properties
#[derive(Debug)]
struct AgentProps {
counter: u128,
}
#[tokio::main]
async fn main() -> Result<()> {
// create & initialize agents properties
let properties = AgentProps { counter: 0 };
// create an agent with the properties and default configuration
let mut agent = Agent::new(properties)
.config(&Config::default())?;
// create publisher for topic "hello"
agent
.publisher()
.topic("hello")
.add()?;
// use a timer for regular publishing of "hello" topic
agent
// get the TimerBuilder from the agent
.timer()
// set a name for the timer
.name("timer")
// every second
.interval(Duration::from_secs(1))
// the timers callback function as a closure
.callback(
|ctx| -> Result<()> {
let counter = ctx
.read()?
.counter;
// the message to send
let text = format!("Hello World! [{counter}]");
// just to see what will be sent
println!("Sending '{}'", &text);
// publishing with stored publisher for topic "hello"
let message = Message::encode(&text);
ctx.put("hello", message)?;
// modify counter in properties
ctx
.write()?
.counter += 1;
Ok(())
}
)
// finally add the timer to the agent
// errors will be propagated to main
.add()?;
// start the agent
agent.start().await?;
Ok(())
}
订阅者
的 subscriber.rs
应看起来像这样
use dimas::prelude::*;
/// The Agent's properties
#[derive(Debug)]
pub struct AgentProps {}
fn callback(_ctx: &Context<AgentProps>, message: Message) -> Result<()> {
let message: String = message.decode()?;
println!("Received '{message}'");
Ok(())
}
#[tokio::main]
async fn main() -> Result<()> {
// create & initialize agents properties
let properties = AgentProps {};
// create an agent with the properties and default configuration
let agent = Agent::new(properties)
.config(&Config::default())?;
// subscribe to "hello" messages
agent
// get the SubscriberBuilder from the agent
.subscriber()
//set wanted message topic (corresponding to publishers topic!)
.topic("hello")
// set the callback function for put messages
.put_callback(callback)
// finally add the subscriber to the agent
// errors will be propagated to main
.add()?;
// start the agent
agent.start().await?;
Ok(())
}
更多示例
您可以在 dimas-fw/dimas/examples 中找到一些简单的示例,以及在 dimas-fw/examples 中找到更复杂的示例
依赖项
~28–41MB
~650K SLoC