Guides
ツール開発ガイド
Python/TypeScriptでツールを開発する方法
基本構造
Toolは Input、Output、run関数 の3つで構成されます。
Python
PydanticのBaseModelでスキーマを定義します。
from pydantic import BaseModel, Field
class Input(BaseModel):
url: str = Field(description="取得するURL")
class Output(BaseModel):
title: str
content: str
def run(input: Input) -> Output:
# 処理を実装
return Output(title="...", content="...")TypeScript
Zodでスキーマを定義します。
import { z } from "zod";
export const input = z.object({
url: z.string().describe("取得するURL"),
});
export const output = z.object({
title: z.string(),
content: z.string(),
});
export async function run(data: z.infer<typeof input>) {
// 処理を実装
return { title: "...", content: "..." };
}外部ライブラリ
ToolSetの設定画面でパッケージを追加すると、コード内でimportできます。
import requests # パッケージ設定で "requests" を追加
from bs4 import BeautifulSoup # "beautifulsoup4" を追加
def run(input: Input) -> Output:
html = requests.get(input.url).text
soup = BeautifulSoup(html, "html.parser")
return Output(title=soup.title.string)バージョン指定も可能です(例: requests==2.31.0)。
環境変数
APIキーなどの機密情報は環境変数で渡します。ToolSetの設定画面で登録できます。
import os
def run(input: Input) -> Output:
api_key = os.environ["SLACK_API_KEY"]
# api_key を使用...export async function run(data: z.infer<typeof input>) {
const apiKey = process.env.SLACK_API_KEY;
// apiKey を使用...
}→ 環境変数
エラーハンドリング
例外を送出すると、エラー情報が記録されます。
def run(input: Input) -> Output:
if not input.url.startswith("https://"):
raise ValueError("URLはhttps://で始まる必要があります")
# ...実践例
Slack通知
import os
import requests
from pydantic import BaseModel, Field
class Input(BaseModel):
channel: str = Field(description="通知先チャンネル")
message: str = Field(description="メッセージ本文")
class Output(BaseModel):
success: bool
ts: str = Field(description="メッセージのタイムスタンプ")
def run(input: Input) -> Output:
response = requests.post(
"https://slack.com/api/chat.postMessage",
headers={"Authorization": f"Bearer {os.environ['SLACK_BOT_TOKEN']}"},
json={"channel": input.channel, "text": input.message},
)
data = response.json()
if not data["ok"]:
raise Exception(data["error"])
return Output(success=True, ts=data["ts"])Webページ取得
import requests
from bs4 import BeautifulSoup
from pydantic import BaseModel
class Input(BaseModel):
url: str
class Output(BaseModel):
title: str
description: str
text: str
def run(input: Input) -> Output:
html = requests.get(input.url).text
soup = BeautifulSoup(html, "html.parser")
title = soup.title.string if soup.title else ""
desc_tag = soup.find("meta", {"name": "description"})
description = desc_tag["content"] if desc_tag else ""
text = soup.get_text()[:2000]
return Output(title=title, description=description, text=text)外部API呼び出し
import os
import requests
from pydantic import BaseModel
class Input(BaseModel):
query: str
class Output(BaseModel):
results: list[dict]
def run(input: Input) -> Output:
response = requests.get(
"https://api.example.com/search",
headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
params={"q": input.query},
)
response.raise_for_status()
return Output(results=response.json()["results"])スキーマのベストプラクティス
descriptionを付与する
AIがToolを選択する際の判断材料になります。
class Input(BaseModel):
query: str = Field(description="検索キーワード")
limit: int = Field(default=10, description="最大取得件数(1-100)")export const input = z.object({
query: z.string().describe("検索キーワード"),
limit: z.number().default(10).describe("最大取得件数(1-100)"),
});Optional型
from typing import Optional
class Input(BaseModel):
query: str
filter: Optional[str] = None # 省略可能ネストした型
class Address(BaseModel):
city: str
country: str = "JP"
class Input(BaseModel):
name: str
address: Addressテスト
画面下部のテストパネルでInputを入力し、Cmd+Enterで実行できます。
Publishせずにドラフト状態のコードをテストできるため、開発中の動作確認に便利です。