Cailyn Yong

Cailyn Yong님의 아티클

Cailyn Yong

Cailyn Yong

심심해서 해커톤 참여해서 10분 안에 아이디어 만들고 논 후기

10분 안에 웹사이트 글 정리해주는 AI 에이전트 만들기

안녕하세요! 오랜만에 개발글로 돌아왔습니다.

오늘은 정말 간단하게 10분 안에

  • 웹사이트 링크 데이터를 스크레이프하고

  • faiss와 같은 백터스페이스 (데이터베이스)에 저장한 다음

  • 웹사이트 데이터를 한번에 요약해주는 LLM 체인

만드는 법에 대해 올릴 예정입니다.

예전에 만들었던 몇가지 사이드프로젝트 중에 웹사이트를 그 사이트 내용에 맞는 트위터 홍보용 게시물로 자동으로 만들어주는 AI Agent 툴을 빌드했었는데 이번에 ETH Con이라는 블록체인 해커톤을 참여하면서 비슷한 아이디어로 빌딩했습니다.

2.jpeg

이번에는 제가 최근에 알게된 기업, FiscalNote라는 곳을 참고하면서 아이디어를 떠올리게 됐습니다. FiscalNote는 Tim Hwang이 창업한 AI 기반 법률·정책 빅데이터 미디어 기업으로 정부 정책을 매일매일 업데이트 받아야하고 자세하게 알아야하는 국회의원 혹은 비즈니스들을 위해 정리, 요약, 분석해주는 서비스입니다.

마찬가지로 블록체인 업계에서는 매일매일 새로운 governance proposal이 올라오는데요, 이 정책들은 블록체인을 어떻게 운영할 것인지, 어떤 기술을 새로 접목시킬 건지, 토큰 수량은 몇개를 배포할건지 등에 대한 것들입니다.

그래서 특정 블록체인 위에서 빌딩을 하고 있는 개발자나 창업가는 새롭게 결정되는 정책들에 대해 무조건 알고 있어야만 하죠. 하지만 매일 올라오는 정책들을 매번 알고 있기가 어려워 아예 따로 이런 정책들만 요약해주는 비서를 두기도 합니다.

이걸 해결하기 위해 저는 이런 정책들을 한번에 요약해주는 AI 에이전트를 LLM을 활용해서 만들었습니다.

바로 빌딩 들어가시죠! :)

저번과 마찬가지로 저희는 가상환경을 만들고 그 안에서 python 코드를 돌릴 예정입니다.

가상 환경을 만드는 과정은 제 전 포스트에서 확인하실 수 있습니다.

1) VSCode를 열어서 새로운 폴더를 만드세요.

2) 폴더 내에서 터미널을 열어 python -m venv venv 명령어를 입력합니다.

3) 다음 source venv/bin/activate 를 입력해서 가상환경을 실행시켜줍니다.

4) 우리에게 필요한 library들을 다운로드 해줍니다.

pip install openai langchain
pip install openai chromadb
pip install bs4
pip install python-dotenv
pip install tiktoken
pip install streamlit

다 install 하셨다면 이제 본격적으로 코드로 들어갈게요! 이번 프로젝트는 코드가 50줄밖에 안됩니다 ㅎㅎ

예전 프로젝트들과 마찬가지로 저희는 OpenAI의 API key를 써야하기 때문에 만든 폴더 내에서 .env라는 파일을 만들어주세요.

그러고 .env 파일 내에 API key를 저장해주세요. 아래 이미지와 같은 형태로.

Screenshot 2023-09-12 at 8.02.04 PM.png폴더 내에 새로운 코드 파일을 만들어주세요. 저는 파일 이름을 summarizer.py 라고 이름 지었습니다. 다음 필요한 library 모듈들을 불러옵니다.

import dotenv
dotenv.load_dotenv()
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import Chroma
from langchain.document_loaders import WebBaseLoader
from langchain.chains import RetrievalQA
from langchain.chat_models import ChatOpenAI
from langchain.prompts import PromptTemplate
import streamlit as st

그 다음 저희는 streamlit이라는 python 코드를 바로 프론트엔드 UI로 만들어주는 패키지를 쓸겁니다. 위에서 맨 마지막 줄에 import streamlit as st 보이시죠? 저희는 앞으로 코드에 st를 쓸때마다 streamlit 패키지를 쓴다고 이해하시면 됩니다.

st.title("Chain Reporter")

def get_text():
    input_text = st.text_input("Type in the governance proposal below", key="input")
    return input_text 

user_input = get_text()
  • 첫번째 코드 줄, st.title("Chain Reporter")은 웹사이트 제목이 됩니다.

  • 그 다음 def get_text() 함수는 유저가 웹사이트 링크를 텍스트 박스에 넣었을때 불러와서 input_text라는 변수에 저장하는 것입니다.

  • user_input = get_text() 에서는 get_text()라는 함수를 콜해서 그 결과값인 url 링크를 user_input이라는 곳에 저장하는 겁니다.

이렇게 하고 나서 터미널에 가상환경을 실행시켰다면 streamlit run summarizer.py 를 돌리면 새로운 웹사이트가 아래 이미지처럼 뜹니다.

Screenshot 2023-09-12 at 7.43.18 PM.png다음 유저가 준 url 링크에 있는 웹사이트 내용을 백터스토어에 저장한 다음 그 내용을 정리해주는 llm 체인을 만들겁니다.

if(user_input):
    loader = WebBaseLoader(user_input)
    data = loader.load()

    text_splitter = RecursiveCharacterTextSplitter(chunk_size = 500, chunk_overlap = 0)
    all_splits = text_splitter.split_documents(data)

    vectorstore = Chroma.from_documents(documents=all_splits, embedding=OpenAIEmbeddings())

    question = "Summarize the main points of this proposal"
    docs = vectorstore.similarity_search(question)
    len(docs)

    template = """Use the following pieces of context to answer the question at the end. 
    If you don't know the answer, just say that you don't know, don't try to make up an answer. 
    Use three sentences maximum. Return the result as a list. 
    {context}
    Question: {question}
    Helpful Answer:"""
    QA_CHAIN_PROMPT = PromptTemplate.from_template(template)

    llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0)
    qa_chain = RetrievalQA.from_chain_type(
        llm,
        retriever=vectorstore.as_retriever(),
        chain_type_kwargs={"prompt": QA_CHAIN_PROMPT}
    )
  • 맨 처음 if(user_input)은 유저 인풋이 있어야만 llm이 실행된다는 것입니다.

  • 다음 loader = WebBaseLoader(user_input)은 유저가 준 링크의 내용을 스크레이프해서 loader라는 값에 저장하고,

  • data = loader.load()는 loader에 저장돼있는 내용을 로딩해서 data 값에 저장하는 것입니다.

  • 다음줄에서는 내용이 많은 경우 split을 해주는 것입니다. split을 한다음 vectorstore이라는 값에 저장을 해줍니다.

  • 그 다음 question 변수에는 "이 정책의 핵심 내용들을 정리해줘"라는 명령을 저장합니다.

  • 그럼 docs에서는 질문의 요지에 맞게 답을 찾기 위해 아까 백터스토어에 저장한 내용 내에서 similarity search를 합니다.

  • 이제 LLM을 만들 차례입니다. template에서는 "컨텍스트에 맞게 질문에 대한 알맞는 답을 알려줘. 만약 답을 모른다면 모른다고 말하고 본 내용과 관련없는 새로운 이상한 결과물을 출력하지 마."라고 써있습니다.

  • 이 템플릿을 이제 QA_CHAIN_PROMPT에 넣어주고, 다음 줄에서는 ChatOpenAI 기반의 llm을 만들어줍니다. 저희는 gpt-3.5을 썼습니다.

  • 마지막으로 qa_chain에서는 RetrievalQA이라는 질의응답이 가능한 형태의 llm을 써서 아까 만든 템플릿을 저장한 QA_CHAIN_PROMPT을 넣어줍니다.

이제 이 function을 실제 웹사이트에서 쓸 수 있도록 해줍니다!

if(user_input):
    result = qa_chain({"query": question})
    result["result"]

이렇게 한다음, 아까 뜬 웹사이트에서 텍스트 박스에 url 링크를 입력하고 엔터키를 누르면 llm체인이 돌아가기 시작하고, 몇 초 후에는 내용을 요약한 결과값이 나옵니다.

Screenshot 2023-09-12 at 7.58.38 PM.png이런식으로 블록체인 정책 뿐만 아니라 template의 내용을 바꿔가면서 논문 요약 정리를 해주는 에이전트를 만들 수도 있고, 빠르게 마케팅 홍보 트윗도 생성해주는 에이전트도 만들 수 있습니다.

이렇게 만들고 발표까지 야심차게 하고 놀았습니다. ㅋㅋㅋㅋ

KakaoTalk_Photo_2023-09-12-20-15-56.jpeg풀 투토리얼 동영상은 유투브에서 확인하실 수 있습니다! (영어 주의) https://youtu.be/MeRXRDQU-2A?si=O6fpZiTwmhF44zui

전체 코드 이미지입니다.

Screenshot 2023-09-12 at 8.03.55 PM.png오늘도 긴글 읽어주셔서 감사합니다! 혹시 질문이 있거나 코드가 안된다면 답글로 남겨주세요. 최대한 도와드리겠습니다 :)

20
13
Cailyn Yong

Cailyn Yong

Why AI might not save the world

이번주 동안 여러 블록체인 이벤트들이 열리며 오랜만에 만난 업계 쪽 친구와 함께 인공지능의 미래와 방향에 대해 새벽에 두시간 가량의 열띤 토론을 나눴습니다.

제 친구는 꽤 오랫동안 블록체인 업계에서 개발자로 있던 분이었고, 저는 작년에 친구를 KBW 주간때 만나 계속 인연을 유지하다가 지금은 제가 AI 쪽으로 넘어온 상태가 됐습니다.

이번주 동안 만난 친구들은 다 블록체인 쪽에 있어서 제가 AI로 갔다고 했을때 AI가 블록체인보다 어떤 점에서 가능성이 더 많은지, 실제로 세상을 혁신적으로 바꿀 수 있는 기술인지에 대해 많은 대화를 나눴습니다.

저희가 나눴던 주제들은 대략 이렇습니다.

  • AI를 통해 금전적인 이익을 얻고자 하는 사람들 vs 보수적인 관점으로 바라보며 조심스럽게 대하는 사람들

  • AI에 의한 미래는 더 나은 세상이 된다 vs 오히려 세상을 더 쉽게 망칠 수 있을 것이다

  • AI는 10년 안에 대부분의 일자리를 대체할 것인지 vs 오히려 더 많은 기회가 생겨날 것인지

  • AI에 의해 나쁜 의도를 가진 사람들은 더욱 더 쉽게 목적을 달성할 것이다

Bootleggers와 Baptists는 a16z의 Marc Andreessen이 정의한 개념들입니다. 어떠한 사회적 변화가 나타났을때 그 기회를 통해 금전적인 이익을 좇는 사람들을 Bootlegger라고 하며, 반대로 이런 급격한 변화 때문에 컨트롤 할 수 없는 상황들을 대비하기 위해 법적 규제와 통제가 필요하다고 주장하는 사람들을 Baptists라고 합니다.

저는 AI를 활용한 스타트업을 창업한 사람으로써 Bootlegger의 관점을 갖고 있는 반면 제 친구는 조금 더 conservative(보수적인) 관점을 갖고 있었습니다.

저는 영상 크리에이터들을 위한 GenAI 스타트업을 하면서 모두가 컨텐츠를 쉽게 생산할 수 있는 인프라를 만들고자 했는데요, 제가 생각했던 미래의 모습은

  1. 인공지능이 대부분의 일자리를 대체할 것이며,

  2. 사람들은 인생의 의미를 찾기 위해 컨텐츠를 만들 것이고,

  3. 모두가 컨텐츠 크리에이터가 될 것이기에 우리는 이 욕구를 위한 대비를 해야한다 였습니다.

이런 얘기를 전달했을때 친구는

  1. 인공지능은 대부분의 일자리를 대체하지 않을 것이고, 오히려 일의 능률이 올라감에 따라 더 많은 공급 발생 -> 제품/서비스 가격 낮아짐 -> 소비자 수요 올라감 -> 더 많은 일자리/기회가 창출될 것이며,

  2. 사람들은 인생의 의미를 찾기 위해 남에게 관심 받기 위해 만드는 컨텐츠보다는 공감 받기 위해 만드는 컨텐츠가 많을 것이고,

  3. 그렇기에 모두가 단순히 현재 인플루언서와 같은 형태의 크리에이터가 되진 않을 것이다

라고 답변했습니다.

현재 AI 업계에서는 이런 컨텐츠들을 더 빨리, 더 많이 자동화시켜서 만들 수 있게 하는 서비스들이 많습니다. 유투브 릴스/쇼츠 자동화, 편집 자동화 AI 뿐만 아니라 AI로 얼굴 사진을 보정해주는 앱, AI 프로필 등 되게 다양한 제품들이 있는데, 컨텐츠의 공급이 급격히 늘어날수록 과연 사회의 어떤 면에서 어떻게 이바지하는가에 대해 자연스럽게 대화가 흘러가게 됐습니다.

