Google Colab에서 이 노트북 실행하기
아래의 모든 단계를 실행 가능한 노트북 형태로, 오디오 요약을 인라인으로 재생하며 확인할 수 있습니다. 설치할 것이 없습니다.
동작 방식
각각 하나의 역할을 담당하는 다섯 개의 엔드포인트:
여기서의 검색은 의도적으로 단순합니다. Python 리스트에 담긴 벡터, 반복문으로 계산하는 코사인 유사도. 몇 십 개의 자료라면 이 정도의 기계 장치가 적당하며, 움직이는 부품이 눈에 보이는 상태를 유지할 수 있습니다. 이를 넘어서는 규모라면 프라이빗 RAG 봇 만들기에서 같은 파이프라인을 실제 벡터 데이터베이스와 재순위화 단계와 함께 다룹니다.
준비하기
의존성 하나, 그리고 API 설정 페이지에서 얻은 키.notebook.py를 만들고 import와 설정부터 시작합니다. 맨 아래의 두 리스트가 노트북의 전체 상태입니다. sources는 여러분이 추가한 것을 기록하고, chunks는 검색 가능한 조각들을 담습니다.
HOSTS는 진행자 이름을 목소리에 매핑합니다. 두 목소리 모두 tts-xai-v1에서 온 것이며, 이는 중요합니다. 목소리는 모델에 속하고, 한 계열의 목소리를 다른 계열의 모델로 보내는 것이 speech 엔드포인트에서 가장 흔한 첫 실수입니다.
오래되지 않을 모델 고르기
프로젝트에 chat 모델을 하드코딩하면 그 프로젝트는 반드시 낡습니다. Venice는/models/traits를 통해 각 역할을 현재 어떤 모델이 맡고 있는지 공개하므로, 특정 이름을 지정하는 대신 현재의 기본값을 요청할 수 있습니다.
most_intelligent는 추론이 많이 필요한 요약을 위한 더 강한 모델을 골라주고, default_reasoning은 사고 과정을 드러내며 사고하는 모델을 제공합니다. 전체 목록은 Models를 참고하세요.
자료 추가하기
자료는 URL이거나 디스크의 파일이며, Venice에는 각각을 위한 엔드포인트가 있습니다. 둘 다 평문 텍스트를 반환합니다. 그게 핵심입니다. 이후의 노트북은 자료가 어디서 왔는지 신경 쓰지 않습니다./augment/scrape는 원본 HTML 대신 Markdown을 반환하므로 상용구를 벗겨낼 필요가 없습니다. /augment/text-parser는 PDF, Word, Excel, 그리고 최대 25 MB의 평문 텍스트를 받아들이며, 텍스트와 함께 토큰 수도 알려줍니다. 옵션 전체는 문서 처리에서 다룹니다.
청크 분할과 임베딩
문서 전체를 임베딩하면 그 안의 모든 내용을 평균 낸 벡터 하나가 나오는데, 이는 특정 주장을 검색하기에는 너무 뭉툭합니다. 나누면 각각이 무언가를 의미하는 벡터가 됩니다. 고정된 글자 수가 아니라 문단 경계로 나누세요. 문장 중간에서 잘린 청크는 검색이 잘 되지 않습니다. 임베딩이 조각의 임베딩이 되기 때문입니다.embed는 배치로 처리합니다. 엔드포인트가 리스트를 받기 때문이며, 64개 청크에 대한 한 번의 요청이 64번의 요청보다 실제 소요 시간에서 훨씬 저렴합니다. text-embedding-bge-m3는 1024차원을 반환하며 다국어 자료를 잘 처리합니다.
이제 자료를 추가하는 것은 읽고, 나누고, 임베딩하고, 기록하는 일입니다. 각 벡터의 크기는 함께 저장해 둡니다. 그 값은 변하지 않으며, 유사도 반복문 안에서 다시 계산하는 것은 낭비이기 때문입니다.
number가 이후 인용을 가능하게 하는 것입니다. 각 청크는 자신이 어느 자료에서 왔는지 기억하므로, 답변이 그 자료를 가리킬 수 있습니다.
적절한 구절 검색하기
질문 벡터와 모든 청크 벡터 사이의 코사인 유사도, 정렬, 상위 k개. 수천 개의 청크 정도라면 질문 벡터를 만들어낸 네트워크 호출보다 이 계산이 더 빠르게 실행됩니다.인용과 함께 답하기
근거 있는 답변과 자신만만한 추측의 차이는 전적으로 프롬프트에 달려 있습니다. 두 개의 지시가 그 일을 합니다. 노트에서만 답하라는 것, 그리고 노트가 부족하면 그렇다고 말하라는 것. 두 번째가 없으면 모델은 조용히 기억으로 그 빈틈을 채우는데, 그것이 바로 여러분이 설계로 배제하고자 하는 실패 모드입니다. 프롬프트에서 노트에 번호를 매기면 모델에게 인용 어휘를 제공하는 셈이 됩니다. 모델이[2]라고 쓰면, 여러분은 그것을 자료로 되돌려 풀 수 있습니다.
요약 대본 쓰기
여기서부터 노트북은 검색창이기를 그만둡니다. 요약(summary)은 읽는 것이고, 오디오 요약(overview)은 듣는 것이며, 둘은 서로 다른 문체를 원합니다. 대화는 오디오에서 더 잘 작동합니다. 서로 주고받는 흐름이 페이스를 대신 만들어 주고, 한 진행자의 질문이 다음 아이디어를 소개하는 자연스러운 방식이 되기 때문입니다. 세 가지 제약이 중요하며, 셋 모두 텍스트가 아니라 오디오에서 비롯됩니다:- markdown 없음, URL 없음. speech 모델은
https://docs.venice.ai를 한 글자씩 읽습니다. - 약어는 풀어서 표기. 처음 등장할 때는 tee가 아니라 T E E.
- 턴 길이를 다양하게. 균일한 길이의 턴은 두 사람이 서로에게 목록을 읽어주는 것처럼 들립니다.
speaker의 enum은 모든 턴이 여러분이 가진 목소리 중 하나에 매핑되도록 보장합니다.
spread는 유사도로 검색하는 대신 컬렉션 전체에서 청크를 표본으로 뽑습니다. n번째 청크마다 하나씩 고르는 것은 조악하지만 잘 통합니다. 긴 문서의 끝부분에 도달하는데, 앞의 열두 개만 취하는 방식으로는 결코 그럴 수 없기 때문입니다.
턴 수는 지시가 아니라 힌트로 취급하세요. 여기서 16개를 요청하면 자료가 할 말이 얼마나 많은지에 따라 16개부터 28개까지 나온 적이 있습니다. 딱딱한 상한이 필요하면 프롬프트와 씨름하는 대신 렌더링 전에 turns를 잘라내세요.
두 목소리를 하나의 트랙으로 렌더링하기
각 턴은 하나의 speech 요청이 되며, 목소리는 누가 말하고 있는지에 따라 정해집니다.pool.map은 입력 순서를 유지하므로, 어떤 요청이 먼저 끝나든 턴은 작성된 순서대로 돌아옵니다. 워커 4개는 최대치가 아니라 의도적인 상한입니다. 그 이상으로 동시에 실행하면 낮은 티어에서는 429가 발생하기 시작하며, 작업 시간은 이미 가장 긴 단일 턴에 지배되기 때문입니다.
실행하기
여러분의 것으로 만들기
자료가 전부입니다. 이후의 모든 것은 여러분이 넣은 것에 의해 한계가 정해집니다. 스크래핑된 페이지는 내비게이션과 푸터를 함께 가져오는데, 이는 답변에는 무해하지만 오디오 요약에서는 진행자가 진지하게 문서 목차를 논하는 모습으로 드러납니다. 그런 일이 생기면 임베딩 전에 길이 임계값 이하의 청크를 버리거나 뻔한 상용구를 걸러내세요. 목소리를 바꿔 보세요.HOSTS는 딕셔너리의 두 개 항목입니다. tts-xai-v1은 26개의 목소리를 제공하며, 다른 계열에도 자체 목소리가 있습니다. GET /models?type=tts는 모델별 voices를 나열합니다. 뚜렷하게 대비되는 두 목소리가 그저 다르기만 한 두 목소리보다 따라가기 쉽습니다.
자신의 목소리를 복제하세요. 음성 복제는 짧은 샘플을 HOSTS에 곧바로 넣을 수 있는 음성 핸들로 바꿔줍니다.
세 번째 참여자를 추가하세요. 파이프라인에서 발화자가 둘이라고 가정하는 것은 스키마의 enum뿐입니다. 오직 질문만 하는 인터뷰어를 추가하면 분위기가 상당히 달라집니다.
대본을 보관하세요. turns를 오디오 옆의 JSON 파일로 쓰는 데는 두 줄이 들지만, 한 문장을 손보고 싶을 때마다 다시 렌더링해야 하는 수고를 덜어줍니다.
다음으로 볼 만한 것
프라이빗 RAG 봇
실제 벡터 데이터베이스와 재순위화를 갖춘 동일한 검색 파이프라인입니다.
웹 검색으로 인용된 답변
자료를 직접 지정하는 대신 자동으로 찾아냅니다.
텍스트 음성 변환
speech 엔드포인트, 목소리, 스트리밍에 대한 레퍼런스.
문서 처리
text parser가 받아들이는 것 모두와 반환하는 것.