Notice
Recent Posts
Recent Comments
Link
«   2026/06   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
Tags
more
Archives
Today
Total
관리 메뉴

개발자가 될래요

[플레이데이터 SK네트웍스 Family AI 캠프 23기] 11주차 회고 본문

SKN_Family_AI

[플레이데이터 SK네트웍스 Family AI 캠프 23기] 11주차 회고

Youcan 2026. 2. 8. 19:52

회고 방식


The four Fs

  • FACTS(사실, 객관) : 이번 일주일 동안 있었던 일, 내가 한 일
  • FEELINGS(느낌, 주관) : 나의 감정적인 반응, 느낌
  • FINDINGS(배운 것) : 그 상황으로부터 내가 배운 것, 얻은 것
  • FUTURE(미래) : 배운 것을 미래에는 어떻게 적용할 지

FACTS

이번 주는 LLM을 호출하는 단계에서 더 나아가, LangChain 기반으로 구성 요소를 조립해서 만드는 방식을 집중적으로 다뤘다.

 

1. Fine-tuning 결과물 사용 (sarcastic chatbot)

- 이미 만들어진 파인튜닝 모델 ID를 지정하고, 시스템 프롬프트로 답변 말투를 고정한 뒤, 호출하는 형태를 실습했다.

FINE_TUNED_MODEL = "ft:gpt-4.1-mini-2025-04-14..."
SYSTEM = "너는 사실을 말하지만, 빈정대거나 비꼬는 말투로 응답하는 챗봇이다."

def run_ft_chat(user_text: str):
    response = client.chat.completions.create(
        model=FINE_TUNED_MODEL,
        messages=[
            {"role":"system","content":SYSTEM},
            {"role":"user","content":user_text}
        ],
        temperature=0.7
    )
    return response.choices[0].message.content

 



2. KorQuAD 데이터셋으로 파인튜닝 데이터 형태 만들기

- json 파일을 받아 구조를 확인하고, question -> answer 형태로 정제한 뒤, OpenAI fine-tuning에서 쓰는 JSONL(messages 배열) 포맷으로 변환해 파일로 저장했다.

results = []
for q, a in final_refined_dict.items():
    results.append({
        "messages": [
            {"role":"system","content":"당신은 정보력이 강한 챗봇입니다."},
            {"role":"user","content":q},
            {"role":"assistant","content":a}
        ]
    })

with open("korquad_finetuning_train.jsonl","w",encoding="utf-8") as f:
    for row in results:
        f.write(json.dumps(row, ensure_ascii=False) + "\n")

 

3. LangSmith 트레이싱

- .env 기반으로 LANGSMITH_TRACING, LANGSMITH_ENDPOINT, LANGSMITH_PROJECT, LANGSMITH_API_KEY를 세팅하고, Agent의 실행 결과를 확인한다.

from dotenv import load_dotenv
import os

load_dotenv()

os.environ['OPENAI_API_KEY'] = os.getenv("openai_key")
os.environ['LANGSMITH_TRACING'] = 'true'        # LangSmith 트레이싱 활성화
os.environ['LANGSMITH_ENDPOINT'] = 'https://api.smith.langchain.com'       # LangSmith API 엔드포인트 설정
os.environ['LANGSMITH_PROJECT'] = 'skn23-langchain'             # LangSmith 프로젝트명 설정
os.environ['LANGSMITH_API_KEY'] = os.getenv("langsmith_key")           # .env의 langsmith_key 값을 LANGSMITH_API_KEY로 등록

from langchain_core.prompts import PromptTemplate
from langchain.chat_models import init_chat_model
from langchain_core.output_parsers import StrOutputParser

prompt = PromptTemplate.from_template('{country}의 수도는 어디인가요?')
llm = init_chat_model('gpt-4.1-mini')
output_parser = StrOutputParser()       # 응답을 최종 문자열로 변환

chain = prompt | llm | output_parser    # chain : 프롬프트 -> LLM -> 파서 

print(chain.invoke(input={'country' : '대한민국'})) # dict 형태로 변수를 주입해서 실행
print(chain.invoke('대한민국'))         # 프롬프트 템플릿 변수가 2개 이상인 경우 오류가 발생할 수 있다.


# 대한민국의 수도는 서울특별시입니다.
# 대한민국의 수도는 서울특별시입니다.

 

 

 

 

4. LCEL (LangChain Expression Language)

- RunnableLambda, RunnableSequence, RunnableParallel, RunnablePassthrough 같은 Runnable들을 조합하면서 체인처럼 코드로 조립하는 실습을 하였다.

 

 

 

FEELINGS

 

이번 주는 이론적인 내용이나 개념 이해보다는 어떤 라이브러리를 조합해서 어떻게 프롬프트를 설정하느냐가 더 중요했던 것 같다. 그리고 prompt | llm | parser 로 연결되는 형태를 반복 실습하면서 빠르게 적응할 수 있었던 것 같다.

 

 

FINDINGS

 

LangChain은 “기능”이 아니라 “설계 방식”을 주는 도구이다.

기존에 LLM에 대해 배우기 전에 'LangChain'이라는 이름을 들었을 때는, 특정 기능을 가지고 있는 라이브러리 라고 생각했었는데, LLM을 그냥 호출하는 게 아니라 구성요소 단위로 나눠서 교체/확장 가능하게 만드는 방식이었다.

- Prompt는 Prompt대로, Model은 Model대로, Parser는 Parser대로, Retrieval은 Retrieval대로 분리한 상태에서, 한 부분만 바꿔도 전체 파이프라인을 유지할 수 있었다.

 

 

FUTURE

프로젝트를 시작하기 전까지 시간이 조금 남아있는 상태이기 때문에, 그동안 프로젝트 아이디어를 생각해보고, 각 도메인 마다 어떻게 LLM을 어떤 방식으로 사용해야 좋을지, 프롬프트는 어떻게 작성하는 것이 좋을지 고민하는 시간을 가질 것 같다.