컨텐츠의 공급이 더 많아진다면 이런 인프라를 빌딩한 Bootleggers들이 돈을 더 많이 버는 상황이 되겠지만, 사실상 이런 미래가 오게 된다면 모두가 더더욱 SNS에 중독된 상태로 절대 빠져나갈 수 없는 무한 쇼츠/릴스 루프를 돌며 점점 현실에서부터 멀어지는 현상을 겪게 될 것 같습니다. 현실보다는 가상세계에 중독되며, 일론 머스크가 말했던 것처럼 핸드폰과 내 자신을 떼어낼 수 없는 완전한 사이보그가 되겠죠.

인터넷이 처음 공급되면서 사실은 저희가 생각했던 것만큼 일의 능률과 효율이 급격하게 올라가진 않았습니다. 마찬가지로 AI에 의해 더 많은 업무들이 자동화되고 모두가 자신만의 AI Personal Assistant가 있게 된다면 사회 전반적으로 어느정도 productivity가 올라가겠지만, 그와 마찬가지로 - 오히려 더 크고 빠른 속도로 - SNS와 가상세계에 대한 중독성이 강해질 것입니다.

그래서 저는 미래에 대해 그렇게 희망적이진 않은 것 같습니다. 그렇기에 더더욱 이런 신기술을 활용해서 이익을 취하고자 하는 사람으로써 새로운 서비스/제품을 만들고자 할때 매번 제 자신에게 질문을 던집니다. "내가 지금 만들고 있는게 사회에 이로운 것인가? 이걸 하는게 도덕적으로 맞는건가?" 어떤 면으로라도 조금 더 이로운 방향으로 이바지할 수 있다면 만들 것 같습니다.

하지만 이미 주변에서는 급격한 속도로 새로운 제품들이 매일 나오고 있고, 개인, 스타트업, 기업 차원에서 뿐만 아니라 정부, 국가 전체 차원에서도 AI를 활용한 제품들을 계속 만들며 강화시키고 있습니다. 중국과 같은 경우에는 완변한 통제를 위한 용도로 AI를 쓰고 있습니다.

Marc Andreessen은 이에 맞서 "We should seek to win the race to global AI technological superiority and ensure that China does not." 라고 했지만, 사실상 우리가 지금 너무나도 쉽게 간과하고 있을 수 있는 점은 AI 기술이 발전됨에 따라 중국에서 뿐만 아니라 전세계적으로 우리의 모든 personal 데이터가 AI 모델들에 학습되고 있다는 것입니다. 인스타그램 계정이 공개 계정이라면 이미 대부분의 AI 기업에서는 당신의 사생활 데이터를 모두 수집해서 "개인화"라는 명분으로 모델들을 빌딩하고 있을 것입니다.

기업들은 이런 '개인화'를 통해 컨텐츠 추천 알고리즘, 광고 알고리즘 등을 만들고 있습니다. 소비자의 입장에서는 나에게만 맞춘 슈퍼컴퓨터 혹은 인공지능 비서가 생긴다면 너무 편리하겠지만 우리가 던져야할 질문은 "at what cost?"입니다. 우리도 모르게 점점 이런 알고리즘에 빠져들어 헤어나올 수 없는 지경이 되고 있으며, 더 많은 반응.좋아요.댓글.공유를 할 수록 나의 데이터를 더 수집해가면서 옭아매고 있습니다. 이런 미래에서는 나도 모르게 무의식적으로 컨트롤 당하게 되는 경우가 많아질 것 같아 더 두렵습니다.

그래서 정말 웃기기도 하고 멋있다고 든 생각이지만, 제 친구는 이런 authoritarian, totalitarian, centralized된 미래가 만일 올거에 대비하기 위해 더더욱 블록체인을 하고 있다고 했습니다. 누구도 미래를 예측할 수는 없지만, 이런 신기술이 왔을때에는 최대한 어떻게 도덕적으로 접근해야하는지, 나에게 어떤 영향을 끼치게 될건지, 내가 무언가를 만든다면 사회에 어떤 영향을 끼칠건지에 대해 1시간이라도 진지하게 고민하는 시간이 필요하다고 생각합니다.

제가 제 친구와 함께 토론했던 내용들을 Marc Andreessen이 "Why AI WIll Save the World"라는 글에서 대부분 짚고 넘어간 것 같아 글을 공유합니다.

36
17
Cailyn Yong

Cailyn Yong

추석 전 갓생살기 챌린지 (생산성 툴 평생 할인쿠폰 포함)

w_10x_club.png안녕하세요, 여러분!

한달 전쯤 10X 자기개발 Club을 처음 오픈하고 난 뒤 많은 분들께서 클럽을 조인해주셨습니다.

클럽의 취지는 내가 달성하고자 하는 인생 목표들을 10배의 법칙으로 이루기 위해 매일매일 1) 인생 목표들을 적었는지, 2) 오늘 목표들을 달성하기 위해 어떤 일을 했는지, 3) 내일은 어떤 일을 할건지 클럽 멤버분들과 공유했습니다.

KakaoTalk_Photo_2023-09-07-09-58-51 002.jpegKakaoTalk_Photo_2023-09-07-09-58-50 001.jpeg저는 시작할 당시에 적었던 목표들이 10개정도 됐었는데 그중에서 2개 정도가 벌써 달성이 됐더라구요. 그 중 하나가 “매일 새로운 사람들 만나기”였는데 적는대로 실제로 되다보니까 순간 무섭게 느껴졌습니다. 조금 쉬면서 만나고 싶어도 매일매일 새로운 분들을 계속 만나게 돼서.. ㅋㅋㅋㅋㅋ

한달이 지난 후, 클럽에서 10X 자기개발 생산성 챌린지를 개최하고자 합니다!

10X 자기개발 챌린지

활동 기간: 자유롭게 참여 ~ 09.27(수)

🏆 챌린지 소개

  • 10X 자기개발 챌린지는 언제든지 시작해서 9월 27일까지 평일동안 자신의 목표 달성여부를 카톡방에 올려 인증하는 챌린지 입니다.

  • 올리는 내용은 정해져 있지 않습니다. 삶의 목표를 정한 후, 그 목표들을 실천하기 위해 오늘 하루 무엇을 했는지, 내일은 무엇을 할건지 매일 기록해서 올리는 단톡방입니다.

  • 자기소개도 없이 그냥 매일 메모장처럼 편하게 바로 올려주세요!

🏁 완주 기준

  • 완주에 대한 기준은 없습니다. 메모장 처럼 편하게 매일 인증해주세요.

  • (선택) 참여 기간 중 1회 정도 메이커로그 작성을 통해 생산성이 얼마나 올라갔는지, 본래 목표로 한 바를 얼마나 달성할 수 있었는지 남겨주세요.

🎈 참여 조건

  • 디스콰이엇 프로필(이력, 스킬, 관심 토픽)을 성실하게 채워주신 후, 댓글을 남겨드린 분들께 커피챗으로 운영 중인 카톡방 비밀번호와 참여 방법을 안내 드립니다.

  • 꼭 Akiflow를 활용하지 않으셔도 됩니다, 편하신 생산성 툴을 활용하여 참여해주세요.

🎁 보상 안내

  • 챌린지 참여만으로도 생산성 관리 툴 Akiflow 평생 할인 30% 쿠폰을 드립니다. Akiflow에 대한 자세한 글을 아래 도언님의 메이커로그를 참고해주세요.

  • 챌린지 시작 전에 정민교님의 Akiflow 온보딩 세션에 참여할 수 있습니다.

    • 기본적인 Akiflow 사용법

    • Akiflow로 Ritual을 잡기 위한 팁 (from Steve & William)

  • Akiflow는 Task + Time Blocking UX 매우 편한 생산성 Tool 입니다.

10X 자기개발 Club

자기개발 클럽 단톡방

18
52
Cailyn Yong

Cailyn Yong

팀러너스, 스캐터랩, 라이너AI, 뤼튼에게 배운 것

이번 AGI Town 6회차 밋업을 가지며 어떤 인사이트들을 얻었는지 공유합니다.

이번 이벤트에서는 디어젠, Upstage, 팀러너스, 하이퍼커넥트, 라이너 AI, 스캐터랩, 뤼튼 엔지니어분들과 CEO가 오셔서 세션들을 진행했습니다.

이벤트 참가 전 제가 머릿속에서 가장 크게 갖고 있던 질문들은 :

  • 이 팀들은 뭐가 다를까?

  • 어떤 가설들을 세우며 어떤 BM들을 갖고 있는가?

  • AI-native 프로덕트 방향으로 가고 있는가?

  • Sustainability와 profitability를 어떻게 동시에 유지하지? 남는게 있을까?

이벤트 동안에 가장 공통적으로 나왔던 질문들은 :

  • GenAI 제품/서비스들은 어떻게 유저 리텐션을 높이는지?

  • Monetization을 어떻게 했고, 비즈니스 모델은 어떤 것들이 잘 됐는지?

  • 할루시네이션 결과물들을 어떻게 활용하는지? 자신의 제품/서비스에게 득인가 독인가

스캐터랩의 루다 (AI-native, B2C)

루다: Character AI

Problem statement:

  • 기본적으로 캐릭터 AI 뿐만 아니라 LLM 기술에 의존하는 어떠한 서비스도 상용화 시키기 위해서는 거짓된/틀린 정보(할루시네이션)가 결과물로 발생되면 안됨. 고객사가 원하는게 확실하고 캐릭터 챗봇이 답변해야하는 것도 확실해야하는데 LLM의 기술은 불확실해서 발생할 수 있는 문제들이 존재함.

  • 사람들은 캐릭터 AI와 대화를 할때 정말 인간과 대화하는 것 같은 느낌을 원하고 실제로 사람과 관계를 형성하는 것처럼 하는 것을 원함.

Solution:

  • BM: 루다 내에서 "선물하기" 기능. 루다 팀에서 "크레파스," "원피스"와 같은 디지털 자산을 만들면 유저가 이걸 사서 직접 루다에게 선물해줄 수 있음. 선물해주면 루다는 자기가 받은 선물을 기억하고 나중에 선물받은 원피스를 입은 사진으로 프로필이 바뀌는 형태가 됨. 친밀도가 올라감. (실제 사람과 관계 형성하는 것처럼)

  • Use cases: 의료 업계에서 심리상담 캐릭터 봇 -> 환자가 어떤 고민들을 갖고 있는지 이해하고 각 고민별로 해결하는 방식

  • 오히려 LLM의 결과물이 모호해도 괜찮은 영역을 타겟하고 있음. 결과물이 세팅되어 있지 않을수록, 유니크한 답변들이 나올수록 루다의 재미/가치가 올라가는 사업 모델을 구상함. 그래서 오히려 할루시네이션이 득이 되는 경우가 됨.

  • AI 기술을 중심축으로 활용하는 새로운 패러다임이 발생할 것이라고 믿음.

  • B2C로 가장 잘 monetization하는 곳이라고 생각함.

라이너 AI (AI-augmented & AI-native, B2C)

라이너: AI summarization, new type of Google search

Problem statement:

  • 기존에는 생산성 업무들을 위한 툴을 만듦 -> 하이라이터 자료 아카이빙. 그래서 생성AI를 원래 서비스에 입힐때 기존의 유저들과 맞서야하는 문제가 발생함. 코어가 중요한가 새로운 미션이 중요한가? 결정해야 했음.

  • 할루시네이션은 기회보다는 독에 더 가까움. 예를 들어 홍길동전에 대해 검색을 하면 홍길동 보다는 삼국지의 주요 인물들에 대해 설명을 하는 경우가 있음. 이건 본문에 삼국지에 대해 먼저 설명을 하다가 홍길동전에 대한 이야기가 함께 섞여 있어서 할루시네이션이 발생한 것. 그렇다면 본문에서 주요 내용만 뽑아내는 기술이 중요하고, 2000토큰을 사용하며 모든 본문을 읽어볼수는 없으니 더 효율적인 방식으로 summarization을 해야함.

Solution:

  • ChatGPT 이후에 사람들이 구글 서치는 죽었다고 생각함. 구글 서치를 disrupt하긴 했지만 사람들이 컨텐츠를 소비하고자 하는 욕구는 여전히 존재함. 그렇다면 어떤 미디엄으로 사람들이 유입될지 언정 컨텐츠를 소비하고자 하는 사람들을 위해서는 더 좋은 UX 플랫폼을 제공해줄 수 있음.

  • Structured retrieval: 본문 활용을 위한 기술 연구를 계속 하고 있음. 

뤼튼 (AI-native, B2C/B2B)

뤼튼: 업무 자동화 생성 툴

Problem statement:

  • 다른 생산성 툴 (ChatGPT, )을 사용했던 유저들은 뤼튼을 쓸 때 적응하기 쉽지만 일반적인 사용자들은 생성된 결과물에 할루시네이션이 발생하면 데이터가 유출됐다고 생각하거나 모델에 잘못이 있다고 생각함.

  • 생성해준다는걸 이해 못하고 기존에 뤼튼이 갖고 있는 데이터베이스 내에서 답변을 검색 한다고 생각함. 그래서 서비스를 잘 사용하도록 배우게 하는게 은근 어렵다는걸 느낌.

  • 서비스들이 여전히 일반인들에겐 불친절.

  • 할루시네이션 탐지 보다는 유저가 대화를 언제 이탈하는지 집중적으로 보고 있음.

  • 사람보다 인공지능의 결과물을 믿는 경우가 발생함.

