docs: Add example using TypedDict in structured outputs how-to guide (#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 <eyurtsev@gmail.com>
This commit is contained in:
Artur Barseghyan 2024-11-13 17:53:37 +01:00 committed by GitHub
parent 3e972faf81
commit 2ab5673eb1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -56,7 +56,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 3, "execution_count": 1,
"id": "6d55008f", "id": "6d55008f",
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
@ -81,7 +81,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 4, "execution_count": 2,
"id": "070bf702", "id": "070bf702",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@ -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)" "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": {}, "metadata": {},
"output_type": "execute_result" "output_type": "execute_result"
} }
@ -147,7 +147,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 8, "execution_count": 3,
"id": "70d82891-42e8-424a-919e-07d83bcfec61", "id": "70d82891-42e8-424a-919e-07d83bcfec61",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@ -159,7 +159,7 @@
" 'rating': 7}" " 'rating': 7}"
] ]
}, },
"execution_count": 8, "execution_count": 3,
"metadata": {}, "metadata": {},
"output_type": "execute_result" "output_type": "execute_result"
} }
@ -199,7 +199,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 6, "execution_count": 4,
"id": "6700994a", "id": "6700994a",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@ -207,11 +207,10 @@
"data": { "data": {
"text/plain": [ "text/plain": [
"{'setup': 'Why was the cat sitting on the computer?',\n", "{'setup': 'Why was the cat sitting on the computer?',\n",
" 'punchline': 'Because it wanted to keep an eye on the mouse!',\n", " 'punchline': 'Because it wanted to keep an eye on the mouse!'}"
" 'rating': 7}"
] ]
}, },
"execution_count": 6, "execution_count": 4,
"metadata": {}, "metadata": {},
"output_type": "execute_result" "output_type": "execute_result"
} }
@ -250,12 +249,14 @@
"source": [ "source": [
"### Choosing between multiple schemas\n", "### Choosing between multiple schemas\n",
"\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", "cell_type": "code",
"execution_count": 19, "execution_count": 7,
"id": "9194bcf2", "id": "9194bcf2",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@ -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))" "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": {}, "metadata": {},
"output_type": "execute_result" "output_type": "execute_result"
} }
@ -274,7 +275,6 @@
"from typing import Union\n", "from typing import Union\n",
"\n", "\n",
"\n", "\n",
"# Pydantic\n",
"class Joke(BaseModel):\n", "class Joke(BaseModel):\n",
" \"\"\"Joke to tell user.\"\"\"\n", " \"\"\"Joke to tell user.\"\"\"\n",
"\n", "\n",
@ -302,17 +302,17 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 20, "execution_count": 8,
"id": "84d86132", "id": "84d86132",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
{ {
"data": { "data": {
"text/plain": [ "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": 20, "execution_count": 8,
"metadata": {}, "metadata": {},
"output_type": "execute_result" "output_type": "execute_result"
} }
@ -321,6 +321,91 @@
"structured_llm.invoke(\"How are you today?\")" "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": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"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", "cell_type": "markdown",
"id": "e28c14d3", "id": "e28c14d3",
@ -347,7 +432,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 9, "execution_count": 11,
"id": "aff89877-28a3-472f-a1aa-eff893fe7736", "id": "aff89877-28a3-472f-a1aa-eff893fe7736",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@ -415,7 +500,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 11, "execution_count": 12,
"id": "283ba784-2072-47ee-9b2c-1119e3c69e8e", "id": "283ba784-2072-47ee-9b2c-1119e3c69e8e",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@ -423,11 +508,11 @@
"data": { "data": {
"text/plain": [ "text/plain": [
"{'setup': 'Woodpecker',\n", "{'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}" " 'rating': 7}"
] ]
}, },
"execution_count": 11, "execution_count": 12,
"metadata": {}, "metadata": {},
"output_type": "execute_result" "output_type": "execute_result"
} }
@ -465,7 +550,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 12, "execution_count": 13,
"id": "d7381cb0-b2c3-4302-a319-ed72d0b9e43f", "id": "d7381cb0-b2c3-4302-a319-ed72d0b9e43f",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@ -474,10 +559,10 @@
"text/plain": [ "text/plain": [
"{'setup': 'Crocodile',\n", "{'setup': 'Crocodile',\n",
" 'punchline': 'Crocodile be seeing you later, alligator!',\n", " 'punchline': 'Crocodile be seeing you later, alligator!',\n",
" 'rating': 7}" " 'rating': 6}"
] ]
}, },
"execution_count": 12, "execution_count": 13,
"metadata": {}, "metadata": {},
"output_type": "execute_result" "output_type": "execute_result"
} }
@ -579,7 +664,7 @@
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 15, "execution_count": 14,
"id": "df0370e3", "id": "df0370e3",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
@ -590,7 +675,7 @@
" 'punchline': 'Because it wanted to keep an eye on the mouse!'}" " 'punchline': 'Because it wanted to keep an eye on the mouse!'}"
] ]
}, },
"execution_count": 15, "execution_count": 14,
"metadata": {}, "metadata": {},
"output_type": "execute_result" "output_type": "execute_result"
} }
@ -733,7 +818,7 @@
"source": [ "source": [
"query = \"Anna is 23 years old and she is 6 feet tall\"\n", "query = \"Anna is 23 years old and she is 6 feet tall\"\n",
"\n", "\n",
"print(prompt.invoke(query).to_string())" "print(prompt.invoke({\"query\": query}).to_string())"
] ]
}, },
{ {
@ -913,9 +998,9 @@
], ],
"metadata": { "metadata": {
"kernelspec": { "kernelspec": {
"display_name": "poetry-venv-2", "display_name": "Python 3 (ipykernel)",
"language": "python", "language": "python",
"name": "poetry-venv-2" "name": "python3"
}, },
"language_info": { "language_info": {
"codemirror_mode": { "codemirror_mode": {
@ -927,7 +1012,7 @@
"name": "python", "name": "python",
"nbconvert_exporter": "python", "nbconvert_exporter": "python",
"pygments_lexer": "ipython3", "pygments_lexer": "ipython3",
"version": "3.11.9" "version": "3.11.4"
} }
}, },
"nbformat": 4, "nbformat": 4,