React Native - AI 추천 데이터를 일관성있게 정리 후 다른 페이지로 넘겨 자동 입력하기

황씨·2024년 10월 17일
post-thumbnail

음 루틴 앱 프로젝트를 진행중인데,
AI에게 루틴을 추천해달라고 하고 나온 값을 가지고 내 루틴에 추가하는 로직을 짜려고한다.

우선 가장 머리가 아팠던 것은, AI 에게 루틴관련 대답만 받아야하는데

" 사용자에 따라서 천차만별인 질문을 어떻게 일관적으로 정리해서 리스트에 뿌려야할까?🤔🤔🤔 "

이것이 문제였다. 완벽하게 해결한 것은 아니지만 어느정도 정리되도록 노력하긴했다.

루틴 추천 페이지 RecommendRoutine.js

try {
            const apiKey = `${chatGPT_apiKey}`;
            const response = await axios.post(
                "https://api.openai.com/v1/chat/completions",
                {
                    model: "gpt-4o-mini",
                    messages: [
                        {
                            role: "system",
                            content:
                                "당신은 일상 루틴 추천을 전문으로 하는 AI 어시스턴트입니다." +
                                "사용자의 질문과 상관없이 항상 그들의 하루를 개선할 수 있는 구체적인 일상 루틴으로 답변하십시오." +
                                "일상 루틴 제공과 관련이 없는 질문에는 답변하지 마십시오." +
                                "한글로 답해주고, 예를들어 침대정리하기, 물잔 마시기, 비타민과 유산균 먹기, 20분동안 명상하기, 격렬한 운동 1분 이런식으로 간단하게 단답형식으로 말해줘 내가 예를들어서 말한그대로 하는게 아니라 저런식으로 표현해달라는거야, 앞에 순서를나타내는 번호 붙일필요는 없어",
                        },
                        { role: "user", content: userInput },
                    ],
                    max_tokens: 500,
                    temperature: 0.7,
                    top_p: 0.9,
                },
                {
                    headers: {
                        Authorization: `Bearer ${apiKey}`,
                        "Content-Type": "application/json",
                    },
                }
            );
            console.log("API 응답:", response.data);

            const routine = response.data.choices[0].message.content; //질문하고 받은 응답 값

            //질문 내용을 줄바꿈을 기준으로 해서 배열로 변환
            //필터 메서드로 배열의 각 요소에 대해 조건 검사를 하여 조건을 만족하는 요소만 남김
            //line.trim() 문자열 앞뒤 공백제거, ! = "" 공백제거한 결과가 빈 문자열 아니면 해당 요소를 배열에 남김
            const routineArray = routine.split("\n").filter((line) => line.trim() !== "");  

            // 만들어진 배열을 상태로 저장해서 나중에 데이터 표시할 수 있도록 함
            // setRecoomendation 은 recommedation에다가 상태값을 변경해주는 업데이트 함수임
            setRecommendation(routineArray);
        } catch (error) {
            console.error("루틴 추천 받는데 에러났음", error);
            setRecommendation(["루틴 추천 중 오류 발생"]);
        } finally {
            setLoading(false);
        }

대답해주는 시스템에게 역할 부여해주는 방식으로 진행했다.
AI 시스템에게 직업을 정해주고, 그외 조건들을 추가시켜 필요한 답변만 응답 할 수 있도록
content를 정해주었다.

(사실 역할 부여하는데 있어서 참 많은 시도를 해보았는데 이게 그나마 최선이었다..😭
더 좋은 방법이 있다면 누군가 좀 알려주세요...)

추가로 대답해준 내용을 배열처리해서 그거를 리스트로 보여주기 위한 작업을 했다.

const [recommendation, setRecommendation] = useState([]);

