ブログに戻る

Comma のエージェントがネイティブ SSH に対応

はじめるドキュメントを読む

自宅サーバーの夜間バックアップが終わらなくなりました。ログはサーバーにあり、サーバーはルーターの内側にあります。Comma には、手作業でコピーして往復させるコマンドの一覧ではなく、何が起きたのかを突き止めてほしいところです。Comma のエージェントは、別の AI エージェントをそのマシンにインストールすることなく、SSH 経由でそのマシン上で作業できるようになりました。

エージェントはサンドボックスの外にいる

ほとんどのクラウドエージェントは、自分のサンドボックスの中で動きます。サンドボックスとは、モデルループ、ツール、ファイルを抱えたコンテナや VM で、エージェントが存在する間ずっと起動したままです。Comma を支える分散ハーネスである Salix は、これらを切り離します。エージェントループはどのサンドボックスにも属さずハーネス内で動き、CPU コアあたり 100 を超えるエージェントを収容します。クラウド VM やデバイスはコマンドを実行する場所であり、作業にコンピューターが必要なときだけ使われます。

そのため、エージェントはサーバーで作業するためにサーバーへ移ることはありません。ハーネスからネイティブの SSH ツールを呼び出します。

  • ssh.open、ssh.write、ssh.read、ssh.screen は、全画面プログラムを含む対話型ターミナル用です。

  • ssh.exec は単発のコマンド用で、stdout、stderr、終了ステータスを分けて返します。

  • ssh.list_files、ssh.download、ssh.upload は、SFTP によるファイル操作用です。

  • ssh.close と ssh.list は、接続のライフサイクル管理用です。

エージェントは Group SSH 鍵で認証します。これはワークスペースごとに 1 つの鍵で、そのワークスペースのエージェントが共有します。ssh.public_key がこの鍵を返すので、ほかの SSH クライアントと同じように、マシンの ~/.ssh/authorized_keys に追加します。

ハーネスがマシンに接続する方法は 3 つあります。

1. 公開アドレス

マシンにすでに到達可能な SSH サーバーがあれば、エージェントはその IP アドレスか DNS 名に接続します。

json
{ "tool": "ssh.open", "params": { "host": "203.0.113.10", "user": "deploy" } }

2. 公開アドレスのないマシンには Tailcat

NAT の内側にあるノート PC や自宅サーバーには、ハーネスから接続できるアドレスがないことがよくあります。Tailcat を使えば、受信ポートも VPN もアカウントもなしに接続できます。Tailcat はそのマシン上で動き、送信方向の接続だけを使い、tc で始まるアドレスを表示します。

Tailcat 自体を SSH サーバーにすることもできます。Group の公開鍵を指定して起動します。

sh
tailcat serve --ssh-authorized-keys='ssh-ed25519 AAAA...' ssh

これで、Tailcat を実行しているアカウントとして、ログインシェル、コマンド実行、SFTP が使えます。sshd は不要で、SSH の設定も変わりません。マシンですでに OpenSSH が動いている場合は、代わりに tailcat serve 22 を使えば、ログインは OpenSSH が処理します。あとはアドレスをエージェントに渡します。

json
{ "tool": "ssh.open", "params": { "tailcat": "tc...", "user": "deploy" } }

3. あなた自身の Tailscale ネットワーク

マシンがすでに tailnet に参加しているなら、ワークスペースをその tailnet に参加させられます。Comma アプリの設定から接続するか、エージェントに頼んでください。tailnet の管理者がログインリンクを開いてノードを承認します。ノードにはデフォルトで tag:comma-agent タグが付くので、どのデバイスのどのポートに届くかは tailnet のポリシーで厳密に決められます。たとえば、自宅サーバーの 22 番ポートだけに絞れます。

エージェントは tailnet.peers でデバイスを一覧し、MagicDNS 名か Tailscale アドレスで接続します。

json
{
  "tool": "ssh.open",
  "params": { "host": "nas.tail1234.ts.net", "via_tailnet": true, "user": "deploy" }
}

信頼とライフタイム

どの経路でも、ホストへの最初の接続でそのホスト鍵を記録します。その後の接続で別の鍵が提示されると、host_key_mismatch と両方のフィンガープリントを返して接続を拒否します。エージェントは ssh.known_hosts.remove で古い鍵を削除する前に、あなたに確認します。

SSH 接続は 1 つのエージェントセッションに属します。30 分使われないと閉じ、エージェントの再起動やプラットフォームのデプロイをまたいでは残りません。長い作業はリモートマシンの tmux や screen で行ってください。コマンドには上限があります。ssh.exec はデフォルトで 60 秒、最大 600 秒でタイムアウトし、タイムアウトは報告されるだけで、自動で再試行されることはありません。

バックアップの件なら、たとえばこう頼めます。「ログを読んでディスク容量を確認して。ただし、ファイルの削除や設定の変更はしないで。まず何が分かったかを教えて。」

Try Comma, Now.

はじめる