{
  "video_id": "pEkxRQFNAs4",
  "channel_slug": "dataindependent",
  "channel_handle": "dataindependent",
  "title": "Extract Topics From Video/Audio With LLMs (Topic Modeling w/ LangChain)",
  "duration_seconds": 1054.0,
  "url": "https://www.youtube.com/watch?v=pEkxRQFNAs4",
  "upload_date": "",
  "transcript": "I guarantee you have a use case for\ntopic modeling and if you don't well you\ncan help millions of people that do\ntopic modeling is the art of extracting\ngroups of information from a longer body\nof text or a series of documents you\nknow those chapters you sometimes see on\nYouTube videos well that's likely\nsomeone doing mental topic modeling\nreviewing the entire video and labeling\nthe segments of the video they deem\nimportant same thing goes on for\npodcasts where's the opportunity well it\ntakes a lot of manual work to go through\nan entire podcast or video to extract\nthose segments and that structured data\nis really valuable to the right person\nif you could find a buyer for this you\ncould create a productionized service\nfor YouTube videos podcasts meeting\nnotes legal documents movie scripts\nbooks lecture notes and many more for\nexample if we check out the acquired\npodcast website we see that they don't\nhave topics actually listed on their\nepisodes that'd be pretty awesome if you\nran this exercise gave them a couple\nepisodes worth of topics and then say\nhey here's the price if you want your\nfull episode list then you could rinse\nand repeat this for other podcast videos\nor really anything where there's a\nseries of information involved the\nemphasis on my tutorials is to learn the\nins and outs of building with AI in this\ntutorial we're going to go through a\ntopic modeling method that I used while\nparsing information from the my first\nmillion podcast this tutorial was\nreleased to community members earlier so\nif you want to get notified about new\ncontent make sure to subscribe and sign\nup for the community in the description\nalright so for today we're going to take\na two pass approach this is the method\nthat I found worked best for my use case\nbut you may want to experiment with your\nown so I'm going to run through the\nentire document via mapreduce and then\npull out the topics and bullet points as\nmy first pass so we're going to go\nthrough each individual token this may\nbe a little bit expensive as you get\nthrough it so please look at your\nexpense preferences as you start to\nbuild more then for a second pass I'm\ngoing to iterate through each topic\nbullet point and then expand on them\nwith a subset of context that was\nselected via retrieval that is a\nlong-winded way of saying hey I don't\nwant to pull out a lot of detailed\ninformation within my first pass because\nI noticed it was a little hard for the L\nM to get me the topics and details in\nthe first pass but so I'm going to split\nit into two so for the second pass I'm\ngoing to do a question and answer like\nretrieval uh with context but we'll go\nover that in a second here my\nassumptions is that you do not have a\ntable of contexts or contents so if you\ndid like for a book or a textbook or a\nmovie well that would be helpful and\nyou'd likely you'll want to use that but\nlet's assume not because I want to make\nthis as general as possible and then\nfinally that you want to learn the nuts\nand bolts about how to do this you could\ngo give a third party tool access to\nyour data and then it could go do it\nitself but if you wanted more control\nover the process this is going to be\nhelpful okay these are the use cases we\ntalked about and if you want to check\nout the tweet that started it all\nuh I uh posted about it you can go check\nthat out all right so let's get started\nhere so first thing I'm going to import\na bunch of packages I'm not going to go\nthrough each one but but if you have any\nquestions on those please leave comments\ndown below all right so for the setup\nI'm actually going to use two different\nlanguage models here so I'm going to use\nGPT 3.5 turbo the June 16th Edition as\nwell as GPT 4 June 16th Edition the\nreason why I'm doing this is because\nsome tasks that we're about to do are\ngood for GPT 3.5 we don't need too much\nreasoning power but some you know we\nwant the extra horsepower and so we can\nuse gbt4 I just like calling those out\nas llm3 and llm4 so I can remember which\none's which next you're going to need\nyour actual transcript that we're going\nto parse here now I put three different\ntranscripts so you can experiment with\ndifferent ones but we're just going to\ngo through one today which is going to\nbe the my first million uh Steph Smith\nepisode okay let's load this one up then\nlet's load up a sample and see what\nwe're working with here so we have a\nspeaker's name we have the timestamp\nwhich a sentence was said and then we\nhave their actual transcript now I\nnoticed that the transcript isn't 100\nreliable but I'd give it about a 97\npercent reliability here then what we're\ngoing to do is we're going to split our\ntranscript and so this is going to be\nmuch too long to put in a single prompt\nthe full thing at least and so we want\nto split it up now I'm going to load up\nmy recursive character text splitter I'm\ngoing to set my separators and the first\none I'm going to set is the double new\nline because the transcript is separated\nby double new lines or at least the\nspeaker portions and so that'll be a\ngood indicator for us now for chunk size\nI'm going to put 10 000 characters and\nthis is so we have a good amount of\ninformation that's put in there now keep\nin mind that characters does not equal\ntokens it's going to be about four\ncharacters per token so it's going to\nroughly be about 2 000 different um 2000\ndifferent tokens here and then for the\nchunk overlap you can set this as what\nyou want I usually like to do it around\n10 to 20 so I make sure I don't lose any\ncontext or information but again this is\ngoing to be specific to your use case I\nencourage you to play around with this\nnow for this exercise I'm only going to\ndo a subset of the transcript and it's\ngoing to be about the first 23 000\ncharacters the reason why I'm doing this\nbecause this transcript is kind of long\nand I don't want to have to go through\nthe whole thing just right now for this\ntutorial but I want to show you that it\nworks so let's look at a sub subsection\nright here I'm going to do that by first\nloading up my transcript which we had up\nabove and then taking only the first 23\n000 characters let's do this and so we\nactually spit our transcript into three\ndifferent documents and the first\ndocument is 2800 tokens next up we're\ngoing to work on extracting the topic\ntitles in a short description so what I\nwant to do is I want to go through a\nmapreduce meaning I'm just going to\nprocess each one of those three chunks\nand then say hey gbt what topics do you\nsee within this podcast transcript now\nthe important part here is we're going\nto make a custom prompt and the reason\nwhy we're doing this is because the\ntopics that I care about for this\nspecific domain are kind of nuanced and\nI want to be able to do further\ninstructions to the language model the\nout of the box prompts from linkchang do\na good job for generic use cases but I\nreally want to hone into these now this\nis going to be a point of\ndifferentiation for your products itself\nso when you do this I highly suggest\nthat you customize this for your own\ndomain okay I'm going to go through this\nfirst prompt just so you can see it and\nI can talk about my thought process a\nbit more you are a helpful assistant\nthat helps retrieve topics talked about\nin a podcast transcript your goal is to\nto extract the topic names and a brief\none sentence description of the topic I\ndon't want it to give too many details\nand overload itself I just want a brief\nreference to it okay topics include and\nthen I give a long list of topics that\ncould be interesting to pull out from\nthe my first million podcast they talk\nabout a lot of things including business\nideas interesting stories ways to make\nmoney etc etc and I wanted to know that\nthat's what I mean by topics not its\ngeneral definition of what it thinks it\nknows that topics are and then I go\nthrough some formatting so brief\ndescription I give an example topic and\nthen colon and then brief description do\nnot respond with numbers just bullet\npoints I went through a lot of these\nbased off of iterations and so there's\nno one-size-fits-all solution so you\nhave to iterate through these and add\nyour own then I gave it a bunch of\nexamples and so this is things that I\npulled out manually so that it would\nknow what I was looking for Sam's\nElizabeth Murdoch story Sam got a call\nfrom Elizabeth Murdock when he just\nlaunched the hustle et cetera Etc I do\nthis so the language model knows the\ntypes of examples that I want to see and\nthe types of language I wanted to use\nokay I'm going to wrap that up in a\nsystem map prompt and then for the human\ntemplate I'm going to say hey here's the\nstart of the transcript and this text\nplaceholder is going to be the chunk\ntext that we saw up above so for each\none of the three chunks this will get\nplaced in there and then we're going to\nwrap both of these up into a chat prompt\ntemplate which has both these messages\nplaced in them okay let's run that\nand so that was our map prompt and now\nwe're going to have our combined prompt\nso what's going to happen is all the\nresults those bullet points that we're\ngoing to get from the map prompt well\nthere's going to be some duplicates in\nthere right and so I want it to\nconsolidate those and the way I'm going\nto do that is through a combined prompt\nand the emphasis here is to de-duplicate\nany bullet points that you see don't\nonly pull topics from the transcript\ndon't use any examples we have some\nexamples here wrap it up in a chat\nprompt combined and then so for the\nfirst pass we're actually going to run\nthrough these and the way I'm going to\ndo this is I'm going to use the load\nsummarize chain now you may be wondering\nGreg we aren't really generating a\nsummary and you're correct however I\nreally like the load summarize chain\njust to kind of hijack the map reduced\nchain that it provides me here I found\nthat the out of the box map reduce\nchange from Langston is still a bit\ncomplicated so this one's just super\neasy for me the language model we're\ngoing to use here is actually going to\nbe gpt4 because we're going to be using\nsome more reasoning power to understand\nwhat are the important topics in art\nwe're going to call our mapreduce method\nor on our chain type we're going to pass\nit our mapped prompt which is going to\nbe what it's going to do via the um the\nfirst pass and then the combined prompt\nwhich is how it's going to do its\nconsolidation okay I commented out for\nBose equals Trooper you could do that if\nyou want to all right we loaded up our\nchain and then now once we run this cell\nthis is what's actually going to run so\nI'm going to skip to 402 when the video\nis done\nall right we found some topics here\nlet's see what we have let's go through\nthese I'm going to print these topics\nand so now we have a bunch of bullet\npoints Children's Place based business\nideas Sean discussed a concept of a\nmembership-based children's play space\nbut clarified he doesn't endorse it\ninteresting okay Steph Smith's career\nJourney sampar shared how Steph Smith\njoined Trends and later moved to\nAndreessen Horowitz awesome so we have a\nbunch of topics that were pulled out\nfrom this podcast which is pretty cool\nbecause now we can start to make some\nstructured data out of the unstructured\ntext that would assist within the\npodcast itself all right the next step\nthat I want to do is I want to convert\nthis big long string which was a turn\nfrom the language model I want to turn\nthat into structured data so we can go\nuse it elsewhere more easily and the way\nwe're going to do that is actually use\nthe new function calling functionality\nfrom open AI so the way I'm going to do\nthat is I'm going to define a schema\nhere with a few different properties\nit's going to be a string and the\ndescription is going to be a title of\nthe topic listed so this I just want you\nto extract the topic name the next one\nis going to be a description so this is\nthe description that we see within the\ntext right here so you can think of this\nas another extraction topic because I'm\nattracting more texture mirror and the\nlast one we're going to do is what I'm\ncalling a tag now this is going to be a\nstring again and the description is\ngoing to be the type of content being\ndescribed because if you go and look at\nthis we have some different business\nideas we have some life advice and life\nhacks or whatever maybe so we want to\nknow if this is a business model life\nadvice health and wellness or one of the\nstories let's run through this and let's\nsee what our structured topics are all\nright so we got some structured data\nback we have our topic name children's\nplay Space business idea we have a\ndescription and then the tag is business\nmodels because we're talking about a\nbusiness idea right here which is really\ncool now the reason why I'm showing this\nis because the structured data piece is\nsuper important and the more structure\nyou can give it the more valuable it's\ngoing to be to somebody else and the\nless work that they have to do so in\naddition to tag I encourage you to see\nwhat other ways you can qualify data and\nmake it more structured for somebody\nelse all right so next up we're going to\nmove on to step two which is expand on\nthe topics that we found so we have this\ntopic name and we have a short\ndescription but what if you want a\nlittle bit of a longer description or a\nlonger summary or you may just want to\ntransform this into something completely\ndifferent altogether and maybe it's not\na summary the way we're going to do that\nis a little bit with the retrieval\nmethod and we're actually going to do\nthe vector store Dance Now what that\nmeans is we're going to chunk up our\ntranscript one more time but we're going\nto do it in smaller documents so what we\nwant to do is we want to generate a\nsummary based off of a certain topic but\nwe don't want to do it on the full\ntranscript again because that's going to\nbe a lot of tokens I only want the the\nchunks that are relevant to the topic\nthat we're talking about in order to\ngenerate more context on top of there\nnow when I first came across this\nproblem I thought to myself man that\nsounds a lot like question answering\nwhen you do a similarity search for your\nyour embeddings and your chunks and all\nthat so I decided to apply the same\nmethod here all right let's jump in and\nsee what it looks like we're going to do\nour recursive character text splitter\nagain but the chunk size is going to be\nfour thousand now this is 4 000\ncharacters which is about half the size\nthat we had from our 10 000 up above and\nwe have a chunk overlap of about 20 or\n800 here now for the docs we're just\ngoing to split our regular transcript\nand this is still going to be the\nsubsection of the transcript that we are\nlooking at beforehand and let's see how\nmany docks we have here so we have eight\ndocs instead of the three that we had up\nabove so roughly they were cut in half a\nlittle bit more we're going to create\nour embeddings engine and we're just\ngoing to use open AI embeddings but you\ncan use whatever embeddings engine you\nwant here now we're going to use pine\ncone and I had a heck of a time trying\nto get chroma and face to work before\nthis so it wasn't working for me I\nwouldn't normally recommend using a\nremote Vector store for this light of a\nuse case but substitute whatever Vector\nstore you want here all right we're\ngoing to initialize pine cone and then\nmy index name is going to be topic\nmodeling and I just created that online\nand then we're going to create our doc\nSource from here so what it's doing is\nactually creating our index for us and\nit's going and putting the index up in\nthe cloud for us so this is no longer\nlocal if you want to delete your vectors\nwithin Pinecone in an easy way you can\njust call out your index here and then\ndo index.delete and delete all equals\ntrue and this will kind of just reset\nfor you in case you ever want to just\npractice again we're going to skip over\nthat all right now what we're going to\ndo is we're going to do another custom\nprompt now the reason why we're doing\nthis is because I want the uh similarity\nsearch from a retrieval but I don't want\nit just to answer a question per se I\nwanted to do a little bit of a longer\nsummary so you will be given a text from\na podcast transcript which contains many\ntopics so because our chunks they're not\njust going to contain our one topic that\nwe may want it could be more your goal\nis to write a summary five sentences or\nless about a topic the user chooses do\nnot respond with information that isn't\nrelevant to the topic the topic that the\noops that the user user gives you and\nthen here we're going to get the context\nnow this placeholder here is going to be\nreplaced with the chunks from the\ntranscript that are supposed to be\nrelevant to what the user says all right\nnow this in the human message right here\nthis would normally be the question that\nthe user asks however what we're going\nto do is we're going to place this with\nthe topic title and the topic\ndescription that we want because that's\nwhat I want similar documents to be\nfound off of not necessarily a question\nand I left this as a question here\nbecause just for clarity this is the\ndefault namespace that and uses all\nright we're going to go through that and\nwe're going to put both those messages\nin a chat prompt template based off\nthese messages right here then we're\ngoing to set up our QA our retrieval QA\nso this is the retrieval part and this\nis question and answering but we kind of\nmade our custom prompts up here so it's\nnot so question and answering it's more\nwell retrieval custom I don't know what\nyou want to call it and then from chain\ntype we're going to put in our doc\nsearch that we have and we're going to\nput our chain type keyword arguments now\nverbose equals true if you want to see\nall the magic happen in the background\nbut here's the cool part because we're\ngoing to put in our custom chat prompt\nwhich is what we made it up here and\nthen we're going to run through this so\nI'm going to say for Topic in the\nstructured topics that we had Above This\nis the dictionary that we had I'm only\ngoing to look at the first three well\nI'll tell you what let's do a couple\nmore let's do five I'm going to look at\nthe first five and I'm going to say hey\nthe query in this case is going to be\nthe topic name and the topic description\nthis would normally be where the\nquestion went but I want to find similar\ndocuments based off of this query not\nthe question which is why I did this and\nthen the expanded topic I call this\nexpanded because we're asking for a five\nsentence summary up above here so this\nis the expanded topic and this is what\nwe get when we do the QA dot run with\nour query in there and let's just start\nto iterate through this and see what we\nstart to get here I'm going to print out\nthe topic name in the description and\nthen I'm going to print out the expanded\ntopic so if we take a look at our first\none here\nthe hearing aids business this is the\nfirst topic that we talked about up here\nuh Sean and Sam discuss the potential\nprofitability of the hearing aid\nbusiness but if we scroll down we start\nto get more information on it so Sean\nand Sam discuss the potential of the\nhearing aid business noting that it\ncould be profitable Venture they believe\na direct consumer hearing aids could be\na significant Market cool so now we\nstarted to expand on the information\nthat we have here we have children's\nplay Space business so here was the\ndescription that we had before and now\nwe have a longer description so my point\nin showing you this here is you know a\nsummary it's not so bad but you may have\nyour own use cases that you want to pull\nout your extra information for and this\nis a convenient way to do it all right\nso we roll through here and there's more\ninformation about more topics all right\nnow that is the end of our regular\nscheduled programming but now we're\ngoing to do chapters of time stamps so\nthere could be a lot of instances where\nyou actually have the time stamps for\nyour transcript that you have and you\nwant to actually pull out the different\nchapters further so it could be a\nYouTube video it could be a podcast\ntranscript or whatever uh well we're\ngoing to do something extremely similar\nand we're going to do the same method\nwhat we're going to do here is we're\ngoing to set up another custom prompt\nwhat is the first time stamp when the\nspeaker\nwhen the speakers started talking about\na topic that the user gives it should be\na question mark only respond with the\ntimestamp nothing else and then I give\nit an example timestamp here so there's\nmy custom prompt and just to remind you\nwhat this looks like so if I look at my\ntranscript one more time let's do this\nit's going to be nice and long but let\nme print this out then what we have here\nis we have the transcript right here and\nwe have what the person says so what\nwe're going to do here is we're going to\nsay hey language model here's where\nsomebody's talking about a topic what's\nthe smallest timestamp that you see that\nyou see on here now I tried this a bunch\nof different ways some of which using\nthe the function calling the open AI\njust came out with but really the\neasiest one was just go through it and\njust ask and it's pretty good of finding\nthat out all right so here's our QA\nagain we're going to go for it and this\ntime we're going to have our custom\nprompt which is the new custom prompt up\nhere and then our topic time stamps and\nso I'm putting just a placeholder here\nbut what I want to do is I want to go\nthrough each Topic in each of the\nstructured topics that we had up above\nwhich I think was something like 10 or\n15.\nhere's the query and in this case we\nhave the topic name and then the\ntimestamp is going to be the output of\nthis retrieval process that we have up\nhere and then what I'm going to do is\nappend the timestamp which was found\nwhich is the answer from the language\nmodel and the topic name and throw it\nright in this list and then let's let's\njoin it first into a larger list and\nlet's sort it so we can see them all in\norder awesome so what we have here is\nnow our timestamps that were returned\nfrom here so for the very first topic\nthe hearing aids business and this is\njust the topic name remember it's not\nthe description it the language model is\ntelling us that this is the first thing\nthat was talked about because it was\nbasically opened up the subject here and\nthen the next topic was the children's\nplay Space Business Health and die hack\nSteph Smith's career let's go check this\nout and let's see what the first topic\nis I'm over here on steno.ai I'm going\nto play the first topic d2c hearing aids\nI think that's actually going to be a\nbig deal and that's pretty cool that was\nthe first thing that was talked about on\nthere which is awesome all right my\nfriend so that's my take on how to pull\nout the chapters or the topics from a\ntranscript piece of text now I'm super\ncurious to see what you do with this\nproject yourself and so when you apply\nto your own domain please let me know I\nlove getting emails from folks comments\ntweets whatever it may be I just want to\nsee you build and see what you end up\ndoing thank you very much for the join\ntoday and we'll see you later bye",
  "transcript_chars": 23183,
  "ingested_at": "2026-05-15T04:41:41.246996+00:00",
  "source": "channel",
  "yt_meta": {
    "view_count": 17560,
    "like_count": 576,
    "channel_id": "UCyR2Ct3pDOeZSRyZH5hPO-Q",
    "categories": [
      "People & Blogs"
    ],
    "tags": []
  }
}