팀러너스 (AI-native, B2C)

팀러너스: B2C를 위한 AI 컨텐츠 플랫폼

Problem statement:

  • 소비자는 기업이 어떤 기술을 쓰는데에 관심 갖지 않는다. "AI"를 쓴다고 해서 돈을 더 지불하는 것도 아니고, 소비자는 오로지 더 편하고 싸고 재미있는걸 찾을 뿐. 그래서 AI인지 아닌지가 중요하지 않은 일상의 가치를 제공하는 제품을 만들고자 함.

  • 여태까지 만든 모든 제품들 중 대부분은 성인 서비스로 바뀜.

  • AI 프로필 스튜디오와 같은 제품들은 리텐션이 매우 낮음.

  • 모바일 앱보다 AI 앱을 만드는게 천배 어려움. 왜냐면 생성된 결과물에 대한 정답이 없기 때문. 사람마다 원하는 결과물이 다르고, 얼마나 잘 만들어진 사진인지에 대해 정답이 없음. 어떤 유저는 자신과 닮은 사진을 원하고 어떤 유저는 안 닮더라도 예쁘게 나온걸 좋아함.

  • GPU가 너무 비쌈! 그래서 수익성을 내기가 쉽지 않음. 유저에게 돈을 받을 수 밖에 없는 구조가 발생.

Solution:

  • 리텐션이 낮아서 한번 돈을 지불하고 쓰는 서비스 모델보다 "오늘의 무료 사진"이라는 서비스로 매일 새로운 컨셉/필터 사진을 무료로 써볼 수 있는 제품을 만듦.

  • 유저에게 돈 받기 vs 시간 받기: 유저의 체류 시간을 늘리는걸 목표로 잡음. 이 목표를 달성하기 위해 고객 단톡방에서 힌트를 얻을 수 있었음. 고객들은 자신이 겪은 문제보다는 자신의 사진에 대해 얘기하고 싶었고, 다음은 어떤 컨셉/필터를 원하는지, 누가 새로운 컨셉의 필터로 사진을 만들면 '나도 해보고 싶다' 이런식의 대화가 자꾸 나옴. -> 나온 프로덕트: 자기가 원하는 매거진 컨셉 올리면 그 컨셉에 맞게 새로운 사진 생성. 이를 통해 팔로워를 모아서 인플루언서가 될 수 있음.

  • 오히려 유저들은 새로운 필터를 살때마다 "지불"보다는 팔로워와 인기를 얻기 위한 "투자"라고 생각하게 됨. 인기를 얻고 싶은 소수의 열성 유저들이 비용을 지불해서 건전한 손익구조를 만들 수 있었음.

  • 팀러너스는 PMF 찾기전에는 세계 최고의 AI 제품팀을 만들려고 함. 목적 조직. 모두가 하나의 스쿼드로 움직이는게 더 빠름.

19
5
Cailyn Yong

Cailyn Yong

[HRZ Ventures 허진호 VC] GPT wrapper 말고 10년 후의 미래를 생각해야한다

HRZ Ventures의 허진호 대표님과 오늘 커피챗을 하며 제가 그동안 고민하고 있던 질문들에 대한 답을 얻어내고 너무 값진 인사이트들을 배운 것 같아 여러분과 공유합니다.

저의 전 글에서 어떤 고민들을 갖고 있었는지 확인할 수 있습니다:

가장 큰 질문들은

  1. 누구나 따라할 수 있게끔 모든 코드가 오픈소스 되어있다면 내 스타트업 제품은 단순히 GPT wrapper가 되는거 아닌가? Foundation model들에게 의존하고 있는거라면 기술적 우위가 없는거 아닌가?

  2. 내가 현재 만들고 있는 프로젝트를 api를 제공해주는 OpenAI, 뤼튼 같은 곳들 혹은 Runway, Stable Diffusion, Zapier 같은 곳들이 똑같이 만든다면 살아남을 수 있을까?

결론부터 말하자면, 스타트업은 기술적 우위를 가질 수 없습니다. 애초에 기술적 우위를 갖는다는게 포인트가 아닙니다.

현재 단계에서 스타트업은 다른 거대 B2B SaaS 기업이 이미 구축하고 있는 고객과 인프라의 moat를 이길 수가 없습니다. 업무자동화 툴, 혹은 챗봇을 만들었다 하더라도 이미 훨씬 앞서나가고 있는 기업이 이런 툴들을 만들고 배포한다면 게임 끝입니다.

하지만 제가 앞서 전 포스트에서도 말했듯이, "api를 제공해주는 곳, 혹은 큰 기업들은 거시적인 관점에서 사업 개발을 한다는 것, 즉 일반인들이 실제로 자신의 업무 환경에 쓸만한 툴들은 직접 만들어주지 않는 다는 점" 때문에 현 시점에서는 당장의 수익을 볼 수 있을 것입니다.

모든 기업들은 2-3년 안에 기업의 이익과 효율성을 위해 "비즈니스의 AI화," 즉 자동화 AI 툴들을 무조건적으로 도입할 것입니다. 이를 위한 AI 컨설팅, 노코드 툴, 앱/서비스 구축을 해주는 곳들도 이미 폭발적으로 늘어나고 있죠.

그렇다면 스타트업은 여기서 그치지 않고 이 2-3년 윈도우 내에서 살아남을 방법을 찾아야합니다.

이런 툴들을 만들어주는 에이전시가 되는걸로 끝날 것이냐, 아님 이를 통해 자신만의 moat를 쌓고 롱텀으로 바라보며 next Google, Amazon, Apple이 될것이냐 선택해야 합니다.

그렇다면 결국 누가 살아남을 것인가? 방법은 다양합니다.

  1. 가장 기본적으로 인프라와 api를 제공해주는 곳들: OpenAI, Langchain, Hugging Face, Pinecone, Stability, Cohere

  2. 기존에 자신의 서비스에 AI를 입히는 곳: Adobe Premiere Pro, VSCode Copilot, etc.

  3. AI-native: AI를 통해 생겨난 완전히 새로운 서비스와 비즈니스 모델

허진호 VC가 가장 집중적으로 바라보고 있는 곳은 AI-native 스타트업들입니다.

허진호 VC에 대한 소개를 간략히 하자면, 이 분은 94년에 최초의 인터넷접속서비스사업자인 아이네트 설립하며 한국 인터넷 대중화에 앞장서서 기여한 분입니다.

90년대에 닷컴버블이 일어나면서 Yahoo!부터 Hotmail, Amazon, Netscape, Ebay와 같은 곳들이 엄청나게 생겨나기 시작했습니다.

인터넷이 1995-6년 처음 만들어지고 배포되면서 Google, Naver와 같은 곳들은 2000년 전후반으로 나타나다가, 10년이 지난 후 Facebook, Youtube, Netflix, Shopify가 생기며 웹 기술을 활용한 최고의 아웃풋들이 나타난거죠.

모바일이 2008년 처음 나오고 나서 10년 후에는 어떤 곳들이 나왔을까요? 한국에서는 카카오톡, 토스, 쿠팡, 당근과 같은 곳들이 발생하기 시작합니다.

현재 AI 기술은 정확히 처음 인터넷/웹이 생겼을때, 처음 모바일이 나왔을때와 같습니다.

그렇기에 지금은 GPT wrapper와 같은 앱들은 당연히 생겨날 수 밖에 없습니다.

하지만 99%는 죽을거고, 살아남기 위해서는 툴로 고객을 유입한 다음 그걸 통해서 네트워크, 커뮤니티를 만들어서 자신만의 moat를 키우는 것입니다.

그렇기 때문에 저희는 10년 후에 AI에 의해 우리의 삶이 어떻게 변화될건지 항상 생각해야합니다.

AI-native 스타트업은 AI 덕분에 가능해진 완전히 새로운 유형의 제품/서비스를 뜻합니다.

Google이 웹이 생겨난 이후 광고주들이 키워드를 구매하면 광고가 게재되도록 하는 비즈니스 모델을 누가 예상할 수 있었을까요?

즉 AI 기술에 의해 앞으로 10년 내에는 이렇게 우리가 지금 단계에서는 상상할수도 없는 제품/서비스들이 너무 당연하게 자리잡고 있을 것이고, 이런 방향으로 계속 실험하며 나아가는 곳들이 살아남을 것 같습니다.

아예 처음부터 나에게 personalized된 컴퓨터가 나올수도 있고, 내 핸드폰에는 나를 위해 어떤 업무도 다 해결해줄 수 있는 fully autonomous siri가 나올수도 있습니다.

기존에 불가능했던 사업 모델들을 새로운 기술 덕분에 어떻게 바뀌게 되었는지 그런 흐름을 따라가야합니다.

예를 들어, 기존에는 우리가 누군가와 함께 차를 탄다는 상상도 못했었지만 우버가 태어났고, 우리는 우리가 알지도 못하는 누군가의 집에서 숙박한다는 것을 상상하지 못했지만 에어비앤비가 나타났습니다. 지금은 온라인상에서 우리가 잘 알지도 못하는 크리에이터에게 별풍선을 쏴주며 수익을 내주고 있죠.

AI 시대에서는 정말 상상하지도 못한 변화들이 일어날 것 같습니다.

스타트업은 그렇기에 최대한 계속 제품/서비스들을 만들어보고, 시장과 부딪히며 실패해보고 배워나가야 합니다.

뭐라도 해야합니다.

뭐라도 하면 다음 단계로 갈 수 있을 것입니다.

허진호 VC의 Two Cents 웹사이트를 공유합니다. 꼭 다들 읽어보세요! 정말 많이 배울 수 있습니다 :

29
9
Cailyn Yong

Cailyn Yong

스타트업이 AI 산업에서 살아남는 법

Screenshot 2023-08-26 at 10.14.07 PM.png

최근 들어 가장 많이 고민하는 점들에 대해 적고자 합니다.

4월부터 여러 랭체인/AI 사이드프로젝트들을 하면서 들었던 생각들입니다.

  1. 개발자라면 누구나 손쉽게 리소스 documentation을 읽고 오픈소스된 모델/코드로 이런 프로젝트들을 만들 수 있는데, 내 프로젝트는 이 상황에서 어떻게 기술적 우위를 가질 수 있을것인가?

  2. 누구나 만들 수 있고 차별성이 없다면 실제로 수익을 내고 있는 프로젝트들은 몇개나 되는가? 이때까지만 해도 찾지 못했고, 그저 유저에게 좋고 재밌는 앱들 위주로 나옴. 하지만 일회성 아이디어들이 대부분이었고 돈을 지불하면서까지 쓸만한 아이디어는 없었다. 현재 수익을 내고 있는 곳들은 큰 foundation model들을 갖고 있는 애들, 혹은 api를 제공해주는 곳들임.

  3. 내가 현재 만들고 있는 프로젝트를 api를 제공해주는 OpenAI, 뤼튼 같은 곳들 혹은 Runway, Stable Diffusion, Zapier 같은 곳들이 똑같이 만든다면 살아남을 수 있을까?

따라서 스타트업의 입장에서는 어떤 방식으로 접근해야할지 생각을 해봐야 합니다.

현재 단계에서 가장 큰 기회는 사람들이 이런 방대한 양의 리소스가 있음에도 불구하고 배울 시간이 나지 않아서, 진입장벽이 높다 생각해서, 아님 그만큼 이런 정보에 노출되지 않아서 막상 많이 쓰지 않는다는 것입니다.

두번째 기회는 api를 제공해주는 곳, 혹은 큰 기업들은 거시적인 관점에서 사업 개발을 한다는 것, 즉 일반인들이 실제로 자신의 업무 환경에 쓸만한 툴들은 직접 만들어주지 않는 다는 것입니다.

그렇다면 10X AI Club을 왜 개설하게 됐는지에 대해 얘기를 하자면,

정보의 격차가 존재하지 않음에도 불구하고, 몇 시간만 투자하면 자신의 삶을 훨씬 효율적으로 살아갈 수 있도록 바꿀 수 있음에도 불구하고 시간이 나지 않아서, 혹은 새로운 것을 배우는 것에 대해 선뜻 나서지지 않는 분들 위해 만들었습니다.

몇년 안에 인공지능은 저희 삶 속에 알게 모르게 엄청나게 스며들 것입니다.

저는 이런 미래에 대비하고자 꾸준히 배우고 있고, 더 많은 사람들이 알았으면 하는 바람이 큽니다.

정말로 모두가 AI에 대해 제대로 알고, 자신이 직접 어떻게 활용할 수 있는지 알아갈 수 있었으면 좋겠습니다.

얼른 컨텐츠 더 만들러 총총...

18
3
Cailyn Yong

Cailyn Yong

Fountain: GPT4를 활용한 실리콘밸리 고용 플랫폼

안녕하세요, 10X AI Club Cailyn입니다.

오늘은 B2B SaaS를 제공하고 있는 기업 중에서 AI를 활용하고 있는 Fountain이라는 기업을 소개합니다.

