ランタイム
呼び出しの中で使えるファイル、HTTP、画像と、その上限。
呼び出しは毎回まっさらな状態から始まります。Subako は呼び出しのたびに Module をインスタンス化してリクエストを 1 つ渡し、Module が応答したら停止します。そのため、メモリの内容は次の呼び出しに残りません。呼び出しをまたいで残るのは、Session Volume 上のファイルです。
ファイルシステム
呼び出しから見えるのは、次のディレクトリだけです。
| パス | アクセス | 内容 |
|---|---|---|
/volume/tmp |
読み書き | Session Volume の Temporary 領域。常に使え、Session の最後の操作から 24 時間で消去されます。 |
/volume/data |
読み書き | Data 領域。Agent のバージョンで有効にしている場合に使えます。Session が削除されるまで保持されます。 |
/package |
読み取り専用 | Package 自身の assets/ の中身が、同じパス構成で置かれます。たとえば assets/templates/report.typ は /package/templates/report.typ になります。 |
/skills/<name> |
読み取り専用 | Session の Agent に付与された Skill。それぞれ Grant の名前で置かれます。 |
作業ディレクトリも環境変数もないので、絶対パスを使ってください。どの SDK でも、各言語のふだんのファイル API (std::fs、os、TypeScript SDK の fs) でこれらを読み書きできます。
Session Volume
Volume は呼び出しではなく Session に属しているので、Tool 同士で作業を受け渡すのに使えます。たとえば、ある Function が書き込んだ /volume/tmp/export.csv を別の Function が読めます。モデルは Platform package の files で中身を確認でき、人は Session の Session Volume タブからダウンロードできます。Session のすべての Tool が同じ Volume を共有するので、Tool ごとに専用のディレクトリを使ってください。
大きな結果はファイルに書き込み、そのパスと短い要約を返してください。モデルが読んだ内容はすべてコンテキストに入りますが、パスを知っているだけのファイルはコンテキストを消費しません。そのファイルは次の Tool が読めますし、モデルも Platform package の files で 1 ページずつ確認できます。
Volume の容量は最大 10 GiB です。上限に達すると、ファイルを削除するまで書き込めなくなります。読み取りと削除はその間もできます。
Package の Asset
Package には、テンプレート、フォント、プロンプト、参照テーブル、小さなモデルの重みなど、コードから読むもののコードには埋め込むべきでないファイルを同梱できます。Bundle の assets/ の下に置くと、どの呼び出しからも /package で読み取り専用として読めます。
- subako-package.json
- module.wasm
- assets/
- templates/
- report.typ
- fonts/
- Inter.ttf
- templates/
let template = std::fs::read_to_string("/package/templates/report.typ")?;const template = fs.readText("/package/templates/report.typ");template, err := os.ReadFile("/package/templates/report.typ")各言語のテンプレートのビルドスクリプトは、コードと同じ場所にある assets/ ディレクトリを Bundle にコピーします。Asset はバージョンの一部なので、テンプレートを変えるには新しくアップロードし直します。Session は、自身が解決したバージョンのファイルを読み続けます。Asset はアップロード時のチェック中にも読めるので、Module の起動時に読み込んでかまいません。1 つの Bundle には、全体の上限 64 MiB の範囲内で最大 10,000 個の Asset ファイルを含められます。typst のサンプルは、この方法で PDF のテンプレートを同梱しています。
HTTP
Module はソケットを持たず、HTTP リクエストは Subako を経由して送ります。Subako は Grant のネットワークの設定を適用し、外に出るリクエストに Credential を付けます。SDK を使えば、これを各言語の標準の HTTP として扱えます。
use subako_function_sdk::http::{self, Request, ResponseBody};
let response = http::request(&Request::get("https://api.example.com/orders/1042"))?;resp, err := http.Get("https://api.example.com/orders/1042") // いつもどおりの net/httpconst response = await fetch("https://api.example.com/orders/1042");レスポンスボディは、256 KiB までのテキストならそのまま返されます。それより大きいものやバイナリは、代わりに Volume のファイルに直接保存されます。Volume のファイルをリクエストボディとして送ることもできるので、大きなデータの転送が Module のメモリを通ることはありません。リダイレクトは 10 ホップまでたどり、ホップごとに Grant と照合し直します。別の Origin に移るときは、authorization Header と Cookie Header を外します。
応答する
Tool は、値かエラーで応答します。値は SDK がモデル向けに JSON にシリアライズし、エラーはモデルがそのまま読みます。
- うまくいかなかったことをモデルに知らせたいときは、エラーを返します (Rust では
ToolError、Go ではerror、TypeScript では throw したError)。「注文 1042 はありません」「API が 429 を返しました」などです。モデルはメッセージを読んで、次にどうするかを判断します。 - panic、trap、0 以外の終了コードは クラッシュ になります。モデルに伝わるのは、Function が停止したことと、stderr に書かれた最後の 4 KiB だけです。できるだけ、モデルが対処できるエラーを返してください。
ログは stderr に出力します。stdout はプロトコル専用なので、ほかのものを出力すると呼び出しが壊れます。
画像
Tool は、作成した画像や見つけた画像をモデルに見せられます。値と一緒に、Volume 上の PNG、JPEG、GIF、WebP ファイルのパスを返してください。Subako は呼び出しの後にそのファイルを読み、長辺が 2000 ピクセル以下になるよう縮小して、モデルに渡すとともに、会話内の呼び出しの下に表示します。モデルに渡すのは、Agent のバージョンのモデルで 画像を読む が有効な場合です。
Ok(Answer::new(Plot { path: path.clone() }).with_image_file(path))res, err := subakofn.ImageResult(plot, plot.Path)
return res, plot, errreturn answer({ path }).withImageFile(path);制限
| 制限 | |
|---|---|
| 1 回の呼び出しの実行時間 | Grant の Timeout。既定は 60 秒、最大 300 秒 |
| メモリ | 512 MiB |
| 1 回の呼び出しでの Volume への書き込み | 1 GiB |
| Module が stdout に書き込む量の合計 | 1 MiB。これより大きい結果はファイルに書き込みます |
| 保持される stderr | 64 KiB。クラッシュ時には最後の 4 KiB が報告されます |
| そのまま返される HTTP レスポンスボディ | UTF-8 テキストで 256 KiB |
| Subako に送る HTTP リクエスト | 8 MiB。これより大きいボディは Volume のファイルとして送ります |
| 1 つの結果に含める画像 | 20 枚。それぞれ最大 10 MiB |
| Session Volume | 10 GiB |
待ち時間 (HTTP の応答待ちや sleep) も実行時間に含まれ、課金の対象になります。
Package のアップロード時
Subako はアップロード時に Module を一度実行して、Tool の一覧を取得します。このときは Volume もネットワークも使えず、10 秒以内に応答する必要があります。起動処理はどちらにも頼らないようにし、短時間で終わるようにしてください。起動処理は、呼び出しのたびに毎回実行されます。