agentleFS
awaku7awaku7/agentcli/skills/create-tool/SKILL.md

create-tool

Skill12 starsChanged 10 days agoApache-2.0View on GitHub

新規ツール(Python + JSON)を生成し、i18n翻訳(本体の全対応ロケール)・ruff/black整形・py_compile検証まで一貫実行する。

3 other projects use a version of this.

Adopted by

Most recently taken up by

The file

Files
SKILL.md

目的

agentcli に新規ツールを追加する一連の工程を自動実行する。 手作業で抜けがちな i18n翻訳(本体の全対応言語)・コード整形・構文チェック まで含めて完了する。

入力(このスキルがユーザーに確認すること)

ユーザーに以下を質問し、全て揃ったら実行を開始する。

  1. ツール名: 英小文字+アンダースコア(例: pdf_ocr)
  2. 英語説明: tool.description に使う1行(簡潔に)
  3. 引数定義: 各引数の name / type / required / description(英、簡潔に)
  4. 実装概要: run_tool() の処理内容
  5. x_search_terms(英): 検索ワード配列(省略可)

質問テンプレート

これから新規ツールを作成します。以下を教えてください:
1. ツール名(例: pdf_ocr)
2. 英語の説明(簡潔に)
3. 引数(JSON形式、説明は簡潔に)
4. 実装の概要(何をするツールか)
5. x_search_terms(省略可)

注: 日本語を含む全ロケールの翻訳は translate_text で自動生成する。

LLM が自動判断する項目(ユーザーには聞かない)

以下の項目はユーザー入力ではなく、LLMがツールの実装内容から判断して設定する。

項目判断基準
tool_genreツールの機能から判断。ファイル操作→file、API呼出→external、デバイス制御→iot、開発補助→devel、汎用→basic
BUSY_LABEL時間のかかる処理なら True、即時返却なら False
STATUS_LABEL任意。表示用ラベル文字列、なければ None
LAZY_LOAD重いimport(PIL/numpy等)が必要な場合のみ True
tool_level基本的に省略(=0)。システム内部用なら -1(隠し)
x_parallel_safe副作用なし並列実行安全なら True、状態変更するなら False
additionalProperties基本的に False

環境

  • Python 実行環境(python_exec ツール)
  • 既存ツール: translate_text / lint_format / python_compile / create_file
  • src/uagent/tools/ が書き込み可能

実行フロー(この順序で固定)

Step 0: 重複チェック

  • search_files(glob="<name>_tool.*", path="src/uagent/tools") で既存ツールと重複しないか確認
  • 重複あればスキル中断しユーザーに報告

Step 1: Python ファイル生成

create_file で src/uagent/tools/<name>_tool.py を生成する。

テンプレート

from __future__ import annotations

# src/uagent/tools/<name>_tool.py

from .i18n_helper import make_tool_translator

_ = make_tool_translator(__file__)

from typing import Any

BUSY_LABEL = False  # LLM判断
STATUS_LABEL = None

TOOL_SPEC: dict[str, Any] = {
    "type": "function",
    "tool_genre": "<genre>",  # LLM判断
    "x_parallel_safe": False,
    "function": {
        "name": "<name>",
        "description": _(
            "tool.description",
            default="<english description>",
        ),
        "x_search_terms": _(
            "x_search_terms",
            default=[<x_search_terms_english_array>],
        ),
        "x_search_terms_en": [<x_search_terms_english_array>],
        "parameters": {
            "type": "object",
            "properties": {
                <param_name>: {
                    "type": "<type>",
                    "description": _(
                        "param.<param_name>.description",
                        default="<english description>",
                    ),
                }
            },
            "required": [<required_param_names>],
            "additionalProperties": False,
        },
    },
}

def run_tool(args: dict[str, Any]) -> str:
    <implementation>

ルール

  • _("key", default="...") で全ユーザー向け文字列をラップ
  • key は tool.description, param.<name>.description の命名規則
  • x_search_terms は _("x_search_terms", default=[...])(i18n経由で現在ロケールの配列を読む)
  • x_search_terms_en は英語配列を直書き(英語検索用の fallback、i18n を通さない)
  • run_tool() は必ず str を返す
  • エラーハンドリングを含める

Step 2: JSON ファイル生成(本体の全対応ロケール、翻訳込み)

