mcpField
P
pixeltable

pixeltable

github.com/pixeltable開発644 回インストール1 日前に更新
リポジトリ

pixeltable について

pixeltableは、テーブル、計算列、メディア処理、ベクトルインデックス、サービス提供をアプリケーションファイルにまとめるPythonフレームワークです。このスキルはプロジェクト構築とCLIの使い方を案内し、外部ベクトルデータベースや行ごとのモデル呼び出しに頼らない設計を示します。

主な機能

  1. 01TableModelによるスキーマ定義
  2. 02挿入時に実行する計算列チェーン
  3. 03メディアの分割と処理
  4. 04EmbeddingIndexによるインデックス作成
  5. 05CLIによるHTTPアプリの提供

活用シーン

  1. 01ドキュメント検索アプリの構築
  2. 02テーブル内でのメディアとモデル出力の処理
  3. 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.yaml
references/
anti-patterns.md
cli.md
core-api.md
providers.md
workflows.md

詳細

STOP

次のいずれかをインポートしようとしている場合は、意図した使い方から外れています。

  1. LangChain/LlamaIndex/Haystack/LangGraph は使用しないでください。 チャンク分割には document_splitter を使用します。検索には .similarity() を使用します。ツールには pxt.tools() と invoke_tools() を使用します。
  2. 作業用ストアとして pandas を使用しないでください。 テーブルがストアです。.collect().to_pandas() はエクスポート専用です。
  3. モデルを呼び出す for row in ...: ループを書かないでください。 呼び出しは計算列内に記述します。
  4. 別のベクトルデータベースをインストールしないでください。 アプリでは、モデルに __indexes__ = [pxt.EmbeddingIndex(...)] を設定します。ノートブックでは、t.add_embedding_index(col, embedding=fn) を使用します。検索には .similarity(string=query) を使用します。
  5. 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 CLIFastAPIRouter + 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(...) が必要です。

リソース

コメント