Unlocking the Future with Technology

Innovate, Integrate, Inspire

Popular blog posts

mockup

All blog posts

[LangChain] 블로그 본문을 자동으로 요약해보자 (feat. ChatGPT)

똑똑한 ChatGPT를 이용해보자

SEO 최적화, 글 읽는 사람의 배려를 위해서도 있지만 결국은 내가 쓴 글을 내가 더 잘 이해하려 ChatGPT의 능력을 빌려보도록 합시다!. 물론 ChatGPT 사이트에 방문하여 수동으로 요약할 수 있지만 몇 번 하다 안할게 분명하니.. 자동화시키려 노력하였습니다.

LangChain은 Javascript와 Python만 지원하는데 FastAPI로 간단하게 구현하기 위해 Python을 사용하였다.

그런데 어디다 배포를 할 것이냐!

Oracle free tier를 이미 블로그 서버로 이용 중이기 때문에 fly.io에 배포하려 한다!

Python을 써본지가 오래되었고 FastAPI 또한 처음 써보는 것이라 알음알음 검색해가며 구현해보았습니다.

그래도 일단 작동하게 만드는게 중요하니까...!

ChatGPT가 내 블로그 글을 자동으로 요약하게 만들어보자

먼저 ChatGPT API Key를 발급받아보자. 검색해보니 API를 특정 한도까지 무료로 이용가능하다고 했는데 안되길래 5달러만 충전하니 그 뒤로는 잘되었다. 음.. 왜지? 어쨌든 키를 발급받고 langchain을 설치한다.

요약 기능을 수행할 클래스를 일단 만들어본다

import os
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from bs4 import BeautifulSoup as bs

블로그 본문이 html 태그도 같이 저장되어서 html 태그를 제거해주려 BeautifulSoup도 설치해주었다.

class LLM:
    llm = ChatOpenAI(openai_api_key=os.getenv("OPENAI_API_KEY"))
    prompt = ChatPromptTemplate.from_messages(
        [
            (
                "system",
                "너는 나의 충실한 조수이다. 그리고 너는 내가 제공하는 문서를 최대 3줄로 요약해 줄 것이다. 너가 요약한 문서는 SEO에 사용될 것이다.",
            ),
            ("human", "{text}"),
        ]
    )
    chain = prompt | llm

    def remove_html_tags(self, text):
        soup = bs(text, "lxml")
        clean_text = soup.text
        return clean_text

    def summarize_text(self, text):
        clean_text = self.remove_html_tags(text)
        summary = self.chain.invoke({"text": {clean_text}})
        return summary

LLM이라는 클래스를 한 개 만들었다. html 태그를 제거하고 chatGPT한테 요약할 본문을 넘겨준다.

그럼 아주 똑똑한 ChatGPT는 수준 높게 요약된 본문을 다시 나에게 넘겨준다

이제 컨트롤러를 만들어보자

먼저, main.py에 fastAPI를 설치한다.

그리고 간단하게 API_KEY를 발급하고 해당 키를 가지고있어야 chatGPT에 작업을 요청할 수 있게 해보자.

class Post(BaseModel):
    content: str

@app.post("/api/llm")
def summerize_post(post: Post, Authorization: Union[str, None] = Header(default=None)):
    if Authorization == os.getenv("API_KEY"):
        raw_content = post.content
        clean_text = llm.summarize_text(raw_content)
        return {"content": clean_text.content}
    else:
        raise HTTPException(status_code=401, detail="Unauthorized")

CORS 도 설정했다

origins = ["http://localhost:8080"]

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["POST", "GET"],
    allow_headers=["*"],
)

요약은 아주 잘된다

요약이 잘되는 결과를 캡처하지 못하였으나 아주 똑똑하신 ChatGPT께서 3줄로 잘 요약하여 전달해준다.

블로그는 SEO가 중요하다고 한다. 그래서 Vue.js에서 Nuxt.js로 이사했다.

그리고 본문을 요약하고 meta tag description에 넣어준다.

이런게 얼마나 영향이 있는지 궁금하지만.. 그 전에 글이나 많이 써놓아야..

이제는 맞춤법을 어떻게 글 작성 창에서 바로 확인할지 고민해보아야겠다.

17 July 2024
[Nginx] 누가 내 서버에 접근했는지 알아보자(feat. 접근로그)

1. 접근 로그 형식을 설정해보자

Ubuntu 기준으로

vim /etc/nginx/nginx.conf

nginx 설정 파일을 vim으로 연다.

여러개의 내장 변수를 통해 남기고 싶은 정보만 로그에 남길 수 있다.

http {
  log_format my_log
    '[$time_local] $remote_addr '
    '$request_method $server_protocol '
    '$scheme $server_name $uri $status '
    '$request_time $body_bytes_sent '
    '"$http_referer" "$http_user_agent"';
}

$time_local : 서버가 요청 받은 시점의 로컬 시간
$remote_addr : 방문자 IP
$request_method : 요청 메소드
$scheme : HTTP or HTTPS
$status : HTTP 응답코드
$request_time : 요청 처리에 걸린 시간
$body_bytes_sent : 보낸 데이터 크기
$http_referer : 해당 요청을 보내기 전 거쳐 온 URL
$http_user_agent : 클라이언트가 사용한 브라우저 정보

2. 서버별로 로그 파일 생성 경로를 지정해보자

server { 
    access_log /var/log/nginx/my_blog/access.log my_log;
}

access_log [로그 파일 생성 경로] [로그 포맷 이름];

형식을 통해 로그 포맷과 로그 파일 생성 경로를 지정할 수 있다.

위의 설정을 통해 생성된 로그는

[18/Jun/2024:21:43:57 +0900] *.*.*.* GET HTTP/1.1 https example.com /api/category/all 200 0.001 93 "-" "node"

와 같이 출력된다.

error_log 또한 서버 별로 로그 파일 생성 경로를 지정할 수 있다.

server { 
    error_log /var/log/nginx/my_blog/error.log warn;
}

error_log는 로그 레벨을 설정할 수 있다.

debug, info, notice, warn, error, erit, alert, emerg 이다. (오른쪽으로 갈수록 심각하다)

error_log는 access_log와는 다르게 로그 형식 지정이 불가능하다.

18 June 2024
all-post-img
  • 1
@Designed By gomdolog.