https://python.langchain.com/docs/expression_language/cookbook/sql_db
Querying a SQL DB
We can replicate our SQLDatabaseChain with Runnables.
Runnables를 사용하여 SQLDatabaseChain을 복제할 수 있습니다.
from langchain.prompts import ChatPromptTemplate
template = """Based on the table schema below, write a SQL query that would answer the user's question:
{schema}
Question: {question}
SQL Query:"""
prompt = ChatPromptTemplate.from_template(template)
이 코드는 Langchain의 ChatPromptTemplate를 사용하여 SQL 쿼리 생성을 위한 템플릿을 정의하는 부분입니다. 이 템플릿은 다음과 같은 정보로 구성되어 있습니다:
- {schema}: 이 부분에는 테이블 스키마(schema)에 대한 정보가 들어가게 됩니다. 테이블 스키마는 데이터베이스 테이블의 구조를 설명하며, 사용자의 질문에 대한 SQL 쿼리를 작성하는 데 필요한 테이블 및 열(컬럼)의 정보를 포함합니다.
- {question}: 이 부분에는 사용자가 묻는 질문이 들어가게 됩니다. 사용자의 질문은 테이블 스키마에 대한 정보를 기반으로한 SQL 쿼리를 생성하기 위한 출발점 역할을 합니다.
이러한 템플릿을 사용하여 사용자가 제공한 질문과 관련된 SQL 쿼리를 생성하는 프로세스를 단순화할 수 있습니다.
from langchain.utilities import SQLDatabase
이 코드는 langchain 라이브러리에서 제공하는 SQLDatabase 클래스를 가져오는 부분입니다. SQLDatabase 클래스는 SQL 데이터베이스와 상호 작용하는 데 사용됩니다. 이 클래스를 사용하면 SQL 쿼리를 실행하고 데이터베이스에서 결과를 가져오는 등의 데이터베이스 작업을 쉽게 수행할 수 있습니다. 이것은 SQL 데이터베이스와의 연결 및 데이터 검색과 같은 작업을 수행하는 데 도움이 되는 유틸리티 클래스입니다.
We'll need the Chinook sample DB for this example. There's many places to download it from, e.g. https://database.guide/2-sample-databases-sqlite/
이 예에서는 Chinook 샘플 DB가 필요합니다. 다운로드할 수 있는 곳은 많습니다. https://database.guide/2-sample-databases-sqlite/
db = SQLDatabase.from_uri("sqlite:///./Chinook.db")
def get_schema(_):
return db.get_table_info()
def run_query(query):
return db.run(query)
from langchain.chat_models import ChatOpenAI
from langchain.schema.output_parser import StrOutputParser
from langchain.schema.runnable import RunnablePassthrough
model = ChatOpenAI()
sql_response = (
RunnablePassthrough.assign(schema=get_schema)
| prompt
| model.bind(stop=["\nSQLResult:"])
| StrOutputParser()
)
이 코드는 SQL 데이터베이스와 상호 작용하고 사용자의 SQL 쿼리를 처리하는 일련의 작업을 수행하는 부분입니다.
- 먼저 SQLDatabase 클래스를 사용하여 SQLite 데이터베이스에 연결하는 db 객체를 생성합니다. 이 데이터베이스에는 Chinook.db라는 이름의 데이터베이스가 사용됩니다.
- get_schema 함수는 데이터베이스에서 테이블 스키마 정보를 가져오는 역할을 합니다. 이 함수는 입력으로 어떤 값도 받을 수 있지만 사용하지 않으며 데이터베이스의 테이블 정보를 반환합니다.
- run_query 함수는 SQL 쿼리를 실행하고 결과를 반환하는 역할을 합니다. 이 함수는 입력으로 SQL 쿼리를 받아 실행하고 실행 결과를 반환합니다.
- sql_response 변수는 SQL 데이터베이스와 모델을 연결하는 체인을 설정합니다. 이 체인은 다음과 같이 구성됩니다:
- RunnablePassthrough.assign(schema=get_schema): 이 부분에서 get_schema 함수를 실행하여 데이터베이스의 테이블 스키마 정보를 schema 변수에 할당합니다.
- prompt: SQL 쿼리 작성을 유도하는 프롬프트를 생성합니다.
- model.bind(stop=["\nSQLResult:"]): ChatOpenAI 모델을 사용하며, 이 모델의 출력에서 SQL 결과를 구분하기 위한 정지 문자열("\nSQLResult:")을 설정합니다.
- StrOutputParser(): 모델의 출력을 문자열로 파싱하여 반환합니다.
이로써, sql_response 체인은 사용자로부터 SQL 쿼리를 입력받아 데이터베이스에서 실행하고 결과를 출력하는 작업을 수행합니다.
sql_response.invoke({"question": "How many employees are there?"})
'SELECT COUNT(*) FROM Employee'
이 코드는 sql_response 체인을 사용하여 SQL 쿼리를 실행하고 결과를 얻는 예시를 보여줍니다.
sql_response.invoke({"question": "How many employees are there?"})는 사용자의 질문을 포함하는 딕셔너리를 입력으로 전달합니다. "question" 키에는 사용자가 묻는 SQL 질문이 포함되어 있습니다. 이 경우, 사용자가 "How many employees are there?"라는 SQL 질문을 던졌다고 가정합니다.
체인은 다음과 같이 동작합니다:
- RunnablePassthrough.assign(schema=get_schema): get_schema 함수를 호출하여 데이터베이스의 테이블 스키마 정보를 가져옵니다. 이 정보는 schema 변수에 저장됩니다.
- prompt: SQL 질문 작성을 유도하는 프롬프트를 사용자에게 보여줍니다.
- 사용자가 SQL 질문을 작성하고 제출하면 이 질문은 모델에 전달되어 실행됩니다.
- model.bind(stop=["\nSQLResult:"]): 모델의 실행 결과를 반환하고, 결과 문자열에서 "\nSQLResult:" 문자열 이후의 내용은 무시됩니다. 따라서 SQL 결과만 추출됩니다.
- StrOutputParser(): 모델의 출력을 문자열로 파싱하여 반환합니다.
따라서 sql_response.invoke는 사용자의 SQL 질문에 대한 실행 결과를 반환하며, 해당 SQL 질문은 데이터베이스에서 실행된 결과를 포함합니다. 결과에는 "How many employees are there?" SQL 질문에 대한 답변이 포함되어 있을 것입니다.
template = """Based on the table schema below, question, sql query, and sql response, write a natural language response:
{schema}
Question: {question}
SQL Query: {query}
SQL Response: {response}"""
prompt_response = ChatPromptTemplate.from_template(template)
위의 소스 코드는 SQL 스키마, 질문, SQL 쿼리 및 SQL 응답을 기반으로 자연어 응답을 작성하는 데 사용되는 템플릿을 정의하고 있습니다.
템플릿은 다음과 같은 정보를 기반으로 작성됩니다:
- {schema}: SQL 스키마 정보를 표시할 위치입니다.
- {question}: 사용자의 질문을 표시할 위치입니다.
- {query}: SQL 쿼리를 표시할 위치입니다.
- {response}: SQL 응답 내용을 표시할 위치입니다.
따라서 이 템플릿은 주어진 SQL 스키마, 사용자의 질문, SQL 쿼리 및 SQL 응답을 바탕으로 자연어 응답을 작성하는 데 사용됩니다. 예를 들어, SQL 데이터베이스의 스키마와 사용자의 질문을 받아들이고, 해당 질문과 SQL 쿼리, 그리고 SQL 응답을 채워서 사용자에게 응답을 제공하는 데 활용될 수 있습니다.
full_chain = (
RunnablePassthrough.assign(query=sql_response)
| RunnablePassthrough.assign(
schema=get_schema,
response=lambda x: db.run(x["query"]),
)
| prompt_response
| model
)
이 코드는 SQL 데이터베이스와 상호 작용하여 SQL 쿼리를 실행하고 결과를 기반으로 한 자연어 응답을 생성하기 위한 작업 체인을 설정하는 데 사용됩니다.
- RunnablePassthrough.assign(query=sql_response): 이 부분에서, 사용자로부터 SQL 쿼리를 생성하는 데 사용할 sql_response 템플릿을 가져오고, 이를 query라는 이름으로 할당합니다.
- RunnablePassthrough.assign(schema=get_schema, response=lambda x: db.run(x["query"])): 여기서는 SQL 스키마 정보를 가져오는 get_schema 함수를 설정하고, SQL 쿼리를 실행하고 그 결과를 가져오는 db.run(x["query"]) 함수를 설정합니다. 이러한 정보는 후속 단계에서 사용됩니다.
- prompt_response: 이 템플릿은 SQL 스키마, 사용자의 질문, SQL 쿼리 및 SQL 응답을 기반으로 자연어 응답을 생성하기 위해 사용됩니다. 이러한 정보를 채우고 사용자에게 반환할 자연어 응답을 작성합니다.
- model: 이 부분에서는 ChatOpenAI 모델을 사용하여 자연어 응답을 생성하고 반환합니다.
이런 식으로 전체 체인은 SQL 쿼리를 실행하고 SQL 스키마와 사용자의 질문, SQL 응답 정보와 함께 ChatOpenAI 모델을 사용하여 자연어 응답을 생성합니다.
full_chain.invoke({"question": "How many employees are there?"})
AIMessage(content='There are 8 employees.', additional_kwargs={}, example=False)
'LangChain > LangChain Expression Language' 카테고리의 다른 글
LC - Cookbook - Adding moderation (0) | 2023.11.07 |
---|---|
LC - Cookbook - Adding memory (0) | 2023.11.07 |
LC - Cookbook - Routing by semantic similarity (0) | 2023.11.07 |
LC - Cookbook - Code Writing (0) | 2023.11.06 |
LC - Cookbook - Agents (0) | 2023.11.06 |
LC - Cookbook - Multiple chains (0) | 2023.11.05 |
LC - Cookbook - RAG (Retrieval-Augmented Generation) (0) | 2023.11.05 |
LC - Cookbook - Prompt + LLM (1) | 2023.10.29 |
LangChain - How to - Route between multiple Runnables (1) | 2023.10.28 |
LangChain - How to - Use RunnableParallel/RunnableMap (1) | 2023.10.28 |