도구 설명자 계획자

·3분 읽기

원문: Koog Documentation — tool-descriptor-schemer 이 글은 Koog 공식 문서의 tool-descriptor-schemer 페이지를 한국어로 옮긴 번역본입니다. 문서 구조와 링크 의미를 유지하되, MkDocs 전용 UI 문법은 블로그에서 읽기 좋도록 정리했습니다.

도구 설명자 계획자

ToolDescriptorSchemerToolDescriptor을 특정 LLM 공급자와 호환되는 JSON 스키마 개체로 변환하는 확장 포인트입니다. Kotlin과 Java 모두에서 구현할 수 있습니다.

핵심 사항:

  • 위치: ai.koog.agents.core.tools.serialization.ToolDescriptorSchemer
  • 계약: 단일 함수 scheme(toolDescriptor: ToolDescriptor): JsonObject 또는 generate(ToolDescriptor toolDescriptor): JsonObject(Java)
  • 제공되는 구현:
    • OpenAICompatibleToolDescriptorSchemer — OpenAI 스타일 함수/도구 정의와 호환되는 스키마를 생성합니다.
    • OllamaToolDescriptorSchemer — Ollama 도구 JSON과 호환되는 스키마를 생성합니다.
1// Interface2interface ToolDescriptorSchemaGenerator {3fun generate(toolDescriptor: ToolDescriptor): JsonObject4}

그것을 사용하는 이유

Kotlin 또는 Java로 기존 또는 신규 LLM 제공업체에 대한 사용자 정의 체계를 제공하려면 이 인터페이스를 구현하여 Koog의 ToolDescriptor를 예상되는 JSON 스키마 형식으로 변환하세요.

구현예

다음은 SPI에 연결하는 방법을 보여주기 위해 매개변수 유형의 하위 집합만 렌더링하는 Kotlin과 Java의 최소 사용자 정의 구현입니다. 실제 구현은 모든 ToolParameterType(String, Integer, Float, Boolean, Null, Enum, List, Object, AnyOf)을 포괄해야 합니다.

코틀린

12class MinimalSchemer : ToolDescriptorSchemaGenerator {3    override fun generate(toolDescriptor: ToolDescriptor): JsonObject = buildJsonObject {4        put("type", "object")5        putJsonObject("properties") {6            (toolDescriptor.requiredParameters + toolDescriptor.optionalParameters).forEach { p ->7                put(p.name, buildJsonObject {8                    put("description", p.description)9                    when (val t = p.type) {10                        ToolParameterType.String -> put("type", "string")11                        ToolParameterType.Integer -> put("type", "integer")12                        is ToolParameterType.Enum -> {13                            put("type", "string")14                            putJsonArray("enum") { t.entries.forEach { add(JsonPrimitive(it)) } }15                        }16                        else -> put("type", "string") // fallback for brevity17                    }18                })19            }20        }21        putJsonArray("required") { toolDescriptor.requiredParameters.forEach { add(JsonPrimitive(it.name)) } }22    }23}

자바

1public static class MinimalSchemer extends OpenAICompatibleToolDescriptorSchemaGenerator {2    @Override3    public JsonObject generate(ToolDescriptor toolDescriptor) {4        Map<String, JsonElement> root = new LinkedHashMap<>();5        root.put("type", JsonPrimitive("object"));67        // properties8        Map<String, JsonElement> props = new LinkedHashMap<>();9        for (ToolParameterDescriptor p : concat(toolDescriptor.getRequiredParameters(), toolDescriptor.getOptionalParameters())) {10            Map<String, JsonElement> prop = new LinkedHashMap<>();11            prop.put("description", JsonPrimitive(p.getDescription()));1213            ToolParameterType t = p.getType();14            if (t == ToolParameterType.String.INSTANCE) {15                prop.put("type", JsonPrimitive("string"));16            } else if (t == ToolParameterType.Integer.INSTANCE) {17                prop.put("type", JsonPrimitive("integer"));18            } else if (t instanceof ToolParameterType.Enum) {19                prop.put("type", JsonPrimitive("string"));20                String[] entries = ((ToolParameterType.Enum) t).getEntries();21                List<JsonElement> enumVals = new ArrayList<>();22                for (String e : entries) enumVals.add(JsonPrimitive(e));23                prop.put("enum", new JsonArray(enumVals));24            } else {25                prop.put("type", JsonPrimitive("string")); // fallback for brevity26            }2728            props.put(p.getName(), new JsonObject(prop));29        }30        root.put("properties", new JsonObject(props));3132        // required array33        List<JsonElement> required = new ArrayList<>();34        for (ToolParameterDescriptor p : toolDescriptor.getRequiredParameters()) {35            required.add(JsonPrimitive(p.getName()));36        }37        root.put("required", new JsonArray(required));3839        return new JsonObject(root);40    }4142    private static List<ToolParameterDescriptor> concat(List<ToolParameterDescriptor> a, List<ToolParameterDescriptor> b) {43        List<ToolParameterDescriptor> res = new ArrayList<>(a.size() + b.size());44        res.addAll(a);45        res.addAll(b);46        return res;47    }48}

클라이언트와 함께 사용

일반적으로 구성자를 직접 호출할 필요는 없습니다. Koog 클라이언트는 ToolDescriptor 개체 목록을 수락하고 공급자에 대한 요청을 직렬화할 때 내부적으로 올바른 체계를 적용합니다.

아래 예에서는 간단한 도구를 정의하고 이를 OpenAI 클라이언트에 전달합니다. 클라이언트는 내부적으로 OpenAICompatibleToolDescriptorSchemer을 사용하여 JSON 스키마를 구축합니다.

코틀린

1val client = OpenAILLMClient(apiKey = System.getenv("OPENAI_API_KEY"), toolsConverter = MinimalSchemer())23val getUserTool = ToolDescriptor(4    name = "get_user",5    description = "Returns user profile by id",6    requiredParameters = listOf(7        ToolParameterDescriptor(8            name = "id",9            description = "User id",10            type = ToolParameterType.String11        )12    )13)1415val prompt = Prompt.build(id = "p1") { user("Hello") }16val responses = runBlocking {17    client.execute(18        prompt = prompt,19        model = OpenAIModels.Chat.GPT4o,20        tools = listOf(getUserTool)21    )22}

자바

1// Custom schemer extending the OpenAI-compatible one is Kotlin-only in the docs; for Java example we reuse MinimalSchemer from above.2OpenAILLMClient client = new OpenAILLMClient(System.getenv("OPENAI_API_KEY"), new OpenAIClientSettings(), null, null, new OpenAICompatibleToolDescriptorSchemaGenerator());34ToolDescriptor getUserTool = new ToolDescriptor(5    "get_user",6    "Returns user profile by id",7    Collections.singletonList(new ToolParameterDescriptor(8        "id",9        "User id",10        ToolParameterType.String.INSTANCE11    )),12    Collections.emptyList()13);1415Prompt prompt = Prompt.builder("p1")16    .user("Hello")17    .build();1819List<Message.Response> responses = client.execute(prompt, OpenAIModels.Chat.GPT4o, java.util.List.of(getUserTool));

생성된 스키마에 직접 액세스해야 하는 경우(디버깅 또는 사용자 지정 전송을 위해) 공급자별 스키마를 인스턴스화하고 JSON을 직접 직렬화할 수 있습니다.

코틀린

1val json = Json { prettyPrint = true }2val schema = OpenAICompatibleToolDescriptorSchemaGenerator().generate(getUserTool())

자바

1