# LlamaIndex에서 툴 사용하기

**명확한 툴 세트를 정의하는 것이 성능에 중요합니다.** [1단원](../../unit1/tools)에서 논의했듯이, 명확한 툴 인터페이스는 LLM이 사용하기 쉽습니다.
인간 엔지니어를 위한 소프트웨어 API 인터페이스와 마찬가지로, 툴이 어떻게 작동하는지 이해하기 쉽다면 더 많은 것을 얻을 수 있습니다.

**LlamaIndex에는 네 가지 주요 유형의 툴**이 있습니다:

![툴](https://huggingface.co/datasets/agents-course/course-images/resolve/main/en/unit2/llama-index/tools.png)

1. `FunctionTool`: 모든 Python 함수를 에이전트가 사용할 수 있는 툴로 변환합니다. 함수가 어떻게 작동하는지 자동으로 파악합니다.
2. `QueryEngineTool`: 에이전트가 쿼리 엔진을 사용할 수 있게 하는 툴입니다. 에이전트는 쿼리 엔진 위에 구축되므로 다른 에이전트도 툴로 사용할 수 있습니다.
3. `Toolspecs`: 커뮤니티에서 만든 툴 세트로, 종종 Gmail과 같은 특정 서비스를 위한 툴을 포함합니다.
4. `Utility Tools`: 다른 툴에서 나오는 대량의 데이터를 처리하는 데 도움이 되는 특별한 툴입니다.

아래에서 각각에 대해 더 자세히 살펴보겠습니다.

## FunctionTool 만들기

<Tip>
<a href="https://huggingface.co/agents-course/notebooks/blob/main/unit2/llama-index/tools.ipynb" target="_blank">이 노트북</a>을 따라가며 Google Colab에서 코드를 실행해볼 수 있습니다.
</Tip>

FunctionTool은 모든 Python 함수를 래핑하고 에이전트가 사용할 수 있게 만드는 간단한 방법을 제공합니다.
동기 또는 비동기 함수를 툴에 전달할 수 있으며, 선택적으로 `name`과 `description` 매개변수도 함께 전달할 수 있습니다.
이름과 설명은 특히 중요합니다. 에이전트가 언제, 어떻게 툴을 효과적으로 사용할지 이해하는 데 도움이 되기 때문입니다.
아래에서 FunctionTool을 만드는 방법을 살펴보고 호출해보겠습니다.

```python
from llama_index.core.tools import FunctionTool

def get_weather(location: str) -> str:
    """주어진 위치의 날씨를 가져오는 데 유용합니다."""
    print(f"{location}의 날씨를 가져오는 중")
    return f"{location}의 날씨는 맑습니다"

tool = FunctionTool.from_defaults(
    get_weather,
    name="my_weather_tool",
    description="주어진 위치의 날씨를 가져오는 데 유용합니다.",
)
tool.call("뉴욕")
```

<Tip>함수 호출이 있는 에이전트나 LLM을 사용할 때, 선택된 툴(그 툴에 대해 작성된 인수)은 툴의 목적과 인수에 대한 툴 이름과 설명에 크게 의존합니다. <a href="https://docs.llamaindex.ai/en/stable/examples/workflow/function_calling_agent/">함수 호출 가이드</a>에서 함수 호출에 대해 더 알아보세요.</Tip>

## QueryEngineTool 만들기

이전 단원에서 정의한 `QueryEngine`은 `QueryEngineTool` 클래스를 사용하여 쉽게 툴로 변환할 수 있습니다.
아래 예제에서 `QueryEngine`에서 `QueryEngineTool`을 만드는 방법을 살펴보겠습니다.

```python
from llama_index.core import VectorStoreIndex
from llama_index.core.tools import QueryEngineTool
from llama_index.llms.huggingface_api import HuggingFaceInferenceAPI
from llama_index.embeddings.huggingface import HuggingFaceEmbedding
from llama_index.vector_stores.chroma import ChromaVectorStore

embed_model = HuggingFaceEmbedding("BAAI/bge-small-en-v1.5")

db = chromadb.PersistentClient(path="./alfred_chroma_db")
chroma_collection = db.get_or_create_collection("alfred")
vector_store = ChromaVectorStore(chroma_collection=chroma_collection)

index = VectorStoreIndex.from_vector_store(vector_store, embed_model=embed_model)

llm = HuggingFaceInferenceAPI(model_name="Qwen/Qwen2.5-Coder-32B-Instruct")
query_engine = index.as_query_engine(llm=llm)
tool = QueryEngineTool.from_defaults(query_engine, name="some useful name", description="some useful description")
```

## Toolspecs 만들기

`ToolSpecs`를 조화롭게 함께 작동하는 툴 모음으로 생각하세요 - 잘 정리된 전문가 툴킷처럼요.
정비사의 툴킷이 차량 수리를 위해 함께 작동하는 보완적인 툴들을 포함하는 것처럼, `ToolSpec`은 특정 목적을 위해 관련된 툴들을 결합합니다.
예를 들어, 회계 에이전트의 `ToolSpec`은 스프레드시트 기능, 이메일 기능, 계산 툴을 우아하게 통합하여 재무 작업을 정확하고 효율적으로 처리할 수 있습니다.

<details>
<summary>Google Toolspec 설치</summary>
<a href="./llama-hub">LlamaHub 섹션</a>에서 소개된 대로, 다음 명령어로 Google toolspec을 설치할 수 있습니다:

```python
pip install llama-index-tools-google
```
</details>

이제 toolspec을 로드하고 툴 리스트로 변환할 수 있습니다.

```python
from llama_index.tools.google import GmailToolSpec

tool_spec = GmailToolSpec()
tool_spec_list = tool_spec.to_tool_list()
```

툴에 대한 더 자세한 보기를 얻기 위해 각 툴의 `metadata`를 살펴볼 수 있습니다.

```python
[(tool.metadata.name, tool.metadata.description) for tool in tool_spec_list]
```

### LlamaIndex의 모델 컨텍스트 프로토콜 (MCP)

LlamaIndex는 [LlamaHub의 ToolSpec](https://llamahub.ai/l/tools/llama-index-tools-mcp?from=)을 통해 MCP 툴 사용도 허용합니다.
단순히 MCP 서버를 실행하고 다음 구현을 통해 사용을 시작할 수 있습니다.

MCP에 대해 더 깊이 알고 싶다면 [무료 MCP 강의](https://huggingface.co/learn/mcp-course/)를 확인할 수 있습니다.

<details>
<summary>MCP Toolspec 설치</summary>
<a href="./llama-hub">LlamaHub 섹션</a>에서 소개된 대로, 다음 명령어로 MCP toolspec을 설치할 수 있습니다:

```python
pip install llama-index-tools-mcp
```
</details>

```python
from llama_index.tools.mcp import BasicMCPClient, McpToolSpec

# 127.0.0.1:8000에서 실행 중인 mcp 서버가 있다고 가정하거나, mcp 클라이언트를 사용하여 자체 mcp 서버에 연결할 수 있습니다.
mcp_client = BasicMCPClient("http://127.0.0.1:8000/sse")
mcp_tool = McpToolSpec(client=mcp_client)

# 에이전트 가져오기
agent = await get_agent(mcp_tool)

# 에이전트 컨텍스트 생성
agent_context = Context(agent)
```

## 유틸리티 툴

종종 API를 직접 쿼리하는 것은 **과도한 양의 데이터를 반환할 수 있으며**, 그 중 일부는 관련이 없거나, LLM의 컨텍스트 윈도우를 넘치거나, 사용하는 토큰 수를 불필요하게 증가시킬 수 있습니다.
아래에서 두 가지 주요 유틸리티 툴을 살펴보겠습니다.

1. `OnDemandToolLoader`: 이 툴은 기존 LlamaIndex 데이터 로더(BaseReader 클래스)를 에이전트가 사용할 수 있는 툴로 변환합니다. 툴은 데이터 로더에서 `load_data`를 트리거하는 데 필요한 모든 매개변수와 자연어 쿼리 문자열로 호출할 수 있습니다. 실행 중에 먼저 데이터 로더에서 데이터를 로드하고, 인덱싱하고(예를 들어 벡터 스토어로), 그런 다음 '온디맨드'로 쿼리합니다. 이 세 단계 모두가 단일 툴 호출에서 발생합니다.
2. `LoadAndSearchToolSpec`: LoadAndSearchToolSpec은 기존 툴을 입력으로 받습니다. 툴 스펙으로서 `to_tool_list`를 구현하며, 해당 함수가 호출되면 두 개의 툴이 반환됩니다: 로딩 툴과 검색 툴입니다. 로드 툴 실행은 기본 툴을 호출한 다음 출력을 인덱싱합니다(기본적으로 벡터 인덱스로). 검색 툴 실행은 쿼리 문자열을 입력으로 받아 기본 인덱스를 호출합니다.

<Tip>toolspecs와 유틸리티 툴은 <a href="https://llamahub.ai/">LlamaHub</a>에서 찾을 수 있습니다</Tip>

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