(트러블 슈팅) 버튼 클릭시 응답 출력, 함수 호출 로직

2star_·2024년 11월 30일
0

Shelter_PJ

목록 보기
9/12

버튼 클릭시 응답이 바로 출력되지 않음

Streamlit에서 "가까운 대피소 검색" 버튼을 눌렀을 때, 응답이 바로 출력되지 않고 두 번 눌러야 정상 작동하는 현상이 발생

원인 분석

Streamlit의 상태 관리 문제:

버튼 클릭 이벤트(st.button)가 클릭 순간에만 True를 반환하고, 이후 상태가 초기화.
또한, UI 갱신이 제대로 이루어지지 않았다.

버튼 클릭 후 상태 업데이트와 클릭시 응답 생성이 연속적으로 처리되지 않았다.

해결 방법


# 세션 상태 초기화
if "button_clicked" not in st.session_state:
    st.session_state.button_clicked = False 

# 위치 기반 대피소 검색 버튼
if latitude and longitude:
    if st.button("가까운 대피소 검색"):
        # 명시적인 요청 메시지 추가
        user_message = "현재 위치에서 가까운 대피소 정보를 알려줘."
        st.session_state.messages.append({"role": "user", "content": user_message})

        # 모델에 위치 정보 전달하여 응답 생성
        response = get_response(user_input=user_message, user_location={"latitude": latitude, "longitude": longitude})

        # 챗봇 응답 추가
        st.session_state.messages.append({"role": "ai", "content": response["response"]})

        # # 함수 호출 결과가 있으면 추가
        # if "function_call" in response:
        #     function_result = response["function_call"]["result"]
        #     st.session_state.messages.append({"role": "function", "content": function_result})

        # 버튼 클릭 상태 초기화
        st.rerun()  # 즉시 화면 재렌더링

수정
st.session_state를 활용해 상태 관리:
버튼 클릭 여부를 상태로 저장하고, 클릭 시 동작을 명시적으로 처리.

st.rerun()으로 즉시 화면 재렌더링:
버튼 클릭 후 새 상태를 반영한 UI를 즉각 업데이트.

결과
버튼을 한 번 클릭하면 즉시 "가까운 대피소" 정보를 기반으로 한 챗봇 응답이 출력됩니다.
두 번 클릭해야 하는 문제가 해결되었고, 버튼 클릭 후 UI가 매끄럽게 동작합니다.

함수 호출 결과를 기반으로 응답을 생성하지 않음

문제 상황

대피소 검색 함수(find_nearest_shelters)가 실행되었지만, OpenAI API가 이 결과를 활용하지 않고 일반적인 메시지만 출력했습니다. 예를 들어:

입력:
"현재 위치에서 가장 가까운 대피소를 알려줘."

출력:
"대피소 정보를 확인 중입니다. 안전에 유의하세요."

이와 같은 응답만 나왔고, 실제 대피소 정보는 포함되지 않았습니다.

해결 코드

def get_response(user_input: str, user_location: dict = None):
    """
    사용자 입력을 받아 모델 응답을 처리하고, 함수 호출이 필요한 경우
    적절히 실행하여 최종 응답을 반환합니다.
    """
    # 1. 사용자 입력 메시지 생성
    user_message = chat_template.format_messages(user_input=user_input)

    # 2. 위치 정보 추가
    if user_location:
        location_message = {
            "role": "system",
            "content": f"현재 사용자의 위도: {user_location['latitude']}, 경도: {user_location['longitude']}입니다."
        }
        user_message.append(location_message)

    # 3. 이전 대화 기록 불러오기
    messages = memory.load_memory_variables({})["history"] + user_message

    # 4. 모델 호출로 응답 생성
    response = model.invoke(messages)

    # 5. 대화 기록 저장
    memory.save_context({"input": user_input}, {"output": response.content})

    # 6. 함수 호출 처리
    function_call = response.additional_kwargs.get("function_call")
    if function_call:
        function_name = function_call.get("name")
        function_args = function_call.get("arguments")

        # 파라미터 처리
        if isinstance(function_args, str):
            function_args = json.loads(function_args)

        # 위치 정보 병합
        if user_location:
            function_args['latitude'] = user_location.get("latitude")
            function_args['longitude'] = user_location.get("longitude")

        if function_name == "find_nearest_shelters":
            # 6.1 대피소 검색 함수 실행
            function_result = find_nearest_shelters(
                latitude=function_args.get("latitude"),
                longitude=function_args.get("longitude"),
                address=function_args.get("address")
            )

            # 6.2 함수 결과를 모델 컨텍스트에 추가
            function_message = {
                "role": "function",
                "name": function_name,
                "content": function_result
            }
            messages.append(function_message)

            # 6.3 최종 응답 생성
            final_response = model.invoke(messages)

            # 대화 기록에 최종 응답 저장
            memory.save_context({"input": function_result}, {"output": final_response.content})

            return {
                "function_call": {
                    "name": function_name,
                    "arguments": function_args,
                    "result": function_result
                },
                "response": final_response.content
            }

    # 함수 호출이 없는 경우 일반 응답 반환
    return {"response": response.content}

수정 포인트

함수 호출 결과를 모델 컨텍스트에 추가:

FunctionMessage 형태로 모델 대화 컨텍스트에 포함하여, 모델이 이를 바탕으로 최종 응답을 생성하도록 수정했습니다.
위치 정보 병합:

사용자 위치 정보를 find_nearest_shelters 호출 시 누락되지 않도록 병합.
최종 응답 생성:

함수 호출 결과를 모델 컨텍스트에 추가한 후, 이를 포함한 최종 응답을 모델에서 생성.


이러게 사용자 위치기반 정보를 streamlit에서 받아오고 이를 get_response함수에서 처리를 할 수 있도록 수정해서 해결했다.

profile
안녕하세요.

0개의 댓글

관련 채용 정보