본문 바로가기
WIKI 기술 지식 베이스

Rust SDK

원문 보기 위키 갱신

AgentFS Rust SDK로 고성능 상태 저장(stateful) AI 에이전트를 만들어 보세요.

출처: 문서

본문

설치

Cargo.toml에 AgentFS를 추가하세요:

[dependencies]
agentfs = "0.1"
tokio = { version = "1", features = ["full"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"

빠른 시작

use agentfs::{AgentFS, AgentFSOptions};
use anyhow::Result;

#[tokio::main]
async fn main() -> Result<()> {
    // Persistent storage with identifier
    let agent = AgentFS::open(AgentFSOptions::with_id("my-agent")).await?;
    // Creates: .agentfs/my-agent.db

    // Or use ephemeral in-memory database
    let ephemeral = AgentFS::open(AgentFSOptions::ephemeral()).await?;

    // Use the three main APIs
    agent.kv.set("key", "value").await?;              // Key-value store
    agent.fs.write_file("/file.txt", b"data").await?; // Filesystem
    agent.tools.record(...).await?;                   // Tool tracking

    Ok(())
}

핵심 API

AgentFS 구조체

모든 AgentFS 작업의 주 진입점이에요.

AgentFS::open(options: AgentFSOptions)

AgentFS 데이터베이스를 만들거나 열어요.

use agentfs::{AgentFS, AgentFSOptions};

// Persistent storage with identifier
let agent = AgentFS::open(AgentFSOptions::with_id("my-agent")).await?;
// Creates: .agentfs/my-agent.db

// Ephemeral in-memory database
let ephemeral = AgentFS::open(AgentFSOptions::ephemeral()).await?;

AgentFSOptions 설정:

pub struct AgentFSOptions {
    /// Optional unique identifier for the agent.
    /// - If Some(id): Creates persistent storage at `.agentfs/{id}.db`
    /// - If None: Uses ephemeral in-memory database
    pub id: Option<String>,
}

impl AgentFSOptions {
    /// Create options for a persistent agent with the given ID
    pub fn with_id(id: impl Into<String>) -> Self;

    /// Create options for an ephemeral in-memory agent
    pub fn ephemeral() -> Self;
}

필드

  • kv: 키-값 저장소 인터페이스
  • fs: 파일시스템 인터페이스
  • tools: 도구 호출 추적 인터페이스
  • db: 기반 Turso 데이터베이스에 직접 접근

키-값 저장소 API

Serde 직렬화를 지원하는 빠르고 타입 안전한 저장소예요.

kv.set<T: Serialize>(key: &str, value: T)

직렬화 가능한 어떤 값이든 저장해요.

use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize)]
struct UserPreferences {
    theme: String,
    language: String,
}

// Store structured data
agent.kv.set("user:preferences", UserPreferences {
    theme: "dark".to_string(),
    language: "en".to_string(),
}).await?;

// Store primitives
agent.kv.set("counter", 42).await?;
agent.kv.set("active", true).await?;

kv.get<T: DeserializeOwned>(key: &str) -> Option<T>

값을 가져와서 역직렬화해요.

// Get with type inference
let prefs: Option<UserPreferences> = agent.kv.get("user:preferences").await?;

// Handle missing values
if let Some(count) = agent.kv.get::<i32>("counter").await? {
    println!("Counter: {}", count);
}

// With default
let theme = agent.kv.get::<String>("theme").await?.unwrap_or("light".to_string());

kv.delete(key: &str)

키-값 쌍을 제거해요.

agent.kv.delete("session:expired").await?;

kv.list(options: ListOptions)

필터링과 페이지네이션으로 키를 나열해요.

use agentfs::ListOptions;

// List all keys
let all_keys = agent.kv.list(ListOptions::default()).await?;

// Filter by prefix
let user_keys = agent.kv.list(ListOptions {
    prefix: Some("user:".to_string()),
    limit: Some(100),
    cursor: None,
}).await?;

// Paginate
let page1 = agent.kv.list(ListOptions {
    limit: Some(10),
    ..Default::default()
}).await?;

let page2 = agent.kv.list(ListOptions {
    limit: Some(10),
    cursor: page1.cursor,
    ..Default::default()
}).await?;

kv.clear()

모든 키-값 쌍을 제거해요.

agent.kv.clear().await?;

파일시스템 API

에이전트 데이터를 관리하는 POSIX 스타일 파일시스템 작업이에요.

fs.write_file(path: &str, data: &[u8])

필요하면 부모 디렉터리를 만들면서 파일에 바이트를 기록해요.

// Write text
agent.fs.write_file("/report.md", b"# Report\nContent...").await?;

// Write string
let content = "Hello, World!";
agent.fs.write_file("/greeting.txt", content.as_bytes()).await?;

