Skip to main content
Open in Kaggle  Open in Colab  Download Notebook
This documentation page is also available as an interactive notebook. You can launch the notebook in Kaggle or Colab, or download it for use with an IDE or local Jupyter installation, by clicking one of the above links.
Convert a table with computed columns into a callable function for multi-agent workflows and pipeline composition.

Problem

You have a table that runs a complex pipeline—LLM calls, tool use, post-processing—and you want to reuse that entire pipeline from other tables. Copy-pasting computed column definitions is error-prone and hard to maintain.

Solution

What’s in this recipe:
  • Create an “agent” table with computed columns
  • Convert the table to a callable UDF with pxt.udf(table, return_value=...)
  • Use the table UDF in other tables’ computed columns
You wrap an entire table pipeline as a function. When you call this function from another table, it inserts a row into the agent table, runs all computed columns, and returns the specified output column.

Setup

%pip install -qU pixeltable openai
import os
import getpass

if 'OPENAI_API_KEY' not in os.environ:
    os.environ['OPENAI_API_KEY'] = getpass.getpass('OpenAI API Key: ')
import pixeltable as pxt
from pixeltable.functions.openai import chat_completions
# Create a fresh directory
pxt.drop_dir('table_udf_demo', force=True)
pxt.create_dir('table_udf_demo')
Connected to Pixeltable database at: postgresql+psycopg://postgres:@/pixeltable?host=/Users/pjlb/.pixeltable/pgdata
Created directory ‘table_udf_demo’.
<pixeltable.catalog.dir.Dir at 0x17fd6e9d0>

Create an agent table with computed columns

You create a table that encapsulates a complete pipeline. This example builds a summarization agent:
# Create the agent table with input column
summarizer = pxt.create_table(
    'table_udf_demo.summarizer',
    {'text': pxt.String}
)
Created table ‘summarizer’.
# Add the LLM call as a computed column
summarizer.add_computed_column(
    response=chat_completions(
        messages=[{
            'role': 'user',
            'content': 'Summarize this in one sentence:\n\n' + summarizer.text
        }],
        model='gpt-4o-mini'
    )
)
Added 0 column values with 0 errors.
No rows affected.
# Extract the summary text
summarizer.add_computed_column(
    summary=summarizer.response.choices[0].message.content
)
Added 0 column values with 0 errors.
No rows affected.

Convert the table to a UDF

You use pxt.udf(table, return_value=...) to convert the table into a callable function. The return_value specifies which column to return:
# Convert the summarizer table into a callable UDF
summarize = pxt.udf(
    summarizer,
    return_value=summarizer.summary
)

Use the table UDF in another table

You can now use summarize() as a computed column in any other table:
# Create a table that uses the summarizer
articles = pxt.create_table(
    'table_udf_demo.articles',
    {'title': pxt.String, 'content': pxt.String}
)
Created table ‘articles’.
# Add the table UDF as a computed column
articles.add_computed_column(
    summary=summarize(text=articles.content)
)
Added 0 column values with 0 errors.
No rows affected.
# Insert articles - summaries are generated automatically
articles.insert([
    {
        'title': 'Climate Report',
        'content': 'Global temperatures rose by 1.2 degrees Celsius above pre-industrial levels last year, marking the hottest year on record. Scientists attribute this to continued greenhouse gas emissions and a strong El Nino pattern. The report calls for immediate action to reduce carbon emissions.'
    },
    {
        'title': 'Tech Merger',
        'content': 'Two major semiconductor companies announced a merger valued at $50 billion. The combined entity will control 30% of the global chip market. Regulators in multiple countries will review the deal over the next 18 months.'
    },
])
Inserting rows into `articles`: 2 rows [00:00, 196.58 rows/s]
Inserted 2 rows with 0 errors.
2 rows inserted, 6 values computed.
# View results
articles.select(articles.title, articles.summary).collect()

Explanation

How table UDFs work:
Consumer table row → Table UDF called → Agent table inserts row →
Computed columns run → Return value extracted → Consumer gets result
When to use table UDFs vs @pxt.query:
Key benefits:
  • Encapsulation: Hide complex pipeline details behind a simple function call
  • Reusability: Use the same agent from multiple consumer tables
  • Persistence: All intermediate results are stored in the agent table for debugging
  • Composition: Chain agents together for multi-stage workflows

See also