Skip to content

Commit 717c3c1

Browse files
Add SQL agent strategy (opea-project#1039)
* initial code for sql agent llama Signed-off-by: minmin-intel <[email protected]> * add test for sql agent Signed-off-by: minmin-intel <[email protected]> * update sql agent test Signed-off-by: minmin-intel <[email protected]> * fix bugs and use vllm to test sql agent Signed-off-by: minmin-intel <[email protected]> * add tag-bench test and google search tool Signed-off-by: minmin-intel <[email protected]> * test sql agent with hints Signed-off-by: minmin-intel <[email protected]> * fix bugs for sql agent with hints and update test Signed-off-by: minmin-intel <[email protected]> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * add readme for sql agent and fix ci bugs Signed-off-by: minmin-intel <[email protected]> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * add sql agent using openai models Signed-off-by: minmin-intel <[email protected]> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * fix bugs in sql agent openai Signed-off-by: minmin-intel <[email protected]> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * make wait time longer for sql agent microservice to be ready Signed-off-by: minmin-intel <[email protected]> * update readme Signed-off-by: minmin-intel <[email protected]> * fix test bug Signed-off-by: minmin-intel <[email protected]> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * skip planexec with vllm due to vllm-gaudi bug Signed-off-by: minmin-intel <[email protected]> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * debug ut issue Signed-off-by: minmin-intel <[email protected]> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * use vllm for all uts Signed-off-by: minmin-intel <[email protected]> * debug ci issue Signed-off-by: minmin-intel <[email protected]> * change vllm port Signed-off-by: minmin-intel <[email protected]> * update ut Signed-off-by: minmin-intel <[email protected]> * remove tgi server Signed-off-by: minmin-intel <[email protected]> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * align vllm port Signed-off-by: minmin-intel <[email protected]> * remove unnecessary files and fix bugs Signed-off-by: minmin-intel <[email protected]> * connect to db with full uri Signed-off-by: minmin-intel <[email protected]> * update readme and use vllm mainstream Signed-off-by: minmin-intel <[email protected]> * rm unnecessary log Signed-off-by: minmin-intel <[email protected]> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * update readme Signed-off-by: minmin-intel <[email protected]> * update test script Signed-off-by: minmin-intel <[email protected]> --------- Signed-off-by: minmin-intel <[email protected]> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 70c151d commit 717c3c1

28 files changed

+1532
-115
lines changed

comps/agent/langchain/README.md

Lines changed: 30 additions & 34 deletions
Large diffs are not rendered by default.
File renamed without changes.
246 KB
Loading
284 KB
Loading

comps/agent/langchain/requirements.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
# used by microservice
22
docarray[full]
3-
4-
#used by tools
5-
duckduckgo-search
63
fastapi
74
huggingface_hub
85
langchain
6+
7+
#used by tools
8+
langchain-google-community
99
langchain-huggingface
1010
langchain-openai
1111
langchain_community

comps/agent/langchain/src/agent.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,15 @@ def instantiate_agent(args, strategy="react_langchain", with_memory=False):
3333
from .strategy.ragagent import RAGAgent
3434

3535
return RAGAgent(args, with_memory, custom_prompt=custom_prompt)
36+
elif strategy == "sql_agent_llama":
37+
print("Initializing SQL Agent Llama")
38+
from .strategy.sqlagent import SQLAgentLlama
39+
40+
return SQLAgentLlama(args, with_memory, custom_prompt=custom_prompt)
41+
elif strategy == "sql_agent":
42+
print("Initializing SQL Agent")
43+
from .strategy.sqlagent import SQLAgent
44+
45+
return SQLAgent(args, with_memory, custom_prompt=custom_prompt)
3646
else:
3747
raise ValueError(f"Agent strategy: {strategy} not supported!")

comps/agent/langchain/src/config.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,16 @@
7272

7373
if os.environ.get("timeout") is not None:
7474
env_config += ["--timeout", os.environ["timeout"]]
75+
76+
# for sql agent
77+
if os.environ.get("db_path") is not None:
78+
env_config += ["--db_path", os.environ["db_path"]]
79+
80+
if os.environ.get("db_name") is not None:
81+
env_config += ["--db_name", os.environ["db_name"]]
82+
83+
if os.environ.get("use_hints") is not None:
84+
env_config += ["--use_hints", os.environ["use_hints"]]
85+
86+
if os.environ.get("hints_file") is not None:
87+
env_config += ["--hints_file", os.environ["hints_file"]]

comps/agent/langchain/src/strategy/base_agent.py

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,5 +36,37 @@ def compile(self):
3636
def execute(self, state: dict):
3737
pass
3838

39-
def non_streaming_run(self, query, config):
39+
def prepare_initial_state(self, query):
4040
raise NotImplementedError
41+
42+
async def stream_generator(self, query, config):
43+
initial_state = self.prepare_initial_state(query)
44+
try:
45+
async for event in self.app.astream(initial_state, config=config):
46+
for node_name, node_state in event.items():
47+
yield f"--- CALL {node_name} ---\n"
48+
for k, v in node_state.items():
49+
if v is not None:
50+
yield f"{k}: {v}\n"
51+
52+
yield f"data: {repr(event)}\n\n"
53+
yield "data: [DONE]\n\n"
54+
except Exception as e:
55+
yield str(e)
56+
57+
async def non_streaming_run(self, query, config):
58+
initial_state = self.prepare_initial_state(query)
59+
print("@@@ Initial State: ", initial_state)
60+
try:
61+
async for s in self.app.astream(initial_state, config=config, stream_mode="values"):
62+
message = s["messages"][-1]
63+
if isinstance(message, tuple):
64+
print(message)
65+
else:
66+
message.pretty_print()
67+
68+
last_message = s["messages"][-1]
69+
print("******Response: ", last_message.content)
70+
return last_message.content
71+
except Exception as e:
72+
return str(e)
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# SQL Agents
2+
3+
We currently have two types of SQL agents:
4+
5+
1. `sql_agent_llama`: for using with open-source LLMs, especially `meta-llama/Llama-3.1-70B-Instruct` model.
6+
2. `sql_agent`: for using with OpenAI models, we developed and validated with GPT-4o-mini.
7+
8+
## Overview of sql_agent_llama
9+
10+
The architecture of `sql_agent_llama` is shown in the figure below.
11+
The agent node takes user question, hints (optional) and history (when available), and thinks step by step to solve the problem.
12+
13+
![SQL Agent Llama Architecture](../../../assets/sql_agent_llama.png)
14+
15+
### Database schema:
16+
17+
We use langchain's [SQLDatabase](https://python.langchain.com/docs/integrations/tools/sql_database/) API to get table names and schemas from the SQL database. User just need to specify `db_path` and `db_name`. The table schemas are incorporated into the prompts for the agent.
18+
19+
### Hints module:
20+
21+
If you want to use the hints module, you need to prepare a csv file that has 3 columns: `table_name`, `column_name`, `description`, and make this file available to the agent microservice. The `description` should include useful information (for example, domain knowledge) about a certain column in a table in the database. The hints module will pick up to five relevant columns together with their descriptions based on the user question using similarity search. The hints module will then pass these column descriptions to the agent node.
22+
23+
### Output parser:
24+
25+
Due to the current limitations of open source LLMs and serving frameworks (tgi and vllm) in generating tool call objects, we developed and optimized a custom output parser, together with our specially designed prompt templates. The output parser has 3 functions:
26+
27+
1. Decide if a valid final answer presents in the raw agent output. This is needed because: a) we found sometimes agent would make guess or hallucinate data, so it is critical to double check, b) sometimes LLM does not strictly follow instructions on output format so simple string parsing can fail. We use one additional LLM call to perform this function.
28+
2. Pick out tool calls from raw agent output. And check if the agent has made same tool calls before. If yes, remove the repeated tool calls.
29+
3. Parse and review SQL query, and fix SQL query if there are errors. This proved to improve SQL agent performance since the initial query may contain errors and having a "second pair of eyes" can often spot the errors while the agent node itself may not be able to identify the errors in subsequent execution steps.
30+
31+
## Overview of sql_agent
32+
33+
The architecture of `sql_agent` is shown in the figure below.
34+
The agent node takes user question, hints (optional) and history (when available), and thinks step by step to solve the problem. The basic idea is the same as `sql_agent_llama`. However, since OpenAI APIs produce well-structured tool call objects, we don't need a special output parser. Instead, we only keep the query fixer.
35+
36+
![SQL Agent Architecture](../../../assets/sql_agent.png)
37+
38+
## Limitations
39+
40+
1. Agent is only allowed to issue "SELECT" commands to databases, i.e., agent can only query databases but cannot update databases.
41+
2. We currently does not support "streaming" agent outputs on the fly for `sql_agent_llama`.
42+
3. Users need to pass the SQL database URI to the agent with the `db_path` environment variable. We have only validated SQLite database connected in such way.
43+
44+
Please submit issues if you want new features to be added. We also welcome community contributions!
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Copyright (C) 2024 Intel Corporation
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
from .planner import SQLAgentLlama
5+
from .planner import SQLAgent

0 commit comments

Comments
 (0)