최근에 Fountain이라는 곳을 EO 영상으로도 접하게 되고 Keith Ryu 대표님의 창업 스토리를 알아가면서 요즘 기업들에서는 어떻게, 어떤 AI tool들을 쓰고 있는지 궁금해서 더 알아봤습니다.

Fountain에 대해서 먼저 간략히 소개를 하자면, 시간제로 일하는 분들을 위한 고용 플랫폼입니다. 개발자, 디자이너 프리랜서보다는 물류 센터, retail 산업에서 종사하고 있는 시간제 생산직을 빠르게 채용해야 하는 Uber 같은 곳들이 사용하는 SaaS인거죠.

Keith가 찾은 PMF은 이런 생산직군을 필요로 하는 곳들에서 사람은 빨리, 더 많이 채용해야하는데 그 채용 과정이 너무 오래 걸린다는 점이었습니다.

이 PMF를 통해 지금은 Series C, 총 $218.9M 투자를 받았습니다.

Fountain AI

그렇다면 지금 Fountain은 AI tool들을 어떻게 활용하고 있을까요?

Fountain에서는 Fountain AI라는 툴을 공개했는데, GPT4를 활용한 conversational AI입니다.

이런 채용 과정을 더더욱 빠르고 효율적으로 개선하고자 챗봇을 만들었는데요, HR 사람 없이도 채용하고자 하는 기업의 정보들을 학습시킨 다음 GPT4가 스스로 유저의 질문에 대답할 수 있도록 만들었습니다.

Screenshot 2023-08-24 at 7.30.50 PM.pngGPT4와 LLM을 써서 만들었다면 당연히 지원자 맞춤 personalization도 가능하겠죠?

Screenshot 2023-08-24 at 7.31.08 PM.png조금 더 파인튜닝하기 위해 LLM에게 기존의 지원자 정보나 평상시에 가장 많이 물어봤던 질문들에 대한 데이터를 학습시켰다면 더더욱 Fountain의 취지에 맞는 대화형 AI 챗봇을 만들 수 있었을겁니다.

Screenshot 2023-08-24 at 7.34.58 PM.png사실 창업을 할때 처음 랜딩페이지를 만들고나서 가장 중요한건 실제로 랜딩페이지를 방문한 유저들과 바로바로 소통을 하며 rentention rate를 높이는 것이라고 생각합니다.

저도 창업을 하면서 뼈저리게 느꼈던 건 한번 그 과정에서 잠재고객을 잃으면 영원히 잃는거라고 생각을 했고, 이걸 방지하고자 랜딩페이지에 챗봇을 올렸던 적이 있습니다.

저는 바로 고객과 소통을 하고 싶은데, 제가 로봇이 아닌 이상 24시간 내내 지켜보면서 답장을 하기엔 불가능이라고 생각을 했죠.

이런 과정을 자동화하고자 저는 미리 챗봇 템플릿에 고객들이 물어볼만한 질문들을 몇가지 예상한 다음 답변들을 바로 보낼 수 있도록 썼습니다.

하지만 이것또한 일일이 쓰는데에 시간을 많이 잡아먹었고, 내가 예상하지 못한 질문을 유저가 하면 그쪽에서 하염없이 기다리는 방법밖에 없는 일이 발생되기 마련이었습니다.

이걸 해결해주는건 바로 이런 GPT4를 탑재한 챗봇이라고 믿습니다.

실제로 chat api를 제공해주는 샌드버드에서는 역시나 발빠르게 이러한 기능을 제공해주고 있습니다. ChatGPT AI bot으로, 이런 질문/답변 템플렛을 작성하지 않아도 기존에 학습한 데이터를 토대로 GPT가 바로바로 답변을 생성할 수 있도록 하는거죠. https://sendbird.com/products/chatgpt-integration

이 AI 챗봇들을 통해 나오는 활용 사례들과 효과들은

  • 빠르게 랜딩페이지 잠재 고객과 대화하고 rentention rate 높이기

  • 반복적인 온보딩 과정들 자동화하기

로 볼 수 있을 것 같습니다.

그렇다면 내 스타트업을 위한 이런 대화형 AI 챗봇은 실제로 어떻게 만드는 걸까요? 이건 저의 다음 포스트에서 직접 개발 과정들을 공유하며 누구나 만들어 볼 수 있도록 하겠습니다 :)

오늘도 글 읽어주셔서 감사하고 10X AI Club 많은 관심 부탁드리겠습니다. 🙂

17
5
Cailyn Yong

Cailyn Yong

[Part 3] 2시간 안에 업무 자동화 AI Agent 만들기: 구글 검색 기능

AI Agent 만들기의 마지막 파트입니다.

Part 1: 전체 프로그램 셋업, OpenAI API 연결, Vector Store 연결

Part 2: 커스텀 LLM 체인 직접 만들고나서 실행하기

Part 3: Agent가 나 대신 실제 구글 검색하는 기능 만들기

SerpAPI key 받아오기

저번 파트에서 성공적으로 코드를 수행했다면 이제 AI 에이전트가 업무를 하기 위해 먼저 to-do list를 만들고 태스크 중 중요도가 높은 태스크부터 진행할 것입니다.

하지만 실제 구글 검색을 통해서 모은 자료가 아니기 때문에 정보가 정확하지 않고 hallucination 결과값들을 내뱉을 수 있습니다.

이번 파트에서는 이를 방지하고자 Google SerpAPI라는 것을 써서 에이전트가 실제 웹과 연결되어 구글링을 할 수 있도록 할 것입니다.

웹 검색을 하기 위해서는 Part 1에서 OpenAI를 쓰기 위해 OpenAI API secret key를 받은것처럼 SerpAPI key를 받아야합니다.

https://serpapi.com/ 여기로 가서 계정을 만든 다음, 옆에 API Dashboard라는 곳에서 Api key 버튼을 누르고 API key를 만드세요. OpenAI API key와 마찬가지로 이걸 복사해서 코드에 붙여넣을 겁니다.

import os
os.environ["OPENAI_API_KEY"] = " "
os.environ["SERPAPI_API_KEY"] = " "

기존 코드의 두번째 줄 바로 밑에 os.environ[”SERPAPI_API_KEY”] = “” 를 복붙하고 “ “ 사이에 방금 만든 SerpAPI key를 붙여넣으세요.

Part 1에서 나왔듯이 저희는 구글 검색을 가능하게 하려면 알맞는 모듈들을 불러와야합니다.

from collections import deque
from typing import Dict, List, Optional, Any

from langchain import LLMChain, OpenAI, PromptTemplate
from langchain.embeddings import OpenAIEmbeddings
from langchain.llms import BaseLLM
from langchain.vectorstores.base import VectorStore
from pydantic import BaseModel, Field
from langchain.chains.base import Chain

from langchain.vectorstores import FAISS
from langchain.docstore import InMemoryDocstore

기존의 모듈 코드(위 코드) 밑에 아래 코드를 붙여넣습니다.

from langchain.agents import ZeroShotAgent, Tool, AgentExecutor
from langchain import OpenAI, SerpAPIWrapper, LLMChain

이제 구글 검색이 가능한 LLM 체인을 만들겁니다.

Part 2에서 세번째 체인인 class ExecutionChain(LLMChain)은 현재 구글 검색이 불가능합니다. (아래 코드)

class ExecutionChain(LLMChain):
    """Chain to execute tasks."""

    @classmethod
    def from_llm(cls, llm: BaseLLM, verbose: bool = True) -> LLMChain:
        """Get the response parser."""
        execution_template = (
            "You are an AI who performs one task based on the following objective: {objective}."
            " Take into account these previously completed tasks: {context}."
            " Your task: {task}."
            " Response:"
        )
        prompt = PromptTemplate(
            template=execution_template,
            input_variables=["objective", "context", "task"],
        )
        return cls(prompt=prompt, llm=llm, verbose=verbose)

그래서 이 코드를 아래 코드로 대체할 것입니다.

todo_prompt = PromptTemplate.from_template(
    "You are a planner who is an expert at coming up with a todo list for a given objective. Come up with a todo list for this objective: {objective}"
)
todo_chain = LLMChain(llm=OpenAI(temperature=0), prompt=todo_prompt)
search = SerpAPIWrapper()
tools = [
    Tool(
        name="Search",
        func=search.run,
        description="useful for when you need to answer questions about current events",
    ),
    Tool(
        name="TODO",
        func=todo_chain.run,
        description="useful for when you need to come up with todo lists. Input: an objective to create a todo list for. Output: a todo list for that objective. Please be very clear what the objective is!",
    ),
]

prefix = """You are an AI who performs one task based on the following objective: {objective}. Take into account these previously completed tasks: {context}."""
suffix = """Question: {task}
{agent_scratchpad}"""
prompt = ZeroShotAgent.create_prompt(
    tools,
    prefix=prefix,
    suffix=suffix,
    input_variables=["objective", "task", "context", "agent_scratchpad"],
)

이 코드로 대체할 건데요, 기존의 코드와 이 새로운 코드랑 비교를 해봅시다.

가장 먼저 코드의 첫줄을 보면 todo_prompt가 있습니다. 이건 기존 코드의 프롬프트 템플릿과 똑같은 기능을 해주고 있습니다. 하지만 prompt의 내용이 바꼈는데요, 기존에는 그저 ‘태스크를 컨텍스트에 맞게 실행해라’였다면 이번에는 조금 더 구체적으로 먼저 todo list을 만들으라고 하네요.

이 템플릿을 기반으로 저희는 todo_chain을 다음 줄에서 만듭니다.

세번째 줄에 있는 search = SerpAPIWrapper()는 저희가 처음에 불러온 SerpAPI 검색 기능을 쓰기 위해 셋업을 해놓는 것입니다.

재미있게도 저희는 todo_chain이 쓰면 좋을만한 툴들을 만들어주고 이걸 적절한 상황에서 각 툴을 알맞게 쓸 수 있도록 할 수 있습니다.

tools = [ … ] 코드 블록을 보면 저희는 크게 두가지 툴, “Search” tool과 “TODO” tool을 만든 것을 볼 수 있습니다.

Search tool은 실제 구글 검색을 하면서 정확한 정보를 불러와야할때 쓰는 툴이 되는거고, TODO tool은 todo list을 만들어야 할때 쓰이는 툴이 되는 것입니다.

마지막으로 기존의 코드와 비슷한 코드 부분은 prefix = “…” 부터 prompt = ZeroShotAgent까지의 코드입니다. 여기서는 이제 만든 todo list을 기반으로 태스크를 하나씩 실행하게끔 하는 Agent을 만든겁니다.

거의 다 왔습니다.

기존 코드에서 바꿔야 할 부분이 몇가지 더 있습니다.

@classmethod
    def from_llm(
        cls, llm: BaseLLM, vectorstore: VectorStore, verbose: bool = False, **kwargs
    ) -> "BabyAGI":
        """Initialize the BabyAGI Controller."""
        task_creation_chain = TaskCreationChain.from_llm(llm, verbose=verbose)
        task_prioritization_chain = TaskPrioritizationChain.from_llm(
            llm, verbose=verbose
        )
        execution_chain = ExecutionChain.from_llm(llm, verbose=verbose)
        return cls(
            task_creation_chain=task_creation_chain,
            task_prioritization_chain=task_prioritization_chain,
            execution_chain=execution_chain,
            vectorstore=vectorstore,
            **kwargs,
        )

위 코드를 아래 코드와 같이 대체합니다.

@classmethod
    def from_llm(
        cls, llm: BaseLLM, vectorstore: VectorStore, verbose: bool = False, **kwargs
    ) -> "BabyAGI":
        """Initialize the BabyAGI Controller."""
        task_creation_chain = TaskCreationChain.from_llm(llm, verbose=verbose)
        task_prioritization_chain = TaskPrioritizationChain.from_llm(
            llm, verbose=verbose
        )
        llm_chain = LLMChain(llm=llm, prompt=prompt)
        tool_names = [tool.name for tool in tools]
        agent = ZeroShotAgent(llm_chain=llm_chain, allowed_tools=tool_names)
        agent_executor = AgentExecutor.from_agent_and_tools(
            agent=agent, tools=tools, verbose=True
        )
        return cls(
            task_creation_chain=task_creation_chain,
            task_prioritization_chain=task_prioritization_chain,
            execution_chain=agent_executor,
            vectorstore=vectorstore,
            **kwargs,
        )

기존 코드에서 만들었던 세번째 체인, execution_chain = ExecutionChain.from_llm(llm, verbose=verbose) 코드 대신 저희가 만든 구글 검색 기능이 가능한 ZeroShotAgent으로 바꿔줘야합니다.

return cls (…) 부분에서 execution_chain=execution_chain도 execution_chain=agent_executor로 대체합니다.

llm_chain = LLMChain(llm=llm, prompt=prompt)
tool_names = [tool.name for tool in tools]
agent = ZeroShotAgent(llm_chain=llm_chain, allowed_tools=tool_names)
agent_executor = AgentExecutor.from_agent_and_tools(
    agent=agent, tools=tools, verbose=True
)

새롭게 추가된 코드를 좀 더 자세히 들여다보면, tool_names에서 저희가 만든 두가지 툴들, Search tool과 TODO tool을 둘다 쓸 수 있도록 루프를 돌고 있습니다.

