Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PowerBI major refinement in working of tool and tweaks in the rest #5090

Merged
merged 7 commits into from
May 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 6 additions & 10 deletions langchain/agents/agent_toolkits/powerbi/prompt.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,24 @@
"""Prompts for PowerBI agent."""


POWERBI_PREFIX = """You are an agent designed to interact with a Power BI Dataset.
POWERBI_PREFIX = """You are an agent designed to help users interact with a PowerBI Dataset.

Assistant has access to tools that can give context, write queries and execute those queries against PowerBI, Microsofts business intelligence tool. The questions from the users should be interpreted as related to the dataset that is available and not general questions about the world. If the question does not seem related to the dataset, just return "I don't know" as the answer. The query language that PowerBI uses is called DAX and it is quite particular and complex, so make sure to use the right tools to get the answers the user is looking for.
Agent has access to a tool that can write a query based on the question and then run those against PowerBI, Microsofts business intelligence tool. The questions from the users should be interpreted as related to the dataset that is available and not general questions about the world. If the question does not seem related to the dataset, just return "This does not appear to be part of this dataset." as the answer.

Given an input question, create a syntactically correct DAX query to run, then look at the results and return the answer. Sometimes the result indicate something is wrong with the query, or there were errors in the json serialization. Unless the user specifies a specific number of examples they wish to obtain, always limit your query to at most {top_k} results. You can order the results by a relevant column to return the most interesting examples in the database.

Assistant never just starts querying, assistant should first find out which tables there are, then how each table is defined and then ask the question to query tool to create a query and then ask the query tool to execute it, finally create a complete sentence that answers the question, if multiple rows need are asked find a way to write that in a easily readible format for a human. Assistant has tools that can get more context of the tables which helps it write correct queries.
Given an input question, ask to run the questions against the dataset, then look at the results and return the answer, the answer should be a complete sentence that answers the question, if multiple rows are asked find a way to write that in a easily readible format for a human, also make sure to represent numbers in readable ways, like 1M instead of 1000000. Unless the user specifies a specific number of examples they wish to obtain, always limit your query to at most {top_k} results.
"""

POWERBI_SUFFIX = """Begin!

Question: {input}
Thought: I should first ask which tables I have, then how each table is defined and then ask the question to query tool to create a query for me and then I should ask the query tool to execute it, finally create a nice sentence that answers the question.
Thought: I can first ask which tables I have, then how each table is defined and then ask the query tool the question I need, and finally create a nice sentence that answers the question.
{agent_scratchpad}"""

POWERBI_CHAT_PREFIX = """Assistant is a large language model built to help users interact with a PowerBI Dataset.

Assistant has access to tools that can give context, write queries and execute those queries against PowerBI, Microsofts business intelligence tool. The questions from the users should be interpreted as related to the dataset that is available and not general questions about the world. If the question does not seem related to the dataset, just return "I don't know" as the answer. The query language that PowerBI uses is called DAX and it is quite particular and complex, so make sure to use the right tools to get the answers the user is looking for.

Given an input question, create a syntactically correct DAX query to run, then look at the results and return the answer. Sometimes the result indicate something is wrong with the query, or there were errors in the json serialization. Unless the user specifies a specific number of examples they wish to obtain, always limit your query to at most {top_k} results. You can order the results by a relevant column to return the most interesting examples in the database.
Assistant has access to a tool that can write a query based on the question and then run those against PowerBI, Microsofts business intelligence tool. The questions from the users should be interpreted as related to the dataset that is available and not general questions about the world. If the question does not seem related to the dataset, just return "This does not appear to be part of this dataset." as the answer.

Assistant never just starts querying, assistant should first find out which tables there are, then how each table is defined and then ask the question to query tool to create a query and then ask the query tool to execute it, finally create a complete sentence that answers the question, if multiple rows need are asked find a way to write that in a easily readible format for a human. Assistant has tools that can get more context of the tables which helps it write correct queries.
Given an input question, ask to run the questions against the dataset, then look at the results and return the answer, the answer should be a complete sentence that answers the question, if multiple rows are asked find a way to write that in a easily readible format for a human, also make sure to represent numbers in readable ways, like 1M instead of 1000000. Unless the user specifies a specific number of examples they wish to obtain, always limit your query to at most {top_k} results.
"""

POWERBI_CHAT_SUFFIX = """TOOLS
Expand Down
10 changes: 5 additions & 5 deletions langchain/agents/agent_toolkits/powerbi/toolkit.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
from langchain.tools.powerbi.prompt import QUESTION_TO_QUERY
from langchain.tools.powerbi.tool import (
InfoPowerBITool,
InputToQueryTool,
ListPowerBITool,
QueryPowerBITool,
)
Expand All @@ -25,6 +24,7 @@ class PowerBIToolkit(BaseToolkit):
powerbi: PowerBIDataset = Field(exclude=True)
llm: BaseLanguageModel = Field(exclude=True)
examples: Optional[str] = None
max_iterations: int = 5
callback_manager: Optional[BaseCallbackManager] = None

