Open6

Claude AI の Artifacts の仕組みを調べたら面白かった

mizchimizchi

tl;dr

  • Claude AI の Artifacts で tsx の React コードをプレビューできた
  • 中身は Next.js の Static Build の成果物
  • おそらく Next.js の開発サーバーをプロダクションにデプロイし、前段の Cloudflare でキャッシュしていそう
mizchimizchi

claude.ai の Feature Preview で Artifacts を有効にすると、React のコードがプレビューできるのに気づいた。

HTML をプレビューできたのを知っていたが、TSX はどこで処理しているのだろう?と疑問に思って、中身を覗いてみた。

iframe 下で Next.js の静的ビルドモードの成果物を表示している。
つまり、生成されたコードを何らかの形で(開発モードの?) Next.js に渡して、その結果をキャッシュしているのではないか。

mizchimizchi

試しに中身がほとんど同じコードを生成させてみたが(カウンターの初期値が1)、異なる成果物で、チャンクがほとんど一致した。
つまり、同一設定の Next.js サーバーがコンテンツを吐き出し続けている。

おそらく /src/pages/[id].tsx に生成されたコードを書き込むか、仮想的なFSを用意して(全部一台のマシンのローカルFSで管理してるとは思えないので、こっちな気がする)、初回だけ Next.js で生成し、残りはキャッシュしているのだろう。 traceroute www.claudeusercontent.com で確かめると、anthropic のアプリケーションサーバの前段に cloudflare がいた。

おそらく cloudflare workers ではない。開発モードの Next.js は動的 eval が禁止されているので、 cloudflare workers にデプロイ出来ない。

最初は ISR かと思ったが、ISR は props の差分は吸収できるが、コードそのものを動的評価できない。

mizchimizchi

セキュリティ的な懸念点として、pages のnext の機能や SSR 時に攻撃できるのでは、と思って試したが、流石にクライアントでしか評価しないようになっていた。

例えばこういうコードを評価させた。

import React from 'react';

export async function getStaticProps(context) {
  return {
    props: { foo: 1 },
  }
}

const Counter = (props) => {
  return (
    <div className="p-4 bg-gray-100 rounded-lg shadow-md">
      <h2 className="text-xl font-bold mb-2">Counter Component</h2>
      <div className="bg-white p-2 rounded border border-gray-300">
        <pre className="text-sm">
          <code>{JSON.stringify(props, null, 2)}</code>
        </pre>
      </div>
      <p className="mt-2 text-sm text-gray-600">
        Note: getStaticProps is not executed in this client-side environment.
      </p>
    </div>
  );
};

export default Counter;

getStaticProps を通らないので出力は {}

export default function Counter(props) {
  return <pre><code>{Object.keys(globalThis)}</code></pre>
}

サーバーサイドの globalThis を取れないかと思ったが、ブラウザコンテキストしか評価されなかった。

mizchimizchi

ライブラリは使えるか

共通の node_modules で管理してるはずなので、ライブラリを npm install した際に副作用起きるはず、と思って試したが外部ライブラリは参照できないようだった。

mizchimizchi

というわけで、TSX+Tailwind でマークアップされたコンポーネントを生成させる環境として便利、という話