I’m trying to do sql retrieval using a langchain sql agent, pretty much as done in the following snippet:
llm = HuggingFaceEndpoint(
repo_id="meta-llama/Meta-Llama-3-8B-Instruct",
task="text-generation",
max_new_tokens=512,
do_sample=False,
repetition_penalty=1.03,
temperature=0.01
)
_AGENT_FORMAT_INSTRUCTIONS="""
## Use exactly the following format. Don't merge one step content with the next one:
- Question: the input question you must answer.
- Thought: you should always think about what to do.
- Action: the action to take, should be one of [{tool_names}].
- Action Input: the input to the action. DO NOT INCLUDE THE WORD 'Observation'.
- Observation: the result of the action.
... (this Thought/Action/Action Input/Observation can repeat N times)
- Final Thought: I now know the final answer.
- Final Answer: the final answer to the original input question.
- SQL Query used to get the Answer: the final sql query used for the final answer
"""
def answer_query_agent(question: str):
db = SQLDatabase(engine=sqlalchemy_engine)
toolkit = SQLDatabaseToolkit(db=db, llm=llm)
output_parser = StructuredChatOutputParserWithRetries.from_llm(llm=the_llm)
agent_executor: AgentExecutor = create_sql_agent(
agent_type=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
llm=llm,
toolkit=toolkit,
format_instructions=_AGENT_FORMAT_INSTRUCTIONS,
verbose=True,
agent_executor_kwargs={"handle_parsing_errors": True},
max_iterations=15,
top_k=15,
output_parser=output_parser)
try:
resp: Dict[str, Any] = agent_executor.invoke({"input": question})
print(f'** Executor result **nn{resp}')
except OutputParserException as e:
print(f"Error parsing output: {e}")
if e.send_to_llm:
# Optionally, send the observation and llm_output back to the model
print(f"Observation: {e.observation}")
print(f"LLM Output: {e.llm_output}")
return resp
When I run a question which doesn’t have to return any result, the agent confuses heavily the instructions, resulting in adding a Observation term to Action Input
as it is showed in the debug traces below (only relevant part showed):
[llm/start] [chain:SQL Agent Executor > chain:RunnableSequence > llm:HuggingFaceEndpoint] Entering LLM run with input:
{
"prompts": [
"Answer the following questions as best you can. You have access to the following tools:nnsql_db_query - Input to this tool is a detailed and correct SQL query, output is a result from the database. If the query is not correct, an error message will be returned. If an error is returned, rewrite the query, check the query, and try again. If you encounter an issue with Unknown column 'xxxx' in 'field list', use sql_db_schema to query the correct table fields.nsql_db_schema - Input to this tool is a comma-separated list of tables, output is the schema and sample rows for those tables. Be sure that the tables actually exist by calling sql_db_list_tables first! Example Input: table1, table2, table3nsql_db_list_tables - Input is an empty string, output is a comma-separated list of tables in the database.nsql_db_query_checker - Use this tool to double check if your query is correct before executing it. Always use this tool before executing a query with sql_db_query!nnn## Use exactly the following format. Don't include the pattern 'nObservation' as an Action Input value:nn- Question: the input question you must answer.n- Thought: you should always think about what to do.n- Action: the action to take, should be one of [sql_db_query, sql_db_schema, sql_db_list_tables, sql_db_query_checker].n- Action Input: the input to the action.n- Observation: the result of the action.n... (this Thought/Action/Action Input/Observation can repeat N times)n- Final Thought: I now know the final answer.n- Final Answer: the final answer to the original input question.n- SQL Query used to get the Answer: the final sql query used for the final answernnnnBegin!nnQuestion: which companies have a commitment with sustainabilitynThought: I need to find the companies that have a sustainability commitment. I should look for a table that contains company information and a field that indicates whether or not they have a sustainability commitment. I will first list all the tables in the database using sql_db_list_tables.nAction: sql_db_list_tablesnAction Input: ''nObservationnObservation: company, salesnThought:"
]
}
[llm/end] [chain:SQL Agent Executor > chain:RunnableSequence > llm:HuggingFaceEndpoint] [128ms] Exiting LLM run with output:
{
"generations": [
[
{
"text": "nI see two tables: company and sales. I should check the schema of these tables to see if there is a field that indicates whether or not a company has a sustainability commitment. I will use sql_db_schema to get the schema of these tables.nAction: sql_db_schemanAction Input: company, salesnObservation",
"generation_info": null,
"type": "Generation"
}
]
],
"llm_output": null,
"run": null
}
[chain/start] [chain:SQL Agent Executor > chain:RunnableSequence > parser:ReActSingleInputOutputParser] Entering Parser run with input:
{
"input": "nI see two tables: company and sales. I should check the schema of these tables to see if there is a field that indicates whether or not a company has a sustainability commitment. I will use sql_db_schema to get the schema of these tables.nAction: sql_db_schemanAction Input: company, salesnObservation"
}
[chain/end] [chain:SQL Agent Executor > chain:RunnableSequence > parser:ReActSingleInputOutputParser] [1ms] Exiting Parser run with output:
[outputs]
[chain/end] [chain:SQL Agent Executor > chain:RunnableSequence] [149ms] Exiting Chain run with output:
[outputs]
[tool/start] [chain:SQL Agent Executor > tool:sql_db_schema] Entering Tool run with input:
"company, sales
Observation"
[tool/end] [chain:SQL Agent Executor > tool:sql_db_schema] [0ms] Exiting Tool run with output:
"Error: table_names {'salesnObservation'} not found in database"
Any way of or hint on how can I prevent the Observation
word being appended to the Action Input
as showed just above?