agent = ZeroShotAgent(llm_chain=llm_chain, allowed_tools=tool_names) 이 코드에서는 llm_chain 기반, 저희가 만든 두개의 툴 기반으로 ZeroShotAgent를 만든다는 것입니다.

그러고 다음 줄, agent_executor 에서는 이 agent를 실행한다는 코드입니다.

마지막으로 Part 2에서 만들었던 BabyAGI Controller 부분에서 아래 코드를 찾으세요.

class BabyAGI(Chain, BaseModel):
    """Controller model for the BabyAGI agent."""

    task_list: deque = Field(default_factory=deque)
    task_creation_chain: TaskCreationChain = Field(...)
    task_prioritization_chain: TaskPrioritizationChain = Field(...)
    execution_chain: ExecutionChain = Field(...)
    task_id_counter: int = Field(1)
    vectorstore: VectorStore = Field(init=False)
    max_iterations: Optional[int] = None

여기서도 저희가 처음에 만들었던 세번째 execution 체인 대신 새롭게 만든 구글 검색 기능 체인으로 대체해줘야합니다. 그래서 execution_chain: ExecutionChain = Field(...) 코드를 execution_chain: AgentExecutor = Field(...) 코드로 바꿔주세요.

그럼 아래 코드와 같이 생겼습니다.

class BabyAGI(Chain, BaseModel):
    """Controller model for the BabyAGI agent."""

    task_list: deque = Field(default_factory=deque)
    task_creation_chain: TaskCreationChain = Field(...)
    task_prioritization_chain: TaskPrioritizationChain = Field(...)
    execution_chain: AgentExecutor = Field(...)
    task_id_counter: int = Field(1)
    vectorstore: VectorStore = Field(init=False)
    max_iterations: Optional[int] = None

테스트해보기!

이제 실제로 구글 검색 기능이 되는지 테스트 해보겠습니다.

파일을 돌리기 위해서는 Part 1에서 만든 가상환경 안에 들어가 있어야합니다.

가상 환경 안에 들어와있다면 아래 사진처럼 뜹니다. 만약 들어와있지 않다면 터미널에서 source venv/bin/activate을 입력하고 엔터를 누르세요.

Screenshot 2023-08-21 at 4.32.23 PM.png다음 저희는 serpAPI를 쓰기 위해 다운로드해야하는 패키지가 있습니다. 터미널에 pip install google-search-results를 입력해주세요.

이제 python agent.py 를 입력하면 코드가 돌려집니다.

첫번째 결과값으로 오늘 서울의 날씨를 구글에서 검색을 했고, 결과값으로 ”오늘의 날씨는 화창하며 최저 기온은 16도, 최고 기온은 24도입니다. 바람은 약하고 대기질 지수가 낮습니다.”가 나왔습니다.

Screenshot 2023-08-21 at 4.35.36 PM.png두번째 태스크를 돌리면 8월달에 서울의 평균 기온이 -6도에서 30도 사이라는 결과값이 나왔는데, 별로 정확하진 않네요. 아무래도 hallucination이 발생한 것 같습니다.

Screenshot 2023-08-21 at 4.35.48 PM.png마지막 태스크로 서울의 현재 습도를 검색한 결곽로 83% 정도의 습도, extremely humid라는 결과값이 나왔습니다.

Screenshot 2023-08-21 at 4.35.59 PM.png

Part 3 마무리

이로써 Part 3가 마무리되었습니다!

SerpAPI에서는 구글 검색 뿐만 아니라 네이버 검색, 구글 지도, 유투브 검색 기능 등 정말 다양한 API를 제공하고 있으니 SerpAPI 사이트에서 documentation을 확인하면서 써보세요 :)

오늘 저희가 만들었던 agent와 같이 비슷한 구조로 만드시면 됩니다.

"Write a weather report for Seoul today”라는 프롬트 대신 “conduct Facebook market analysis”라는 프롬트도 해보면서 코드를 돌려보세요! 생각보다 재미있는 결과값들이 나옵니다. ㅎㅎ

오늘도 긴 글 읽어주셔서 감사합니다. 문제가 생기거나 코드가 잘 이해되지 않는 부분이 있으면 언제든지 포스트에 댓글로 달아주시거나 저한테 커피챗으로 연락주세요.

15
3
Cailyn Yong

Cailyn Yong

[Part 2] 2시간 안에 업무 자동화 AI Agent 만들기: LLM 체인 직접 써보기

Part 1에 이이서 오늘은 Part 2를 올립니다.

Part 1: 전체 프로그램 셋업, OpenAI API 연결, Vector Store 연결

Part 2: 커스텀 LLM 체인 직접 만들고나서 실행하기

Part 3: Agent가 나 대신 실제 구글 검색하는 기능 만들기

LLM 체인 만들기

Part 1에서 기본적인 것들이 연결됐으니 이제 실제 LLM 체인을 만들어볼거에요.

일단 저희가 만들 AI agent가 어떻게 작동되냐면, 먼저 유저가 “페이스북 시장 조사 좀 해줘”라고 하면 이 업무를 하기 위해 해야할 태스크들을 리스트업합니다. 그 다음 태스크별로 실행을 하고 결과값을 생성합니다.

이를 하기 위해서는 3개의 체인이 활용됩니다.

  1. 태스크를 생성하고 리스트에 추가하는 체인

  2. 태스크 중 중요도 높은 태스크부터 처리하게끔 관리하는 체인

  3. 각 태스크를 실제로 실행하는 체인

First LLM Chain

유저 프롬트에 맞게 태스크를 생성하고 리스트에 추가하는 첫번째 체인 코드입니다.

class TaskCreationChain(LLMChain):
    """Chain to generates tasks."""

    @classmethod
    def from_llm(cls, llm: BaseLLM, verbose: bool = True) -> LLMChain:
        """Get the response parser."""
        task_creation_template = (
            "You are a task creation AI that uses the result of an execution agent"
            " to create new tasks with the following objective: {objective},"
            " The last completed task has the result: {result}."
            " This result was based on this task description: {task_description}."
            " These are incomplete tasks: {incomplete_tasks}."
            " Based on the result, create new tasks to be completed"
            " by the AI system that do not overlap with incomplete tasks."
            " Return the tasks as an array."
        )
        prompt = PromptTemplate(
            template=task_creation_template,
            input_variables=[
                "result",
                "task_description",
                "incomplete_tasks",
                "objective",
            ],
        )
        return cls(prompt=prompt, llm=llm, verbose=verbose)

여기서 코드를 일일이 이해할 필요는 없고, 크게 어떻게 작동되는지만 알면 됩니다.

일단 맨 처음에 TaskCreationChain이라는 클래스를 생성했고, 이 클래스를 호출했을때 업무 자동화를 하기 위한 명령 템플릿이 task_creation_template에 작성돼있습니다.

말그대로 LLM 체인에게 이렇게 해라 라고 명시하는 겁니다.

task_creation_template = ( … )에 작성돼있는 텍스트를 보면, “너는 태스크를 생성하는 AI이고 태스크 별로 실행까지 하는 에이전트야. 내가 입력하는 {objective}에 맞게 태스크를 생성하고, 가장 최근에 실행된 태스크의 결과값은 {result}에 저장하고, 태스크에 관한 설명은 {task_description}에 저장될거야. 아직 실행되지 않은 태스크들은 {incomplete_tasks}에 저장해. 결과값을 통해 아직 실행되지 않은 태스크들을 실행하고 결과값들은 배열 형태로 정리해줘”라고 써져 있습니다.

이런 프롬트 템플릿은 제가 원하는대로 언제든지 바꿀 수 있습니다. 직접 코드로 개발을 하지 않아도 정말 텍스트로 AI에게 명령하는거죠.

다음 코드 줄에서는 이 task_creation_template을 prompt라는 곳에 저장하고, 인풋은 “result”, “task_description”, “incomplete_tasks”, “objective”이라는 것을 확인할 수 있습니다.

코드를 복붙하고 나면 이렇게 생겼습니다.

Screenshot 2023-08-16 at 5.37.29 PM.pngSecond LLM Chain

다음은 태스크 중 중요도 높은 태스크들을 먼저 실행하게끔 관리하는 두번째 체인 코드입니다.

class TaskPrioritizationChain(LLMChain):
    """Chain to prioritize tasks."""

    @classmethod
    def from_llm(cls, llm: BaseLLM, verbose: bool = True) -> LLMChain:
        """Get the response parser."""
        task_prioritization_template = (
            "You are a task prioritization AI tasked with cleaning the formatting of and reprioritizing"
            " the following tasks: {task_names}."
            " Consider the ultimate objective of your team: {objective}."
            " Do not remove any tasks. Return the result as a numbered list, like:"
            " #. First task"
            " #. Second task"
            " Start the task list with number {next_task_id}."
        )
        prompt = PromptTemplate(
            template=task_prioritization_template,
            input_variables=["task_names", "next_task_id", "objective"],
        )
        return cls(prompt=prompt, llm=llm, verbose=verbose)

첫번째 체인과 아주 비슷한 형식이죠?

이번에 task_prioritization_template에는 “너는 {task_names} 태스크들 중에서 중요도 높은 태스크부터 실행되도록 순번을 관리하는 AI야. 최종 {objective} 목표를 염두하면서 순번 관리를 해줘. 태스크들 중 어떤것도 지우지 말고 결과값은 리스트 형태로 보여줘: “#. 첫번째 태스크, #. 두번째 태스크”. 태스크 리스트는 태스크 숫자 아이디로 {next_task_id} 시작해줘.” 라고 써져 있습니다.

첫번째 체인 코드 밑에 또 복붙하세요.

Screenshot 2023-08-16 at 5.45.40 PM.pngThird LLM Chain

이제 마지막 체인, 실제 태스크를 실행하게끔 하는 체인 코드입니다.

class ExecutionChain(LLMChain):
    """Chain to execute tasks."""

    @classmethod
    def from_llm(cls, llm: BaseLLM, verbose: bool = True) -> LLMChain:
        """Get the response parser."""
        execution_template = (
            "You are an AI who performs one task based on the following objective: {objective}."
            " Take into account these previously completed tasks: {context}."
            " Your task: {task}."
            " Response:"
        )
        prompt = PromptTemplate(
            template=execution_template,
            input_variables=["objective", "context", "task"],
        )
        return cls(prompt=prompt, llm=llm, verbose=verbose)

여기서 템플릿에는 “너는 큰 목표 {objective}에 맞게 한 개의 태스크를 실행하는 AI야. 전에 실행 완료된 태스크들의 {context}를 생각하면서 태스크를 실행하도록 해. 너의 태스크: {task}.”라고 써져있습니다.

마찬가지로 코드를 두번째 체인 코드 밑에 복붙하세요.

Screenshot 2023-08-16 at 5.48.17 PM.pngBabyAGI Controller

이제 BabyAGI 컨트롤러를 만들 차례입니다. 위에서 만든 세 개의 체인들을 활용해서 유저가 인풋을 주면 그 인풋에 맞게 자동으로 태스크들을 생성하고 처리하게끔 만들어야 합니다.

def get_next_task(
    task_creation_chain: LLMChain,
    result: Dict,
    task_description: str,
    task_list: List[str],
    objective: str,
) -> List[Dict]:
    """Get the next task."""
    incomplete_tasks = ", ".join(task_list)
    response = task_creation_chain.run(
        result=result,
        task_description=task_description,
        incomplete_tasks=incomplete_tasks,
        objective=objective,
    )
    new_tasks = response.split("\\n")
    return [{"task_name": task_name} for task_name in new_tasks if task_name.strip()]

위 코드는 1) 처음에 에이전트가 해야할 태스크 리스트업을 했을때 첫 태스크를 완료하고 난 뒤 아직 실행되지 않은 다음 태스크를 불러오고, 2) 나머지 미완료 태스크들을 다시 생성 + 리스트업하기 위해 첫번째 태스크 생성 체인을 불러오는 코드입니다.

def prioritize_tasks(
    task_prioritization_chain: LLMChain,
    this_task_id: int,
    task_list: List[Dict],
    objective: str,
) -> List[Dict]:
    """Prioritize tasks."""
    task_names = [t["task_name"] for t in task_list]
    next_task_id = int(this_task_id) + 1
    response = task_prioritization_chain.run(
        task_names=task_names, next_task_id=next_task_id, objective=objective
    )
    new_tasks = response.split("\\n")
    prioritized_task_list = []
    for task_string in new_tasks:
        if not task_string.strip():
            continue
        task_parts = task_string.strip().split(".", 1)
        if len(task_parts) == 2:
            task_id = task_parts[0].strip()
            task_name = task_parts[1].strip()
            prioritized_task_list.append({"task_id": task_id, "task_name": task_name})
    return prioritized_task_list

위 코드는 저희가 만든 두번째 태스크 순번 관리 체인을 실행하기 위한 코드입니다.

def _get_top_tasks(vectorstore, query: str, k: int) -> List[str]:
    """Get the top k tasks based on the query."""
    results = vectorstore.similarity_search_with_score(query, k=k)
    if not results:
        return []
    sorted_results, _ = zip(*sorted(results, key=lambda x: x[1], reverse=True))
    return [str(item.metadata["task"]) for item in sorted_results]

