북극의 한가운데서 산타의 엘프 팀은 전 세계 어린이들이 보낸 수백만 통의 편지를 어떻게 처리할 것인가라는 거대한 물류 문제에 직면했습니다. 산타는 결연한 표정으로 크리스마스 작전에 인공 지능을 도입하기로 결정합니다.
산타는 최신 AI 기술이 탑재된 컴퓨터 앞에 앉아 Jupyter Notebook에서 Python 스크립트를 작성하기 시작합니다. 목표는 야심찬 만큼이나 간단했습니다. 생성형 AI와 LLM의 힘을 활용해 손으로 쓴 편지를 해석하고 필요한 데이터를 추출하여 Elasticsearch에서 정리하는 것이었습니다.
설치
Elasticsearch와 Kibana 설치
설치 중에 설치할 Elastic Stack 8.x를 선택해 주세요. 설치하는 동안 다음과 같은 설치 정보를 확인할 수 있습니다:
다음 데모에서는 Elastic Stack 8.11을 사용하겠습니다.
Python
원하는 버전의 Python을 설치할 수 있습니다. 버전 3.8 이상. 또한 다음 Python 패키지를 설치해야 합니다:
pip3 install python-dotenv elasticsearch langchain openai
Data
표시를 위해 현재 디렉터리에 다음 .env 파일을 만들어야 합니다:
.env
1. $ pwd
2. /Users/liuxg/python/elser
3. $ cat .env
4. ES_USER="elastic"
5. ES_PASSWORD="yarOjyX5CLqTsKVE3v*d"
6. ES_ENDPOINT="localhost"
7. OPENAI_API_KEY="YourOwnOpenAiKey"
Elasticsearch 구성에 따라 위의 값을 수정할 수 있습니다. 이를 사용하려면 OpenAI 키를 요청해야 합니다.
Elasticsearch에 액세스할 수 있으려면 현재 작업 디렉터리에 Elasticsearch 자격 증명을 복사해야 합니다:
1. $ pwd
2. /Users/liuxg/python/elser
3. $ cp ~/elastic/elasticsearch-8.11.0/config/certs/http_ca.crt .
4. $ ls http_ca.crt
5. http_ca.crt
해독하려는 손글씨 편지는 해당 주소 다운로드할 수 있습니다:
애플리케이션 디자인
프로젝트의 현재 디렉토리에서 실행됩니다:
1. $ pwd
2. /Users/liuxg/python/elser
3. $ jupyter notebook
첫 번째 단계는 OpenAI 및 Elasticsearch API에 액세스하기 위한 자격 증명으로 사용할 환경 변수를 설정하는 것입니다.
1. import os
3. from dotenv import load_dotenv
5. load_dotenv()
7. # OpenAI API Key
8. OPENAI_API_KEY = os.getenv('OPENAI_API_KEY')
9. OPENAI_API_URL = "https://..com/v1/chat/completions"
11. elastic_user=os.getenv('ES_USER')
12. elastic_password=os.getenv('ES_PASSWORD')
13. elastic_endpoint=os.getenv("ES_ENDPOINT")
14. openai_api_key=os.getenv('OPENAI_API_KEY')
다음으로 산타는 디지털화된 크리스마스 편지 이미지를 사용하여 스크립트를 작성하고 "gpt-4-vision-preview"를 사용하여 텍스트를 추출했습니다. 이 중요한 단계는 손으로 쓴 텍스트를 디지털 텍스트로 변환하는 것입니다. "GPT-4-vision-preview"는 이미지 처리 및 분석 기능을 포함하도록 확장된 OpenAI의 GPT-4 언어 모델의 실험적 버전입니다.
1. from PIL import Image
2. import requests
3. import numpy as np
5. from langchain.chat_models import ChatOpenAI
6. from langchain.schema.messages import HumanMessage, SystemMessage
8. image_path = 'https://..com/.png'
10. chat = ChatOpenAI(model="gpt-4-vision-preview", max_tokens=512, openai_api_key=openai_api_key)
11. result = chat.invoke(
12. [
13. HumanMessage(
14. content=[
15. {"type": "text", "text": "What is in the picture? Please provide a detailed introduction."},
16. {
17. "type": "image_url",
18. "image_url": {
19. "url": image_path,
20. "detail": "auto",
21. },
22. },
23. ]
24. )
25. ]
26. )
29. print(result.content)
그러면 LangChain이 작동하여 텍스트를 분석하고 자녀의 이름과 위시리스트와 같은 주요 요소를 식별합니다.
1. from langchain.prompts import PromptTemplate
2. from langchain.chat_models import ChatOpenAI
3. from langchain.schema import StrOutputParser
5. chain = ChatOpenAI(model="gpt-3.5-turbo", max_tokens=1024)
7. prompt = PromptTemplate.from_template(
8. """
9. Extract the list and child's name from the text below and return the data in JSON format using the following name:
10. - "child_name", "wishlist".
12. {santalist}
14. """
15. )
17. runnable = prompt | chain | StrOutputParser()
19. letter = result.content
20. wishlist = runnable.invoke({"santalist": letter})
21. print(wishlist)
산타는 데이터베이스를 조금 더 보강하기로 결정하고 AI에게 선물의 무게를 추정해 달라고 요청했습니다. 이렇게 해서 그는 Kibana에서 목록을 생성하여 아이들의 선물을 각 가방에 나누어 썰매의 공간에 넣을 수 있었습니다. 정말 체계적이었습니다!
1. chain = ChatOpenAI(model="gpt-3.5-turbo", max_tokens=1024)
3. prompt = PromptTemplate.from_template(
4. """
6. {santalist_json}
8. From the JSON above, include a new attribute in the JSON called 'weight',
9. which will calculate the total estimated weight of each item in the list in kilograms.
11. You will first need to estimate the weight of each item individually.
12. After that, sum these values to obtain the total weight.
13. Extract only the numerical value.
15. """
16. )
18. runnable = prompt | chain | StrOutputParser()
20. new_wishlist = runnable.invoke({"santalist_json": wishlist})
21. print(new_wishlist)
이제 데이터가 구조화되었으므로 이제 Elasticsearch에 데이터를 작성할 차례입니다.
1. from elasticsearch import Elasticsearch
2. import json
4. url = f"https://{elastic_user}:{elastic_password}@{elastic_endpoint}:9200"
5. es = Elasticsearch(url, ca_certs = "./http_ca.crt", verify_certs = True)
7. es.info() # should return cluster info
9. # Parse the JSON string
10. json_string = new_wishlist
11. data = json.loads(json_string)
13. # Index name
14. index_name = "santa_claus_list"
16. # Index the document
17. response = es.index(index=index_name, document=data)
19. # Print the response from Elasticsearch
20. print(response)
산타와 엘프들은 개발 도구를 사용하여 데이터를 쉽게 검색하고 분석할 수 있습니다. 이를 통해 편지가 가장 많이 발견된 올해의 선물 트렌드를 명확하게 파악할 수 있으며, 특별하거나 긴급한 소원을 표현하는 편지는 물론 선물의 무게까지 파악할 수 있습니다. ES|QL 을 사용한 쿼리와 마찬가지로.
1. POST /_query?format=txt
2. {
3. "query": """
4. FROM santa_claus_list
5. | STATS sum_toy = SUM(weight) BY child_name
6. | LIMIT 100
7. """
8. }
지금까지는 하나의 문자만 처리되었습니다. 동일한 루틴에 따라 여러 문자를 처리할 수 있습니다. 결국 다음과 같은 통계를 얻을 수 있습니다:
1. # result
2. sum_toy | child_name
3. ---------------+---------------
4. 30.5 |Maria
5. 1.5 |Mike
6. 3.0 |Theo
7. 2.5 |Isabella
8. 40.0 |William
9. 30.0 |Olivia
이 혁신적인 솔루션을 통해 산타는 요청을 보다 효율적으로 처리할 수 있을 뿐만 아니라 전 세계 어린이들의 기쁨과 희망에 대한 귀중한 인사이트를 얻을 수 있으며, 이 모든 것은 AI, LangChain 및 Elasticsearch의 힘 덕분입니다. 올해 크리스마스는 역대 가장 마법적이고 잘 조직된 크리스마스 중 하나가 될 것입니다!
위의 코드는 다음 주소에서 다운로드할 수 있습니다: github.com/liu-xiao-gu...





