Skip to content

Commit

Permalink
add how-to guide on structured output prebuilt react agent (#794)
Browse files Browse the repository at this point in the history
  • Loading branch information
isahers1 authored Jan 22, 2025
2 parents b290953 + 86a566b commit 31131e6
Show file tree
Hide file tree
Showing 2 changed files with 255 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/docs/how-tos/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ See the [multi-agent tutorials](../tutorials/index.md#multi-agent-systems) for i
- [How to add memory to a ReAct agent](react-memory.ipynb)
- [How to add a system prompt to a ReAct agent](react-system-prompt.ipynb)
- [How to add Human-in-the-loop to a ReAct agent](react-human-in-the-loop.ipynb)
- [How to return structured output from a ReAct agent](react-return-structured-output.ipynb)

## LangGraph Platform

Expand Down
254 changes: 254 additions & 0 deletions examples/how-tos/react-return-structured-output.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,254 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# How to return structured output from the prebuilt ReAct agent\n",
"\n",
"\n",
"!!! info \"Prerequisites\"\n",
"\n",
" - [Agent Architectures](../../concepts/agentic_concepts/)\n",
" - [Chat Models](https://python.langchain.com/docs/concepts/chat_models/)\n",
" - [Tools](https://python.langchain.com/docs/concepts/tools/)\n",
" - [Structured Output](https://python.langchain.com/docs/concepts/structured_outputs/)\n",
"\n",
"\n",
"To return structured output from the prebuilt ReAct agent you can provide a response_format parameter with the desired output schema to [`createReactAgent`](https://langchain-ai.github.io/langgraphjs/reference/functions/prebuilt.createReactAgent.html):"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import { z } from \"zod\";\n",
"import { createReactAgent } from \"@langchain/langgraph/prebuilt\";\n",
"\n",
"const responseFormat = z.object({\n",
" // Respond to the user in this format\n",
" mySpecialOutput: z.string(),\n",
"})\n",
"\n",
"const graph = createReactAgent({\n",
" llm: llm,\n",
" tools: tools,\n",
" // specify the schema for the structured output using `responseFormat` parameter\n",
" responseFormat: responseFormat\n",
"})"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The agent will return the output in the format specified by the `responseFormat` schema by making an additional LLM call at the end of the conversation, once there are no more tool calls to be made. You can read [this guide](./respond-in-format) to learn about an alternate way - treating the structured output as another tool = to achieve structured output from the agent.\n",
"\n",
"## Setup\n",
"\n",
"First, we need to install the required packages.\n",
"\n",
"```bash\n",
"yarn add @langchain/langgraph @langchain/openai @langchain/core zod\n",
"```\n",
"\n",
"This guide will use OpenAI's GPT-4o model. We will optionally set our API key\n",
"for [LangSmith tracing](https://smith.langchain.com/), which will give us\n",
"best-in-class observability."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"// process.env.OPENAI_API_KEY = \"sk_...\";\n",
"\n",
"// Optional, add tracing in LangSmith\n",
"// process.env.LANGSMITH_API_KEY = \"ls__...\"\n",
"process.env.LANGSMITH_TRACING = \"true\";\n",
"process.env.LANGSMITH_PROJECT = \"ReAct Agent with system prompt: LangGraphJS\";"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Code"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import { ChatOpenAI } from \"@langchain/openai\";\n",
"import { createReactAgent } from \"@langchain/langgraph/prebuilt\";\n",
"import { tool } from \"@langchain/core/tools\";\n",
"import { z } from \"zod\";\n",
"\n",
"const weatherTool = tool(\n",
" async (input): Promise<string> => {\n",
" if (input.city === \"nyc\") {\n",
" return \"It might be cloudy in nyc\";\n",
" } else if (input.city === \"sf\") {\n",
" return \"It's always sunny in sf\";\n",
" } else {\n",
" throw new Error(\"Unknown city\");\n",
" }\n",
" },\n",
" {\n",
" name: \"get_weather\",\n",
" description: \"Use this to get weather information.\",\n",
" schema: z.object({\n",
" city: z.enum([\"nyc\", \"sf\"]).describe(\"The city to get weather for\"),\n",
" }),\n",
" }\n",
");\n",
"\n",
"const WeatherResponseSchema = z.object({\n",
" conditions: z.string().describe(\"Weather conditions\"),\n",
"});\n",
"\n",
"const tools = [weatherTool];\n",
"\n",
"const agent = createReactAgent({\n",
" llm: new ChatOpenAI({ model: \"gpt-4o\", temperature: 0 }),\n",
" tools: tools,\n",
" responseFormat: WeatherResponseSchema,\n",
"}); "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Usage\n",
"\n",
"Let's now test our agent:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"const response = await agent.invoke({\n",
" messages: [\n",
" {\n",
" role: \"user\",\n",
" content: \"What's the weather in NYC?\",\n",
" },\n",
" ],\n",
"})"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can see that the agent output contains a `structuredResponse` key with the structured output conforming to the specified `WeatherResponse` schema, in addition to the message history under `messages` key"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{ conditions: 'cloudy' }\n"
]
}
],
"source": [
"response.structuredResponse"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Customizing system prompt\n",
"\n",
"You might need to further customize the second LLM call for the structured output generation and provide a system prompt. To do so, you can pass an object with the keys `prompt`, `schema` to the `responseFormat` parameter:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"const agent = createReactAgent({\n",
" llm: new ChatOpenAI({ model: \"gpt-4o\", temperature: 0 }),\n",
" tools: tools,\n",
" responseFormat: {\n",
" prompt: \"Always return capitalized weather conditions\",\n",
" schema: WeatherResponseSchema,\n",
" }\n",
"}); \n",
"\n",
"const response = await agent.invoke({\n",
" messages: [\n",
" {\n",
" role: \"user\",\n",
" content: \"What's the weather in NYC?\",\n",
" },\n",
" ],\n",
"})"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can verify that the structured response now contains a capitalized value:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{ conditions: 'Cloudy' }\n"
]
}
],
"source": [
"response.structuredResponse"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "TypeScript",
"language": "typescript",
"name": "tslab"
},
"language_info": {
"codemirror_mode": {
"mode": "typescript",
"name": "javascript",
"typescript": true
},
"file_extension": ".ts",
"mimetype": "text/typescript",
"name": "typescript",
"version": "3.7.2"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

0 comments on commit 31131e6

Please sign in to comment.