def execute_task(
    vectorstore, execution_chain: LLMChain, objective: str, task: str, k: int = 5
) -> str:
    """Execute a task."""
    context = _get_top_tasks(vectorstore, query=objective, k=k)
    return execution_chain.run(objective=objective, context=context, task=task)

마지막으로 _get_top_tasks는 가장 첫번째 순서인 태스크를 불러오는 거고, execute_task는 저희가 세번째로 만든 태스크 실행하는 체인을 불러와서 첫번째 순서 태스크부터 실행하게끔 하는 코드입니다.

이 모든 코드를 순서대로 복붙하세요. 그럼 아래 이미지처럼 생겼습니다.

Screenshot 2023-08-16 at 6.01.24 PM.png이제 정말 거의 다왔습니다.

여태까지 만든 모든 코드 블록들을 저희 AI Agent가 적절하게 쓸 수 있도록 짜집기 해줄거에요.

여기서 class BabyAGI 코드 블록이 실질적으로 AI Agent의 역할을 한다고 생각하시면 됩니다.

class BabyAGI(Chain, BaseModel):
    """Controller model for the BabyAGI agent."""

    task_list: deque = Field(default_factory=deque)
    task_creation_chain: TaskCreationChain = Field(...)
    task_prioritization_chain: TaskPrioritizationChain = Field(...)
    execution_chain: ExecutionChain = Field(...)
    task_id_counter: int = Field(1)
    vectorstore: VectorStore = Field(init=False)
    max_iterations: Optional[int] = None

    class Config:
        """Configuration for this pydantic object."""

        arbitrary_types_allowed = True

    def add_task(self, task: Dict):
        self.task_list.append(task)

    def print_task_list(self):
        print("\033[95m\033[1m" + "\n*****TASK LIST*****\n" + "\033[0m\033[0m")
        for t in self.task_list:
            print(str(t["task_id"]) + ": " + t["task_name"])

    def print_next_task(self, task: Dict):
        print("\033[92m\033[1m" + "\n*****NEXT TASK*****\n" + "\033[0m\033[0m")
        print(str(task["task_id"]) + ": " + task["task_name"])

    def print_task_result(self, result: str):
        print("\033[93m\033[1m" + "\n*****TASK RESULT*****\n" + "\033[0m\033[0m")
        print(result)

    @property
    def input_keys(self) -> List[str]:
        return ["objective"]

    @property
    def output_keys(self) -> List[str]:
        return []

    def _call(self, inputs: Dict[str, Any]) -> Dict[str, Any]:
        """Run the agent."""
        objective = inputs["objective"]
        first_task = inputs.get("first_task", "Make a todo list")
        self.add_task({"task_id": 1, "task_name": first_task})
        num_iters = 0
        while True:
            if self.task_list:
                self.print_task_list()

                # Step 1: Pull the first task
                task = self.task_list.popleft()
                self.print_next_task(task)

                # Step 2: Execute the task
                result = execute_task(
                    self.vectorstore, self.execution_chain, objective, task["task_name"]
                )
                this_task_id = int(task["task_id"])
                self.print_task_result(result)

                # Step 3: Store the result in Pinecone
                result_id = f"result_{task['task_id']}_{num_iters}"
                self.vectorstore.add_texts(
                    texts=[result],
                    metadatas=[{"task": task["task_name"]}],
                    ids=[result_id],
                )

                # Step 4: Create new tasks and reprioritize task list
                new_tasks = get_next_task(
                    self.task_creation_chain,
                    result,
                    task["task_name"],
                    [t["task_name"] for t in self.task_list],
                    objective,
                )
                for new_task in new_tasks:
                    self.task_id_counter += 1
                    new_task.update({"task_id": self.task_id_counter})
                    self.add_task(new_task)
                self.task_list = deque(
                    prioritize_tasks(
                        self.task_prioritization_chain,
                        this_task_id,
                        list(self.task_list),
                        objective,
                    )
                )
            num_iters += 1
            if self.max_iterations is not None and num_iters == self.max_iterations:
                print(
                    "\033[91m\033[1m" + "\n*****TASK ENDING*****\n" + "\033[0m\033[0m"
                )
                break
        return {}

    @classmethod
    def from_llm(
        cls, llm: BaseLLM, vectorstore: VectorStore, verbose: bool = False, **kwargs
    ) -> "BabyAGI":
        """Initialize the BabyAGI Controller."""
        task_creation_chain = TaskCreationChain.from_llm(llm, verbose=verbose)
        task_prioritization_chain = TaskPrioritizationChain.from_llm(
            llm, verbose=verbose
        )
        execution_chain = ExecutionChain.from_llm(llm, verbose=verbose)
        return cls(
            task_creation_chain=task_creation_chain,
            task_prioritization_chain=task_prioritization_chain,
            execution_chain=execution_chain,
            vectorstore=vectorstore,
            **kwargs,
        )

이 코드는 굉장히 긴데 겁먹을 필요 없구요, 그저 단계별로 결과값이 어떻게 프린트될지 예쁘게 formatting해주는 코드입니다. 코드를 자세히 보시면 Step 1, Step 2, Step 3, Step 4가 있습니다.

  • Step 1: 첫번째 태스크 불러오기

  • Step 2: 태스크 실행하기 (저희가 만들었던 세번째 체인, 태스크 실행하는 체인이 여기서 쓰입니다)

  • Step 3: 결과값을 Vector Store에 저장하기 (처음에 만들었던 vector store 기억하시죠? 여기에 저장되는 겁니다)

  • Step 4: 새로운 태스크들을 생성하고 중요도 높은 순으로 순번 관리하기 (저희가 만든 첫번째 체인 (태스크 생성 체인)과 두번째 체인 (순번 관리 체인)이 여기서 쓰입니다)

코드를 그대로 복붙하면 아래 이미지처럼 생겼습니다.

Screenshot 2023-08-16 at 6.09.05 PM.png테스트해보기!!

OBJECTIVE = "Write a weather report for Seoul today"

llm = OpenAI(temperature=0)

# Logging of LLMChains
verbose = False
# If None, will keep on going forever
max_iterations: Optional[int] = 3
baby_agi = BabyAGI.from_llm(
    llm=llm, vectorstore=vectorstore, verbose=verbose, max_iterations=max_iterations
)

baby_agi({"objective": OBJECTIVE})

마지막으로 위 코드를 복붙합니다. OBJECTIVE는 유저 인풋입니다. AI Agent에게 어떤 업무를 시키고 싶은지에 따라 텍스트로 작성하면 됩니다.

저는 “서울의 날씨 리포트를 작성해줘”라는 인풋을 주었습니다.

여기서 max_iterations는 몇번의 루프를 돌건지 제한을 두는 것입니다. 지금은 3번의 루프만 돌게끔 해놨고, 만약 지정을 하지 않는다면 무한대로 루프가 돌아갈 것입니다.

복붙했다면 터미널에 python agent.py 명령어를 실행합니다. 이제 AI Agent가 자동으로 일을 하기 시작할겁니다!!

첫번째 태스크인 "todo list 만들기"를 실행한 결과입니다. 제가 "서울의 날씨 리포트를 써줘"라고 해서 이 업무를 하기 위해 만든 태스크 리스트입니다. 리포트를 작성하기 위해 1. 현재 서울의 온도, 2. 오늘 날씨 변화, 3. 습도, 4. 바람 속도와 방향, 5. UV index, 6. 미세먼지 인덱스 등을 리스트업 했습니다.

Screenshot 2023-08-16 at 6.56.40 PM.png첫번째 태스크를 성공적으로 실행했으면 리스트에서 제외하고 두번째 태스크인 "서울의 현재 온도"를 실행합니다. 결과값으로 "National Weather Service Website"에서 불러온 정보를 토대로 현재 서울의 날씨는 24도라고 하네요.

Screenshot 2023-08-16 at 6.56.56 PM.png다음으로 세번째 태스크를 실행합니다. 마찬가지로 두번째 태스크를 제외시킨 리스트가 업데이트됩니다.

결과값으로는 오늘 서울의 기온은 8도에서 13도 사이에서 왔다갔다 할거라고 하네요. (실제 구글링을 하지 않은 가상의 결과값들이기 때문에 정보가 정확하지 않습니다)

Screenshot 2023-08-16 at 6.57.07 PM.pngPart 2 마무리

max_iterations: Optional[int] = 3 숫자를 바꾸면서 몇번의 루프를 돌릴건지 테스트해봐도 되고, 직접 prompt template들을 수정하면서 특정 업무에 집중된 AI agent를 만들 수 있습니다.

예를 들어서 나는 자동으로 시장 조사를 해주는 에이전트를 만들고 싶다면 처음에 저희가 만든 세개의 체인들의 prompt template을 수정할 수 있겠죠?

혹시나 만드시면서 어려움을 겪거나 질문이 있으면 포스트에 댓글로 남겨주시거나 커피챗 요청 보내주세요! 10X AI Club의 두번째 글, 정말 길었는데 읽어주셔서 감사합니다.

다음 Part 3에서는 저희가 만든 AI Agent가 실제로 구글을 검색하면서 정확한 자료 조사를 할 수 있도록 만들 예정입니다.

27
12
Cailyn Yong

Cailyn Yong

[Part 1] 2시간 안에 업무 자동화 AI Agent 만들기

본 글은 제가 4월에 직접 만든 AI Agent를 개발하는 과정을 공유하는 글입니다. 비전공자, 비개발자여도 누구나 직접 개발할 수 있도록 도움을 드리고자 씁니다.

세 파트로 나뉘어져 있습니다.

Part 1: 전체 프로그램 셋업, OpenAI API 연결, Vector Store 연결

Part 2: 커스텀 LLM 체인 직접 만들고나서 실행하기

Part 3: Agent가 나 대신 실제 구글 검색하는 기능 만들기

파트 3까지 모두하면 달성할 수 있는 것:

  • 자동으로 기본 업무 처리를 해주는 AI 에이전트 직접 만들기

  • 구글 검색 기능

  • step-by-step 개발 과정 알아가기

앞으로 추후 AI 관련 프로젝트 개발 아티클들은 10X AI Club에서 지속적으로 올라올 예정이니 클럽 가입 부탁드리겠습니다! 정기적 오프라인 모임 및 세미나도 열 계획이니 많은 관심 부탁드리겠습니다 :)

이 프로젝트는 Langchain BbyAGI User Gide docs를 참고하며 만든 에이전트입니다. https://python.langchain.com/docs/use_cases/agents/baby_agi

코드부터 프로젝트가 웹사이트에서 실제 작동되는 것까지 모든 단계들을 이 글에서 확인할 수 있습니다.

제 노트북이 맥이다보니 맥북 화면 구성으로 설명드리는 점 참고 부탁드립니다!

VSCode 다운로드 및 코드 셋업

코딩 프로젝트를 만들기 위해서는 VSCode라는 코딩 에디터 프로그램을 사용합니다.

https://code.visualstudio.com/ 사이트에 들아가신 후 다운로드합니다.

프로그램을 다운로드 후 실행하면 첫 화면이 보입니다.

Screenshot 2023-08-15 at 11.11.52 PM.png여기서 “Open”이라는 버튼을 누른 후 프로젝트를 저장할 새로운 파일을 만듭니다. “New Folder” > “ai-agent”라는 폴더를 만듭니다 (파일 이름은 상관없습니다!).

Screenshot 2023-08-15 at 11.12.15 PM.pngScreenshot 2023-08-15 at 11.12.36 PM.png폴더 “Open”을 누르면 다음과 같은 화면이 됩니다.

Screenshot 2023-08-15 at 11.12.52 PM.png그 다음 agent.py라는 새로운 파일을 만듭니다. AI-AGENT라는 탭 위에 허버하시면 New File + 버튼 보이시죠? 그걸 누른후 파일 이름을 agent.py라고 하시면 됩니다.

Screenshot 2023-08-15 at 11.20.31 PM.pngagent.py 파일은 파이썬 코드 파일입니다. 파이썬 코드를 돌리기 위해서는 가상의 환경을 셋업해줘야합니다. 전혀 어렵지 않고 코드 몇줄만 실행하면 됩니다!

먼저 맥북 상단 탭에서 “Terminal”을 누른 후 “New Terminal”을 누릅니다. 기본 명령어들을 이 터미널이라는 곳에서 입력할 수 있어요.

Screenshot 2023-08-16 at 4.52.11 PM.png그럼 이런 화면이 뜨게 될겁니다. 터미널에 cailynyongyong@MacBook-Pro-2 ai-agent라고 보이시죠? 내가 만든 ai-agent라는 폴더 안에 들어가 있다는 뜻입니다.

Screenshot 2023-08-16 at 4.54.31 PM.png여기서 이제 파이썬 코드를 실행하기 위해 가상의 환경을 만들어줄거에요. 터미널에 python -m venv venv라는 명령어를 입력 후 엔터를 눌러주세요. 생성이 되면 왼쪽에 “venv”라는 폴더가 만들어진걸 확인할 수 있습니다.

