본문 바로가기
ReactNative

ReactNative ChatGPT를 활용한 묻고&답하기 예시

by 리틀홍콩 2023. 2. 26.
728x90

chatGPT의 활약이 정말 대단합니다.

그 상승기류에 스타트업이 빠르게 도입을해서 더불어 관심을 가지게 되는 케이스가 많아지는 것 같습니다.

 

 

스타트업에 부는 AI 열풍…고도화·전문성 서비스 ‘각광’ - 이뉴스투데이

[이뉴스투데이 고선호 기자] 최근 오픈AI가 개발한 인공지능(AI) 대화형 메신저 ‘챗GPT(ChatGPT)’의 등장에 AI에 대한 관심이 그 어느때보다 뜨겁다. 챗GPT가 언어에 특화된 모델인만큼, 특정 분야에

www.enewstoday.co.kr

 

 

여행 계획·맛집 추천에 '챗GPT'...스타트업계, 줄줄이 서비스 고도화

(사진제공=마이리얼트립)대화형 인공지능(AI) 챗GPT가 세계적인 열풍을 불러일으키면서 이를 서비스에 접목하는 스타트업들이 잇따라 등장하고 있다.2

www.etoday.co.kr

 

그래서 한번 저도 시범삼아 테스트를 진행해보았습니다.

결과적으로 답변이 잘 와지는걸 확인했습니다!

 

구현예시)

chatGPT api를 활용한 예시

 

코드

import React, {useEffect, useCallback, useRef, useState} from 'react'
import {SafeAreaView, StyleSheet, View, Image, TextInput, TouchableOpacity, Text, ScrollView, Dimensions, Platform, ActivityIndicator} from 'react-native'
import {COLOR} from '@app/lib/styles'
import {ico_information, ico_information_red} from '@app/assets'

export default function Presenter() {
  const [keyword, setKeyword] = useState('')
  const [loading, setLoading] = useState<boolean>(false)
  const [resultList, setResultList] = useState([])
  const [errorMsg, setErrorMsg] = useState('')
  const [inputHeight, setInputHeight] = useState(50)
  const [tootlipVisible, setTooltipVisible] = useState<boolean>(false)
  let scrollRef = useRef()

  const apiKey = 'API 키 입력'

  const requestOpenAI = async (keyword: string) => {
    setLoading(true)
    const prompt = keyword.trim()
    const url = 'https://api.openai.com/v1/completions'
    const headers = {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${apiKey}`,
    }
    const data = {
      prompt: prompt,
      max_tokens: 2048, // 최대 2048
      model: 'text-davinci-003'
    }

    fetch(url, {
      method: 'POST',
      headers: headers,
      body: JSON.stringify(data),
    })
      .then(response => {
        return response.json()
      })
      .then(data => {
        const resText = data?.choices[0]?.text?.trim()
        setResultList(prev => prev.concat([{user: 'chatGPT', data: resText}]))
      })
      .catch(err => {
        alert('error')
      })
      .finally(() => {
        setLoading(false)
      })
  }

  return (
    <SafeAreaView style={styles.full_screen}>
      <ScrollView
        ref={ref => (scrollRef = ref)}
        style={{flex: 1, height: Dimensions.get('screen').height}}
        onContentSizeChange={() => {
          scrollRef?.current?.scrollToEnd({animated: false})
        }}>
        <View style={styles.wrapper}>
          {resultList?.map((item, index) => {
            return (
              <View
                style={{
                  alignItems: index % 2 === 0 ? 'flex-end' : 'flex-start',
                  paddingHorizontal: 20,
                  marginBottom: 12,
                }}>
                <View>
                  <Text
                    style={{
                      borderWidth: 1,
                      borderRadius: 8,
                      padding: 10,
                      maxWidth: Dimensions.get('screen').width * 0.7,
                      backgroundColor: index % 2 === 0 ? COLOR.YELLOW1 : COLOR.GRAY7,
                    }}>
                    {item?.data}
                  </Text>
              </View>
            )
          })}

          {loading && resultList?.length > 0 && (
            <View
              style={{
                borderWidth: 1,
                borderRadius: 8,
                padding: 10,
                marginLeft: 10,
                maxWidth: Dimensions.get('screen').width * 0.7,
                backgroundColor: COLOR.GRAY7,
              }}>
              <ActivityIndicator />
              <Text style={{textAlign: 'center', marginTop: 20}}>요청하신 데이터를 검색중입니다.</Text>
            </View>
          )}
        </View>
      </ScrollView>
      <View style={{flexDirection: 'row', justifyContent: 'space-between', paddingHorizontal: 20}}>
        <TextInput
          multiline
          placeholder="키워드를 입력해주세요."
          onChangeText={setKeyword}
          onContentSizeChange={event => {
            setInputHeight(event.nativeEvent.contentSize.height)
          }}
          value={keyword}
          numberOfLines={5}
          style={{width: Dimensions.get('screen').width * 0.7, backgroundColor: COLOR.WHITE, borderWidth: 1, paddingLeft: 10, paddingRight: 10, height: Math.max(40, inputHeight)}}
        />
        <TouchableOpacity
          style={{height: 50, borderWidth: 1, width: 60, justifyContent: 'center', alignItems: 'center'}}
          onPress={() => {
            if (loading) return
            setLoading(true)
            if (resultList.length === 0) {
              setResultList([{user: 'me', data: keyword.trim()}])
            } else {
              setResultList(prev => prev.concat([{user: 'me', data: keyword.trim()}]))
            }
            requestOpenAI(keyword)
            setKeyword('')
          }}>
          <Text>검색</Text>
        </TouchableOpacity>
      </View>
    </SafeAreaView>
  )
}

const styles = StyleSheet.create({
  full_screen: {
    flex: 1,
    backgroundColor: 'white',
    position: 'relative',
  },
  wrapper: {
    flex: 1,
    paddingTop: 29,
    paddingBottom: 100,
    justifyContent: 'space-between',
    backgroundColor: 'white',
  },
  recommend: {
    borderWidth: 1,
    borderRadius: 8,
    marginRight: 10,
    height: 25,
    padding: 3,
  },
  recommendTxt: {
    marginRight: 10,
    height: 25,
    padding: 5,
    color: COLOR.RED1,
  }
})

 

댓글