로그인
구독
프롬프트 히스토리

강의 PPT, script 컨텐츠 생성 자동화

T
Two_Jay
카테고리
비어 있음
이번에 강의 컨텐츠 작성/감수 업무를 하면서 생각하고 있던 강의 PPT, Script 자동화를 구현해 보았습니다. 기존에 손수 대본과 피피티를 만들고, 검수하려고 계획되었던 업무를, 생성형 AI를 이용해서 구현하는 쪽으로 바꾸었습니다. 이렇게 생각한 이유가 몇 가지 있었는데 다음과 같았습니다.
1.
7일의 시간 동안 3-4 명의 인원으로 60개 ppt의 700여 슬라이드와 슬라이드 각각의 대본을 손수 작업해야하는 (정말 말도 안되는) 작업량.
2.
전문적 내용을 담는 것이 아니라, 특정 대상층에 맞는 컨텐츠의 배치를 고려해야 했음. 즉, 전체 테스크에서 산출해야 하는 컨텐츠의 정보 수준이 항상 동일해야 했음.
3.
클라이언트가 요구하는, 컨텐츠 정보의 수준이 깊지 않았음.

입출력 정의

전체 작업의 과정은 초안 레벨의 PPT와 대본을 만들고, 이를 도메인 전문가가 검토하는 식으로 정했습니다. 0to1 작업은 LLM을 이용해서 빠르게 진행하고, 이후 검수 작업에서 퀄리티를 늘려가면서 결과물을 만들어내는 것으로 잡았습니다.
그러면 강의 하나를 PPT로 만들기 위해서는 어떻게 생성형 AI를 적용시킬 수 있을까요?
일단 실행 인터페이스는 간단하게 다음과 같이 잡았습니다. 아주 간단한 데이터에서 시작해봅시다.

1. 강의의 대주제가 될 키워드 1개 : "딥러닝", "머신러닝" 등.
2. 청중의 주된 특성을 적은 txt 파일 하나
그 다음 우리가 결과로 나올 때에 산출하는 데이터는 다음과 같습니다.

1. 강의의 PPT 초안
2. 강의 슬라이드 별 대본
그러면 이제 좀 그림이 아래와 같이 정리되겠죠. 우리는 이제 아래에서 어떤 로직을 채워넣을 지 고민하면 됩니다.

설계 및 구현

