Discourse AIのカスタムツールとしてのFLUX.1 Kontext Max

先週、Flux は FLUX.1 Kontext という非常に印象的なモデルをリリースしました。

Black Forest Labs による発表ブログ

OpenAI のモデルよりも若干安価でありながら、優れた結果が得られるため、特に興味深いです。OpenAI のモデルは デザイナーペルソナ 経由で利用できます。

実際に使ってみる

この記事では、そのためのツールを追加する方法と、Discourse AI の高度な機能について説明します。

そのためのツール

ツールを定義するには、まず \u003chttps://bfl.ai\u003e でサインアップし、API キーを生成して、クレジットを購入する必要があります。

それが完了したら:

/admin/plugins/discourse-ai/ai-tools で新しいカスタムツールを定義します。

説明

\u003e 高度な画像作成・編集ツール - upload://… としてマークされた Discourse アップロードを編集できます。

要約

\u003e FLUX Kontext を使用して画像を編集または作成します。

パラメータ

  • prompt: string: 生成したいものを記述します。最良の結果を得るには、2〜3文で詳細に記述してください (必須)。
  • input_image: string: 変更したい upload://…
  • seed: number: ランダムシード。同じスタイルで出力を維持したい場合は、数値を同じにしてください。
  • aspect_ratio: string: 画像のアスペクト比。21:9 から 9:21 の間でなければなりません。正方形の画像の場合は 1:1 を使用してください。デフォルトは 16:9 です。

スクリプト

const apiKey = YOUR_API_KEY;
const apiUrl = "https://api.us1.bfl.ai/v1/flux-kontext-max"; 

function invoke(params) {
  let seed = parseInt(params.seed);
  if (!(seed > 0)) {
    seed = Math.floor(Math.random() * 1000000) + 1;
  }

  const body = {
    prompt: params.prompt,
    seed: seed,
    aspect_ratio: params.aspect_ratio || "16:9"
  };

  // input_image が提供されている場合は追加
  if (params.input_image) {
    body.input_image = upload.getBase64(params.input_image);
  }

  const result = http.post(apiUrl, {
    headers: {
      "x-key": apiKey,
      "Content-Type": "application/json"
    },
    body: JSON.stringify(body)
  });

  if (result.status !== 200) {
    return { error: `APIリクエストがステータス ${result.status} で失敗しました`, body: body };
  }
  
  const parsed = JSON.parse(result.body);
  const pollingUrl = parsed.polling_url;
  
  let pollResult = JSON.parse(http.get(pollingUrl).body);
  let checks = 0;
  
  while (pollResult.status === "Pending" && checks < 30) {
      sleep(1000);
      pollResult = JSON.parse(http.get(pollingUrl).body);
      checks++;
  } 
  
  let image;
  
  if (pollResult.status === "Ready") {
      const imageUrl = pollResult.result.sample;
      const base64 = http.get(imageUrl, { base64Encode: true }).body;
      image = upload.create("generated_image.jpg", base64);
      
      const raw = `\n\n![${params.prompt}](${image.short_url})`;
  
      chain.setCustomRaw(raw);
   }
  
  return { 
    result: "画像が正常に生成されました", 
    seed: seed,
    aspect_ratio: params.aspect_ratio || "16:9",
    output_image: image?.short_url
  };
}

function details() {
  return "Segmind の Flux Kontext Max モデルを使用して画像を生成しました";
}

解説

これは、より高度なツール機能の一部を示しています。特に、\u003chttps://github.com/discourse/discourse-ai/pull/1391\u003e で追加された機能のいくつかは、これが機能するために必要となります。

  1. http.post を使用した POST リクエスト — カスタムツールは任意の URL に POST できます!
const result = http.post(apiUrl, {
  headers: {
    "x-key": apiKey,
    "Content-Type": "application/json"
  },
  body: JSON.stringify(body)
});
  1. API での base64 エンコードペイロードのサポート

Base64 エンコードされたアップロードを取得します。

body.input_image = upload.getBase64(params.input_image);

HTTP リクエストの結果を Base64 で取得します。

const base64 = http.get(imageUrl, { base64Encode: true }).body;

Base64 文字列からアップロードを作成します。

image = upload.create("generated_image.jpg", base64);
  1. 推測を避けてトークンを節約するために、投稿でのレンダリングを強制します。
chain.setCustomRaw(raw);
  1. API はポーリングを伴います。Discourse AI は、ポーリング間の待機のために sleep プリミティブを提供します。
while (pollResult.status === "Pending" && checks < 30) {
  sleep(1000);
  pollResult = JSON.parse(http.get(pollingUrl).body);
  checks++;
}

これが役立つことを願っています!質問やアイデアがあれば、お気軽にお寄せください!

「いいね!」 4