const routine = response.data.choices[0].message.content; //질문하고 받은 응답 값

            //질문 내용을 줄바꿈을 기준으로 해서 배열로 변환
            //필터 메서드로 배열의 각 요소에 대해 조건 검사를 하여 조건을 만족하는 요소만 남김
            //line.trim() 문자열 앞뒤 공백제거, ! = "" 공백제거한 결과가 빈 문자열 아니면 해당 요소를 배열에 남김
            const routineArray = routine.split("\n").filter((line) => line.trim() !== "");  

            // 만들어진 배열을 상태로 저장해서 나중에 데이터 표시할 수 있도록 함
            // setRecoomendation 은 recommedation에다가 상태값을 변경해주는 업데이트 함수임
            setRecommendation(routineArray);

routine 에다가 질문하고 응답한 값을 할당해주고
응답값을 줄바꿈을 기준으로해서 배열로 변환해준다.

배열값(routineArray)을 setRecommendation() 함수를 이용해서
recommendation에다가 상태값을 업데이트 시켜준다.
그럼 처음에는 빈 값이던 recommendation이 질문 후에는 업데이트 되어서
루틴 배열이 담기게 된다.

자 이제 화면에 뿌려줘야 겠지?

<ScrollView>
  {recommendation.length > 0 ? (
      recommendation.map((routine, index) => (        //map() 으로 배열의 각 요소를 순회하면 새로운 컴포넌트 생성
           <TouchableOpacity key={index} style={styles.aiList}
              onPress={() => handleRoutineSelect(routine)}
           >
              <Image
                 style={[styles.aiListIcon]}
                 source={require("../../../assets/img/ic_checked_03.png")}
              ></Image>
              <Text style={styles.aiListText}>{routine}</Text>
           </TouchableOpacity>
    ))
    ) : (
        <Text></Text>
    )}
</ScrollView>

처음 렌더링 때는 recommendation 상태 값이 비어있으니 아무것도 나오지 않을 것이고
질문 후 상태 값이 업데이트가 될 것이다
map() 함수를 이용해서 배열의 각 요소를 순회하면서 리스트를 뿌려준다.

콘솔에다가 routine 과 index를 찍어보면 해당 값이 나온다.

첫 번째 순회:
routine = "침대 정리하기"
index = 0
두 번째 순회:
routine = "물잔 마시기"
index = 1
세 번째 순회:
routine = "비타민과 유산균 먹기"
index = 2

추천만 해주면 사용자가 좋아할까? 내 루틴으로 바로 추가할 수 있게 해주면 더 좋아하겠지? ㅎㅋ

const navigation = useNavigation();

const handleRoutineSelect = (routine) => {
        navigation.navigate("AddRoutine", {selectedRoutine: routine});
};

리스트를 클릭하면 AddRoutine 페이지로 루틴데이터를 가지고 넘어가보자

루틴 추가 페이지 AddRoutine.js

route 객체를 통해서 전달된 데이터에 접근해보자!

const route = useRoute();

useEffect(() => {
        if (route.params?.selectedRoutine) {
            setRoutineName(route.params.selectedRoutine);
        }
    }, [route.params?.selectedRoutine]); 
    
    <RoutineInput
      placeholder="루틴을 입력해주세요"
      value={routineName}
      onChangeText={setRoutineName}
      onPress={navigateToRecommendRoutine}
      buttonImage={require("../../../assets/img/ic_ai.png")} // 아이콘 이미지를 props로 전달
    />

추천페이지에서 selectedRoutine 에다가 선택한 루틴을 넣어서 AddRoutine으로 넘기고
루틴추가페이지에서 route로 접근해서
잘넘겨주었다

🥲 AI 사용법에 대해서 더 좋은 방법을 아는 고수들이 있다면 공유 부탁드립니다 ㅜ

쨋든 ! 처음보다는 훨나아진 루틴 추천 및 추가 작업 과정이었다..

profile
성격존나급한 개발자

1개의 댓글

comment-user-thumbnail
2024년 10월 17일

오! 너무 어렵네요오!

답글 달기