OpenAPIServiceConnector
OpenAPIServiceConnector
Haystack 생태계와 OpenAPI 서비스 사이의 인터페이스 역할을 하는 컴포넌트예요.
출처: 문서
본문
MCP를 대신 고려해 보세요: 이 OpenAPI 컴포넌트들은 Haystack을 외부 API에 연결하는 레거시 방식이에요. 대부분의 사용 사례에서는
MCPTool을 권장해요. 파이프라인과 에이전트가 외부 툴·서비스를 쓰도록 하는 현대적이고 표준화된 방법이기 때문이죠.
OpenAPIServiceConnector는 Haystack 생태계와 OpenAPI 서비스 사이의 다리 역할을 해요. 이 컴포넌트는 ChatMessage의 정보를 이용해 서비스 메서드를 동적으로 호출해요. ChatMessage에서 파라미터 페이로드를 파싱하고, 서비스 인증, 메서드 호출, 응답 포맷팅을 처리해서 OpenAPI 서비스를 쉽게 통합할 수 있게 해주죠.
OpenAPIServiceConnector를 쓰려면 openapi-haystack 패키지를 설치해야 해요.
pip install openapi-haystack
OpenAPIServiceConnector 컴포넌트에는 init 파라미터가 없어요.
더 알아보기 (Learn more)
단독으로 쓰기
이 컴포넌트는 주로 파이프라인에서 쓰도록 만들어졌어요. OpenAPIServiceToFunctions가 툴 호출 기능이 있는 LLM과 함께 실제 툴 호출 파라미터를 해석해서 OpenAPIServiceConnector의 호출 파라미터로 주입하죠.
파이프라인에서 쓰기
Serper 검색 엔진을 파이프라인에 연결한다고 해 볼게요. 여기서 OpenAPIServiceConnector는 OpenAPIServiceToFunctions의 기능을 사용해요. OpenAPIServiceToFunctions가 먼저 Serper의 OpenAPI 스펙을 가져와서 툴 호출 기능이 있는 LLM이 이해할 수 있는 함수 정의로 바꿔요. 그 다음 OpenAPIServiceConnector가 이 스펙으로 Serper 서비스를 활성화해요.
더 정확히 말하면, OpenAPIServiceConnector가 Serper OpenAPI 스펙에 정의된 메서드를 동적으로 호출해요. 채팅 메시지를 읽어 툴 호출 파라미터를 추출하고, Serper 서비스와 인증을 처리하며, 올바른 API 호출을 만들어요. 커넥터는 요청 포맷팅과 응답 처리 같은 Serper API 요구 사항을 따르도록 보장해요.
여기서는 예시로 Serper를 썼지만, OpenAPI를 준수하는 어떤 서비스든 될 수 있어요.
info: 아래 코드 스니펫을 실행하려면 자체 Serper와 OpenAI API 키가 있어야 해요.
import json
import requests
from typing import Any
from haystack import Pipeline
from haystack.components.converters import OutputAdapter
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.dataclasses import ChatMessage
from haystack.dataclasses.byte_stream import ByteStream
from haystack_integrations.components.connectors.openapi import OpenAPIServiceConnector
from haystack_integrations.components.converters.openapi import (
OpenAPIServiceToFunctions,
)
def prepare_fc_params(openai_functions_schema: dict[str, Any]) -> dict[str, Any]:
return {
"tools": [{"type": "function", "function": openai_functions_schema}],
"tool_choice": {
"type": "function",
"function": {"name": openai_functions_schema["name"]},
},
}
serperdev_spec = requests.get("https://bit.ly/serper_dev_spec").json()
system_prompt = requests.get("https://bit.ly/serper_dev_system").text
user_prompt = "Why was Sam Altman ousted from OpenAI?"
pipe = Pipeline()
pipe.add_component("spec_to_functions", OpenAPIServiceToFunctions())
pipe.add_component(
"prepare_fc_adapter",
OutputAdapter(
"{{functions[0] | prepare_fc}}",
dict[str, Any],
{"prepare_fc": prepare_fc_params},
),
)
pipe.add_component("functions_llm", OpenAIChatGenerator())
pipe.add_component("openapi_connector", OpenAPIServiceConnector())
pipe.add_component(
"message_adapter",
OutputAdapter(
"{{system_message + service_response}}",
list[ChatMessage],
unsafe=True,
),
)
pipe.add_component("llm", OpenAIChatGenerator())
pipe.connect("spec_to_functions.functions", "prepare_fc_adapter.functions")
pipe.connect(
"spec_to_functions.openapi_specs",
"openapi_connector.service_openapi_spec",
)
pipe.connect("prepare_fc_adapter", "functions_llm.generation_kwargs")
pipe.connect("functions_llm.replies", "openapi_connector.messages")
pipe.connect("openapi_connector.service_response", "message_adapter.service_response")
pipe.connect("message_adapter", "llm.messages")
result = pipe.run(
data={
"functions_llm": {
"messages": [
ChatMessage.from_system("Only do tool/function calling"),
ChatMessage.from_user(user_prompt),
],
},
"openapi_connector": {
"service_credentials": serper_dev_key,
},
"spec_to_functions": {
"sources": [ByteStream.from_string(json.dumps(serperdev_spec))],
},
"message_adapter": {
"system_message": [ChatMessage.from_system(system_prompt)],
},
},
)
print(result["llm"]["replies"][0].text)
# Sam Altman was ousted from OpenAI on November 17, 2023, following
# a "deliberative review process" by the board of directors. The board concluded
# that he was not "consistently candid in his communications". However, he
# returned as CEO just days after his ouster.