llm-worker-rs/README.md

3.1 KiB

worker

worker は、複数の LLM プロバイダーを横断して扱える統合ワーカーです。モデル呼び出し、ツール実行、プロンプト構築、フック連携など、対話アプリに必要な機能を 1 つの API にまとめます。

特徴

  • 主要 LLM プロバイダーを単一のインターフェースで利用
  • プロンプト/パーシャル読み込みを利用者実装の ResourceLoader へ委譲
  • ツール連携とストリーミング応答、フックによるカスタマイズに対応

利用手順

worker のプロンプト/パーシャル解決は利用者側に委譲されています。以下の流れで組み込みます。

  1. ResourceLoader を実装して、テンプレートやパーシャルが参照する識別子から文字列を返す。
  2. Worker::builder() にプロバイダー・モデル・ロールと合わせて resource_loader を渡し、Worker を生成。
  3. セッションを初期化し、process_task_with_history などの API でイベントストリームを処理。
use futures_util::StreamExt;
use worker::{LlmProvider, PromptError, ResourceLoader, Role, Worker};

struct FsLoader;

impl ResourceLoader for FsLoader {
    fn load(&self, id: &str) -> Result<String, PromptError> {
        std::fs::read_to_string(id)
            .map_err(|e| PromptError::FileNotFound(format!("{}: {}", id, e)))
    }
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let role = Role::new("assistant", "Helper", "You are a helpful assistant.");

    let mut worker = Worker::builder()
        .provider(LlmProvider::Claude)
        .model("claude-3-sonnet-20240229")
        .resource_loader(FsLoader)
        .role(role)
        .build()?;

    worker.initialize_session()?;
    let events = worker
        .process_task_with_history("こんにちは!".into(), None)
        .await;

    futures_util::pin_mut!(events);
    while let Some(event) = events.next().await {
        println!("{event:?}");
    }
    Ok(())
}

ツールを登録する

#[worker::tool] マクロで関数を装飾すると、Tool 実装を自動生成できます。

use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use worker::ToolResult;

#[derive(Debug, Deserialize, Serialize, JsonSchema)]
struct EchoArgs {
    text: String,
}

#[worker::tool(name = "echo")]
async fn echo(args: EchoArgs) -> ToolResult<String> {
    Ok(args.text)
}

worker.register_tool(Box::new(EchoTool::new()))?;

フックを登録する

#[worker::hook] マクロで非同期関数を装飾すると、WorkerHook 実装が生成されます。

use worker::{HookContext, HookResult};

#[worker::hook(hook_type = "OnMessageSend")]
async fn log(context: HookContext) -> (HookContext, HookResult) {
    println!("sending: {}", context.content);
    (context, HookResult::Continue)
}

worker.register_hook(Box::new(LogHook::new()));

ドキュメント

  • API の詳細は cargo doc --open で参照できます。
  • プロンプトシステムの概要: docs/prompt-composer.md
  • サンプルコード: worker/examples/