Files
wehub-resource-sync a0c8464e58
Build Package / build (ubuntu-latest) (push) Failing after 1s
CodeQL / Analyze (python) (push) Failing after 1s
Core Typecheck / core-typecheck (push) Failing after 1s
Linting / lint (push) Failing after 1s
llama-dev tests / test-llama-dev (push) Failing after 1s
Publish Sub-Package to PyPI if Needed / publish_subpackage_if_needed (push) Has been skipped
Sync Docs to Developer Hub / sync-docs (push) Failing after 0s
Build Package / build (windows-latest) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:26:52 +08:00

519 lines
17 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"id": "77cd2b62-d55c-48cd-8629-c726b41eafbd",
"metadata": {},
"source": [
"# Function Calling Program for Structured Extraction\n",
"\n",
"<a href=\"https://colab.research.google.com/github/run-llama/llama_index/blob/main/docs/examples/output_parsing/function_program.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>\n",
"\n",
"This guide shows you how to do structured data extraction with our `FunctionCallingProgram`. Given a function-calling LLM as well as an output Pydantic class, generate a structured Pydantic object. We use three different function calling LLMs:\n",
"- OpenAI\n",
"- Anthropic Claude\n",
"- Mistral\n",
"\n",
"In terms of the target object, you can choose to directly specify `output_cls`, or specify a `PydanticOutputParser` or any other BaseOutputParser that generates a Pydantic object.\n",
"\n",
"in the examples below, we show you different ways of extracting into the `Album` object (which can contain a list of Song objects).\n",
"\n",
"**NOTE**: The `FunctionCallingProgram` only works with LLMs that natively support function calling, by inserting the schema of the Pydantic object as the \"tool parameters\" for a tool. For all other LLMs, please use our `LLMTextCompletionProgram`, which will directly prompt the model through text to get back a structured output."
]
},
{
"cell_type": "markdown",
"id": "3719f4ff-480a-4c39-b897-a37a9c841245",
"metadata": {},
"source": [
"## Define `Album` class\n",
"\n",
"This is a simple example of parsing an output into an `Album` schema, which can contain multiple songs.\n",
"\n",
"Just pass `Album` into the `output_cls` property on initialization of the `FunctionCallingProgram`."
]
},
{
"cell_type": "markdown",
"id": "42273736-e2a1-46b3-8d50-cfe02e00afa5",
"metadata": {},
"source": [
"If you're opening this Notebook on colab, you will probably need to install LlamaIndex 🦙."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "65a0a440-c8ee-42d8-986b-3b16984baff6",
"metadata": {},
"outputs": [],
"source": [
"!pip install llama-index"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c8275a82-a581-48c2-9f7b-1f8ac89413e3",
"metadata": {},
"outputs": [],
"source": [
"from pydantic import BaseModel\n",
"from typing import List\n",
"\n",
"from llama_index.core.program import FunctionCallingProgram"
]
},
{
"cell_type": "markdown",
"id": "0a6372f5-8e29-487d-8bcc-f7c2f532e01d",
"metadata": {},
"source": [
"Define output schema"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a3eb837d-326b-45d6-8cfa-d1a7b6bbe56c",
"metadata": {},
"outputs": [],
"source": [
"class Song(BaseModel):\n",
" \"\"\"Data model for a song.\"\"\"\n",
"\n",
" title: str\n",
" length_seconds: int\n",
"\n",
"\n",
"class Album(BaseModel):\n",
" \"\"\"Data model for an album.\"\"\"\n",
"\n",
" name: str\n",
" artist: str\n",
" songs: List[Song]"
]
},
{
"cell_type": "markdown",
"id": "13a01b4a-7fef-429c-8b10-7ec7dc8f3e25",
"metadata": {},
"source": [
"## Define Function Calling Program\n",
"\n",
"We define a function calling program with three function-calling LLMs: \n",
"- OpenAI \n",
"- Anthropic\n",
"- Mistral"
]
},
{
"cell_type": "markdown",
"id": "3b19fcbf-da16-43c4-9df8-f01810fac7cb",
"metadata": {},
"source": [
"### Function Calling Program with OpenAI\n",
"\n",
"Here we use gpt-3.5-turbo.\n",
"\n",
"We demonstrate structured data extraction \"single\" function calling and also parallel function calling, allowing us to extract out multiple objects."
]
},
{
"cell_type": "markdown",
"id": "a2ca1d28-7e14-4a9d-be51-84110974dc6e",
"metadata": {},
"source": [
"#### Function Calling (Single Object)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5599fdb4-ac24-4925-9ea9-f559b31222a2",
"metadata": {},
"outputs": [],
"source": [
"from llama_index.core.program import FunctionCallingProgram\n",
"from llama_index.llms.openai import OpenAI"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f8d86c9e-9177-4e47-aa96-3c346d845592",
"metadata": {},
"outputs": [],
"source": [
"prompt_template_str = \"\"\"\\\n",
"Generate an example album, with an artist and a list of songs. \\\n",
"Using the movie {movie_name} as inspiration.\\\n",
"\"\"\"\n",
"llm = OpenAI(model=\"gpt-3.5-turbo\")\n",
"\n",
"program = FunctionCallingProgram.from_defaults(\n",
" output_cls=Album,\n",
" prompt_template_str=prompt_template_str,\n",
" verbose=True,\n",
")"
]
},
{
"cell_type": "markdown",
"id": "62dedb60-2f34-4086-a2e8-294d64baf154",
"metadata": {},
"source": [
"Run program to get structured output. "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d8991fed-467f-4f4d-8bfa-5b3a4782b766",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"=== Calling Function ===\n",
"Calling function: Album with args: {\"name\": \"The Shining Soundtrack\", \"artist\": \"Various Artists\", \"songs\": [{\"title\": \"Main Title\", \"length_seconds\": 180}, {\"title\": \"Rocky Mountains\", \"length_seconds\": 240}, {\"title\": \"Lullaby\", \"length_seconds\": 200}, {\"title\": \"The Overlook Hotel\", \"length_seconds\": 220}, {\"title\": \"Grady's Story\", \"length_seconds\": 180}, {\"title\": \"The Maze\", \"length_seconds\": 210}]}\n",
"=== Function Output ===\n",
"name='The Shining Soundtrack' artist='Various Artists' songs=[Song(title='Main Title', length_seconds=180), Song(title='Rocky Mountains', length_seconds=240), Song(title='Lullaby', length_seconds=200), Song(title='The Overlook Hotel', length_seconds=220), Song(title=\"Grady's Story\", length_seconds=180), Song(title='The Maze', length_seconds=210)]\n"
]
}
],
"source": [
"output = program(movie_name=\"The Shining\")"
]
},
{
"cell_type": "markdown",
"id": "56dab4b5-b403-467d-a3d8-f6423f8b39ec",
"metadata": {},
"source": [
"The output is a valid Pydantic object that we can then use to call functions/APIs. "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "4b39a61a-761b-47b4-a8e7-fb2c0636f805",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Album(name='The Shining Soundtrack', artist='Various Artists', songs=[Song(title='Main Title', length_seconds=180), Song(title='Rocky Mountains', length_seconds=240), Song(title='Lullaby', length_seconds=200), Song(title='The Overlook Hotel', length_seconds=220), Song(title=\"Grady's Story\", length_seconds=180), Song(title='The Maze', length_seconds=210)])"
]
},
"execution_count": null,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"output"
]
},
{
"cell_type": "markdown",
"id": "35b98612-089e-45f7-b639-90121c6158eb",
"metadata": {},
"source": [
"#### Function Calling (Parallel Function Calling, Multiple Objects)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "40eea03f-c331-4af5-9f86-a11927325cd2",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"=== Calling Function ===\n",
"Calling function: Album with args: {\"name\": \"The Shining\", \"artist\": \"Various Artists\", \"songs\": [{\"title\": \"Main Theme\", \"length_seconds\": 180}, {\"title\": \"The Overlook Hotel\", \"length_seconds\": 240}, {\"title\": \"Redrum\", \"length_seconds\": 200}]}\n",
"=== Function Output ===\n",
"name='The Shining' artist='Various Artists' songs=[Song(title='Main Theme', length_seconds=180), Song(title='The Overlook Hotel', length_seconds=240), Song(title='Redrum', length_seconds=200)]\n",
"=== Calling Function ===\n",
"Calling function: Album with args: {\"name\": \"The Blair Witch Project\", \"artist\": \"Soundtrack Ensemble\", \"songs\": [{\"title\": \"Into the Woods\", \"length_seconds\": 210}, {\"title\": \"The Rustling Leaves\", \"length_seconds\": 180}, {\"title\": \"The Witch's Curse\", \"length_seconds\": 240}]}\n",
"=== Function Output ===\n",
"name='The Blair Witch Project' artist='Soundtrack Ensemble' songs=[Song(title='Into the Woods', length_seconds=210), Song(title='The Rustling Leaves', length_seconds=180), Song(title=\"The Witch's Curse\", length_seconds=240)]\n",
"=== Calling Function ===\n",
"Calling function: Album with args: {\"name\": \"Saw\", \"artist\": \"Horror Soundscapes\", \"songs\": [{\"title\": \"The Reverse Bear Trap\", \"length_seconds\": 220}, {\"title\": \"Jigsaw's Game\", \"length_seconds\": 260}, {\"title\": \"Bathroom Escape\", \"length_seconds\": 180}]}\n",
"=== Function Output ===\n",
"name='Saw' artist='Horror Soundscapes' songs=[Song(title='The Reverse Bear Trap', length_seconds=220), Song(title=\"Jigsaw's Game\", length_seconds=260), Song(title='Bathroom Escape', length_seconds=180)]\n"
]
}
],
"source": [
"prompt_template_str = \"\"\"\\\n",
"Generate example albums, with an artist and a list of songs, using each movie below as inspiration. \\\n",
"\n",
"Here are the movies:\n",
"{movie_names}\n",
"\"\"\"\n",
"llm = OpenAI(model=\"gpt-3.5-turbo\")\n",
"\n",
"program = FunctionCallingProgram.from_defaults(\n",
" output_cls=Album,\n",
" prompt_template_str=prompt_template_str,\n",
" verbose=True,\n",
" allow_parallel_tool_calls=True,\n",
")\n",
"output = program(movie_names=\"The Shining, The Blair Witch Project, Saw\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "eb9dcab1-1bf7-4cfb-bd82-eaf71d809f1b",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[Album(name='The Shining', artist='Various Artists', songs=[Song(title='Main Theme', length_seconds=180), Song(title='The Overlook Hotel', length_seconds=240), Song(title='Redrum', length_seconds=200)]),\n",
" Album(name='The Blair Witch Project', artist='Soundtrack Ensemble', songs=[Song(title='Into the Woods', length_seconds=210), Song(title='The Rustling Leaves', length_seconds=180), Song(title=\"The Witch's Curse\", length_seconds=240)]),\n",
" Album(name='Saw', artist='Horror Soundscapes', songs=[Song(title='The Reverse Bear Trap', length_seconds=220), Song(title=\"Jigsaw's Game\", length_seconds=260), Song(title='Bathroom Escape', length_seconds=180)])]"
]
},
"execution_count": null,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"output"
]
},
{
"cell_type": "markdown",
"id": "8eee2f40-fdbd-4141-b388-d6fb4f178ae4",
"metadata": {},
"source": [
"### Function Calling Program with Anthropic\n",
"\n",
"Here we use Claude Sonnet (all three models support function calling)."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f114bd12-b109-408f-9281-6bde2a95c162",
"metadata": {},
"outputs": [],
"source": [
"from llama_index.core.program import FunctionCallingProgram\n",
"from llama_index.llms.anthropic import Anthropic"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "6df92b19-eb63-483d-9eff-b1f5b9e17fe4",
"metadata": {},
"outputs": [],
"source": [
"prompt_template_str = \"Generate a song about {topic}.\"\n",
"llm = Anthropic(model=\"claude-3-sonnet-20240229\")\n",
"\n",
"program = FunctionCallingProgram.from_defaults(\n",
" output_cls=Song,\n",
" prompt_template_str=prompt_template_str,\n",
" llm=llm,\n",
" verbose=True,\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "79e48c86-0b08-496b-b855-ddffbb1d8e04",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"=== Calling Function ===\n",
"Calling function: Song with args: {\"title\": \"The Boy Who Lived\", \"length_seconds\": 180}\n",
"=== Function Output ===\n",
"title='The Boy Who Lived' length_seconds=180\n"
]
}
],
"source": [
"output = program(topic=\"harry potter\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "8677eedd-cf80-422d-bb64-4fbdb8885967",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Song(title='The Boy Who Lived', length_seconds=180)"
]
},
"execution_count": null,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"output"
]
},
{
"cell_type": "markdown",
"id": "f93b3cee-8d6e-4d96-97e4-2299d289bc9c",
"metadata": {},
"source": [
"### Function Calling Program with Mistral\n",
"\n",
"Here we use mistral-large."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e46076ba-0e95-4f32-a886-220b7ed74309",
"metadata": {},
"outputs": [],
"source": [
"from llama_index.core.program import FunctionCallingProgram\n",
"from llama_index.llms.mistralai import MistralAI"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c039af17-2e03-4c53-b708-35e79b50a32c",
"metadata": {},
"outputs": [],
"source": [
"# prompt_template_str = \"\"\"\\\n",
"# Generate an example album, with an artist and a list of songs. \\\n",
"# Use the broadway show {broadway_show} as inspiration. \\\n",
"# Make sure to use the tool.\n",
"# \"\"\"\n",
"prompt_template_str = \"Generate a song about {topic}.\"\n",
"llm = MistralAI(model=\"mistral-large-latest\")\n",
"program = FunctionCallingProgram.from_defaults(\n",
" output_cls=Song,\n",
" prompt_template_str=prompt_template_str,\n",
" llm=llm,\n",
" verbose=True,\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5ba59e21-7e30-474c-a457-7c84e2b72292",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"=== Calling Function ===\n",
"Calling function: Song with args: {\"title\": \"Defying Gravity\", \"length_seconds\": 240}\n",
"=== Function Output ===\n",
"title='Defying Gravity' length_seconds=240\n"
]
}
],
"source": [
"output = program(topic=\"the broadway show Wicked\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "009d870d-247d-4aa5-a0c9-52260f56b631",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Song(title='Defying Gravity', length_seconds=240)"
]
},
"execution_count": null,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"output"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "8a374b38-b151-4ad5-bd06-97c47552bbd3",
"metadata": {},
"outputs": [],
"source": [
"from llama_index.core.output_parsers import PydanticOutputParser\n",
"\n",
"program = LLMTextCompletionProgram.from_defaults(\n",
" output_parser=PydanticOutputParser(output_cls=Album),\n",
" prompt_template_str=prompt_template_str,\n",
" verbose=True,\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "2459a230-5dfd-4c80-89f4-6bbf175b258f",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Album(name='The Fellowship of the Ring', artist='Middle-earth Ensemble', songs=[Song(title='The Shire', length_seconds=240), Song(title='Concerning Hobbits', length_seconds=180), Song(title='The Ring Goes South', length_seconds=300), Song(title='A Knife in the Dark', length_seconds=270), Song(title='Flight to the Ford', length_seconds=210), Song(title='Many Meetings', length_seconds=240), Song(title='The Council of Elrond', length_seconds=330), Song(title='The Great Eye', length_seconds=180), Song(title='The Breaking of the Fellowship', length_seconds=360)])"
]
},
"execution_count": null,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"output = program(movie_name=\"Lord of the Rings\")\n",
"output"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "llama_index_v3",
"language": "python",
"name": "llama_index_v3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3"
}
},
"nbformat": 4,
"nbformat_minor": 5
}