⚠️
포스트에서 나온 프롬프트는 해당 기능의 0.0.0 버전의 초안을 올렸습니다. 고도화시에는 특정 방향으로의 튜닝 및 특화, 번역을 진행했습니다
기반 데이터가 '키워드'에서 시작합니다.
keywords = [ "딥러닝", "머신러닝", "생성형 AI", "자연어처리", "이미지처리", "프롬프트엔지니어링 & RAG" ]
키워드는 단순히 단어일 뿐입니다. 이것만으로는 모든 강의를 생성할 수 없습니다. 아직은 너무 미약하고 양이 작은 정보죠. 이제 이걸 양적으로 먼저 불려볼 겁니다.
강의 제작을 많이 진행해보신 분이라면 ToC(Table of Contents)를 아실 겁니다. 강의를 진행하기 위해서 일종의 컨텐츠들이 어떤 식으로 먼저 나열되어 있는지에 대한 목차인데, 좋은 시작점이 될 것 같습니다. 이를 아래의 프롬프트를 활용해서 ToC를 생성해보죠.
Table of Contents 생성 프롬프트
model : claude-3.5-sonnet
temperature : 0.8
max_tokens : 4000
<audience_characteristics> {audience_characteristics} </audience_characteristics> <output_format> Title : 생성되는 컨텐츠 타이틀 - Chapter 1 : 다루게 될 소주제 1 1. Content 1 : Table 1 주제에 하위 주제인 다룰 컨텐츠.. 2. Content 2 (생략 가능 - 마지막은 반드시 '요약'으로 마칠 것) - Chapter 2 - Chapter 3 - Chapter 4 {/* 이외 출력물의 형태를 수정하고픈 경우 여기에 수정 */} </output_format> <output_rule> - 모든 Content마다 한 줄의 간략한 정보를 ':' 이후에 concat하세요. {/* 이외 출력물의 방향성이나 제약을 제시하고픈 경우 여기에 수정 */} <output_rule> <content_direction> - Title은 주어진 <target_topic>이어야 함. - 실제 실무 작업 대신에 실무자와 소통할 수 있는 정도의 개념을 소개하도록. - 실무적인 코드보다는 개념적인 이해와 도입을 주로 하도록 Content 소주제를 일반적인 개념으로 구성하기. {/* 이외 컨텐츠에 대해서 방향성 제시하고픈 경우 여기에 수정 */} </content_direction> <target_topic> {course_topic_name} </target_topic> 주어진 <target_topic>에 대해 위의 정보들을 참고하여, Table of Contents을 만들어서 정리해줘
강의의 주 대상층이 가지고 있는 특성은 <audience_characteristics>로 별도의 파일을 읽어와서 텍스트로 집어넣도록 했습니다. 강의라는 컨텐츠는 청자의 이해에 맞게 컨텐츠가 조정될 수 있기에, 이는 전체 파이프라인 시작단계에서부터 끝까지 줄곧 등장합니다. 컨텐츠의 선정과, 톤앤매너, 요약의 정도에 영향을 미치는 중요한 정보니깐요.
출력물에 대한 방향을 <output_format>과 <output_rule>로 한정했습니다. <output_format>은 출력물의 형식을, <output_rule>은 출력물의 형식에서 전반적인 방향성을 제어했습니다. 출력물의 형식이 아닌 컨텐츠 내용 자체에서 조절해야하는 방향성은 <content_direction>로 조절했습니다.
<target_topic>은 ToC를 생성할 강의의 전체 타이틀을 적어놓았습니다.
이렇게 하면, 다음과 같은 방향성의 컨텐츠가 나옵니다. 테이블 안에 적힌 컨텐츠의 양과 질은 프롬프트로 조정하니 고도화를 진행할 때에는 ToC에서 어떻게 정보의 방향을 정하고 조절할 지 집중하면 좋을 거 같아요.
Title : 딥러닝 - Chapter 1: 신경망의 기초 1. 뉴런과 퍼셉트론의 이해 : 생물학적 뉴런 구조에서 영감을 받은 인공 뉴런의 수학적 모델링과 단일/다층 퍼셉트론의 작동 원리, 학습 방법을 깊이 있게 탐구합니다. 2. 활성화 함수의 종류와 특징 : 시그모이드, ReLU, tanh 등 다양한 활성화 함수들의 수학적 특성과 장단점을 비교하고 적절한 사용 시점을 학습합니다. 3. 순전파와 역전파의 원리 : 신경망에서 데이터가 전달되는 순전파 과정과 오차를 최소화하기 위한 역전파 알고리즘의 수학적 원리와 구현 방법을 이해합니다. 4. 손실 함수와 최적화 알고리즘 : 모델의 성능을 평가하는 다양한 손실 함수들과 경사하강법, Adam, RMSprop 등 최적화 알고리즘의 작동 원리를 학습합니다. (이하 생략)
이제 이런 테이블을 강의 타이틀마다 뽑았습니다. 강의의 타이틀 하나와 각 챕터의 제목, 그리고 그 안의 컨텐츠들이 있으면, 어느정도는 충분한 정보량이 모였습니다. 이제 다음 스텝으로 넘어갈 차례입니다.이제 스크립트를 생성할 차례입니다.
스크립트 생성 prompt
model : claude-3.5-sonnet
temperature : 0.7
max_tokens : 6000
<chapter_contents> {chapter_contents} {/* 이곳은 챕터 하나의 제목과 소주제만 들어갈 것 */} </chapter_contents> <audience_characteristics> {audience_characteristics} {/* 이전에 정의한 청중 정보 */} </audience_characteristics> <lecture_duration_minute>{duration}</lecture_duration_minute> <lecture_ppt_slide_amount>{slide_amount}</lecture_ppt_slide_amount> <content_direction> - 강의 대본을 만들 때에는 명확한 도입과 결론이 있어야해. - 각 챕터와 하위 컨텐츠의 내용을 <audience_characteristics>에 맞춰서 충분히 다루어주어야 해. 중심되는 내용을 먼저 소개하고, 그 내용을 각각 청중에 맞추어 더 상세하게 설명하는 식으로 충분히 길게 대본을 생성해주었으면 해. 어떤 기술적 개념어를 만난다면, 이를 <audience_characteristics>가 잘 이해할 수 있도록 개념을 상세히 설명하고 넘어가줘. - 대본을 생성할 때에는 네가 PPT를 이용해서 발표를 함을 전제로 하기에, 연속된 내용을 개별적인 슬라이드에 나누어 담아야 해. 내용은 toc에 있는 내용을 충실히 기반으로 삼아줘. - 슬라이드 중에서 내용을 생성할 때는, '도입과 소개', '마무리 인사', '첫 인사' 등에 대해서 절대로 생성하지 말고, <chapter_contents>에서 나타나는 강의에서 다루는 내용만을 곧장 생성해줘. 내용에서 numbered points가 필요할 때에는, 숫자 대신' "첫째," "둘째," 와 같이 생성해. 대본에서 생성되는 문장은 문장 구성 상 완벽한 문장으로 끝나야 해. - 페이지의 수가 현재 다루는 내용의 종류보다 더 크다면, 그 내용을 스크립트 전체적으로 균일하게 다루어 줘. subtitle의 내용은 ToC에 있는 내용을 참고로 해. </content_direction> 위의 정보들을 기반으로 <lecture_duration_minute>동안 진행될 강의 대본을 만들어줘. 생성되는 출력의 양식은 다음과 같이 해줘. <output_format> [slide_1_start] subtitle : (현재 slide에 해당하는 subtitle 내용) (slide에 해당하는 script 내용) [slide_1_end] [slide_2_start] subtitle : (현재 slide에 해당하는 subtitle 내용) (slide에 해당하는 script 내용) [slide_2_end] ... [slide_<lecture_ppt_slide_amount>_start] subtitle : (현재 slide에 해당하는 subtitle 내용) (slide에 해당하는 script 내용) [slide_<lecture_ppt_slide_amount>_end] </output_format>
<audience_characteristics>는 이전에도 사용한 청중 정보를 동일하게 사용합니다. 파라미터에서 <chapter_contents>는 위에서 생성되는 Table of Contents의 챕터 하나분량의 데이터만 가져와서 넣습니다. python 코드에서 생성되는 ToC를 반복해서 파싱해서, 아래의 구조와 같은 형태로 만들어서 프롬프트에 넣어줍니다.
- Chapter 1: 신경망의 기초 1. 뉴런과 퍼셉트론의 이해 : 생물학적 뉴런 구조에서 영감을 받은 인공 뉴런의 수학적 모델링과 단일/다층 퍼셉트론의 작동 원리, 학습 방법을 깊이 있게 탐구합니다. 2. 활성화 함수의 종류와 특징 : 시그모이드, ReLU, tanh 등 다양한 활성화 함수들의 수학적 특성과 장단점을 비교하고 적절한 사용 시점을 학습합니다. 3. 순전파와 역전파의 원리 : 신경망에서 데이터가 전달되는 순전파 과정과 오차를 최소화하기 위한 역전파 알고리즘의 수학적 원리와 구현 방법을 이해합니다. 4. 손실 함수와 최적화 알고리즘 : 모델의 성능을 평가하는 다양한 손실 함수들과 경사하강법, Adam, RMSprop 등 최적화 알고리즘의 작동 원리를 학습합니다.
스크립트는 아래와 같이 생성됩니다. 이제 이렇게 생성된 컨텐츠를 python 코드를 짜서, 정규식 기반으로 각각의 슬라이드에 해당하는 subtitle과 대본 text를 가져와서 정리했습니다.
[slide_1_start] subtitle: 데이터 전처리 프로세스 개요 안녕하세요, 오늘은 데이터 전처리 프로세스에 대해 알아보겠습니다. [후략] [slide_1_end] [slide_2_start] subtitle: 1. 데이터 클리닝 데이터 전처리의 첫 단계는 데이터 클리닝입니다. 이는 원본 데이터에서 ... [후략] [slide_3_start] subtitle: 2. 데이터 통합 두 번째 단계는 데이터 통합입니다. 여러 소스에서 수집된 데이터를 하나의 ... [후략] [slide_3_end] [후략]
"PPT부터 생성하고 스크립트를 만드는 게 편하지 않아요?" PPT 보다 왜 강의 대본을 먼저 생성하는지 궁금해하는 질문이 있을 것 같습니다. 여기서 제가 순서에서 주안점을 둔 것은 정보의 양과, 실제로 생성된 정보들이 어떤 방향으로 쓰이는 지에 대해 집중했습니다.
슬라이드 하나의 내용을 작성하기 위해서는 ToC에 나온 챕터 하나를 슬라이드 갯수대로 흩뿌려놓아야합니다. 즉, 우리가 해야할 것은 각 챕터에서 하위내용 한 줄을 슬라이드 10-12개로 흩뿌려야 하는 것이지요. 이 경우, 다시 정보의 양은 급격하게 줄어듭니다. 키워드 하나보다는 낫지만, 아직도 각각의 슬라이드들에 충분한 정보를 주기에는 정보량이 아직도 모자란 상태이지요. 이런 경우, 각각의 슬라이드 단위로 충분한 정보량이 들어갈 수 있도록 다시 한 번 정보를 증강 시켜주어야 합니다.
그런 경우, 아예 현재 스텝에서 선지가 있을 때에 더 많은 정보를 생성하는 방향으로 가주는 것이 좋습니다. 따라서 슬라이드 내용 대신 슬라이드 하나에 들어갈 강의 대본을 먼저 생성했지요. 정보량을 늘린 것에서 요약하는 것은 쉽지만, 부족한 정보량에서 엔드컨텐츠를 생성하는 것은 언제나 문제를 일으키니, 차라리 충분한 정보량을 보존하면서 더 안전한 스텝을 밟는 쪽으로 선택했습니다.
다만 이렇게 정보의 양을 늘릴 때, 특정한 키워드가 반복해서 나타나면 중요한 정보로 인식되는 경우 답변에서 편향이 강화될 수 있지만, 뭔들 어때요. '강의'라는 컨텐츠에서 '프레젠테이션 내용'은 사실상 강의자의 멘션에서 중요한 부분을 축약한 것입니다. 그런 경우 자연스레 강의자의 멘션에서 자주 나오는 내용은 강의에서 중심이 되는 중요한 내용이고, 이를 각각의 슬라이드 단위로 축약하여도 그런 경향성은 유지됩니다. 오히려 '좋은' 편향으로 작용할 수 있죠.
스크립트를 잘 작성했다면, 아래의 프롬프트를 이용해서 PPT에 들어갈 내용을 만듭니다.
PPT 슬라이드 내용 생성
model : claude-3.5-sonnet
temperature : 0.7
max_tokens : 1000
<script_content> {script_content} </script_content> <chapter_name> {chapter_name} </chapter_name> <subtopic_name> {subtopic_name} </subtopic_name> <audience_characteristics> {audience} </audience_characteristics> <content_direction> - <script_content> 내용을 기반으로 작성하되, 핵심어들과 이에 대한 핵심적인 짧은 설명만 남겨주세요. - 짧은 설명은 남기지 않아도 좋지만, 핵심어는 반드시 제시되어야 합니다. - 슬라이드를 설명하는 핵심어는 둘 이상입니다. - <chapter_name>, <subtopic_name>과 완전히 관련없는 내용이 핵심어로 와서는 안됩니다. - 중심 내용이 아닌, 예시나 예화같은 내용은 핵심어로 여기지 마시오. - 핵심어는 5개 이하로 잡아주세요. - audience에 대한 정보가 출력에 노출되지 않도록 하십시오. </content_direction> <script_content>를 기반으로, PPT 내용으로 들어갈 내용을 생성해 줘. 들어갈 내용을 생성할 때 <content_direction>을 참고해. 핵심어로 뽑아낼 수 있다면, 핵심어 뒤에 ' : '를 붙이고 설명을 붙여주세요. 그게 아니라면, 간단한 축약된 설명만을 남겨주세요. 전체적으로 일관된 경향성을 지켜주세요. 출력물은 아래의 형태를 준수해야 합니다. <output_format> - (핵심어 1) : (핵심어 1에 대한 짧은 설명) - (핵심어 2) : (핵심어 2에 대한 짧은 설명) (이후 생략, 더 만들어도 됨) </output_format>
이제 이런 형태의 데이터가 생성됩니다. 이 데이터는 PPT 장표 내에 넣어줄 겁니다.
- 결측치 처리 : 평균값, 중앙값, 최빈값 등으로 대체하거나 제거 - 이상치 처리 : 통계적 방법으로 검출 후 제거 또는 수정 - 정규화 : 데이터 스케일을 조정하여 모델 성능 향상 - 피처 엔지니어링 : 새로운 특성 생성으로 모델 성능 개선
위와 같은 작업을 전체 슬라이드에 각각 작업을 해주고, 그 내역을 엑셀로 저장합니다. 지금까지는 우리가 이런 스텝을 밟아왔습니다.
PPT 파일을 생성할 때 두 가지 선지가 있었습니다. 직접 python-pptx를 써서 모든 것을 통제하는 코드를 작성하는 것. 그리고 그보다 더 빨리 생성할 수 있는 무언가를 찾는 것. 찾아본 것 중에서는 Canva가 특정한 템플릿으로 내용을 csv나 excel 파일로 정리했을 때, 빠르게 생성할 수 있는 수단이 있어서 이를 활용했습니다. 지금 활용하는 ppt/script 초안 작성 시스템은 아래의 형태로 완성되었습니다.

