Type Descriptors
Contents
Type Descriptors#
Let’s explore type-descriptors for a bit.
Many LLMs are somewhat finicky, and a slightly better phrased prompt may help improve results. So if you want to use your own type-descriptions, you can define a custom one and pass it as an argument when creating an extraction chain.
At the moment, Kor only uses a very limited number of internal types. There’s no way to represent a Union
or even a Boolean
. For the time being use a Text
node (or str
in pydnatic) to capture more complex / missing types.
import enum
from typing import Optional, List
from kor import from_pydantic
from pydantic import BaseModel, Field
Let’s define a schema#
class Action(enum.Enum):
play = "play"
stop = "stop"
previous = "previous"
next_ = "next"
class MusicRequest(BaseModel):
song: Optional[List[str]] = Field(
description="The song(s) that the user would like to be played."
)
album: Optional[List[str]] = Field(
description="The album(s) that the user would like to be played."
)
artist: Optional[List[str]] = Field(
description="The artist(s) whose music the user would like to hear.",
examples=[("Songs by paul simon", "paul simon")],
)
action: Optional[Action] = Field(
description="The action that should be taken; one of `play`, `stop`, `next`, `previous`",
examples=[
("Please stop the music", "stop"),
("play something", "play"),
("play a song", "play"),
("next song", "next"),
],
)
volume: Optional[float] = Field(
description="Set the volume",
)
schema, validator = from_pydantic(MusicRequest, description="Music recorder")
TypeScript#
from kor import TypeScriptDescriptor
descriptor = TypeScriptDescriptor()
print(descriptor.describe(schema))
```TypeScript
musicrequest: { // Music recorder
song: Array<string> // The song(s) that the user would like to be played.
album: Array<string> // The album(s) that the user would like to be played.
artist: Array<string> // The artist(s) whose music the user would like to hear.
action: "play" | "stop" | "previous" | "next" // The action that should be taken; one of `play`, `stop`, `next`, `previous`
volume: number // Set the volume
}
```
BulletPoint#
from kor import BulletPointDescriptor
descriptor = BulletPointDescriptor()
print(descriptor.describe(schema))
* musicrequest: Object # Music recorder
* song: Text # The song(s) that the user would like to be played.
* album: Text # The album(s) that the user would like to be played.
* artist: Text # The artist(s) whose music the user would like to hear.
* action: Selection # The action that should be taken; one of `play`, `stop`, `next`, `previous`
* volume: Number # Set the volume
Custom#
Here’s an example on how to define your own type-description.
from typing import Any
from kor import TypeScriptDescriptor, Object
from kor.nodes import AbstractSchemaNode
class MeowDescriptor(TypeScriptDescriptor):
def visit_default(self, node: "AbstractSchemaNode", **kwargs: Any) -> List[str]:
"""Default action for a node."""
depth = kwargs["depth"]
space = " " + depth * " ~(^._.)" + " "
return [f"{space}{node.id}: {node.__class__.__name__} # {node.description}"]
def visit_object(self, node: Object, **kwargs: Any) -> List[str]:
"""Visit an object node."""
depth = kwargs["depth"]
code_lines = self.visit_default(node, depth=depth)
for child in node.attributes:
code_lines.extend(child.accept(self, depth=depth + 1))
return code_lines
def describe(self, node: Object) -> str:
"""Describe the type of the given node."""
code_lines = node.accept(self, depth=0)
return "\n".join(code_lines)
print(MeowDescriptor().describe(schema))
musicrequest: Object # Music recorder
~(^._.) song: Text # The song(s) that the user would like to be played.
~(^._.) album: Text # The album(s) that the user would like to be played.
~(^._.) artist: Text # The artist(s) whose music the user would like to hear.
~(^._.) action: Selection # The action that should be taken; one of `play`, `stop`, `next`, `previous`
~(^._.) volume: Number # Set the volume