본문 바로가기
데이터&AI/langchain

[langchain공부] langchain 기초 - 2 (feat. function call. 함수호출하기)

by 일등박사 2024. 1. 26.

이번 포스팅에서도 gpt api 를!!!

기존 gpt api 방식과 langchain 방식으로 알아보겠습니다!!!!

 

우선!! gpt의 function call 기능은 지난포스팅에서 알아보았는데요~!!!!

 

 

같은 포스팅 내용을 한번더 활용,

피자 가격을알려주는 챗봇을 만든다고 생각해봅시다!!!

A. openai 패키지만을 이용한 function call 방법

1. 패지키를 호출한뒤, client 객채를 만들고, 필요 함수를 제작합니다

   > chat : openai에 프롬포트 호출하는 함수

   >  pizza_price_info : 피자가격 산출하는 함수

   > functions : 함수의 설명 json

import json
import openai
client = openai.OpenAI(api_key = '{나만의 key}')

def chat(query):
    completion = client.chat.completions.create(
    model="gpt-3.5-turbo",
    messages=[{"role": "user", "content": query}],
    functions=functions,
    )
    message =  completion.choices[0].message
    return message

def pizza_price_info(pizza_name: str):
    if '치즈' in pizza_name :
        pizza_price = {
            "name": pizza_name,
            "price": "10.99달러",
        }
    else:
        pizza_price = {
            "name": pizza_name,
            "price": "9.99달러",
        }        
    return json.dumps(pizza_price)

functions = [
    {
        "name": "pizza_price_info",
        "description": "피자의 가격을 알아봅니다",
        "parameters": {
            "type": "object",
            "properties": {
                "pizza_name": {
                    "type": "string",
                    "description": "The name of the pizza, e.g. Salami",
                },
            },
            "required": ["pizza_name"],
        },
    }
]

  

 

2. 피자 가격을 산출하는 pizza_price_chatbot 함수를 만듭니다!!

def pizza_price_chatbot(query):
    message = chat(query)
    message
    if message.function_call:
        function_name = message.function_call.name
        pizza_name = json.loads(message.function_call.arguments).get("pizza_name")
        print(pizza_name)
        function_response = pizza_price_info(
            pizza_name=pizza_name
        )

        second_response = client.chat.completions.create(
            model="gpt-3.5-turbo-0613",
            messages=[
                {"role": "user", "content": query},
                message,
                {
                    "role": "function",
                    "name": function_name,
                    "content": function_response,
                },
            ],
        )

    return second_response.choices[0].message.content

 

3. 결과물 : 피자가격을 물어보면 잘 답변해줍니다!!

 

 

B. LANGCHAIN을 활용한 function call 방법

위와 동일한 함수를  langchain을 활용하여 만들어 봅니다!

 

 

1. 패지키를 호출한뒤, 기본 langchain 테스트

import json
from langchain.chat_models import ChatOpenAI
from langchain.schema import HumanMessage, AIMessage, ChatMessage

llm = ChatOpenAI(model="gpt-3.5-turbo", openai_api_key  = '{나만의key}')
message = llm.predict_messages(
    [HumanMessage(content="중국의 수도는?")], functions=functions
)
message

 

잘 작동하지요!?

 

 

2. 본격 질문 시작!!

a. 첫 질문을 하여 함수 작동여부 및 답변을 받고!!

query = "김치치즈 피자가 얼마야??"
message_pizza = llm.predict_messages([HumanMessage(content=query)], functions=functions)
message_pizza

 

b. 관련된 결과물을 파싱한 뒤

pizza_name = json.loads(message_pizza.additional_kwargs['function_call']['arguments']).get("pizza_name")
pizza_name

pizza_api_response = pizza_price_info(pizza_name=pizza_name)
pizza_api_response

 

c. 마지막 second prompt를 동작시킵니자

second_response = llm.predict_messages(
    [
        HumanMessage(content=query),
        AIMessage(content=str(message_pizza.additional_kwargs)),
        ChatMessage(
            role="function",
            additional_kwargs={
                "name": message_pizza.additional_kwargs['function_call']['name']
            },
            content=pizza_api_response
        ),
    ],
    functions=functions,
)
second_response

 

짠!!

결론으로, 첫번쨰 GPT openai만 사용한것과 동일한 결과를 확인할 수 있었습니다.

 

이제!!

python의 local 기능을 활용하여 함수명을 변수로처리하여 아래와 같이 모듈을 만들 수 있습니다.

ㅁ 참고 Local 기능

def add(x, y):
    return x + y

func_name = "add"

func = locals()[func_name]

print(func(1, 2))  # 3

 

ㅁ 최종! 알아서 다하기!!

 

query = "김치치즈 피자가 얼마야??"
res_message = llm.predict_messages([HumanMessage(content=query)], functions=functions)
res_message

if len(res_message.additional_kwargs) ==1:
    pizza_name = json.loads(res_message.additional_kwargs['function_call']['arguments']).get("pizza_name")
    print(pizza_name)
    
    func_name=res_message.additional_kwargs['function_call']['name']
    real_func = locals()[func_name]
    pizza_api_response = real_func(pizza_name=pizza_name)
    print(pizza_api_response)
    
    second_response = llm.predict_messages(
    [
        HumanMessage(content=query),
        AIMessage(content=str(res_message.additional_kwargs)),
        ChatMessage(
            role="function",
            additional_kwargs={
                "name": res_message.additional_kwargs['function_call']['name']
            },
            content=pizza_api_response
        ),
    ],
    functions=functions,
    )
    print(second_response.content)

댓글