How to collect user data from chat conversation using OpenAI API

Zoran Šaško
7 min readAug 31, 2024

--

If you are interested in ways how to collect some user data during conversation, using OpenAI API, this article is made for you.

In this article we’ll explore two approaches to collect product ordering request data. We’ll suppose that user wants to order some product from our simple chat application and in this process, system will ask the user for the product name, his name and his email. When all data is collected, we’ll print this data in system log. Instead of printing in system log, you can implement sending data somewhere or storing data in local database.

The final application that we’ll create will look like this:

Chat

First approach — creating custom model

In this approach, we need to create a custom model where we should make a conversation that is very similar to the conversation that user would make with the system.

In official documentation for ‘Fine Tuning’:

and under ‘Tool Calling’ section, we can see how ‘messages’ need to be specified in model, in order to make a model with a data flow from which we can get extract relevant information (product name, user name and email).

In this approach we need to specify at least 10 example conversations, to make this model usable at bear minimum. The more examples that we specify, model will work better, i.e. it will more easier detect fields that needs to be extracted. This approach wasn’t the best for me because I had only 10 examples and sometimes chat system would ask the wrong question in wrong order or some other problem occurred. This might be resolved with more conversation examples, but I found the easier approach and this second approach will be described in next section.

Second approach — specify system initial message to collect data

In this approach, we’ll specify initial system message that will contain all the business logic for collecting the data. Fields that we want to extract will be specified in right order with appropriate data type. It will contain instructions what to so when everything is collected i.e invoke appropriate Python function for storing collected data.

This example we’ll make in Python, so if you’re not familiar with Python, we’ll work from ground zero.

So, lets firstly create an virtual environment in folder where we want to have our project, by invoking the following command:

python -m venv venv

After that, we should activate our virtual environment by writing command:

source venv/bin/activate

After we have activated virtual environment, we need to install some of the libraries that are needed in project, so we have to create ‘requirements.txt’ file with the following Python libraries:

annotated-types==0.7.0
anyio==4.4.0
certifi==2024.7.4
click==8.1.7
distro==1.9.0
exceptiongroup==1.2.2
fastapi==0.112.2
h11==0.14.0
httpcore==1.0.5
httpx==0.27.2
idna==3.8
openai==1.37.1
pydantic==2.8.2
pydantic_core==2.20.1
python-dotenv==1.0.1
sniffio==1.3.1
starlette==0.38.2
tqdm==4.66.5
typing_extensions==4.12.2
uvicorn==0.30.6
websockets==13.0

Then, we need to install requirements in virtual environment by invoking the following command:

pip install -r requirements.txt

Now, we have installed all the libraries that we need, let’s specify the ‘.env’ file.

Since we’ll need to specify OpenAI API Key, we have to register and obtain one from:

and put it in ‘.env’ file:

OPENAI_API_KEY = 'some_api_key'

Now, we are ready to write some chat logic. Chat logic will be created in ‘main.py’ so we’ll start with specifying some imports and specifying which file will be served to the client, when Python server is running (‘index.html’ — which we’ll make later in this article).

As you can see from code above, we are initializing the FastAPI which will be used for handling our main route (‘/’ route) and handling the route for web socket (‘/ws’ route).

We are also specifying the ‘client’ variable which is the OpenAI client object that allows us to invoke chat functionalities from OpenAI API.

Array ‘conversation_history’ will contain conversation steps between user and a system that is needed in OpenAI API calls so it can know what is the context of previous conversation steps and so it can find what is the next step. We’ll clear this array after we have got all the data that we need.

We’ve specified that port on which our application is running is port 8000, but we can change this easily to some other value.

In order for OpenAI to able to detect if some function from the Python, or client side, should be executed, we need to specify it in JSON form like:

Here we specified the function ‘save_product_order’ with appropriate parameters and their data types. Later in the article we’ll make a Python function with the same name that will be invoked when OpenAI API decides that this function should be invoked.

The next function that we’ll implement is the function which will invoke OpenAI API, i.e. based on user input it will return some output from OpenAI API.

Variable ‘bot_instructions’ is the most important thing in specifying how OpenAI API will work. In this variable we have to specify what happens if user writes a message where he’s saying that he wants to order some product. It also should be specified what data should be asked from user and what should be done with the data. All this information is stored in ‘bot_instructions’ variable. It’s specified as a first message in ‘conversation_history’ as a message from ‘system’.

Invoking function ‘await client.chat.completions.create’ we are saying that we want to get response from OpenAI API. We have to specify conversation that we have until now, with ‘tools’ ( which specified what custom function can be invoked from Python side), which model is used and ‘tools_choice’ set to ‘auto’ (means that OpenAI API decides when it should invoke custom tool/function).

If in response message, ‘tool_calls’ attribute is not specified, it means that OpenAI API didn’t find a need to invoke our custom tool/function based on the current conversation, so we are putting the response of first Chat Completion call in ‘conversation_history’ array and returning that response to the user.

If in response message, ‘tool_calls’ attribute exists, we’ll put this message in ‘conversation_history’ array to keep track of this call and try to invoke a custom function that is assigned to the appropriate tool call, by invoking

await invoke_function_in_tool_calls(tool_calls)

After we get response from executing our custom Python function (function ‘save_product_order‘), we’ll put this response in ‘chat_history’ array and for second time invoke OpenAI API to get the result with response that was returned from our custom Python function.

second_response = await client.chat.completions.create

In this Chat Completions invocation, we specify model, chat history array and we set temperature to be very low, so randomness of response is also very low. With the response of second request we know that our custom function is invoked so we can clear ‘conversation_history’ array and return data to the user.

Two methods that need to be defined are ‘invoke_function_in_tool_calls’ where we specify which functions that OpenAI API detect that should be invoked from client side, with appropriate Python function, that in this case has the same name. We also need to parse arguments from ‘function_args’ and invoke this function by invoking ‘async function_to_call’. After we get response from function calling we need to format it in appropriate JSON and use it in later Chat Completion function invocation.

A function that will invoke storing product order currently logs this data to the console. Here you can specify logic for sending this data to some email or store this data in local database.

Now we have created all the logic for running the python web page, handling chat completions and the next step is to define ‘index.html’ where all the data will be displayed and where chat functionality can be tested, via web sockets.

In the HTML from above, we’ve created a simple chat layout with input field for writing a message, submit button that invokes ‘sendMessage’ function. There is also a functionality for receiving web socket messages via ‘onmessage’ method and handling this messages in ‘displayMessage’ function. If received message is from ‘user’, it has different formatting that if message is from ‘assistant’.

Now we are fully ready to run our application by invoking the following command:

python main.py

In the console where you invoked a command for running a python script, after you specified all order data you can see that all the order data is logged out from a Python function that handles this data.

Python debug log

Congratulations, you’ve made your first chat application using OpenAI. 😀

I hope it will help you with your chat application and in case if something is not working with your code, you can download a complete solution from GitHub repository:

https://github.com/zsasko/collect-data-from-conversation-openai-sample

--

--