#
LlamaIndex에서 에이전트 사용하기

이전에 나왔던 도움이 되는 집사 에이전트 알프레드를 기억하시나요? 이제 그가 업그레이드를 받을 차례입니다! 이제 LlamaIndex에서 사용할 수 있는 툴들을 이해했으니, 알프레드에게 더 나은 서비스를 제공할 수 있는 새로운 기능들을 부여할 수 있습니다.

하지만 계속하기 전에, 알프레드 같은 에이전트가 어떻게 작동하는지 다시 한번 상기해봅시다. 1단원에서 우리는 다음을 배웠습니다:

> 에이전트는 사용자가 정의한 목표를 달성하기 위해 AI 모델을 활용하여 환경과 상호작용하는 시스템입니다. 작업을 수행하기 위해 추론, 계획, 액션 실행(종종 외부 툴을 통해)을 결합합니다.

LlamaIndex는 세 가지 주요 유형의 추론 에이전트를 지원합니다:

1. `Function Calling Agents` - 특정 함수를 호출할 수 있는 AI 모델과 함께 작동합니다.
2. `ReAct Agents` - 채팅이나 텍스트 엔드포인트를 수행하는 모든 AI와 함께 작동할 수 있으며, 복잡한 추론 작업을 처리합니다.
3. `Advanced Custom Agents` - 더 복잡한 작업과 워크플로우를 처리하기 위해 더 복잡한 방법을 사용합니다.

> 고급 에이전트에 대한 더 많은 정보는 BaseWorkflowAgent에서 찾을 수 있습니다.

##
에이전트 초기화

> 이 노트북을 따라가며 Google Colab에서 코드를 실행해볼 수 있습니다.

에이전트를 만들기 위해, 먼저 기능을 정의하는 함수/툴 세트를 제공합니다. 몇 가지 기본 툴로 에이전트를 만드는 방법을 살펴보겠습니다. 현재로서는 에이전트가 자동으로 함수 호출 API(사용 가능한 경우) 또는 표준 ReAct 에이전트 루프를 사용합니다.

툴/함수 API를 지원하는 LLM들은 비교적 최신이지만, 특정 프롬프팅을 피하고 제공된 스키마를 기반으로 LLM이 툴 호출을 생성할 수 있게 하여 툴을 호출하는 강력한 방법을 제공합니다.

ReAct 에이전트는 또한 복잡한 추론 작업에 능숙하며, 채팅이나 텍스트 완성 기능이 있는 모든 LLM과 함께 작동할 수 있습니다. 더 상세하며, 수행하는 특정 액션의 추론 과정을 보여줍니다.

    from llama_index.llms.huggingface_api import HuggingFaceInferenceAPI
    from llama_index.core.agent.workflow import AgentWorkflow
    from llama_index.core.tools import FunctionTool

    # 샘플 툴 정의 -- 타입 어노테이션, 함수 이름, 독스트링이 모두 파싱된 스키마에 포함됩니다!
    def multiply(a: int, b: int) -> int:
        """두 정수를 곱하고 결과 정수를 반환합니다"""
        return a * b

    # llm 초기화
    llm = HuggingFaceInferenceAPI(model_name="Qwen/Qwen2.5-Coder-32B-Instruct")

    # 에이전트 초기화
    agent = AgentWorkflow.from_tools_or_functions(
        [FunctionTool.from_defaults(multiply)],
        llm=llm
    )

에이전트는 기본적으로 상태가 없으며, 과거 상호작용을 기억하는 것은 `Context` 객체를 사용하여 선택사항입니다. 이는 여러 메시지에 걸쳐 맥락을 유지하는 챗봇이나 시간이 지남에 따라 진행 상황을 추적해야 하는 작업 관리자처럼 이전 상호작용을 기억해야 하는 에이전트를 사용하고 싶을 때 유용할 수 있습니다.

    # 상태 없음
    response = await agent.run("2 곱하기 2는 무엇인가요?")

    # 상태 기억
    from llama_index.core.workflow import Context

    ctx = Context(agent)

    response = await agent.run("내 이름은 Bob입니다.", ctx=ctx)
    response = await agent.run("내 이름이 뭐였지?", ctx=ctx)

`LlamaIndex`의 에이전트들이 Python의 `await` 연산자를 사용하기 때문에 비동기라는 것을 알 수 있습니다. Python의 비동기 코드가 처음이거나 복습이 필요하다면, 훌륭한 비동기 가이드가 있습니다.

