Skip to content

Commit

Permalink
docs: Add example using TypedDict in structured outputs how-to guide (
Browse files Browse the repository at this point in the history
#27415)

For me, the [Pydantic
example](https://python.langchain.com/docs/how_to/structured_output/#choosing-between-multiple-schemas)
does not work (tested on various Python versions from 3.10 to 3.12, and
`Pydantic` versions from 2.7 to 2.9).

The `TypedDict` example (added in this PR) does.

----

Additionally, fixed an error in [Using PydanticOutputParser
example](https://python.langchain.com/docs/how_to/structured_output/#using-pydanticoutputparser).

Was:

```python
query = "Anna is 23 years old and she is 6 feet tall"

print(prompt.invoke(query).to_string())
```

Corrected to:

```python
query = "Anna is 23 years old and she is 6 feet tall"

print(prompt.invoke({"query": query}).to_string())
```

---------

Co-authored-by: Eugene Yurtsev <[email protected]>
  • Loading branch information
barseghyanartur and eyurtsev authored Nov 13, 2024
1 parent 3e972fa commit 2ab5673
Showing 1 changed file with 114 additions and 29 deletions.
143 changes: 114 additions & 29 deletions docs/docs/how_to/structured_output.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
},
{
"cell_type": "code",
"execution_count": 3,
"execution_count": 1,
"id": "6d55008f",
"metadata": {},
"outputs": [],
Expand All @@ -81,7 +81,7 @@
},
{
"cell_type": "code",
"execution_count": 4,
"execution_count": 2,
"id": "070bf702",
"metadata": {},
"outputs": [
Expand All @@ -91,7 +91,7 @@
"Joke(setup='Why was the cat sitting on the computer?', punchline='Because it wanted to keep an eye on the mouse!', rating=7)"
]
},
"execution_count": 4,
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
Expand Down Expand Up @@ -147,7 +147,7 @@
},
{
"cell_type": "code",
"execution_count": 8,
"execution_count": 3,
"id": "70d82891-42e8-424a-919e-07d83bcfec61",
"metadata": {},
"outputs": [
Expand All @@ -159,7 +159,7 @@
" 'rating': 7}"
]
},
"execution_count": 8,
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
Expand Down Expand Up @@ -199,19 +199,18 @@
},
{
"cell_type": "code",
"execution_count": 6,
"execution_count": 4,
"id": "6700994a",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'setup': 'Why was the cat sitting on the computer?',\n",
" 'punchline': 'Because it wanted to keep an eye on the mouse!',\n",
" 'rating': 7}"
" 'punchline': 'Because it wanted to keep an eye on the mouse!'}"
]
},
"execution_count": 6,
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
Expand Down Expand Up @@ -250,12 +249,14 @@
"source": [
"### Choosing between multiple schemas\n",
"\n",
"The simplest way to let the model choose from multiple schemas is to create a parent schema that has a Union-typed attribute:"
"The simplest way to let the model choose from multiple schemas is to create a parent schema that has a Union-typed attribute.\n",
"\n",
"#### Using Pydantic"
]
},
{
"cell_type": "code",
"execution_count": 19,
"execution_count": 7,
"id": "9194bcf2",
"metadata": {},
"outputs": [
Expand All @@ -265,7 +266,7 @@
"FinalResponse(final_output=Joke(setup='Why was the cat sitting on the computer?', punchline='Because it wanted to keep an eye on the mouse!', rating=7))"
]
},
"execution_count": 19,
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
Expand All @@ -274,7 +275,6 @@
"from typing import Union\n",
"\n",
"\n",
"# Pydantic\n",
"class Joke(BaseModel):\n",
" \"\"\"Joke to tell user.\"\"\"\n",
"\n",
Expand Down Expand Up @@ -302,17 +302,94 @@
},
{
"cell_type": "code",
"execution_count": 20,
"execution_count": 8,
"id": "84d86132",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"FinalResponse(final_output=ConversationalResponse(response=\"I'm just a bunch of code, so I don't have feelings, but I'm here and ready to help you! How can I assist you today?\"))"
"FinalResponse(final_output=ConversationalResponse(response=\"I'm just a computer program, so I don't have feelings, but I'm here and ready to help you with whatever you need!\"))"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"structured_llm.invoke(\"How are you today?\")"
]
},
{
"cell_type": "markdown",
"id": "8b087112c23bafcd",
"metadata": {},
"source": [
"#### Using TypedDict"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "eb0d5855-feba-48fb-84ea-9acb0edb238b",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'final_output': {'setup': 'Why was the cat sitting on the computer?',\n",
" 'punchline': 'Because it wanted to keep an eye on the mouse!',\n",
" 'rating': 7}}"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from typing import Optional, Union\n",
"\n",
"from typing_extensions import Annotated, TypedDict\n",
"\n",
"\n",
"class Joke(TypedDict):\n",
" \"\"\"Joke to tell user.\"\"\"\n",
"\n",
" setup: Annotated[str, ..., \"The setup of the joke\"]\n",
" punchline: Annotated[str, ..., \"The punchline of the joke\"]\n",
" rating: Annotated[Optional[int], None, \"How funny the joke is, from 1 to 10\"]\n",
"\n",
"\n",
"class ConversationalResponse(TypedDict):\n",
" \"\"\"Respond in a conversational manner. Be kind and helpful.\"\"\"\n",
"\n",
" response: Annotated[str, ..., \"A conversational response to the user's query\"]\n",
"\n",
"\n",
"class FinalResponse(TypedDict):\n",
" final_output: Union[Joke, ConversationalResponse]\n",
"\n",
"\n",
"structured_llm = llm.with_structured_output(FinalResponse)\n",
"\n",
"structured_llm.invoke(\"Tell me a joke about cats\")"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "ec753809-c2c1-41c0-a3c5-69855d65475b",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'final_output': {'response': \"I'm just a computer program, so I don't have feelings, but I'm here and ready to help you with whatever you need!\"}}"
]
},
"execution_count": 20,
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
Expand All @@ -321,6 +398,14 @@
"structured_llm.invoke(\"How are you today?\")"
]
},
{
"cell_type": "markdown",
"id": "dd22149ac9d41d57",
"metadata": {},
"source": [
"Responses shall be identical to the ones shown in the Pydantic example."
]
},
{
"cell_type": "markdown",
"id": "e28c14d3",
Expand All @@ -347,7 +432,7 @@
},
{
"cell_type": "code",
"execution_count": 9,
"execution_count": 11,
"id": "aff89877-28a3-472f-a1aa-eff893fe7736",
"metadata": {},
"outputs": [
Expand Down Expand Up @@ -415,19 +500,19 @@
},
{
"cell_type": "code",
"execution_count": 11,
"execution_count": 12,
"id": "283ba784-2072-47ee-9b2c-1119e3c69e8e",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'setup': 'Woodpecker',\n",
" 'punchline': \"Woodpecker who? Woodpecker who can't find a tree is just a bird with a headache!\",\n",
" 'punchline': \"Woodpecker you a joke, but I'm afraid it might be too 'hole-some'!\",\n",
" 'rating': 7}"
]
},
"execution_count": 11,
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
Expand Down Expand Up @@ -465,7 +550,7 @@
},
{
"cell_type": "code",
"execution_count": 12,
"execution_count": 13,
"id": "d7381cb0-b2c3-4302-a319-ed72d0b9e43f",
"metadata": {},
"outputs": [
Expand All @@ -474,10 +559,10 @@
"text/plain": [
"{'setup': 'Crocodile',\n",
" 'punchline': 'Crocodile be seeing you later, alligator!',\n",
" 'rating': 7}"
" 'rating': 6}"
]
},
"execution_count": 12,
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
Expand Down Expand Up @@ -579,7 +664,7 @@
},
{
"cell_type": "code",
"execution_count": 15,
"execution_count": 14,
"id": "df0370e3",
"metadata": {},
"outputs": [
Expand All @@ -590,7 +675,7 @@
" 'punchline': 'Because it wanted to keep an eye on the mouse!'}"
]
},
"execution_count": 15,
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
Expand Down Expand Up @@ -733,7 +818,7 @@
"source": [
"query = \"Anna is 23 years old and she is 6 feet tall\"\n",
"\n",
"print(prompt.invoke(query).to_string())"
"print(prompt.invoke({\"query\": query}).to_string())"
]
},
{
Expand Down Expand Up @@ -913,9 +998,9 @@
],
"metadata": {
"kernelspec": {
"display_name": "poetry-venv-2",
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "poetry-venv-2"
"name": "python3"
},
"language_info": {
"codemirror_mode": {
Expand All @@ -927,7 +1012,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.9"
"version": "3.11.4"
}
},
"nbformat": 4,
Expand Down

0 comments on commit 2ab5673

Please sign in to comment.