// Write binary
let image_data = std::fs::read("./chart.png")?;
agent.fs.write_file("/images/chart.png", &image_data).await?;

fs.read_file(path: &str) -> Vec<u8>

파일 내용을 바이트로 읽어요.

// Read as bytes
let data = agent.fs.read_file("/report.md").await?;

// Convert to string
let text = String::from_utf8(data)?;

// Parse JSON
let json_data = agent.fs.read_file("/config.json").await?;
let config: serde_json::Value = serde_json::from_slice(&json_data)?;

fs.mkdir(path: &str)

디렉터리를 만들고, 옵션으로 부모 디렉터리까지 만들 수 있어요.

// Create single directory
agent.fs.mkdir("/reports").await?;

// Create nested directories
agent.fs.mkdir_p("/reports/2024/Q4").await?;

fs.readdir(path: &str) -> Vec<DirEntry>

메타데이터와 함께 디렉터리 내용을 나열해요.

let entries = agent.fs.readdir("/reports").await?;

for entry in entries {
    println!("Name: {}", entry.name);
    println!("Type: {:?}", entry.entry_type);
    println!("Size: {} bytes", entry.size);
    println!("Modified: {:?}", entry.modified);
}

// Filter by type
let files: Vec<_> = entries
    .iter()
    .filter(|e| e.entry_type == EntryType::File)
    .collect();

fs.stat(path: &str) -> FileStat

파일 또는 디렉터리 메타데이터를 가져와요.

let stat = agent.fs.stat("/report.md").await?;

println!("Size: {} bytes", stat.size);
println!("Type: {:?}", stat.file_type);
println!("Created: {:?}", stat.created);
println!("Modified: {:?}", stat.modified);
println!("Permissions: {:o}", stat.mode);

if stat.is_file() {
    println!("It's a file");
} else if stat.is_directory() {
    println!("It's a directory");
}

fs.exists(path: &str) -> bool

파일이나 디렉터리가 존재하는지 확인해요.

if agent.fs.exists("/config.json").await? {
    let config = agent.fs.read_file("/config.json").await?;
}

fs.rm(path: &str)

파일 또는 빈 디렉터리를 제거해요.

// Remove file
agent.fs.rm("/old-report.md").await?;

// Remove empty directory
agent.fs.rm("/empty-dir").await?;

// Remove directory tree
agent.fs.rm_rf("/old-data").await?;

fs.rename(old_path: &str, new_path: &str)

파일과 디렉터리를 이동하거나 이름을 바꿔요.

// Rename file
agent.fs.rename("/draft.md", "/final.md").await?;

// Move to different directory
agent.fs.rename("/temp/data.json", "/archive/data.json").await?;

fs.copy_file(src: &str, dest: &str)

파일을 새 위치로 복사해요.

agent.fs.copy_file("/template.md", "/new-report.md").await?;

도구 호출 추적 API

에이전트의 도구 호출을 기록하고 조회해요.

tools.record()

시간 정보와 입출력 데이터를 포함해 도구 호출을 기록해요.

use agentfs::ToolCall;
use chrono::Utc;
use serde_json::json;

let start = Utc::now();
// ... perform operation ...
let end = Utc::now();

agent.tools.record(ToolCall {
    name: "web_search".to_string(),
    started_at: start,
    ended_at: end,
    input: json!({
        "query": "rust async programming",
        "max_results": 10
    }),
    output: json!({
        "results_count": 8,
        "success": true
    }),
}).await?;

tools.list(options: ToolListOptions)

기록된 도구 호출을 조회해요.

use agentfs::ToolListOptions;
use chrono::{Duration, Utc};

// Get recent calls
let recent = agent.tools.list(ToolListOptions {
    limit: Some(10),
    ..Default::default()
}).await?;

// Filter by name
let searches = agent.tools.list(ToolListOptions {
    name: Some("web_search".to_string()),
    limit: Some(100),
    ..Default::default()
}).await?;

// Time range query
let last_hour = agent.tools.list(ToolListOptions {
    since: Some(Utc::now() - Duration::hours(1)),
    until: Some(Utc::now()),
    ..Default::default()
}).await?;

tools.get(id: &str) -> Option<ToolCall>

특정 도구 호출의 상세 정보를 가져와요.

if let Some(call) = agent.tools.get("call_123abc").await? {
    let duration = call.ended_at - call.started_at;
    println!("Tool: {}", call.name);
    println!("Duration: {}ms", duration.num_milliseconds());
}

tools.delete(id: &str)

도구 호출 기록을 제거해요.

agent.tools.delete("call_123abc").await?;

tools.clear()

모든 도구 호출 기록을 제거해요.

agent.tools.clear().await?;

지원

더 알아보기 (Learn more)