이제 기본을 마스터했으니, 에이전트에서 더 복잡한 툴을 사용하는 방법을 살펴보겠습니다.

##
QueryEngineTools로 RAG 에이전트 만들기

에이전트 RAG는 에이전트를 사용하여 데이터에 대한 질문에 답하는 강력한 방법입니다. 알프레드가 질문에 답하는 데 도움이 되도록 다양한 툴을 전달할 수 있습니다. 하지만 문서 위에서 자동으로 질문에 답하는 대신, 알프레드는 질문에 답하기 위해 다른 툴이나 흐름을 사용할지 결정할 수 있습니다.

에이전트를 위해 `QueryEngine`을 툴로 래핑하는 것은 쉽습니다. 이렇게 할 때, 이름과 설명을 정의해야 합니다. LLM은 이 정보를 사용하여 툴을 올바르게 사용합니다. 구성 요소 섹션에서 만든 `QueryEngine`을 사용하여 `QueryEngineTool`을 로드하는 방법을 살펴보겠습니다.

    from llama_index.core.tools import QueryEngineTool

    query_engine = index.as_query_engine(llm=llm, similarity_top_k=3) # LlamaIndex의 구성 요소 섹션에서 보여진 대로

    query_engine_tool = QueryEngineTool.from_defaults(
        query_engine=query_engine,
        name="name",
        description="a specific description",
        return_direct=False,
    )
    query_engine_agent = AgentWorkflow.from_tools_or_functions(
        [query_engine_tool],
        llm=llm,
        system_prompt="You are a helpful assistant that has access to a database containing persona descriptions. "
    )

##
다중 에이전트 시스템 만들기

`AgentWorkflow` 클래스는 다중 에이전트 시스템도 직접 지원합니다. 각 에이전트에 이름과 설명을 부여함으로써, 시스템은 단일 활성 발화자를 유지하며, 각 에이전트는 다른 에이전트에게 작업을 넘길 수 있는 능력을 가집니다.

각 에이전트의 범위를 좁힘으로써, 사용자 메시지에 응답할 때 일반적인 정확도를 높이는 데 도움이 될 수 있습니다.

LlamaIndex의 에이전트들은 더 복잡하고 사용자 정의 시나리오를 위해 다른 에이전트의 툴로도 직접 사용될 수 있습니다.

    from llama_index.core.agent.workflow import (
        AgentWorkflow,
        FunctionAgent,
        ReActAgent,
    )

    # 몇 가지 툴 정의
    def add(a: int, b: int) -> int:
        """두 숫자를 더합니다."""
        return a + b

    def subtract(a: int, b: int) -> int:
        """두 숫자를 뺍니다."""
        return a - b

    # 에이전트 설정 생성
    # 참고: 여기서 FunctionAgent 또는 ReActAgent를 사용할 수 있습니다.
    # FunctionAgent는 함수 호출 API가 있는 LLM용입니다.
    # ReActAgent는 모든 LLM용입니다.
    calculator_agent = ReActAgent(
        name="calculator",
        description="기본 산술 연산을 수행합니다",
        system_prompt="당신은 계산기 어시스턴트입니다. 모든 수학 연산에 툴을 사용하세요.",
        tools=[add, subtract],
        llm=llm,
    )

    query_agent = ReActAgent(
        name="info_lookup",
        description="XYZ에 대한 정보를 찾습니다",
        system_prompt="XYZ에 대한 정보를 답하기 위해 RAG 시스템을 쿼리하는 툴을 사용하세요",
        tools=[query_engine_tool],
        llm=llm
    )

    # 워크플로우 생성 및 실행
    agent = AgentWorkflow(
        agents=[calculator_agent, query_agent], root_agent="calculator"
    )

    # 시스템 실행
    response = await agent.run(user_msg="5와 3을 더할 수 있나요?")

> 아직 충분히 배우지 못했나요? AgentWorkflow 기본 소개 또는 에이전트 학습 가이드에서 LlamaIndex의 에이전트와 툴에 대해 더 많은 것을 발견할 수 있으며, 스트리밍, 맥락 직렬화, 사람 개입에 대해 더 읽을 수 있습니다!

이제 LlamaIndex에서 에이전트와 툴의 기본을 이해했으니, LlamaIndex를 사용하여 구성 가능하고 관리 가능한 워크플로우를 만드는 방법을 살펴보겠습니다!

Update on GitHub