고도화 방안

1.
이런 시스템의 퀄리티는 항상 아웃풋에 대한 피드백을 받아가면서 기민하게 수정되어야 합니다. 실제 생성되는 스크립트에서 '인간다움'을 어떤 패턴으로 넣을지, 길이는 적당한지, 다루는 컨텐츠가 청중의 특성과 너무 동떨어지지는 않은지 계속적인 피드백을 받아가면서 프롬프트를 수정하는 것이 필요하죠. 해당 시스템을 만들 때에 언제든 피드백을 열어두고 진행하는 것이 좋습니다.
2.
python-pptx를 통해서 ppt 파일을 생성하도록 고도화할 수 있습니다. 이 경우, 정말 많은 경우의 수를 통제 가능합니다. 대표적으로 아래가 가능합니다.
기존 템플릿 ppt나 산출물 ppt를 python code로 실행/분석/수정/삭제가 가능
배경 정보 수정 가능
텍스트 및 이미지 삽입 가능
기존 ppt를 복사해서 새로운 ppt에 적용 가능
기타 등등등등
python-pptx가 왜 중요한 지 이해가 되지 않으실 분들이 있을 수도 있습니다. 하지만, 코드레벨로 뭔가를 다룰 수 있다는 것은 프롬프트 엔지니어에게 엄청난 가능성을 가져오는 일입니다. 코드는 곧 텍스트고, 텍스트는 곧 prompt-reachable하다는 것을 보여줍니다. 프롬프트로 해당 산출물을 다룰 수 있도록 만들 수 있다는 것이죠.
즉, ppt를 직접 다루기보다는, LLM을 인터페이스 삼아서 ppt를 다룰 수 있는 코드를 생성하도록 할 수 있습니다. 이 경우 python-pptx를 이용해 ppt를 다루는 코드를 생성하도록 llm에 프롬프트로 넣을 수 있겠죠. 코드이기 때문에 특정한 반복적인 작업을 하거나, 형식화가 가능한 경우 템플릿으로 만들어 버리고 매개변수만 LLM이 생성하도록 이끌 수 있구요.
그리고 이렇게 생성되고 만들어진 '텍스트', 즉 python 코드를 eval()로 돌려버릴 수도 있습니다. 금기의 도구이지만, 이럴 때에는 의사의 메스처럼 유용한 도구가 되지요.
💡
코드든, 파일이든, 연극의 대사든, 그 대상이 텍스트라면 LLM으로 생성가능한, Prompt-reachable한 컨텐츠입니다. 내가 목표로 하는 컨텐츠가 LLM으로 다루기 불가능해 보여도, 이를 생성하거나 다룰 수 있는 text based something을 찾아보세요.
⚠️
eval()을 사용할 때에는, 출력물의 제한에 조금 더 고심하셔야 합니다.