class Config:
Expand Down Expand Up @@ -52,12 +52,12 @@ def get_tools(self) -> List[BaseTool]:
),
)
return [
QueryPowerBITool(powerbi=self.powerbi),
InfoPowerBITool(powerbi=self.powerbi),
ListPowerBITool(powerbi=self.powerbi),
InputToQueryTool(
QueryPowerBITool(
llm_chain=chain,
powerbi=self.powerbi,
examples=self.examples,
max_iterations=self.max_iterations,
),
InfoPowerBITool(powerbi=self.powerbi),
ListPowerBITool(powerbi=self.powerbi),
]
8 changes: 8 additions & 0 deletions langchain/tools/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@
NavigateTool,
)
from langchain.tools.plugin import AIPluginTool
from langchain.tools.powerbi.tool import (
InfoPowerBITool,
ListPowerBITool,
QueryPowerBITool,
)
from langchain.tools.scenexplain.tool import SceneXplainTool
from langchain.tools.shell.tool import ShellTool
from langchain.tools.steamship_image_generation import SteamshipImageGenerationTool
Expand Down Expand Up @@ -79,13 +84,16 @@
"GoogleSerperRun",
"HumanInputRun",
"IFTTTWebhook",
"InfoPowerBITool",
"ListDirectoryTool",
"ListPowerBITool",
"MetaphorSearchResults",
"MoveFileTool",
"NavigateBackTool",
"NavigateTool",
"OpenAPISpec",
"OpenWeatherMapQueryRun",
"QueryPowerBITool",
"ReadFileTool",
"SceneXplainTool",
"ShellTool",
Expand Down
10 changes: 5 additions & 5 deletions langchain/tools/powerbi/prompt.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# flake8: noqa
QUESTION_TO_QUERY = """
Answer the question below with a DAX query that can be sent to Power BI. DAX queries have a simple syntax comprised of just one required keyword, EVALUATE, and several optional keywords: ORDER BY, START AT, DEFINE, MEASURE, VAR, TABLE, and COLUMN. Each keyword defines a statement used for the duration of the query. Any time < or > are used in the text below it means that those values need to be replaced by table, columns or other things.
Answer the question below with a DAX query that can be sent to Power BI. DAX queries have a simple syntax comprised of just one required keyword, EVALUATE, and several optional keywords: ORDER BY, START AT, DEFINE, MEASURE, VAR, TABLE, and COLUMN. Each keyword defines a statement used for the duration of the query. Any time < or > are used in the text below it means that those values need to be replaced by table, columns or other things. If the question is not something you can answer with a DAX query, reply with "I cannot answer this" and the question will be escalated to a human.

Some DAX functions return a table instead of a scalar, and must be wrapped in a function that evaluates the table and returns a scalar; unless the table is a single column, single row table, then it is treated as a scalar value. Most DAX functions require one or more arguments, which can include tables, columns, expressions, and values. However, some functions, such as PI, do not require any arguments, but always require parentheses to indicate the null argument. For example, you must always type PI(), not PI. You can also nest functions within other functions.

Expand Down Expand Up @@ -31,7 +31,7 @@
DATEVALUE(<date_text>) - Returns a date value that represents the specified date.
YEAR(<date>), QUARTER(<date>), MONTH(<date>), DAY(<date>), HOUR(<date>), MINUTE(<date>), SECOND(<date>) - Returns the part of the date for the specified date.

Finally, make sure to escape double quotes with a single backslash, and make sure that only table names have single quotes around them, while names of measures or the values of columns that you want to compare against are in escaped double quotes. Newlines are not necessary and can be skipped. The queries are serialized as json and so will have to fit be compliant with json syntax.
Finally, make sure to escape double quotes with a single backslash, and make sure that only table names have single quotes around them, while names of measures or the values of columns that you want to compare against are in escaped double quotes. Newlines are not necessary and can be skipped. The queries are serialized as json and so will have to fit be compliant with json syntax. Sometimes you will get a question, a DAX query and a error, in that case you need to rewrite the DAX query to get the correct answer.

The following tables exist: {tables}

Expand All @@ -57,9 +57,9 @@
----
"""

BAD_REQUEST_RESPONSE = (
"Bad request. Please ask the question_to_query_powerbi tool to provide the query."
RETRY_RESPONSE = (
"{tool_input} DAX: {query} Error: {error}. Please supply a new DAX query."
)
BAD_REQUEST_RESPONSE_ESCALATED = "You already tried this, please try a different query."
BAD_REQUEST_RESPONSE = "Error on this question, the error was {error}, you can try to rephrase the question."
SCHEMA_ERROR_RESPONSE = "Bad request, are you sure the table name is correct?"
UNAUTHORIZED_RESPONSE = "Unauthorized. Try changing your authentication, do not retry."
Loading