음 루틴 앱 프로젝트를 진행중인데,
AI에게 루틴을 추천해달라고 하고 나온 값을 가지고 내 루틴에 추가하는 로직을 짜려고한다.
우선 가장 머리가 아팠던 것은, AI 에게 루틴관련 대답만 받아야하는데
" 사용자에 따라서 천차만별인 질문을 어떻게 일관적으로 정리해서 리스트에 뿌려야할까?🤔🤔🤔 "
이것이 문제였다. 완벽하게 해결한 것은 아니지만 어느정도 정리되도록 노력하긴했다.
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 페이지로 루틴데이터를 가지고 넘어가보자
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 사용법에 대해서 더 좋은 방법을 아는 고수들이 있다면 공유 부탁드립니다 ㅜ
쨋든 ! 처음보다는 훨나아진 루틴 추천 및 추가 작업 과정이었다..
오! 너무 어렵네요오!