[7기 랭체인] Streamlit + Langchain으로 CommitBot 사이트 만들기

개발자라면 피할수없는 Commit 작성하기
이번 팀과제를 하면서 체계적으로 프로젝트를 관리하고 싶어 하는 동료분 덕에 팀과제를 하면서 처음으로 우리만의 커밋 컨밴션도 만들었습니다. 다만 제가 이런 중간과정을 상당히 귀찮아 하는게 문제라면 문제였습니다.
그래서 지금까지는 ChatGPT에 프롬프트를 작성해두고 템플릿화 해서 사용중이었는데요. 이 과정을 좀더 발전시켜서 하나의 웹사이트로 만들어봤습니다.

파이썬, Langchain, streamlit으로 구성했고 저녁10시쯤부터 새벽2시쯤 배포까지 완료했으니 확실히 엄청나게 쉬운 프레임웤인것 같습니다.

지금까지 진행된 사항에는 딱히 랭체인이 필요없었지만 대량의 git diff가 들어올경우 내용을 요약하는 과정을 이후 추가할 예정이고, 또 한글 커밋을 원하는 분들을 위해 한글로 커밋 메세지만 번역하는 기능도 추가할 예정입니다.


먼저 스트리밋, 랭체인, openai를 import합니다.

import streamlit as st
from langchain.chat_models import ChatOpenAI
from langchain.prompts import ChatPromptTemplate
from langchain.chains import LLMChain
from langchain.chains import SequentialChain


그다음 스트리밋 웹사이트의 타이틀을 작성해주고 몇가지 설정을 해줍니다


st.title("Commit Bot")

st.info("""사용법 : 1. openai_key를 입력합니다.\n
2. Commit Convention을 선택합니다.\n
3. git diff를 입력합니다. (git add 후 git diff --cached | pbcopy 하면 복사가 됩니다.)\n
4. Submit 버튼을 누릅니다.
git diff 내용이 너무 많으면 작동하지 않습니다.\n
꼭 작게 나눠서 사용하세요. 파일1개 혹은 해더 + 관련하일 한개 정도로 사용하시는걸 추천합니다.\n
영어만 가능합니다. 한국어는 추후 업데이트 예정입니다.\n
""")

api_key = st.sidebar.text_input('OpenAI API Key', type='password')


사이드 바에서 커밋 컨밴션 선택지에 따라 이후 프롬프트에 적용될 커밋 컨밴션을 작성해줍니다.

사실 이부분에서 토큰을 아끼기 위해 유명한 커밋컨밴션의 경우 “**커밋 컨밴션으로 커밋작성해주세요” 식으로 프롬프트를 구성해봤는데 생각만큼 잘 되지 않아서 커밋컨밴션 룰을 따로 작성해 선택지에 맞춰 적용되도록 했습니다.


options = ["Conventional Commits", "Angular Commit Guidelines", "Gitmoji Commit Guidelines", "Semantic Commit Messages", "Karma Runner Commit Msgs", "Atom Editor Commit Messages", "Custom Commit Convention"]
selected_option = st.sidebar.radio("원하는 선택지를 선택하세요:", options, index=0)

if selected_option == "Conventional Commits":
    selected_option = """Conventional Commits
    Format of the Commit Message:
    The commit message should be structured as follows:
    
    """

커스텀 커밋 컨밴션이 조금 까다로웠는데 우리의 똑똑한 친구 ChatGPT가 해결해주어 잘 적용했습니다.

선택지에서 커스텀 커밋컨밴션을 선택하고 커스텀 커밋컨밴션 입력창에 내용이 입력되어있으면 system prompt에 적용되게 했습니다.

Custom_Commit = st.sidebar.text_area("Custom Commit Convention:", height=100)


이 다음부터는 랭체인의 영역입니다. 필요한 입력값은 다 받았으니 프롬프트에 하나씩 적용시켜 하나의 프롬프트로 만들고 실행시켰습니다. 사실 이렇게 하나의 프롬프트만 동작할때에는 랭체인을 쓸 이유가 없지만, 이후 추가되는 기능을 위해 랭체인으로 구현했습니다.

벌써 2주차쯤 오니 랭체인으로 하나의 프롬프트를 동작시키는건 너무나 쉬운일이었고 코드자체도 쉬웠습니다. 다만 알면 알수록 프롬프트 엔지니어링을 통해 일관된 답변을 얻도록하는게 더 어려웠습니다. 프롬프트 엔지니어링을 더 공부해야 좀더 일관성있는 결과물을 얻을수있겠습니다.


system = "Please refer to the git diff and write your commit message according to the commit convention. Do not include unnecessary comments beyond the commit message."

def generate_commit_message(text_input, commit_convention, system, api_key=None, flag=0):
    if not api_key:
        st.error('API Key is missing.')
        return

    data = {'code': text_input, 'commit_convention': commit_convention, 'system': system}

    llm = ChatOpenAI(temperature=0.9, model="gpt-3.5-turbo-16k-0613", openai_api_key=api_key)  # 수정된 부분
    
    default_prompt = ChatPromptTemplate.from_template(
        """
        instruction : 
        ```
        {system}
        ```
        Commit Convention : 
        ```
        {commit_convention}
        ```
        git diff : 
        ```
        {code}
        ```
        """
    )
    default_chain = LLMChain(llm=llm, prompt=default_prompt, output_key="commit_message")
    overall_chain = SequentialChain(
        chains=[default_chain],
        input_variables=["code", "commit_convention", "system"],
        output_variables=["commit_message"],
        verbose=False
    )
    st.info(overall_chain(data)['commit_message'])

with st.form(key='my_form'):
    text_input = st.text_area(label='Enter your commit message here', height=300)
    submit_button = st.form_submit_button(label='Submit')
    if not api_key.startswith('sk-'):
        st.error('Please enter a valid OpenAI API Key')
    if submit_button and api_key.startswith('sk-'):
        # generate_commit_message(text_input, 'angular', system, api_key=api_key)  # api_key를 명시적으로 전달
        if selected_option == "Custom Commit Convention":
            if Custom_Commit:
                generate_commit_message(text_input, Custom_Commit, system, api_key=api_key, flag=1)
        else:
            generate_commit_message(text_input, selected_option, system, api_key=api_key, flag=0)

깃허브 링크[cfcf26/CommitBot (github.com)]

커밋봇 링크[Streamlit (commitbot.streamlit.app)]

4
4개의 답글

👉 이 게시글도 읽어보세요