サイクルは変わっていない、ツールが増えただけだ
「ループはまったく変わっていません。TOOLS 配列に内容を追加しただけです。」 - s02_tool_use.py オリジナルの単語。
ツールを追加するには何箇所移動する必要がありますか?
S01 のエージェントは bash のみを知っています。 read_file / write_file / edit_file でも機能するようにするにはどう変更しますか?
多くの人の最初の反応は、「ループを変更する」というものです。間違っている。一行もループに触れないでください。 必要なのは次の 3 つだけです:
<オル>run_read(path, limit)) を作成します。 TOOL_HANDLERS マッピングテーブル ("read_file": lambda **kw: run_read(...)) に登録します。 TOOLS 配列に追加します (ツールの名前と受け入れるパラメーターをモデルに伝えます)。 ループで tool_use ブロックが見つかったら、block.name を押してディスパッチ マップ内の関数を検索し、実行して、出力を tool_result に戻します。 bash とまったく同じパスに従います。
# Dispatch map: name → handler lambda TOOL_HANDLERS = { "bash": lambda **kw: run_bash(kw["command"]), "read_file": lambda **kw: run_read(kw["path"], kw.get("limit")), "write_file": lambda **kw: run_write(kw["path"], kw["content"]), "edit_file": lambda **kw: run_edit(kw["path"], kw["old_text"], kw["new_text"]), }
ディスパッチがどのようにルーティングされるかを確認する
以下のウィジェットを使用すると、モデルによって送信される tool_use リクエストをクリックして、特定の Python 関数にどのようにルーティングされるかを確認できます。注: block.name によって、どの行を取得するかが決まります。
safe_path: 省略できない防御線
エージェントにファイルへのアクセス権を与えます。最も可能性の高い安全性の問題はパス エスケープです。モデルは /home/user/project/ で動作するはずでしたが、最終的には read_file("../../etc/passwd") を送信してしまいました。
s02 にはこれに対処する小さな関数があります。
def safe_path(p: str) -> Path: path = (WORKDIR / p).resolve() # 规范化,解析 .. 和软链 if not path.is_relative_to(WORKDIR): raise ValueError(f"Path escapes workspace: {p}") return path
鍵となるのは、.resolve() + .is_relative_to() の 2 つのステップです。絶対パスまで解析し、それがまだサンドボックス内にあるかどうかを確認します。前者がなければ、foo/../../etc は通過できます。後者がなければ、検査さえ行われません。
パスのセキュリティを特定する
次の 5 つのパスはすべて、モデルによって送信される可能性のある read_file パラメーターです。 safe_path ではどれが許可され、どれが拒否されますか? WORKDIR = /home/user/project と仮定します。
危険なツールをエージェントに追加しないでください
ツールを追加するのは簡単ですが、追加するすべてのツールがモデルの新しい機能境界となることに注意してください。 s02 では、bash にはすでにブラックリスト (rm -rf /、sudo、shutdown) があり、write_file には safe_path 制限があります。本番環境にツールを追加する前に、次の 3 つの質問を自問してください。
- このツールを使用すると、 モデルが元に戻せないことを実行できますか? (rm、メール送信、git Push)
- 何が漏れる可能性がありますか? (環境変数、.ssh、Cookie)
- エラー出力はコマンドフィードバックとして扱われますか? (ツール出力による即時注入)
レクチャー s07 では、これらの決定をコードから取り出して宣言型にするための「パーミッション層」を追加します。