python_exec で以下のスクリプトを実行し、src/uagent/tools/<name>_tool.json を一発生成する。

処理内容

  1. Python の _("key", default=...) を英語の唯一の正本として作成
  2. 本体のロケールディレクトリを検出し、en 以外の全ロケールについて translate_text を呼び出して翻訳
  3. JSON には en を書かず、非英語ロケールだけを json.dumps(indent=2, ensure_ascii=False) で書き出し

翻訳対象キー(各ロケール)

  • tool.description
  • x_search_terms(配列の各要素を翻訳)
  • param.<name>.description(各パラメータ)

対応ロケールの検出と Google 言語コード

固定のロケール数や一覧を使わず、作成時点の本体から動的に取得する。

  • src/uagent/locales/*/LC_MESSAGES/uag.po または uag.mo の親ディレクトリ名を列挙する
  • en は Python の default= / x_search_terms_en にのみ保持し、JSON には含めない
  • 現在の本体では次の38ロケールを提供している: ar, bn, cs, da, de, el, en, es, fa, fi, fil, fr, he, hi, hu, id, it, ja, ko, mn, mr, ms, nb, nl, nn, pl, pt, pt_BR, ro, ru, sv, sw, th, tr, uk, vi, zh_CN, zh_TW
  • 新しいロケールが本体に追加された場合は、SKILLの一覧を更新せず自動的に対象へ含める

Google Translate の言語コードは、ロケール名から次の規則で導出する。

  • _ を - に変換: zh_CN → zh-CN, zh_TW → zh-TW, pt_BR → pt-BR
  • nb / nn → no
  • he → iw
  • それ以外はロケール名をそのまま使用

実装戦略

python_exec 内で全ロケールをループ。各ロケールの全テキストを translate_text(texts=[...], target_lang=..., source_lang="en") に一度に渡して翻訳し、戻り値を各キーにマッピングする。

【重要】プレースホルダ保護

translate_text の protect_placeholders はコードファイル自動検出に依存するため、平文の description 文字列に含まれる {path} や {name} 等のプレースホルダは保護されない。Google Translate が {path} を {パス} などに翻訳してしまう。

対処: 翻訳前にプレースホルダを独自トークンで置換し、翻訳後に戻す。

import re

def protect(text: str) -> tuple[str, dict[str, str]]:
    mapping = {}
    def replacer(m):
        orig = m.group(0)
        token = f"__PH_{len(mapping)}__"
        mapping[token] = orig
        return token
    text = re.sub(r'\{[A-Za-z_][A-Za-z0-9_]*\}', replacer, text)
    return text, mapping

def restore(text: str, mapping: dict[str, str]) -> str:
    for token, orig in mapping.items():
        text = text.replace(token, orig)
    return text

各テキストを翻訳前に protect() で処理し、翻訳結果に restore() を適用する。

その他の注意

  • x_search_terms は各言語のネイティブな検索ワードに翻訳する
  • 翻訳エラー・空文字の場合は英語のまま保持(fallback)

Step 3: ruff/black 整形

lint_format(tools=["ruff", "black"], mode="fix", targets=["src/uagent/tools/<name>_tool.py"])

  • ユーザーに確認を求める: 「<name>_tool.py に ruff/black を適用しますか?(y/n)」
  • 承諾されたら実行。拒否されたらスキップ。

Step 4: 構文チェック

python_compile(path="src/uagent/tools/<name>_tool.py") を実行。

  • エラーが出た場合は修正して再チェック(最大3回リトライ)

Step 5: 完了報告

生成ファイル一覧と内容サマリを出力する。

  • src/uagent/tools/<name>_tool.py
  • src/uagent/tools/<name>_tool.json

成功判定

  • python_compile がエラーなし
  • lint_format(mode=check) がエラーなし
  • 2ファイルが存在する
  • JSON に本体の全対応ロケール(src/uagent/locales から検出したロケール)のエントリが含まれている
  • JSON 内の全 {xxx} プレースホルダが元の名前を維持している({パス} などに翻訳されていない)

失敗時のよくある原因

  • translate_text の一時的APIエラー(リトライ可能)
  • JSON のキー名ミス(typo)
  • run_tool() 内の構文エラー
  • 同名ツールが既に存在する(Step 0 で防止)
  • プレースホルダ名が翻訳されてしまう({path} → {パス})。翻訳前の保護処理が必須

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.