Screenshot 2023-08-16 at 4.55.12 PM.png이 가상의 환경을 만들었으니, 이제 이 환경을 실행시켜줄거에요. 이 환경을 실행해야만 파이썬 코드를 돌릴 수 있습니다.

터미널에 source venv/bin/activate라는 명령어를 입력해주세요.

Screenshot 2023-08-16 at 4.55.29 PM.png그럼 성공적으로 터미널에 (venv) cailynyongyong@MacBook-Pro-2 ai-agent 라는게 뜹니다. 가상 환경에 들어왔다는 뜻입니다.

다음으로 터미널에 다음의 명령들을 순서대로 실행합니다.

pip install langchain
pip install openai
pip install faiss-cpu > /dev/null
pip install tiktoken

예를 들어 pip install langchain을 실행하면 다음과 같이 다운로드가 진행되는게 보일겁니다.

Screenshot 2023-08-16 at 6.24.23 PM.png이제 코드를 작성해봅시다!

OpenAI API key 연결, Vector Store 연결

이제 본격적으로 에이전트를 코딩하기 위한 모든 셋업을 할겁니다. 한번에 다 이해 못해셔도 괜찮으니, 코드를 그대로 복붙하시면서 일단 해보는걸 추천드립니다! 저도 그렇게 배웠거든요 ㅎㅎ

처음에는 에이전트를 만들기 위해 필요한 툴들을 불러와야 해요. 이걸 module, 혹은 library라고 푸릅니다. 항상 개발을 할때에는 프로젝트에 필요한 적절한 모듈들을 불러옵니다. 레고처럼 필요한 부품들만 갖고와서 맞추는 것 처럼요.

저희는 OpenAI의 모듈들을 쓸거여서 OpenAI API Key라는 것을 써야합니다. OpenAI 웹사이트에서 계정을 만든 후 https://platform.openai.com/overview 이 곳에 들어갑니다. 상단 오른쪽에서 Personal 버튼 위에 허버하고 View API Keys를 눌러주세요.

Screenshot 2023-08-16 at 6.27.59 PM.png이 페이지에 들어오면 “Create new secret key”를 누르세요.

Screenshot 2023-08-16 at 6.29.57 PM.pngai-agent라는 이름으로 만들고 초록색 버튼을 누르세요. 버튼을 누르면 새로운 secret key가 생성되는데, 바로 복사해서 다른 곳에 저장해두세요. 다시 열어서 볼 수 없거든요. 이 키는 꼭 다른 사람과 공유하지 마세요! 일종의 OpenAI 비밀번호입니다.

Screenshot 2023-08-16 at 6.30.09 PM.png이 키를 이제 어디다가 쓸거냐, 밑에 코드 두번째 줄에 os.environ[”OPENAI_API_KEY”] = “ “ 보이시죠? “ “ 안에 방금 복사한 secret key를 넣습니다.

import os
os.environ["OPENAI_API_KEY"] = " "
from collections import deque
from typing import Dict, List, Optional, Any

from langchain.llms import OpenAI
from langchain.chains import LLMChain
from langchain.prompts import PromptTemplate
from langchain.embeddings import OpenAIEmbeddings
from langchain.llms import BaseLLM
from langchain.vectorstores.base import VectorStore
from pydantic import BaseModel, Field
from langchain.chains.base import Chain

이 코드를 그대로 복사해서 agent.py에 붙입니다.

Screenshot 2023-08-16 at 5.03.43 PM.png각 줄별로 어떤 것을 뜻하는지 이해하기보다는, ‘아 이 에이전트를 만들기 위해서는 이런 모듈들을 불러와야하는구나’라고 알기만 하면 됩니다. 기본적으로 우리는 랭체인을 써서 LLM 체인을 직접 커스터마이징해서 쓸거기 때문에 from langchain import LLMChain, OpenAI 라는 코드가 있습니다. 이 말은 langchain이라는 곳에서 LLMChain, OpenAI 모듈들을 불러와서 쓸거다 라는 뜻이죠.

Vector Store 셋업

다음 스텝은 Vector Store라는 것을 쓰기 위해 추가적으로 불러와야할 모듈들이 있습니다. Vector Store라는 것은 커스텀 LLM을 쓸 때 효율적으로 데이터를 저장하고 불러올 수 있는 공간을 마련해주는 것입니다.

저희는 FAISS라는 Vector Store를 쓸거에요.

from langchain.vectorstores import FAISS
from langchain.docstore import InMemoryDocstore

필요한 모듈들을 불러옵니다. 복사해서 agent.py에 붙여넣으세요.

다음 이 vector store를 내 코드와 연결시키기 위해 이 코드를 작성합니다.

# Define your embedding model
embeddings_model = OpenAIEmbeddings()
# Initialize the vectorstore as empty
import faiss

embedding_size = 1536
index = faiss.IndexFlatL2(embedding_size)
vectorstore = FAISS(embeddings_model.embed_query, index, InMemoryDocstore({}), {})

Vector embedding은 텍스트, 이미지, 오디오와 같은 숫자가 아닌 데이터들을 컴퓨터가 알아듣기 쉽게 숫자화한 형태입니다. 이 embedding들이 vector store에 저장되는거구요.

저희는 embedding model을 OpenAIEmbeddings()라는 모델을 쓸겁니다.

그 다음 vector store를 초기 셋업합니다.

  • import faiss: faiss 벡터 스토어 불러오기

  • embedding_size = 1536: embedding size를 1536으로 합니다.

  • index = faiss.IndexFlatL2(embedding_size): faiss에 이 사이즈로 셋업을 할거라고 알려줍니다.

  • vectorstore = FAISS(embeddings_model.embed_query, index, InMemoryDocstore({}), {}): 이런 기초 작업들을 거친 후 맨 마지막 줄에서 vectorstore를 성공적으로 셋업합니다.

다 복붙하면 코드는 이렇습니다.

Screenshot 2023-08-16 at 5.19.58 PM.pngPart 1 마무리

이로써 Part 1은 끝났습니다! 전체적인 셋업을 했으니 이제 다음 파트에서는 직접 커스텀 LLM 체인들을 만들어줄거에요.

하면서 어려움을 겪었거나 질문이 있으시면 포스트에 댓글 남겨주시거나 커피챗 요청주세요. 그 외 앞으로 올라왔으면 하는 AI 주제들이 있으면 댓글 남겨주세요!

10X AI Club의 첫번째 글 읽어주셔서 감사합니다.

더 많은 AI 사이드프로젝트들의 개발 방법에 대해 배우고 싶다면 10X AI University 신청을 해주세요!

https://dis.qa/bQCLPw

40
26
Cailyn Yong

Cailyn Yong

AI와 LLM의 시대: 더 이상 LLM이 무엇인지 모른채 지낼 수 없습니다.

1년전까지만 해도 대부분의 VC들이 blockchain, metaverse, NFT에 집중을 하고 있었다면 올해는 챗GPT로 인해 판도가 완전히 달라졌습니다.

불경기인 상황에서 투자자들이 유일하게 투자하는 대부분의 스타트업들은 AI-friendly, Generative AI, custom LLM이라는 키워드를 가진 곳들이 되었습니다.

그렇다면 과연 Generative AI는 어떤 것이고, custom LLM은 무슨 뜻인가요?

쉽게 말하자면 Generative AI는 무에서 유인 것을 창조해내는 일, 즉 텍스트로 텍스트, 이미지, 혹은 비디오까지 생성해낼 수 있는 인공지능을 뜻합니다.

LLM은 large language model의 약자인데, 이것은 챗GPT와 같은 인공지능 모델들을 뜻하며, 방대한 양의 자연어 데이터들을 기반으로 챗GPT와 같이 텍스트 prompt로 내가 원하는 결과물을 생성할 수 있게끔 도와주는 모델입니다.

간단한 예를 들어 내 스타트업의 웹사이트 정보들을 다 모아서 LLM에 학습시킨 후 유저가 내 프로덕트와 관련된 질문을 바로 응답해줄 수 있는 챗봇을 만들 수 있게끔 해주는 모델입니다.

블록체인만 하던 저에게 AI와 LLM은 훨씬 더 창의적이고 재밌는 아이디어들을 순식간에 만들 수 있는 분야, 그리고 유저들이 블록체인보다 훨씬 더 쉽게 이해할 수 있는 분야로 다가왔습니다. 처음으로 코딩이 재미있게 느껴졌고, 올해 상반기에 미친듯이 프로젝트들을 만들기 시작했습니다.

2023년 3-6월 동안 했던 모든 사이드 프로젝트들  

4월 19일날, 하루만에 랭체인과 BabyAGI docs를 보면서 나 대신 구글 검색해주면서 해야할 일을 task로 분류해주는 AI Agent를 만들었습니다. “Personal AI Assistant”이라고 부르면서 Github과 Twitter에 올렸는데 생각보다 반응이 좋아서 놀랐습니다. 

1.avif“이걸 하루만에 이렇게 쉽게 만들 수 있다고?”라는 생각이 듦과 동시에 이렇게 쉽게 만들 수 있는건데 왜 트위터 바이럴이 됐는지 의아했고, 점점 다른 바이럴한 트윗들을 보면서 AI 프로덕트는 UI가 심플하고 이해하기 쉬운 프로덕트일수록 일반 유저들이 엄청나게 반응한다는 것을 알게 되었습니다.

그 뒤로 점점 재미를 느껴서 웹사이트를 그 사이트 내용에 맞는 트위터 홍보용 게시물로 자동으로 만들어주는 AI Agent 툴을 빌드했습니다.

2.avif이 쪽으로 더 파고들면서 “이걸로 뭐라도 상품화 시켜봐야겠다”라는 생각이 들었는데 친구가 옆에서 “이거 뤼튼에서 이미 다 하고 있던데?”라고 하더군요. 뤼튼을 찾아봤더니.. 네. 다 해주고 있었습니다. 심지어 OpenAI API나오기 전에 사내 인공지능 모델로 만든거라고 하니까 이게 OpenAI랑 결합되면 끝날 것이다 생각했고, 지금은 너무 당연히도 급격하게 성장하고 있습니다.

그 뒤로 할 다른 프로젝트를 찾아보다가, 6월에 열리는 ETH Seoul 블록체인 해커톤이 열리는걸 듣게 됐고 5월말 한주간 학교에서 친구와 함께 해커톤 준비를 했습니다.

거기서 탄생한건 Solidity Copilot. 블록체인 업계 내에서는 Smart Contract가 해킹 당하는 순간 엄청나게 많은 자금이 도난당하는 것을 막기 위해 smart contract auditing이라는 것을 합니다. Auditing(감사) 회사에 자신의 블록체인 소스 코드를 보내면 코드에 에러가 있는지, 해킹 당할 위험이 있는지를 평가합니다. 이런 평가를 받아야만 업계 내에서 안전하게 쓸 수 있는 앱이라는 인식이 생깁니다.

그러나 돈을 엄청나게 투자 받지 못한 개별 개발자들에겐 이 과정이 매우 비싸고, 시간이 오래 걸린다는 문제점이 있습니다.

이걸 해결하고자 저희는 VSCode Extension 형태로 스마트 컨트랙트 코드의 취약점을 분석하고 자동으로 고쳐주는 간단한 툴을 만들었습니다.

3.avif해커톤 당일날 7명의 심사위원에게 1분짜리 피칭을 했고, 저희 팀을 좋게 봐주시는 분들이 계셔서 해커톤 1위를 하고 $5000을 상금으로 받았습니다.

ETH Seoul에서 많은 분들과 대화를 할때 가장 놀라웠던 건 대부분의 사람들이 랭체인, LLM이 어떤것이 모르고 OpenAI의 API를 쓸 수 있다는 것 조차 모르고 있었습니다.

한심한 소리처럼 들릴 수도 있고, 믿지 않을 수도 있겠지만 저는 장담하건데 근 미래에는 AI가 대부분의 일자리를 대체할 것이라고 생각합니다.

그렇기에 여기서 발생되는 질문은: 나는 내 일자리가 대체되는걸 가만히 보고 냅둘거냐, 아님 인공지능을 활용하여 더 productive하고 유의미한 일을 창조해낼 수 있을 것인가 인데, 두번째로 가기 위해서는 일단 LLM이 뭔지, 챗GPT와 같은 모델들을 나도 어떻게 만들건지 알아가는 것 부터 중요하다고 생각합니다.

그래서 저는 지난 몇개월간 제가 직접 만들면서 배웠던 것들을 공유하고 싶고 알려드리고 싶습니다.

AI, ChatGPT, LLM, Generative AI와 관련된 모든 기초 지식들, 그리고 내 스타트업에 직접 쓸 수 있는 나만의 AI 에이전트를 만드는 것까지 자세하게 알려드리고자 합니다.

10X AI Club에서 인사이트와 개발글들을 올리고 있으니 참가 신청 부탁드리겠습니다.

더불어 더 자세한 개발 사이드프로젝트들을 직접 만들어보고 싶으시다면 10X AI University도 출시했으니 신청 부탁드리겠습니다!

32
6
Cailyn Yong

Cailyn Yong

삶이 가장 힘들었을 때 극복했던 방법

작년 6월은 되는 일이 하나도 없어서 자신감이 바닥을 치고 있었을 때입니다.

