Chatbot irregular responses

Open ai chatbot giving wrong responses after 2nd text inputs. Using text-davinci-002/completions API

I am trying to use openai API-text-davinci-002/completions in react native to create a chatbot assistant. It works for the first text input user types in, but after that it starts giving responses as if chatbot has started talking to itself and responses are completely un-related to what user has typed in. Example screenshots are shown below

Code:

const ChatBot = ({navigation}) => {
  const [data, setData] = useState([]);
  const [loader, setLoader] = useState(false);
  const [firstResponse, setFirstResponse] = useState(false);
  const apiKey = openAiKey;


  const apiUrl =
    '....api.openai.com/v1/engines/text-davinci-002/completions';

  const [textInput, setTextInput] = useState('');


  const handleSend = async () => {
    setLoader(true);
    const prompt = textInput;

    try {
      const response = await fetch(apiUrl, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          Authorization: `Bearer ${apiKey}`,
        },
        body: JSON.stringify({
          prompt: prompt,
          max_tokens: 1024,
          temperature: 0.5,
        }),
      });

      if (!response.ok) {
        throw new Error('Network response was not ok');
      }

      const responseData = await response.json();
      console.log('response', responseData);
      setLoader(false);
      setFirstResponse(true);

      const text = responseData.choices[0].text;
      setData([
        ...data,
        {type: 'user', text: textInput},
        {type: 'bot', text: text},
      ]);

      setTextInput('');
    } catch (error) {
      console.error('Error fetching data:', error);
      setLoader(false);
    }
  };

  
  return (
    <KeyboardAvoidingView
      behavior={Platform.OS === 'ios' ? 'padding' : 'height'} // 'padding' for iOS, 'height' for Android
      style={{flex: 1}}>
      <View style={styles.container}>
        <View
          style={{
            flexDirection: 'row',
            alignItems: 'center',
            justifyContent: 'space-between',
            marginHorizontal: 20,
          }}>
          <TouchableOpacity onPress={() => navigation.goBack()}>
            <MaterialCommunityIcons name="arrow-left" size={25} color="white" />
          </TouchableOpacity>
          <Text style={styles.title}>AI ChatBot</Text>
        </View>

    

        <FlatList
          data={data}
          keyExtractor={(item, index) => index.toString()}
          contentContainerStyle={styles.listContainer}
          style={styles.body}
          renderItem={({item}) => (
            <View style={{flexDirection: 'row', padding: 10}}>
              <Text
                style={{
                  fontWeight: 'bold',
                  color: item.type === 'user' ? 'green' : 'red',
                }}>
                {item.type === 'user' ? 'You: ' : 'Bot: '}
              </Text>
              <Text style={styles.bot}>{item.text}</Text>
            </View>
          )}
        />
        <View
          style={{
            alignItems: 'center',
            flexDirection: 'row',
            marginHorizontal: 20,
          }}>
          <TextInput
            style={styles.input}
            value={textInput}
            onChangeText={text => setTextInput(text)}
            placeholder="Send a message"
            placeholderTextColor="#8E8EA0"
          />
          <TouchableOpacity style={styles.button} onPress={handleSend}>
            {loader ? (
              <ActivityIndicator color="white" />
            ) : (
              <MaterialCommunityIcons
                name="send-circle"
                size={30}
                color="white"
              />
            )}
            {/* <Text style={styles.buttonText}>Send</Text> */}
          </TouchableOpacity>
        </View>
      </View>
    </KeyboardAvoidingView>
  );
};

Looking at your code, your prompt does not include the previous query and response, you are just sending textInput. You need to put previous conversation to provide context.

Maybe something like this

//const prompt = textInput;
let prompt = data.map(item => `${item.type}: ${item.text}`).join('\n');
prompt += '\n' + `user: ${textInput}`;
try {
      const response = await fetch(apiUrl, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          Authorization: `Bearer ${apiKey}`,
        },
        body: JSON.stringify({
          prompt: prompt,
          max_tokens: 1024,
          temperature: 0.5,
        }),

But I suggest Chat completion API instead of Text Completion API for this. It is cheaper and better for this kind of use case.

1 Like

Thanks for your answer, this worked perfectly. I am trying to find more about Chat completion API, can it be directly used in frontend without the need of Nodejs or Python backend (just a query, I couldn’t find answer to)

It is recommended that you need to call all APIs, including Text and Chat Completions API, from the backend to secure your API Key.

Remember that your API key is a secret! Do not share it with others or expose it in any client-side code (browsers, apps). Production requests must be routed through your own backend server where your API key can be securely loaded from an environment variable or key management service.

https://platform.openai.com/docs/api-reference/authentication

1 Like

API is “application programming interface”. We’d expect you are programming in some language.

You can send the HTTP request (including the authorization headers) directly to the API endpoint and get a response. Example usage with CURL. However, you just make more work for yourself by writing that which someone else has already written in many different language libraries.