Langchain으로 SQL Query 만들기, Langgraph로 Agent 만들기

랭체인 과제 1, 2차 과제를 모두 수행 완료 했습니다.

Langchain은 처음이고, Python도 자격증(빅데이터분석기사) 실기시험 때나

머신러닝 관련 강좌 들을 때만 잠깐씩 써본거라 생각보다 시간이 오래 걸렸습니다 T.T


과제 결과물은 거의 다 비슷할테니 괜히 다르게 시도했다 고생했던 과제 2가지를 공유 드리고자 합니다.


1. 버전이 높다고 꼭 좋은건 아니다

랭체인 1-5(SQL 데이터베이스 쿼리하기) 과제를 수행할 때 아무 생각 없이

모델을 ChatGPT ‘gpt-4o’로 설정했는데 계속 이상한 에러 메시지가 나서

고생했습니다 T.T

# Model and Parser
model = ChatOpenAI(model="gpt-4o", temperature=0)
parser = StrOutputParser()

디버깅을 위해 SQL Query를 만드는 부분, Query문을 실행하는 부분 등을 단계적으로 나누어 실행하면서 출력을 확인해 봅니다

execute_query = QuerySQLDataBaseTool(db=db)
query_chain = create_sql_query_chain(model, db)

response = query_chain.invoke({"question": "How many employers are there?"})
print(response)

“How many employers are there?”라는 질문을 Query로 바꿔달라고 했더니

```sql
SELECT COUNT(*) AS "NumberOfEmployees"
FROM "Employee";
```

쓸데 없이 ‘‘‘sql … ‘‘‘ 으로 query문을 감싸 놓았습니다. 이를 제거하기 위해 prompt에 SQL query문만 남기라고 써봐도 소용이 없네요.


혹시나 하는 마음에 ChatGPT 모델을 3.5로 변경해 봤습니다

# Model and Parser
model = ChatOpenAI(model="gpt-3.5-turbo")
parser = StrOutputParser()

Query문이 어떻게 변했을까요?

쓸데없는 사족이 사라지고 깔끔하게 원하는 Query문만 남았습니다.

SELECT COUNT("EmployeeId") AS TotalEmployees
FROM "Employee"

Query를 만드는 부분, 실행하는 부분, SQL 실행 결과를 보고 답을 만다는 prompt 등을 모두 chain으로 엮어서 한번에 실행해 봅니다.

chain = (
    RunnablePassthrough.assign(query=query_chain).assign(result=itemgetter("query") | execute_query)
    | answer_prompt
    | model
    | parser
)

response = chain.invoke({"question": "How many employers are there?"})
print(response)

원하는 형태의 답을 얻었습니다!

There are 8 employers in the Employee table.


Langgraph로 Agent 만들기

랭체인 과제 2-5에서 Agent를 구성할 때 Langgraph를 사용해 보았습니다.

Search tool을 다음과 같이 만들어서 날씨를 물어보면 “32 degrees”를 반환하도록 하였습니다

# Define search tool
@tool
def search(query: str) -> str:
    """Search things about current events."""
    #result = TavilySearchResults(max_results = 1).invoke({"query": query})

    return "32 degrees"

좀 더 개량해서 TavilySearch를 연계하도록 시도하다가 실력 부족으로 일단 그냥 온도를 반환하기로 합니다.

Graph를 이용해서 agent가 질문을 받고, current event에 대한 내용이 있으면 search로 연계되도록 구성했습니다.

# Model and Parser
model = ChatOpenAI(model="gpt-4o", temperature=0)
model_with_tools = model.bind_tools(tools)

parser = StrOutputParser()

graph = MessageGraph()

graph.add_node("agent", model_with_tools)

tool_node = ToolNode(tools)
graph.add_node("search", tool_node)

graph.add_edge(START, "agent")
graph.add_edge("search", END)

def router(state: list[BaseMessage]) -> Literal["search", "__end__"]:
    tool_calls = state[-1].additional_kwargs.get("tool_calls", [])

    if len(tool_calls):
        return "search"
    else:
        return END
    
graph.add_conditional_edges("agent", router)

runnable = graph.compile()

실행 결과를 확인해 보겠습니다.

먼저 New York의 날씨를 물어보면 search가 실행되어 32도라고 대답합니다.

result = runnable.invoke("What is the weather in New York?")

for idx, r in enumerate(result):
    print(r.content)

What is the weather in New York?

32 degrees

미국의 초대 대통령을 물어보는 경우 search 함수가 실행되지 않아 LLM의 출력이 그대로 나옵니다.

result = runnable.invoke("Who was the first presidient of USA?") 
for r in result:
    print(r.content)   

Who was the first presidient of USA?

The first President of the United States was George Washington. He served as President from April 30, 1789, to March 4, 1797.


소감

최근에 ChatGPT API를 사용해 보기 시작했는데 랭체인을 사용해보니

그냥 API 쓰는 것보다 정리가 잘 된 느낌이 듭니다.

아직 랭체인의 구조가 다 들어오지는 않은 것 같아 document에 있는 사례들을 좀 더 꼼꼼히 살펴봐야겠습니다.


향후 계획

불면증 인지행동치료(CBT-I) 매뉴얼을 RAG와 연계하여 불면증에 대해 상담하는 chatbot을 만들어 보려고 합니다. chatbot을 만들고 나면 음성 입출력 I/F를 추가하여 음성으로 불면증 상담하는 서비스를 만들어 보겠습니다.


#11기-랭체인

6
2개의 답글

👉 이 게시글도 읽어보세요