인공지능 개발자 수다(유튜브 바로가기) 자세히보기

자연어처리/Langchain

[Langchain] Tools 사용하기 (1)

Suda_777 2025. 3. 18. 02:28

목차

    반응형

    에이전트(Agent)를 구성할 때는 에이전트가 사용할 수 있는 도구 목록(Tools)을 제공해야 한다.

    또한, 도구는 도구 호출을 지원하는 모델에 연결되어야 한다.

    tool_calling에 체크가 되어 있는 모델을 사용하자 (링크)

     

    Chat models | 🦜️🔗 LangChain

    Chat models are language models that use a sequence of messages as inputs and return messages as outputs (as opposed to using plain text). These are generally newer models.

    python.langchain.com

     

    1. Tool 생성

    1.1. 함수로 Tool 생성

    Tool은 함수를 이용해 데코레이터로 생성할 수 있으며,

    다음과 같은 구성 요소가 있다.

    속성 타입 설명
    name str LLM이나 에이전트에게 제공되는 도구 세트 내에서 고유해야 함
    description str tool 설명. (함수의 주석으로 대체해서 사용할 수도 있음)
    args_schema pydantic.BaseModel input의 형태를 정의함, 권장사항
    return_direct boolean 에이전트에만 해당. True인 경우, 주어진 도구를 호출한 후 에이전트는 중지하고 결과를 사용자에게 직접 반환
    parse_docstring boolean 함수의 주석을 파싱한다. 주석(독스트링)을 적절히 작성하면, LangChain이 해당 정보를 읽고 자동으로 메타데이터에 반영한다. description과 같은 역할을 한다.

     

    예시 코드

    from pydantic import BaseModel, Field
    
    
    class CalculatorInput(BaseModel):
        a: int = Field(description="first number")
        b: int = Field(description="second number")
    
    
    @tool("multiplication-tool", args_schema=CalculatorInput, return_direct=True)
    def multiply(a: int, b: int) -> int:
        """Multiply two numbers."""
        return a * b

     


    1.2. Runnables로 Tool 생성

    as_tool() 메서드로 만들 수 있다.

    from langchain_core.language_models import GenericFakeChatModel
    from langchain_core.output_parsers import StrOutputParser
    from langchain_core.prompts import ChatPromptTemplate
    
    prompt = ChatPromptTemplate.from_messages(
        [("human", "Hello. Please respond in the style of {answer_style}.")]
    )
    
    # Placeholder LLM
    llm = GenericFakeChatModel(messages=iter(["hello matey"]))
    
    chain = prompt | llm | StrOutputParser()
    
    as_tool = chain.as_tool(
        name="Style responder", description="Description of when to use tool."
    )
    as_tool.args

     


    1.3. BaseTool로 Tool 생성

    BaseTool을 상속받고,

    필요한 속성을 정의하고

    메서드를 오버라이딩 해준다.

    from typing import Optional
    
    from langchain_core.callbacks import (
        AsyncCallbackManagerForToolRun,
        CallbackManagerForToolRun,
    )
    from langchain_core.tools import BaseTool
    from langchain_core.tools.base import ArgsSchema
    from pydantic import BaseModel, Field
    
    
    class CalculatorInput(BaseModel):
        a: int = Field(description="first number")
        b: int = Field(description="second number")
    
    
    # Note: It's important that every field has type hints. BaseTool is a
    # Pydantic class and not having type hints can lead to unexpected behavior.
    class CustomCalculatorTool(BaseTool):
        name: str = "Calculator"
        description: str = "useful for when you need to answer questions about math"
        args_schema: Optional[ArgsSchema] = CalculatorInput
        return_direct: bool = True
    
        def _run(
            self, a: int, b: int, run_manager: Optional[CallbackManagerForToolRun] = None
        ) -> str:
            """Use the tool."""
            return a * b
    
        async def _arun(
            self,
            a: int,
            b: int,
            run_manager: Optional[AsyncCallbackManagerForToolRun] = None,
        ) -> str:
            """Use the tool asynchronously."""
            # If the calculation is cheap, you can just delegate to the sync implementation
            # as shown below.
            # If the sync calculation is expensive, you should delete the entire _arun method.
            # LangChain will automatically provide a better implementation that will
            # kick off the task in a thread to make sure it doesn't block other async code.
            return self._run(a, b, run_manager=run_manager.get_sync())

     


    2. Tool 결과 Model에 반환

    Langchain은 도구가 필요할때,

    스스로 찾아서 사용한다는 특징이 있다. (진짜 너무 편리하다..)

    그리고 Tool의 결과는

    모델에 ToolMessage로 전달된다!

     

     

    Model 정의

    import getpass
    import os
    
    if not os.environ.get("GROQ_API_KEY"):
      os.environ["GROQ_API_KEY"] = getpass.getpass("Enter API key for Groq: ")
    
    from langchain.chat_models import init_chat_model
    
    llm = init_chat_model("llama3-8b-8192", model_provider="groq")

     

    도구 정의

    from langchain_core.tools import tool
    
    
    @tool
    def add(a: int, b: int) -> int:
        """Adds a and b."""
        return a + b
    
    
    @tool
    def multiply(a: int, b: int) -> int:
        """Multiplies a and b."""
        return a * b
    
    
    tools = [add, multiply]
    
    llm_with_tools = llm.bind_tools(tools)

     

    도구 호출

    from langchain_core.messages import HumanMessage
    
    query = "What is 3 * 12? Also, what is 11 + 49?"
    
    messages = [HumanMessage(query)]
    
    ai_msg = llm_with_tools.invoke(messages)
    
    print(ai_msg.tool_calls)
    
    messages.append(ai_msg)

     

    반응형