출력물 그 자체를 실행하기 때문에, 파이썬 코드를 제외한 일반적인 메세지가 섞이면 안됩니다. 또한, 반드시 시스템에 치명적인 영향을 미치는 코드(e.g. "rm -rf /*")나 의도하지 않은 동작을 담은 코드를 생성하지 않도록 강한 제어를 프롬프트에 넣으셔야 합니다.
3.
강의 ToC, 스크립트 외에도 강의 전체의 흐름을 계획할 수 있는 플래닝 과정이 필요합니다. 필요하다면 여기서 강의의 길이, 흐름, 특정 시퀸스의 톤앤매너를 별도로 유저의 입력을 받아 주입하여, 특별한 구간에서 '킥'을 심겨둔 대사를 발현하도록 이끌 수 있습니다.
이렇게 한다면, 완전하게 넓은 범위를 커버할 수 있는 강의 자료 생성 자동화가 가능하죠.

마치면서

마치면서 생각해보니 '막 이렇게 남들한테 아이디에이션부터 프롬프트 내용, 고도화 방향까지 다 알려줘도 되요?'라는 질문도 있을까봐. 이렇게 해도 괜찮다고 생각하는 이유는 네 가지가 있습니다.
1.
왠만큼 실력있는 분이라면 눈치채고 계셨겠지만, 위에서 제시된 프롬프트는 시스템에 그대로 사용하지 않았습니다. 이후에도 끊임없이 고도화를 하고, 지금 하는 일이 마친 이후에는 작은 모델에서도 결과물을 잘 뽑아낼 수 있도록 개선이 예정되어 있습니다.
2.
그런 만큼 잘 만들 수 있는 분들이 가져가서 아이디에이션을 더 발전시켜도 좋습니다. 어짜피 그런 분들이라면 이렇게 안 알려줘도 스스로 방법을 찾아서 합니다.
3.
이것보다 더 나은 건 언제든지 만들어 낼 수 있다는 자신감.
4.
마지막 네번째는 아래의 짤로 갈음하겠습니다.
...그렇다니깐요...
'Two-Jay_prompt_engineer' 구독하기
사이트를 구독하면 새 포스트 등 최신 업데이트를 알림과 메일로 가장 먼저 받아보실 수 있습니다.
Slashpage에 가입하고 'Two-Jay_prompt_engineer'을 구독하세요!
구독
👍
1