Toolset
Toolset
여러 Tool을 하나의 단위로 묶어 주는 것이 Toolset이에요.
| 항목 | 내용 |
|---|---|
| 필수 init 변수 | tools: 툴의 리스트 |
| API 레퍼런스 | Toolset |
| GitHub 링크 | https://github.com/deepset-ai/haystack/blob/main/haystack/tools/toolset.py |
| 패키지명 | haystack-ai |
출처: 공식문서
개요 (Overview)
Toolset은 여러 Tool 인스턴스를 하나의 관리 가능한 단위로 묶어요. Chat Generator나 Agent 같은 컴포넌트에 툴을 넘기는 것을 단순화하고, 필터링·직렬화·재사용을 지원해요.
또한 Toolset을 서브클래싱하면 OpenAPI URL, MCP 서버 같은 외부 소스에서 툴을 동적으로 불러오는 구현을 만들 수 있어요.
Toolset 초기화
Tool로 Toolset을 초기화하는 방법은 이래요. 물론 Toolset 안에 ComponentTool이나 MCPTool을 Tool 인스턴스로 사용할 수도 있어요.
from typing import Annotated
from haystack.tools import Toolset, tool
@tool
def add_numbers(
a: Annotated[int, "first number"],
b: Annotated[int, "second number"],
) -> int:
"""Add two numbers."""
return a + b
@tool
def subtract_numbers(
a: Annotated[int, "first number"],
b: Annotated[int, "second number"],
) -> int:
"""Subtract b from a."""
return a - b
math_toolset = Toolset([add_numbers, subtract_numbers])
Toolset에 새 툴 추가하기
from typing import Annotated
from haystack.tools import tool
@tool
def multiply_numbers(
a: Annotated[int, "first number"],
b: Annotated[int, "second number"],
) -> int:
"""Multiply two numbers."""
return a * b
math_toolset.add(multiply_numbers)
Toolset 결합하기
여러 Toolset을 함께 쓰려면 툴이 허용되는 곳에 리스트로 넘기면 돼요.
agent = Agent(
chat_generator=OpenAIChatGenerator(), tools=[math_toolset, another_toolset]
)
Run별 복사본과 툴 선택
Agent 실행은 설정한 Toolset을 절대 수정하지 않아요. run별 상태를 가진 Toolset, 예컨대 SearchableToolset은 각 실행마다 spawn() 메서드로 복사돼서, 동시 실행이 서로에게 상태(예: 발견된 툴)를 새지 않게 해요. 일반 Toolset은 run별 상태가 없어 그대로 공유돼요. 다만 실행이 진행되는 동안 툴을 추가하거나 제거하는 것은 피하세요.
또한 런타임에 실행별로 툴 이름을 넘겨 Agent를 툴의 일부로 제한할 수 있어요. 예: agent.run(tools=["tool_a", "tool_b"]). 이 선택은 그 실행에만 적용되고, SearchableToolset의 검색 같은 동적 동작은 선택된 부분집합 위에서 계속 동작해요.
이를 지원하는 메서드 두 개가 있고 서브클래싱할 때 오버라이드할 수 있어요.
get_selectable_tools(): 이름 기반 선택에 쓸 수 있는 모든 툴을 반환해요. 서브클래스의 순회가 모든 선택 가능한 툴을 드러내지 않는다면 오버라이드하세요.spawn(): 격리할 run 범위 상태가 없는Toolset그 자체를 반환해요. 서브클래스가 run 범위 상태를 가진다면 격리된 run별 복사본을 반환하도록 오버라이드하세요.
사용법 (Usage)
Haystack에서 Tool을 쓸 수 있는 곳이면 어디든 Toolset을 쓸 수 있어요.
:::tip
Haystack에서 Toolset을 쓰는 권장 방법은 툴 호출 루프를 대신 관리해 주는 Agent 컴포넌트와 함께 쓰는 것이에요. 아래 예시들은 세밀한 제어가 필요할 때 Toolset을 ChatGenerator에 직접 넘기는 방법도 보여 줘요.
:::
Agent와 함께
from haystack.components.agents import Agent
from haystack.dataclasses import ChatMessage
from haystack.components.generators.chat import OpenAIChatGenerator
agent = Agent(
system_prompt="You are a helpful assistant that can do math using the tools at your disposal.",
chat_generator=OpenAIChatGenerator(model="gpt-5.4-nano"),
tools=math_toolset,
)
response = agent.run(messages=[ChatMessage.from_user("What is 4 + 2?")])
print(response["messages"][-1].text)
출력:
4 + 2 equals 6.
ChatGenerator와 함께
Toolset을 Chat Generator에 직접 넘길 수 있어요. 모델이 툴 호출을 준비하고, 실행(예: Tool.invoke)은 여러분이 직접 해야 해요.
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.dataclasses import ChatMessage
chat_generator = OpenAIChatGenerator(model="gpt-5.4-nano", tools=math_toolset)
user_message = ChatMessage.from_user("What is 10 minus 5?")
replies = chat_generator.run(messages=[user_message])["replies"]
print(f"assistant message: {replies}")
# If the assistant message contains a tool call, execute it
if replies[0].tool_calls:
tool_call = replies[0].tool_calls[0]
tool = next(t for t in math_toolset if t.name == tool_call.tool_name)
print(f"tool result: {tool.invoke(**tool_call.arguments)}")
출력:
assistant message: [ChatMessage(
_role=<ChatRole.ASSISTANT: 'assistant'>,
_content=[ToolCall(tool_name='subtract_numbers', arguments={'a': 10, 'b': 5}, id='call_awGa5q7KtQ9BrMGPTj6IgEH1')],
_meta={'model': 'gpt-5.4-nano', 'index': 0, 'finish_reason': 'tool_calls', 'usage': {'completion_tokens': 18, 'prompt_tokens': 75, 'total_tokens': 93}}
)]
tool result: 5
파이프라인에서
from haystack import Pipeline
from haystack.components.agents import Agent
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.dataclasses import ChatMessage
pipeline = Pipeline()
pipeline.add_component(
"agent",
Agent(
chat_generator=OpenAIChatGenerator(model="gpt-5.4-nano"),
tools=math_toolset,
),
)
user_input_msg = ChatMessage.from_user(text="What is 2+2?")
result = pipeline.run({"agent": {"messages": [user_input_msg]}})
print(result["agent"]["last_message"].text)
출력:
2 + 2 equals 4.
더 알아보기 (Learn more)
- Tool 문서 — 툴 생성과
@tool데코레이터 - ComponentTool 문서 — Haystack 컴포넌트를 툴로 감싸기