제가 처음으로 도전했던 스타트업은 PMF를 찾지 못해서 진행이 지연되고 있었고 더 이상 할 수 있는 힘이 나지 않아서 실패로 인정을 했습니다.

사업을 접고 그 후 지원했던 컨설팅, VC 인턴 자리들도 다 떨어졌습니다.

여태까지 제가 제 자신에 대해 믿고 있었던 모든 것들이 파괴됐었고 생각보다 저는 훨씬 보잘것 없는 사람이라는 걸 깨달았습니다.

마음이 아픔과 동시에 그 당시 슬럼프에 빠질뻔 한 저를 구해줬던 책이 있었는데, Grant Cardon의 "10배의 법칙"이라는 책을 읽으며 책에서 하라는 대로 무식하게 다 따르기 시작했습니다.

저는 당장 제 방 벽을 화이트보드로 써서 10배의 법칙들을 써내려갔고, 다른 한쪽 벽에는 제 인생 목표들을 10가지 썼습니다 (아침에 눈 뜨자마자 보면서 큰 소리로 읽기 위해).

10배.png이를 토대로 갑자기 삘이 와서 <10배의 법칙> 오픈톡방을 만들어서 친구들을 몇 초대한 후 매일매일 톡방에 이 형식으로 카톡을 올렸습니다.

1. 오늘 삶의 목표들을 적었는지

2. 오늘 목표들을 이루기 위해 한 일들:

3. 내일 할 일들:

4. 힘들었던 부분, 내 자신을 칭찬하고 싶은 부분, 혹은 그 외의 말 아무거나

인스타에 스토리를 매일 올리듯이 10배의 법칙 클럽에 매일 채팅을 보냈고, 그 결과 매일 하루가 끝나기 전 오늘 하루를 회상하면서 제가 10000분의 1 스텝이라도 조금씩 목표를 달성하기 위해 나아가고 있는듯한 느낌이 들었습니다.

클럽을 시작했을 당시에 저는 VC들이 왜 Crypto/blockchain 분야에 투자하는지 알고싶었고, 이걸 혼자서 어떻게라도 배워야겠다는 목표가 있었습니다.

6월 14일 시작해서 한달 후인 7월 10일날 업데이트 차원에서 브런치에 올렸던 글입니다. https://brunch.co.kr/@hyerimyong/16

여기까지 오기에 한 달이라는 시간이 걸렸지만, 블록체인에 투자한 시간만 계산해보면 70시간밖에 되지 않았다. 40-45시간들을 투자한 시점부터 학습 곡선이 좀 빨라진 것 같고, 누군가와 블록체인 관련 대화들을 할 수 있는 정도가 되었다. 내가 어느 정도 스스로 한 것도 있지만 주변에서 많은 푸시를 해주고 동기부여를 해주셔서 버틸 수 있었다. 그분들에게 감사하다.

다시 한달 후가 되어 8월 초에 한국에서 Korea Blockchain Week가 열렸고, 저는 그동안 내가 머리속에 넣어두고 있었던 10배의 법칙들을 실행으로 옮길 수 있는 기회가 되었습니다. https://brunch.co.kr/@hyerimyong/21

6월에 적은 10배의 법칙들을 매일 밤마다 읽으면서 지난 2주간 내가 저 중에서 얼마나 많은 것들을 실현했는지 봤다. 

- 성공은 선택이 아닌 의무: 항상 내 머릿속에 디폴트로 자리 잡혀 있는 말

- 어떤 일이든 우연히 일어나지 않고 나 때문에 생긴다: 내가 여러 자리에 연속으로 초대되는 것을 보면서 적어도 제대로 행동하고 있다고 생각했다. 이벤트 티켓이 없으면 티켓이 생길 때까지 여러분들에게 여쭤보고 구해서 참석했다. 내가 실현하고자 하면 안 되는 일은 절대 없었다. 조금의 창의력과 노력만을 하면 무엇이든 할 수 있다. 못하겠다, 안 할 거다 생각부터 든다면 당신은 현재 간절하지 않은 것이다. 그게 두려워서 기회를 놓친다는 건 정말 안타까운 일이다. 

- 질보다 양이 중요. 내 문제는 재능이 아니라 이름 없음이다: 2주간 내 이름을 적어도 50명에게는 알렸던 것 같다. 내가 어떤 사람인지, 무엇에 관심이 있고 현재 뭘 하고 있는지 알렸고, 감사하게도 가장 많이 들었던 소리는 'You're a very interesting person'이었다. 생각보다 많은 사람들은 내 이야기를 경청해주었고, 덕분에 더 깊은 관계를 유지할 수 있었던 것 같다. 

- Never be satisfied. 행동의 수준을 10배로 높여라: 몸이 망가질 때까지 모든 행사들을 참여하면서 돌아다녔다. 애프터파티, 애프터애프터파티까지 다니면서 사람들과 더 가까워질 수 있었다. 괜찮은 줄 알았는데 사실 현재 목소리가 아예 안 나오고 있고 알게모르게 엄청난 스트레스를 받아서 밥을 제대로 못 먹고 있고 토할 것 같다. 불안장애, 공황장애의 증상들을 겪고 있다. 

- Don't play by the rules. Don't compete, monopolize. 독점해라.: 난 현재 블록체인을 배운 지 2달밖에 되지 않았고, 정식으로 속해있는 곳도 없다. 상관없다. 직원이 아니어서, 블록체인에 대해 아무것도 몰라서 할 수 없는 일은 없다. 그저 배울 의지가 있다면 된다. 처음에는 두려웠지만 그 두려움을 이기고 행동으로 옮기다 보면 점점 무뎌진다. 블록체인 회사 대표님들에게 다가가서 자기소개를 하고 그 프로젝트에 대한 질문을 하는 게 처음엔 무서울 수 있겠지만 계속하다 보면 익숙해진다. 생각보다 많은 분들은 업계에서 newbie라고 하고 대학생이라 배우고 있는 중이라 하면 더 좋아해주시고 더 서포트해주시려고 한다. 내가 지식이 없어서 다른 분들이 나를 멍청하게 볼까봐 걱정이 된다면, 그 걱정은 전혀 안 해도 된다. 오히려 더 친절하게 설명해주시고 더 많은 리소스들을 추천해주신다. 그냥 계속 부딪혀라. 

- 에너지, 노력, 창의력. 만날 수 있는 고객 수에는 한계가 없다.: 매일매일 새로운 사람을 만났고, 또 만나고 또 만나면서 관계를 유지했다. 이분들을 통해 배운건 셀 수 없을 만큼 많다. 

- All in, 무리한 약속. 어차피 살아야 할 인생 열심히 살아라: 모두 실천함. 

- '좀 쉬어'라고 하는 사람을 조심하자. '이 정도면 충분해'는 없다: 주변 분들 중에 나를 걱정해주시면서 조심하라고 하신 분들이 있다. 그분들의 걱정은 좋지만, 난 2주간 내가 어디까지 갈 수 있는지 내 한계치를 시험해보고 싶었기 때문에 일주일 동안 잠을 20시간밖에 자지 못했어도 계속 나아갔다. 지금도 더 더 더 하는 중이다. 더 달리자. 

- Surround yourself with successful people: 항상 같은 무리의 사람들과 지내면 발전할 기회는 10%도 있지 않다고 생각한다. 24살, 25살인 두 대표님을 만났다. 그분들이 어린 나이에 그렇게 빨리 성공할 수 있었던 이유는 인생의 치트키를 찾아서이다. 그 사람들이 공통적으로 하는 생각들과 행동들이 있다. 그걸 캐치하고 따라하려면 현재 나의 bubble에서 벗어나야 한다. 

- 지금 행동하라. 준비는 필요 없음. 필요하다면 이미 늦은 거. 어떻게서든 일단 하고 실패하고 진전: 이 부분에 대해서는 전적으로 동의하지 않는다. 무엇이든 준비는 필요하다. 이 이벤트가 있기 전에 난 최소 100시간의 시간과 노력을 블록체인에 투자했기 때문에 좀 더 쉽게 사람들에게 다가가고 대화를 나눌 수 있었다. 그러니까 더 좋은 기회를 잡으려면 이미 그전부터 노력을 하고 있었어야한다는 것. 

운 좋게도 저를 좋게 봐주시는 분이 여러명 계셨고, 여러 곳에서 스카웃 제의가 들어와서 면접을 본 후 블록체인 스타트업에 들어갈 수 있게 되었습니다.

두달간 클럽을 하면서 그동안 썼던 10개의 목표 중 3-4개가 달성이 되었더라구요.

저때로부터 딱 1년이 지났는데, 저 또한 인간이기에 제가 바랐던 목표가 달성될수록 제 태도가 불성실하게 변했고, 지금은 훨씬 덜 간절해진 것 같은 느낌이 듭니다.

이젠 다시 원점으로 돌아온 기분입니다. 그래서 저는 당시에 저를 살려준 10배의 법칙 클럽을 다시 시작할 생각입니다.

작년에는 소수의 친구들이랑만 클럽을 했는데, 이번에는 더 많은 분들과 함께 클럽을 하고 싶습니다.

친구들이랑 같이 하다보니, 친구들이 올릴 때마다 10배의 법칙이 생각나면서 저도 잊지 않고 계속 올리게 되더라구요.

클럽을 조인하고 싶으시다면 오픈채팅방 링크로 입장해주세요. 저는 오늘부터 매일매일 업로드 할 예정입니다.

채팅방에서 따로 인사나 자기소개 같은거 안하셔도 됩니다. 말 그대로 메모장처럼 쓰는 클럽입니다.

레쯔꼬!

KakaoTalk_Photo_2023-08-11-01-06-51.jpeg(작년 8월 9일 채팅)

10X 자기개발 Club

자기개발 클럽 단톡방

18
6
Cailyn Yong

Cailyn Yong

성공할 아이디어 빠르게 찾는 법 = 불가능

초기 스타트업이라면 돈과 시간이 부족해서 최단 기간 내에 최대한 효율적으로 성공할 아이디어를 찾으려는 목표가 있다. 두가지 방법이 있는데,

  1. 안전한 방법: Idea validation부터 하기. MVP를 개발하기 전, 랜딩페이지와 아이디어만 갖고 얼마나 많은 사람들이 반응을 하는지 보기.

    • 장점: 아이디어가 실패할 일이 없다. 이미 검증이 됐으니까

    • 단점: 이 성공할 아이디어를 찾기까지 무한한 시간이 걸릴 가능성이 높다.

  2. 불안전한 방법: 일단 뭐라도 build하기. 계속 build하면서 실패하고, 또 만들고 또 실패하면서 찾기

    • 장점: 유저와 가장 가깝게 접근하면서 커뮤니케이션 할 수 있는 방법. 실제로 그들이 무엇을 원하는지 더 빨리 찾을 수 있음.

    • 단점: 프로덕트를 만드는데에 쏟는 시간과 비용이 많이 들 수 있음.

우리팀은 현재 불안전한 방법으로 계속 프로덕트를 빌드해서 유저들에게 사용하게하고 버그가 생기면 또 고치고 또 만드는 방식으로 해나갔다. 불안전한 방법의 단점을 커버하고자 팀 내부적으로 "2주단위로-feature는 한가지씩" 이런식으로 계속 제품을 만들고 있다.

어느 한쪽 방법만이 맞다고 할 수 없다. 우리는 2번째 방법으로 해나가고 있고, 이를 통해 빠르게 유저가 무엇을 원하는지와 무엇을 안쓰는지 확인을 할 수 있다. '이게 될까?'라는 상상력 풀가동을 하기보단 일단 빠르게 만들어서 직접 확인해보는게 최선인 것 같다.

덕분에 오늘 잠재고객에게 현재 제품을 쓰게 했는데

  1. 우연히 새로운 타겟 페르소나를 발견했고

  2. 알고보니 우리 제품을 쓰는 사람들이 우리가 가정한 타겟층보단 이 페르소나에 더 가까웠고

  3. 이번주내로 프로덕트를 이 방향으로 업데이트할 예정이다.

CtrlX

Search in Videos

10
4
Cailyn Yong

Cailyn Yong

스타트업 창업한지 1달째 배운점 기록

  • 마케팅보단 프로덕트의 성능과 퀄리티가 중요하다. 쓸데없는 홍보보다는 제품에 먼저 집중을 하자.

  • 내가 만든 뽀대나는 아이디어는 그냥 '오 신기한 툴이네'에서 끝남. 유저를 위한 툴을 만들어야함.

  • 최단기간, 최저가로 product market fit을 찾을 수 있는 창의적인 방법들을 모색하는 것이 젤 중요. 나만의 데이터 지표를 만들기 위함.

  • 단 한명의 유저라도 계속 쓸 의향이 있다면 PMF는 찾은 것.

  • 아이디어가 될 놈인지 구분할 수 있는 지표:

    • '사전 신청하기' 폼에 유효한 이메일을 입력했다면 1점

    • 베타 프로덕트에 할애한 시간만큼 분당 1점

    • 실제로 프로덕트까지 구입했다면 $1당 1점

    • 의견, 격려 혹은 비난, SNS에서 받은 좋아요 수: 0점.

  • 항상 겸손하자. 초심을 잃지 말자.

CtrlX

Search in Videos

20
4