#4. GPT function calling use-case: Ask questions about interview transcripts 👀
Get fast insights about user interview transcripts with ChatGPT function calling. Ask any question, and get back direct quotes relevant to the question! 🤯
Helloooo AI Alchemists! ✨🤖🧪
It’s been such a FUN day! I joined AI Builder’s Club in Sydney, which was a 6 hour-long hackathon that ended with everyone demoing what they had built that day. It happens every other week and it was amaaaazing 🤖🤯
It felt so good to be surrounded by other people who have experimented with LLMs, vector databases, semantic search, retrieval augmented generations and MORE. The exchange of ideas and mutual support was SO energising 💡🥰
This is the app I built and demo’d at the end of the six hours:
Try it out for yourself hereeee: https://user-interviews.streamlit.app/
Funnily enough, there is a startup at the builder’s club whose product is designed for enterprise level user research analysis. Continuous.so use the 100k context Claude2 model with their own backend functions to synthesises insights across multiple interviews. Try them out!
Where this idea came from ✨
Last week, a founder friend asked if it was possible to quickly analyse 18+ user interviews to help them make business decisions. They were swamped with putting out fires and doing on the ground work and didn’t have the time or bandwidth to sort through the interviews to pull out the insights.
It took me 15 minutes to repurpose the code I had written for the thought pattern checker program I wrote about previously, and another five hours to build the front-end 😅 Instead of extracting quotes from a journal entry that represent different thinking patterns, we extract quotes from interview transcripts that are relevant to different questions we have about the data.
I’m SO happy with the results! 🌈☀️
🪖 Veteran interview case study 🎙️
After analysing my friend’s interviews, I immediately wanted to try this out on other datasets. So I browsed around for public interview transcripts I could use to demo and share with you. I came across several interviews with World War 2 veterans discussing their experience of the war, from Veterans Transcripts.
I wasn’t sure what kind of questions I wanted to ask about the data, so I pasted a couple of the interviews into ChatGPT and asked “What questions can I ask to gain the most insight from this data”, then used some of the suggestions:
Why did they enlist in the military?
What was their military training experiences like?
What were their wartime duties?
What emotional and psychological impact did the war have?
What lessons or values did they carry forward as a result of the war?
Here is the full API call to ChatGPT that extracts quotes from the interview transcripts that are related to the questions asked above:
import openai | |
import json | |
# Things for you to change: | |
openai.api_key = "YOUR API KEY" | |
interviews = ["INTERVIEW1","INTERVIEW2", "INTERVIEW3", "INTERVIEW4"] | |
# API call to ChatGPT to extract quotes from interviews that are relevant to your questions. | |
def gpt_api_call(model_type, system_behaviour, user_submitted_content, name_of_function, function_description, properties, required_properties): | |
api_call = openai.ChatCompletion.create( | |
model=model_type, | |
messages=[ | |
{"role": "system", "content": system_behaviour}, | |
{"role": "user", "content": user_submitted_content} | |
], | |
functions=[{ | |
"name": name_of_function, | |
"description": function_description, | |
"parameters": { | |
"type": "object", | |
"properties": properties, | |
"required": required_properties | |
} | |
}], | |
function_call={"name": name_of_function} | |
) | |
output = api_call["choices"][0]["message"] | |
data = json.loads(output["function_call"]["arguments"]) if output.get("function_call") else {} | |
data = data.get('interview', []) | |
return data | |
model_type = "gpt-3.5-turbo-16k" | |
system_behaviour = "You analyze interviews with World War II veterans to gain a deeper understanding of their wartime experiences." | |
name_of_function = "analyze_interview" | |
function_description = "You extract direct quotes from interviews that are related to questions asked about the veteran's experiences during World War II. Be comprehensive in your response. Only use direct quotes." | |
properties = { | |
"interview": { | |
"type": "object", | |
"properties": { | |
"Why did they enlist in the military?": { | |
"type": "array", | |
"items": { | |
"type": "string", | |
"description": "A direct quote from the interview that is relevant to the question 'Why did they enlist in the military?'. Use direct quotes only." | |
} | |
}, | |
"Describe their military training": { | |
"type": "array", | |
"items": { | |
"type": "string", | |
"description": "A direct quote from the interview that is relevant to the question 'Describe their military training'. Use direct quotes only." | |
} | |
}, | |
"What were their wartime duties like?": { | |
"type": "array", | |
"items": { | |
"type": "string", | |
"description": "A direct quote from the interview that is relevant to the question 'What were their wartime duties like?'. Use direct quotes only." | |
} | |
}, | |
}, | |
} | |
} | |
required_properties = ["interview"] | |
category_quotes = {} | |
for interview in interviews: | |
response = gpt_api_call(model_type, system_behaviour, interview, name_of_function, function_description, properties, required_properties) | |
for category, quotes in response.items(): | |
if category not in category_quotes: | |
category_quotes[category] = [] | |
for quote in quotes: | |
category_quotes[category].append(quote) | |
for category, quotes in category_quotes.items(): | |
print(f"{category}\n") | |
for i, quote in enumerate(quotes, start=1): | |
print(f"\"{quote}\"") |
This call was enough to produce the following results, which makes me want to find many more transcripts to do this with. Just magical! ✨
Why did they enlist in the military?
"I was drafted."
"I wanted to leave home and join the guys fighting with the Germans in Spain."
"We thought we had a better chance of what we do in the military."
"The idea of volunteering was appealing to me."
"Well, the situation was I couldn’t afford to go to a Ivy League college or, or a paying college of any kind, I was ready to go to a city college. Living in Queens and Queens College was, was new and beautiful and seems a great place to go, so I applied here rather then a city college. College of the city of New York."
What was their military training experiences like?
"Very little training. It was ridiculous."
"Basic training is basic training and the Army has learned from its mistake."
"We actually had squad and platoon maneuvers attacking a pillbox, attack a trench."
"We were trained to fire everything up to a 30 cm anti-tank round, fired machine guns, Tommy guns, mortars."
"The basic training was very good. I didn’t have any great problem, I think I was, I was a decent a decent trainee, I was neither the top guy, nor the bottom, I was decent. No altercations with other recruits."
What were their wartime duties?
"I was a medic. My job was to pick up wounded soldiers and carry them to the aid station."
"My job was to break German messages and then decrypt them."
"We picked up messages from Norway and Russia using shortwave radios."
"I was part of the intelligence corps, intercepting and breaking German messages."
"As a civilian working for the Signal Corps, I was an inspector in a factory that produced intercoms for tanks. I had to ensure that the copper wires were properly attached and everything was in working order. Later, I went into the Army Specialized Training Program (ASTP) and was trained as a psychologist to classify soldiers for the replacement depot."
What emotional and psychological impact did the war have?
"I was scared to go out on the battlefield and pick up wounded soldiers because of the shells and the danger. But it was our job, so we did it."
"There was always tension and readiness, knowing that the invasion was coming."
"It was a very uncomfortable time, neither here nor there."
"There were moments of fear and confusion, especially during bombings and mine explosions."
"I witnessed and was aware of the Nazi outrages against Jews in Germany, and it made me upset and saddened. There was a strong sense of patriotism after December 7th, 1941, but personally, I didn't feel like enlisting at that time. I was waiting to be drafted."
What lessons or values did they carry forward as a result of the war?
"I learned to appreciate the importance of good medical care and the impact it can have on the well-being of soldiers."
"I learned to adapt and make the most of any situation."
"I gained a deep appreciation for the camaraderie and support of my fellow soldiers."
"I recognized the importance of intelligence and how it can give us an advantage in war."
"I learned the value of friendship and compassion. When a sergeant displayed anti-Semitism, I invited him to my home and showed him around New York City, which I believe changed his perspective for the better."
Limitations 🧐
I ended up using the “gpt-3.5-turbo-16k” model which extends the amount of space for sending interviews to ChatGPT to around 50k characters with enough space for the quotes to be returned too.
However, some of the interviews were even longer than that so I had to paste half at a time for some of them. That worked out okay in this use-case because I just care about the quotes, not which exact interviews they came from. I’d like to learn more about handling this though for the future.
Similarly, the more questions you ask about the interviews, the less quotes you get back for each question. This makes sense because of the limited amount of input/output space. We can get around it by asking one question at a time, but I imagine a future use-case will depend on this problem being solved.
Wrap Up 🌯
Woo hoo, that was fun!
The API call we crafted accepts mulitple user interviews, and extracts quotes that are relevant to specific questions we have about the data.
For example, we were able to extract lessons that world war 2 veterans learned from their wartime experiences, even though the original interviewer never asked them that question 🪖💡
I’ve shared the entire code you need to implement this yourself as a GitHub Gist, and as a full Streamlit app via this code repository. Or, you can just use the live version 🎁
If you need any help setting this up for your own use-cases, reach out to me on LinkedIn, we can set something up! 😄
Until next time,
Stay sparkly ✨
Sneak peak of what’s next 🙈👀
Want to learn how to build a robotic plushy that you can have an actual two-way conversation with? Stay tuned (subscriiibe) for an upcoming newsletter alllll about it 😉 🐼🤖