가수면

[기본] LangChain 본문

Python/LLM

[기본] LangChain

니비앙 2024. 6. 30. 20:37

LLM 애플리케이션 기본 구현 방식

from langchain.prompts.prompt import PromptTemplate
from langchain_openai import ChatOpenAI
from langchain_core.output_parsers import StrOutputParser
from third_parties.linkedin import scrape_linkedin_profile

summary_template = """
링크드인의 유저 정보를 줄테니 아래 요구사항에 맞춰 답변을 생성해주세요.
1. 짧은 요약
2. 흥미로운 사실 2가지

{information}
"""

summary_prompt_template = PromptTemplate(
    input_variables=["information"], template=summary_template)

# temperature :  언어 모델이 얼마나 창의적인지 (0이면 창의적이지 않음)
llm = ChatOpenAI(temperature=0, model="gpt-3.5-turbo")

parser = StrOutputParser()

chain = summary_prompt_template | llm | parser

linkedin_data = scrape_linkedin_profile(
    linkedin_profile_url="https://www.linkedin.com/in/eden-marco/", mock=True)

res = chain.invoke(input={"information": linkedin_data})

print(res)

Prompt templates

사용자 입력을 언어 모델에 전달할 수 있는 형식으로 포맷하는 역할

. from_template / .partial() - 템플릿을 조금 더 유연하게 재사용할 수 있도록 해주는 메소드

예시 1) 프롬프트 명시적 사용

from langchain.prompts import PromptTemplate

# 템플릿과 변수를 명시적으로 지정
template_str = "Hello, {name}! Welcome to {place}."
prompt = PromptTemplate(
    input_variables=["name", "place"],
    template=template_str
)

# 변수 값을 채워서 프롬프트 생성
filled_prompt = prompt.format(name="Alice", place="Wonderland")
print(filled_prompt)  # 출력: Hello, Alice! Welcome to Wonderland.

예시 2) 프롬프트를 유연하게 재사용

from langchain.prompts import PromptTemplate

# 기본 템플릿 문자열
template_str = "Hello, {name}! Welcome to {place}. Your role is {role}."
prompt = PromptTemplate.from_template(template=template_str)

# 일부 변수를 미리 채운 템플릿 생성
partial_prompt = prompt.partial(place="Wonderland")

# 나머지 변수 값을 채워서 프롬프트 생성
filled_prompt = partial_prompt.format(name="Alice", role="Adventurer")
print(filled_prompt)  # 출력: Hello, Alice! Welcome to Wonderland. Your role is Adventurer.

 

Chat models (ChatOpenAI)

메시지를 받아서 출력하는 언어 모델.

 

Output parsers

LLM의 출력은 text 형식이기 때문에 다른 프론트엔드나 백엔드에서 요청을 통해 사용하기 위해선 직렬화가 필요함.

Output parsers는 LLM의 출력 결과를 더 구조화된 형식으로 파싱하는 역할을 함

StrOutputParser 대신 pydantic이나 json 형식으로 구조화한 예시) 

from typing import List, Dict, Any

from langchain.output_parsers import PydanticOutputParser
from langchain_core.output_parsers import JsonOutputParser
from langchain_core.pydantic_v1 import BaseModel, Field


class Summary(BaseModel):
    summary: str = Field(description="summary")
    facts: List[str] = Field(description="interesting facts about them")

    def to_dict(self) -> Dict[str, Any]:
        return {"summary": self.summary, "facts": self.facts}


def ice_break_with(name: str) -> Tuple[Summary, str]:
    linkedin_useename = lookup(name=name)
    linkedin_data = scrape_linkedin_profile(linkedin_profile_url=linkedin_useename)

    summary_template = """
        링크드인의 유저 정보를 줄테니 아래 요구사항에 맞춰 답변을 생성해주세요.
        1. 짧은 요약
        2. 흥미로운 사실 2가지

        {information}
        
        \n{format_instructions}
        """

    summary_prompt_template = PromptTemplate(
        input_variables=["information"],
        template=summary_template,
        partial_variables={"format_instructions": parser.get_format_instructions()})

    # temperature :  언어 모델이 얼마나 창의적인지 (0이면 창의적이지 않음)
    llm = ChatOpenAI(temperature=0, model="gpt-3.5-turbo")

    # parser = StrOutputParser()

    chain = summary_prompt_template | llm | parser

    res: Summary = chain.invoke(input={"information": linkedin_data})

    print(res)

    return res, linkedin_data.get("profile_pic_url")


if __name__ == "__main__":
    ice_break_with(name="Eden Marco")

 

에이전트

에이전트가 실행시킬 도구의 설정과 에이전트에게 지시할 프롬프트가 중요함

from langchain.agents import (
    create_react_agent,
    AgentExecutor,
)
from langchain_core.tools import Tool

    tools_for_agent = [
        Tool(
            name="Crawl Google 4 linkedin profile page",
            func=get_profile_url_tavily,
            description="useful for when you need get the Linkedin Page URL",
        )
    ]
    
    react_prompt = hub.pull("hwchase17/react")	# 에이전트 지침 프롬프트 (프롬프트 참고하기)
    agent = create_react_agent(
        llm=llm, tools=tools_for_agent, prompt=react_prompt)
    agent_executor = AgentExecutor(
        agent=agent, tools=tools_for_agent, verbose=True)

    result = agent_executor.invoke(
        input={"input": prompt_template.format_prompt(name_of_person=name)}
    )

    linked_profile_url = result["output"]
    return linked_profile_url

tools

에이전트가 실행하려는 함수에 대한 정보를 담음.

에이전트는 name과 description을 판단하여 함수를 실행시킬지 말지 결정함.

name

에이전트가 참조할 이름이며 추론 엔진에 제공됨. 로그에 찍히는 이름

func

에이전트가 실행할 작업 함수 이름

description

에이전트가 tool을 참조할지 말지 판단하는 속성으로 간결하면서도 필요한 내용을 담도록 구성하는 것이 매우 중요.

LangSmith

langchain의 전체 상황을 추적할 수 있음

관리 화면 - 로그인 시 접속 됨

docs  - https://docs.smith.langchain.com/

 

Get started with LangSmith | 🦜️🛠️ LangSmith

LangSmith is a platform for building production-grade LLM applications. It allows you to closely monitor and evaluate your application, so you can ship quickly and with confidence. Use of LangChain is not necessary - LangSmith works on its own!

docs.smith.langchain.com

langchain을 설치하면 기본적으로 설치되며, 추가적인 env 설정이 필요하다.

LANGCHAIN_API_KEY=
LANGCHAIN_TRACING_V2=true
LANGCHAIN_PROJECT=프로젝트 이름

langchain 실행 시 '프로젝트 이름'으로 관리 화면에 프로젝트가 생성되며, 해당 화면을 통해 상세 정보들을 파악할 수 있다.

'Python > LLM' 카테고리의 다른 글

프롬프트 엔지니어링  (0) 2024.07.22
토큰 한도 처리 전략  (4) 2024.07.22
Agent 구현  (0) 2024.07.17
Vector Db, Embedding  (0) 2024.07.07
Comments