From 0d2cf768ac6b054697c0750f8f90d862b9bb18d2 Mon Sep 17 00:00:00 2001 From: Lingyi Zhang Date: Tue, 29 Oct 2024 22:02:57 -0400 Subject: [PATCH 1/5] how to use in chain --- ...20013_lingyi_zhang_bind_vizroai_as_tool.md | 48 +++++ vizro-ai/docs/index.md | 3 +- .../user-guides/vizro-ai-langchain-guide.md | 195 ++++++++++++++++++ vizro-ai/mkdocs.yml | 1 + 4 files changed, 246 insertions(+), 1 deletion(-) create mode 100644 vizro-ai/changelog.d/20241029_220013_lingyi_zhang_bind_vizroai_as_tool.md create mode 100644 vizro-ai/docs/pages/user-guides/vizro-ai-langchain-guide.md diff --git a/vizro-ai/changelog.d/20241029_220013_lingyi_zhang_bind_vizroai_as_tool.md b/vizro-ai/changelog.d/20241029_220013_lingyi_zhang_bind_vizroai_as_tool.md new file mode 100644 index 000000000..f1f65e73c --- /dev/null +++ b/vizro-ai/changelog.d/20241029_220013_lingyi_zhang_bind_vizroai_as_tool.md @@ -0,0 +1,48 @@ + + + + + + + + + diff --git a/vizro-ai/docs/index.md b/vizro-ai/docs/index.md index 752d228ae..26952e353 100644 --- a/vizro-ai/docs/index.md +++ b/vizro-ai/docs/index.md @@ -47,7 +47,8 @@ If a feature you need for your dashboard isn't currently supported by Vizro-AI y [:octicons-arrow-right-24: Create advanced charts](pages/user-guides/create-advanced-charts.md)
[:octicons-arrow-right-24: Add charts to a dashboard](pages/user-guides/add-generated-chart-usecase.md)
[:octicons-arrow-right-24: Generate a complex dashboard](pages/user-guides/create-complex-dashboard.md)
- [:octicons-arrow-right-24: Retrieve code for a generated dashboard](pages/user-guides/retrieve-dashboard-code.md) + [:octicons-arrow-right-24: Retrieve code for a generated dashboard](pages/user-guides/retrieve-dashboard-code.md)
+ [:octicons-arrow-right-24: Use Vizro-AI as Langchain tools](pages/user-guides/vizro-ai-langchain-guide.md) - :material-format-font:{ .lg .middle } __Find out more__ diff --git a/vizro-ai/docs/pages/user-guides/vizro-ai-langchain-guide.md b/vizro-ai/docs/pages/user-guides/vizro-ai-langchain-guide.md new file mode 100644 index 000000000..41065032e --- /dev/null +++ b/vizro-ai/docs/pages/user-guides/vizro-ai-langchain-guide.md @@ -0,0 +1,195 @@ +# Using Vizro-AI Methods as LangChain Tools + +This guide demonstrates how to integrate Vizro-AI's plotting and dashboard generation capabilities with LangChain tools. This integration allows you to use Vizro-AI's functionality within a larger LangChain application. + +## 1. Set up the environment + +First, import the required libraries and prepare your data: + +```python +from copy import deepcopy +from typing import Annotated, Any + +import pandas as pd +import vizro.plotly.express as px +from langchain_core.runnables import chain +from langchain_core.tools import InjectedToolArg, tool +from langchain_openai import ChatOpenAI +from vizro_ai import VizroAI + +# Load sample data +df = px.data.gapminder() +dfs = [df] + +# Initialize the LLM +llm = ChatOpenAI(model="gpt-4o-mini") +``` + +## 2. Define LangChain tools + +Basic tools only take string as input and output. Vizro-AI takes Pandas dataframes as input and it's not cost-efficient and secure to pass the full dataset to a LLM. In this case, [bind the Pandas dataframes at run time](https://python.langchain.com/v0.2/docs/how_to/tool_runtime/) is more suitable. + +Now, create tools that wrap Vizro-AI's plotting and dashboard generation capabilities: + +```python +@tool(parse_docstring=True) +def get_plot_code(df: Annotated[Any, InjectedToolArg], question: str) -> str: + """Generate only the plot code. + + Args: + df: A pandas DataFrame + question: The plotting question + + Returns: + Generated plot code + """ + df = pd.DataFrame(df) + vizro_ai = VizroAI(model=llm) + plot_elements = vizro_ai.plot( + df, + user_input=question, + return_elements=True, + ) + return plot_elements.code_vizro + +@tool(parse_docstring=True) +def get_dashboard_code(dfs: Annotated[Any, InjectedToolArg], question: str) -> str: + """Generate the dashboard code. + + Args: + dfs: Pandas DataFrames + question: The dashboard question + + Returns: + Generated dashboard code + """ + vizro_ai = VizroAI(model=llm) + dashboard_elements = vizro_ai.dashboard( + dfs, + user_input=question, + return_elements=True, + ) + return dashboard_elements.code +``` + +## 3. Set up the tool chain + +Create a chain that handles tool execution and data injection: + +```python +# Bind tools to the LLM +tools = [get_plot_code, get_dashboard_code] +llm_with_tools = llm.bind_tools(tools) + +# Create data injection chain +@chain +def inject_df(ai_msg): + tool_calls = [] + for tool_call in ai_msg.tool_calls: + tool_call_copy = deepcopy(tool_call) + + if tool_call_copy["name"] == "get_dashboard_code": + tool_call_copy["args"]["dfs"] = dfs + else: + tool_call_copy["args"]["df"] = df + + tool_calls.append(tool_call_copy) + return tool_calls + +# Create tool router +tool_map = {tool.name: tool for tool in tools} + +@chain +def tool_router(tool_call): + return tool_map[tool_call["name"]] + +# Combine chains +chain = llm_with_tools | inject_df | tool_router.map() +``` + +## 4. Use the chain + +Now you can use the chain to generate plots or dashboards based on natural language queries. The chain will generate code that you can use to create visualizations. + +!!! example "Generate plot code" + + === "Code" + ```py + plot_response = chain.invoke("Plot GDP per capita for each continent") + print(plot_response[0].content) + ``` + === "Vizro-AI Generated Code" + ```py + import plotly.graph_objects as go + from vizro.models.types import capture + + @capture("graph") + def custom_chart(data_frame): + continent_gdp = data_frame.groupby("continent")["gdpPercap"].mean().reset_index() + fig = go.Figure( + data=[go.Bar(x=continent_gdp["continent"], y=continent_gdp["gdpPercap"])] + ) + fig.update_layout( + title="GDP per Capita by Continent", + xaxis_title="Continent", + yaxis_title="GDP per Capita", + ) + return fig + ``` + +!!! example "Generate dashboard code" + + === "Code" + ```py + dashboard_response = chain.invoke("Create a dashboard. This dashboard has a chart showing the correlation between gdpPercap and lifeExp.") + print(dashboard_response[0].content) + ``` + === "Vizro-AI Generated Code" + ```py + ############ Imports ############## + import vizro.models as vm + from vizro.models.types import capture + import plotly.graph_objects as go + + + ####### Function definitions ###### + @capture("graph") + def gdp_life_exp_graph(data_frame): + fig = go.Figure() + fig.add_trace( + go.Scatter(x=data_frame["gdpPercap"], y=data_frame["lifeExp"], mode="markers") + ) + fig.update_layout( + title="GDP per Capita vs Life Expectancy", + xaxis_title="GDP per Capita", + yaxis_title="Life Expectancy", + ) + return fig + + + ####### Data Manager Settings ##### + #######!!! UNCOMMENT BELOW !!!##### + # from vizro.managers import data_manager + # data_manager["gdp_life_exp"] = ===> Fill in here <=== + + + ########### Model code ############ + model = vm.Dashboard( + pages=[ + vm.Page( + components=[ + vm.Graph( + id="gdp_life_exp_graph", + figure=gdp_life_exp_graph(data_frame="gdp_life_exp"), + ) + ], + title="GDP vs Life Expectancy Correlation", + layout=vm.Layout(grid=[[0]]), + controls=[], + ) + ], + title="GDP per Capita vs Life Expectancy", + ) + ``` + +This integration allows you to leverage Vizro-AI's visualization capabilities within a LangChain application, enabling natural language-driven creation of plots and dashboards. diff --git a/vizro-ai/mkdocs.yml b/vizro-ai/mkdocs.yml index 2eeba8ff6..c95fbe9e0 100644 --- a/vizro-ai/mkdocs.yml +++ b/vizro-ai/mkdocs.yml @@ -18,6 +18,7 @@ nav: - DASHBOARDS: - Generate a complex dashboard: pages/user-guides/create-complex-dashboard.md - Retrieve code for a generated dashboard: pages/user-guides/retrieve-dashboard-code.md + - Use Vizro-AI methods as Langchain tools: pages/user-guides/vizro-ai-langchain-guide.md - API Reference: - VizroAI: pages/API-reference/vizro-ai.md - Explanation: From e16ae22db24942304034d1fb2b6d991d515ab1d9 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 30 Oct 2024 02:06:59 +0000 Subject: [PATCH 2/5] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- vizro-core/examples/scratch_dev/README2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vizro-core/examples/scratch_dev/README2.md b/vizro-core/examples/scratch_dev/README2.md index 91cdc18cc..a2d4946ed 100644 --- a/vizro-core/examples/scratch_dev/README2.md +++ b/vizro-core/examples/scratch_dev/README2.md @@ -1 +1 @@ -# Also to be deleted \ No newline at end of file +# Also to be deleted From 896e398f3cfb31667c753bf784865e5fc00f4fff Mon Sep 17 00:00:00 2001 From: Lingyi Zhang Date: Tue, 29 Oct 2024 22:19:15 -0400 Subject: [PATCH 3/5] update text --- .../pages/user-guides/vizro-ai-langchain-guide.md | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/vizro-ai/docs/pages/user-guides/vizro-ai-langchain-guide.md b/vizro-ai/docs/pages/user-guides/vizro-ai-langchain-guide.md index 41065032e..7021e7d17 100644 --- a/vizro-ai/docs/pages/user-guides/vizro-ai-langchain-guide.md +++ b/vizro-ai/docs/pages/user-guides/vizro-ai-langchain-guide.md @@ -1,6 +1,6 @@ -# Using Vizro-AI Methods as LangChain Tools +# Using Vizro-AI methods as LangChain tools -This guide demonstrates how to integrate Vizro-AI's plotting and dashboard generation capabilities with LangChain tools. This integration allows you to use Vizro-AI's functionality within a larger LangChain application. +This guide demonstrates how to integrate Vizro-AI's chart and dashboard generation capabilities as LangChain tools. This integration enables you to use Vizro-AI's functionality within a larger LangChain application. ## 1. Set up the environment @@ -27,7 +27,7 @@ llm = ChatOpenAI(model="gpt-4o-mini") ## 2. Define LangChain tools -Basic tools only take string as input and output. Vizro-AI takes Pandas dataframes as input and it's not cost-efficient and secure to pass the full dataset to a LLM. In this case, [bind the Pandas dataframes at run time](https://python.langchain.com/v0.2/docs/how_to/tool_runtime/) is more suitable. +Basic tools only take string as input and output. Vizro-AI takes Pandas dataframes as input and it's not cost-efficient and secure to pass the full data to a LLM. In this case, [bind the Pandas dataframes at run time](https://python.langchain.com/v0.2/docs/how_to/tool_runtime/) is more suitable. Now, create tools that wrap Vizro-AI's plotting and dashboard generation capabilities: @@ -109,9 +109,9 @@ chain = llm_with_tools | inject_df | tool_router.map() ## 4. Use the chain -Now you can use the chain to generate plots or dashboards based on natural language queries. The chain will generate code that you can use to create visualizations. +Now you can use the chain to generate charts or dashboards based on natural language queries. The chain will generate code that you can use to create visualizations. -!!! example "Generate plot code" +!!! example "Generate chart code" === "Code" ```py @@ -191,5 +191,3 @@ Now you can use the chain to generate plots or dashboards based on natural langu title="GDP per Capita vs Life Expectancy", ) ``` - -This integration allows you to leverage Vizro-AI's visualization capabilities within a LangChain application, enabling natural language-driven creation of plots and dashboards. From 1e7371dfd7b54a221cf7cf5df27ac7b99c2045bc Mon Sep 17 00:00:00 2001 From: Lingyi Zhang Date: Wed, 30 Oct 2024 14:30:17 -0400 Subject: [PATCH 4/5] address comments --- vizro-ai/docs/index.md | 4 +--- .../user-guides/vizro-ai-langchain-guide.md | 22 ++++++++++++------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/vizro-ai/docs/index.md b/vizro-ai/docs/index.md index 26952e353..9d629e9bc 100644 --- a/vizro-ai/docs/index.md +++ b/vizro-ai/docs/index.md @@ -46,9 +46,7 @@ If a feature you need for your dashboard isn't currently supported by Vizro-AI y [:octicons-arrow-right-24: Model usage](pages/user-guides/customize-vizro-ai.md)
[:octicons-arrow-right-24: Create advanced charts](pages/user-guides/create-advanced-charts.md)
[:octicons-arrow-right-24: Add charts to a dashboard](pages/user-guides/add-generated-chart-usecase.md)
- [:octicons-arrow-right-24: Generate a complex dashboard](pages/user-guides/create-complex-dashboard.md)
- [:octicons-arrow-right-24: Retrieve code for a generated dashboard](pages/user-guides/retrieve-dashboard-code.md)
- [:octicons-arrow-right-24: Use Vizro-AI as Langchain tools](pages/user-guides/vizro-ai-langchain-guide.md) + [:octicons-arrow-right-24: Retrieve code for a generated dashboard](pages/user-guides/retrieve-dashboard-code.md) - :material-format-font:{ .lg .middle } __Find out more__ diff --git a/vizro-ai/docs/pages/user-guides/vizro-ai-langchain-guide.md b/vizro-ai/docs/pages/user-guides/vizro-ai-langchain-guide.md index 7021e7d17..fd4b2c5b3 100644 --- a/vizro-ai/docs/pages/user-guides/vizro-ai-langchain-guide.md +++ b/vizro-ai/docs/pages/user-guides/vizro-ai-langchain-guide.md @@ -1,10 +1,15 @@ # Using Vizro-AI methods as LangChain tools -This guide demonstrates how to integrate Vizro-AI's chart and dashboard generation capabilities as LangChain tools. This integration enables you to use Vizro-AI's functionality within a larger LangChain application. +You can use Vizro-AI's functionality within a larger LangChain application. This guide shows how to integrate Vizro-AI's chart and dashboard generation capabilities as LangChain tools. Here are the steps you need to take: + +1. [Set up the environment](#1-set-up-the-environment) +2. [Define LangChain tools](#2-define-langchain-tools) +3. [Set up the tool chain](#3-set-up-the-tool-chain) +4. [Use the chain](#4-use-the-chain) ## 1. Set up the environment -First, import the required libraries and prepare your data: +First, import the required libraries and prepare the LLM: ```python from copy import deepcopy @@ -17,17 +22,13 @@ from langchain_core.tools import InjectedToolArg, tool from langchain_openai import ChatOpenAI from vizro_ai import VizroAI -# Load sample data -df = px.data.gapminder() -dfs = [df] - # Initialize the LLM -llm = ChatOpenAI(model="gpt-4o-mini") +llm = ChatOpenAI(model="gpt-4") ``` ## 2. Define LangChain tools -Basic tools only take string as input and output. Vizro-AI takes Pandas dataframes as input and it's not cost-efficient and secure to pass the full data to a LLM. In this case, [bind the Pandas dataframes at run time](https://python.langchain.com/v0.2/docs/how_to/tool_runtime/) is more suitable. +Basic tools only take string as input and output. Vizro-AI takes Pandas DataFrames as input and it's neither cost-efficient nor secure to pass the full data to a LLM. The recommended approach is to exclude DataFrame parameters from the tool's schema and instead bind them at runtime using [LangChain's runtime binding feature](https://python.langchain.com/v0.2/docs/how_to/tool_runtime/). Now, create tools that wrap Vizro-AI's plotting and dashboard generation capabilities: @@ -115,6 +116,9 @@ Now you can use the chain to generate charts or dashboards based on natural lang === "Code" ```py + # Load sample data + df = px.data.gapminder() + plot_response = chain.invoke("Plot GDP per capita for each continent") print(plot_response[0].content) ``` @@ -141,6 +145,8 @@ Now you can use the chain to generate charts or dashboards based on natural lang === "Code" ```py + dfs = [px.data.gapminder()] + dashboard_response = chain.invoke("Create a dashboard. This dashboard has a chart showing the correlation between gdpPercap and lifeExp.") print(dashboard_response[0].content) ``` From e49884736973de817d5533f632426a8017cb0a14 Mon Sep 17 00:00:00 2001 From: Lingyi Zhang Date: Wed, 30 Oct 2024 14:34:49 -0400 Subject: [PATCH 5/5] tidy --- vizro-ai/docs/pages/user-guides/vizro-ai-langchain-guide.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/vizro-ai/docs/pages/user-guides/vizro-ai-langchain-guide.md b/vizro-ai/docs/pages/user-guides/vizro-ai-langchain-guide.md index fd4b2c5b3..210f36410 100644 --- a/vizro-ai/docs/pages/user-guides/vizro-ai-langchain-guide.md +++ b/vizro-ai/docs/pages/user-guides/vizro-ai-langchain-guide.md @@ -22,7 +22,6 @@ from langchain_core.tools import InjectedToolArg, tool from langchain_openai import ChatOpenAI from vizro_ai import VizroAI -# Initialize the LLM llm = ChatOpenAI(model="gpt-4") ``` @@ -44,7 +43,6 @@ def get_plot_code(df: Annotated[Any, InjectedToolArg], question: str) -> str: Returns: Generated plot code """ - df = pd.DataFrame(df) vizro_ai = VizroAI(model=llm) plot_elements = vizro_ai.plot( df,