pixeltable について
pixeltableは、テーブル、計算列、メディア処理、ベクトルインデックス、サービス提供をアプリケーションファイルにまとめるPythonフレームワークです。このスキルはプロジェクト構築とCLIの使い方を案内し、外部ベクトルデータベースや行ごとのモデル呼び出しに頼らない設計を示します。
主な機能
- 01TableModelによるスキーマ定義
- 02挿入時に実行する計算列チェーン
- 03メディアの分割と処理
- 04EmbeddingIndexによるインデックス作成
- 05CLIによるHTTPアプリの提供
活用シーン
- 01ドキュメント検索アプリの構築
- 02テーブル内でのメディアとモデル出力の処理
- 03FastAPIルートを使ったアプリ提供
MCP 対応
ドキュメントにはDeveloper MCPと、Cloudの読み取り・操作に使える任意のCloud MCPが記載されています。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ pixeltable/ pixeltable-skill --skill pixeltableインストール後、Claude Code で/pixeltableを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
agents/openai.yamlreferences/anti-patterns.mdcli.mdcore-api.mdproviders.mdworkflows.md詳細
STOP
次のいずれかをインポートしようとしている場合は、意図した使い方から外れています。
- LangChain/LlamaIndex/Haystack/LangGraph は使用しないでください。 チャンク分割には
document_splitterを使用します。検索には.similarity()を使用します。ツールにはpxt.tools()とinvoke_tools()を使用します。 - 作業用ストアとして pandas を使用しないでください。 テーブルがストアです。
.collect().to_pandas()はエクスポート専用です。 - モデルを呼び出す
for row in ...:ループを書かないでください。 呼び出しは計算列内に記述します。 - 別のベクトルデータベースをインストールしないでください。 アプリでは、モデルに
__indexes__ = [pxt.EmbeddingIndex(...)]を設定します。ノートブックでは、t.add_embedding_index(col, embedding=fn)を使用します。検索には.similarity(string=query)を使用します。 while not done:のエージェントループを書かないでください。 行を挿入します。計算列のチェーンが実行されます。
anti-patterns.md(6 個のマクロ)を参照してください。
Pixeltable とは?
アプリケーションファイル(app.py)がバックエンドになります。
pxt schema update:TableModelクラスからテーブルを作成します。HTTP は起動しません。- サンプルを挿入するか、
.select()、pxt dashboard、またはpxt schema diffを実行します。計算は挿入時に実行されます。pxt service updateの後、curl で POST します。 pxt service update:HTTP を起動します(ローカルまたはpxt://)。pxt service listは URL を表示します。これがサービング用のコマンドです。pxt service runは使用しないでください。
初回実行:クイックスタート。理由:Pixeltable を選ぶ理由。
新しいプロジェクトを始める
pip install 'pixeltable[serve]' # Python 3.11+
pxt init
pxt service example --out app.py
pxt schema check app.py # validates the file; warns if 'app' is shadowed
pxt schema update app.py my_app
pxt service update app.py my_app -f # no TTY: without -f a pending start exits 3
pxt service list # assigned port; do not hard-code :8000
pxt service example はモデルと FastAPIRouter を書き出します。スキーマのみの場合(HTTP なし)は、pxt schema example --brief --out app.py を実行します。その後、app.py を編集して、再度 pxt schema update を実行します。スキーマを変更した後、ルートが存在する場合は、もう一度 pxt service update ... -f を実行してください。それまでは、ルートは 409 を返します。python app.py は実行しないでください。すべてのフラグについては、cli.md を参照してください。
最後の引数(my_app、または Cloud 上の pxt://org:db)はカタログディレクトリであり、ディスク上のフォルダーではありません。pxt init はプロジェクトのルートを設定します。ローカルでの参照方法は、pxt.get_table('my_app.docs') を使うか、モデルをバインドして import app; app.TableModel.bind_all('my_app') を実行し、その後 app.Docs.insert(...) / app.Docs.select(...).collect() を呼び出します。確認には、pxt ls -l、pxt errors my_app/docs、pxt dashboard を使います。
プロバイダーキー(OPENAI_API_KEY など)は環境変数または ~/.pixeltable/config.toml から取得され、pxt デーモンは起動時に両方を一度だけ読み込みます。ローカルサービスはデーモンからこれらのキーを取得します。どちらかを変更した後は、pxt daemon restart を実行してください(実行するまで、すべてのコマンドが 409 を返します)。その後、pxt service restart my_app/ingest を実行します。
Cloud でも同じファイルを使います。ホストされた [[pixeltable.database]] エントリーを手作業で書き込むより、--add-config-entry を使うことをおすすめします。その後、次を実行します。
pxt login # browser sign-in; or export PIXELTABLE_API_KEY, which wins
pxt db update pxt://org:db --add-config-entry -f # project files, image, workers; not secrets, rows, or HTTP
pxt schema update app.py pxt://org:db -f
pxt service update app.py pxt://org:db -f
プロバイダー呼び出しは自動的に再試行されます(レート制限、503、タイムアウトに対するバックオフ付きの再試行)。また、OPENAI_BASE_URL 経由でプロキシに接続します。モデル呼び出しを独自の再試行ループやクライアントで囲まないでください(providers.md)。コーディングエージェントの使用時は、ユーザー自身のターミナルで pxt login を実行するよう依頼し、チャットでシークレットの値を尋ねないでください。
Pixeltable 0.7.20 以降では、-f または --allow-destructive が必要なために拒否されたコマンドは、終了コード 3 で終了し、next: <command> # <what it does> を表示します。pxt errors は、再計算可能な失敗列ごとにも同じ内容を表示します(スナップショット列は変更されないため、再計算コマンドは表示されません)。そのコマンドがユーザーの依頼どおりの処理を行う場合は実行します。データを削除する場合、他のユーザーが呼び出すものを停止または再起動する場合、あるいはユーザーが指定していない行を再計算する場合は、先に確認してください。Pixeltable ではタスクに必要な処理ができない場合、または回避策を使う場合は、pxt feedback --kind gap '<what was needed, what you tried, what happened>' をユーザーに提示してください。これはプレビューを表示するだけで、何も送信しません。ユーザーが同意した場合に限り、--send を追加します。シングルクォートを使うと、シェルがテキスト内の内容を実行しません。プレースホルダーデータを使い、顧客名、ホスト、パス、シークレットは決して使わないでください。
Cloud 上のプロバイダーキーは、pxt secret set pxt://org OPENAI_API_KEY=... で設定し、pixeltable.toml には記述しないでください。Cloud の参照方法は pxt.get_table('pxt://org:db/docs') です。メディアは、列で destination= を設定しない限り、データベースの管理対象ホームバケットに保存されます。ファイルを共有するには、リンクまたは /sign を使います(Cloud の references/cli.md)。ダッシュボードからの挿入と pxt schema diff でアプリを試してください。失敗の確認には、pxt service logs / pxt db logs を使います。
アプリケーションファイル
pxt service example --out app.py は、この形式を書き出します。編集してから、pxt schema update app.py my_app を実行します。
import pixeltable as pxt
import pixeltable.functions as pxtf
from pixeltable.serving import FastAPIRouter
TableModel = pxt.model_base()
@pxt.udf
def excerpt(text: str, n: int = 12) -> str:
return text if len(text) <= n else f'{text[:n]}...'
class Docs(TableModel, name='docs'):
id = pxt.Column(value=pxtf.uuid.uuid7(), primary_key=True)
title: pxt.String
body: pxt.String | None
title_upper = pxtf.string.upper(title)
summary = excerpt(title)
ingest = FastAPIRouter(name='ingest')
ingest.add_insert_route(
Docs, path='/docs', inputs=[Docs.title, Docs.body],
outputs=[Docs.id, Docs.title_upper, Docs.summary],
)
ingest.add_update_route(
Docs, path='/docs/update', inputs=[Docs.title],
outputs=[Docs.id, Docs.title_upper],
)
ingest.add_compute_route(Docs, path='/titles', inputs=[Docs.title], outputs=[Docs.title_upper])
アノテーションは保存される列です。代入は計算列です。Optional は T | None です。主キーは pxt.Column(..., primary_key=True) です。add_update_route はこれを使って行を照合するため、inputs には記載されていなくても、リクエストボディには id が必要です。モデルにインデックスを指定するには、__indexes__ = [pxt.EmbeddingIndex(...)] とします。
すでに FastAPI を使用している場合は、スキーマを更新した後、ingest.bind('my_app') を実行してから app.include_router(ingest) を呼び出します。または、app.py で fastapi.FastAPI オブジェクトを定義し、各ルーターで include_router() を呼び出します。その後、pxt service update はそのアプリケーションを配信します。カスタムハンドラー内では pxt.get_table() を呼び出してください。workflows.md。
RAG、ビュー、検索については、workflows.md を参照してください。ユーザーから依頼されていない限り、Hugging Face や spaCy を追加しないでください。
アプリとノートブック
- アプリ:
app.py+pxt schema update+pxt service update。モデルにインデックスを作成します。 - ノートブック/REPL:
pxt.create_table()、add_computed_column()、add_embedding_index()。以下の付録ではこの形式を使用します。
参照先
| 必要な情報 | 開くファイル |
|---|---|
pxt schema、pxt service、調査 | cli.md |
| 型、ビュー、UDF、UDA、ツール呼び出し | core-api.md |
| プロバイダーのインポート、引数、出力形式 | providers.md |
| サービング、FastAPIRouter、ルート | workflows.md |
| 誤ったスタック | anti-patterns.md |
app.py を編集して、動画、音声、エージェント、または UI を追加します。ビューには、フィルター(base=Docs.where(...))とイテレーター(frame_iterator、audio_splitter、document_splitter、video_splitter、string_splitter、list_iterator、tile_iterator)があります。UDF を記述する前に pixeltable.functions を確認してください。pxt service example または pxt schema example から始めてください。別の pxt schema update の経路を作らないでください。
API の落とし穴
| 間違い | 正しい書き方 |
|---|---|
openai.vision(...) | 非推奨です(pixeltable.functions で唯一の非推奨関数です)。image_url を指定した chat_completions、または responses を使用してください |
from pixeltable.iterators import ... | pixeltable.iterators パッケージ全体は非推奨の互換用シムです(FrameIterator、VideoSplitter、DocumentSplitter、StringSplitter、AudioSplitter、TileIterator)。関数は pixeltable.functions.* からインポートしてください。例:from pixeltable.functions.video import frame_iterator |
similarity(query) | similarity(string=query)。同様に image=/audio=/video=/document=/vector= を使用します。idx= は、1 つの列に複数のインデックスがある場合にその中から選択します |
ロジックを修正するために if_exists='ignore' を指定して再実行する | アプリ:式を編集し、pxt schema update を実行してから、pxt recompute my_app/docs summary -f を実行します。更新しても古い値は保持されます。ノートブック:t.alter_computed_column(summary=...) を実行すると、その列と依存列が再計算されます |
列の型をその場で変更する(T から T | None、格納列から計算列、stored=) | UNSUPPORTED:更新全体が適用されず、--allow-destructive でも解決しません。計算列の場合は名前を変更します(--allow-destructive -f を 1 回実行)。格納列の場合、名前を変更するとデータが削除されるため、最初から T | None として宣言してください |
t.summary_errortype | 格納された計算列またはメディア列では t.summary.errortype/t.summary.errormsg を使用します。メディアでは t.<col>.fileurl/.localpath を使用します |
pxt.Required[pxt.String] | デフォルトでは NULL 不可です。任意にするには T | None を使用します |
@pxt.udf def f(x: str) に NULL 許容列を渡す | None を受け取る NULL 不可のパラメーターでは、呼び出しがスキップされます。セルは None になり、errormsg は空になります。x: str | None と注釈し、関数本体で None を処理してください |
UDF 本体内で whisper.load_model(...) を呼び出す | 重みが行ごとに再読み込みされます。付属のラッパー(pxtf.whisper.transcribe、clip.using(...))またはモジュールスコープでキャッシュしたローダーを使用してください |
recompute_columns(columns=['summary']) | t.recompute_columns('summary', errors_only=True) |
| TOML ルートまたは廃止された serve CLI | FastAPIRouter + pxt schema update + pxt service update |
app.py の add_embedding_index() | TableModel の __indexes__ を使用します。DSL ではインデックス名に name=、SDK では idx_name= を指定します |
make_video(order_by=...)/stitch_tiles(order_by=...) | どちらも requires_order_by な UDA です。順序指定の式は 位置引数の最初 に指定します。例:make_video(t.pos, t.frame, fps=25)。order_by= を指定するとエラーになります |
app.py のインポート時に pxt.create_table()/get_table() を呼び出す | TableModel + pxt schema update を使用します。インポートによってカタログを変更してはいけません |
EmbeddingIndex(frame, image_embed=clip) | embedding=clip を使用します(テキストと画像の両方に対応)。または string_embed= と image_embed= の両方を指定します。image_embed= だけでは similarity(string=...) に応答できません |
uuid.astype(pxt.String) | uuid.to_string() を使用します(from pixeltable.functions.uuid import to_string)。astype では UUID を String にキャストできません |
dict または list に対する json_col.astype(pxt.String) | 挿入時に失敗します:Expected string, got dict。pxtf.json.dumps(json_col) でシリアライズしてください |
フィールド(.text、.choices[0].message.content)を取り出してください。このフィールドは文字列を格納する Json です。連結または埋め込みの前に .astype(pxt.String) で変換してください。
Notebook/REPL 付録
import pixeltable as pxt
pxt.create_dir('my_project', if_exists='ignore')
t = pxt.create_table('my_project.documents', {
'title': pxt.String,
'content': pxt.String,
'image': pxt.Image,
'video': pxt.Video,
'audio': pxt.Audio,
'doc': pxt.Document,
}, if_exists='ignore')
型はデフォルトで null 非許容です。オプション型は T | None です。pxt.Required は使用しないでください。
from pixeltable.functions.uuid import uuid7
t = pxt.create_table('my_project.items', {
'content': pxt.String,
'uuid': uuid7(),
}, primary_key=['uuid'], if_exists='ignore')
挿入:t.insert([{...}])。計算列:
from pixeltable.functions.openai import chat_completions
t.add_computed_column(
summary=chat_completions(
messages=[{'role': 'user', 'content': t.content}],
model='gpt-4o-mini',
).choices[0].message.content,
if_exists='ignore',
)
ビュー:document_splitter、frame_iterator(pixeltable.functions.video から)、string_splitter、audio_splitter。Notebook のインデックス:t.add_embedding_index('content', embedding=embed_fn, if_exists='ignore')。
クエリ:t.where(...).select(...).collect()。類似度:t.content.similarity(string=query)。@pxt.query では、score=sim のようにエイリアスを指定します。
UDF は、プロジェクトルートからの相対パスであるモジュールパスとして記録されます(app.excerpt)。
Notebook の create_*/add_* では、必ず if_exists='ignore' を指定してください。セルでエラーが発生した場合:t.recompute_columns('summary', errors_only=True)、または pxt recompute my_project/documents summary --errors-only -f を実行します。string_splitter/document_splitter(..., separators='sentence') には spaCy が必要です。埋め込みインデックスでは、モデルの引数をバインドするために .using(...) が必要です。