Skip to content

Commit

Permalink
Document validation of OpenAI output
Browse files Browse the repository at this point in the history
  • Loading branch information
rizerphe committed Jul 3, 2023
1 parent f7991cf commit cbeca90
Show file tree
Hide file tree
Showing 7 changed files with 45 additions and 9 deletions.
2 changes: 2 additions & 0 deletions docs/conversation.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,5 @@ raw_weather_result = conversation.run("get_weather", "What's the weather in San
```

However, for most usecases [@nlp](nlp_interface) should be sufficient; consider using it.

Note: watch out for incomplete or invalid responses from OpenAI - currently they do not bother with validating the outputs, and the generation might cut off in the middle of the JSON output. If either of these happens, the tool will raise either [BrokenSchemaError](openai_functions.BrokenSchemaError) or [InvalidJsonError](openai_functions.InvalidJsonError).
4 changes: 3 additions & 1 deletion docs/nlp_interface.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ def set_current_weather(location: str, description: str):
return "Set the weather successfully"
```

The parameters it takes are:
Note: watch out for incomplete or invalid responses from OpenAI - currently they do not bother with validating the outputs, and the generation might cut off in the middle of the JSON output. If either of these happens, the tool will raise either [BrokenSchemaError](openai_functions.BrokenSchemaError) or [InvalidJsonError](openai_functions.InvalidJsonError).

The parameters `@nlp` takes are:

- `name` - the name of the function sent to the AI, defaulting to the function name itself
- `description` - the description of the function sent to the AI, defaults to getting the short description from the function's docstring
Expand Down
2 changes: 2 additions & 0 deletions docs/skills.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ weather = skill(
)
```

When invalid JSON is passed in for the arguments, either because of the output not adhering to the schema or not being valid JSON at all (both of which camn be caused by OpenAI), the tool will raise either [BrokenSchemaError](openai_functions.BrokenSchemaError) or [InvalidJsonError](openai_functions.InvalidJsonError).

## Union skills

A more advanced one is a [union skillset](openai_functions.UnionSkillSet) that combines others. It exposes one new method:
Expand Down
40 changes: 35 additions & 5 deletions openai_functions/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,28 @@ class OpenAIFunctionsError(Exception):


class FunctionNotFoundError(OpenAIFunctionsError):
"""The function was not found in the given skillset."""
"""The function was not found in the given skillset.
Attributes:
function_name (str): The name of the function that was not found
"""

def __init__(self, function_name: str) -> None:
"""Initialize the FunctionNotFoundError.
Args:
function_name (str): The name of the function that was not found
"""
super().__init__(f"Function {function_name} not found.")
self.function_name = function_name


class CannotParseTypeError(OpenAIFunctionsError):
"""This type of the argument could not be parsed."""
"""This type of the argument could not be parsed.
Attributes:
argtype (Any): The type that could not be parsed
"""

def __init__(self, argtype: Any) -> None:
"""Initialize the CannotParseTypeError.
Expand All @@ -28,7 +45,11 @@ def __init__(self, argtype: Any) -> None:


class NonSerializableOutputError(OpenAIFunctionsError):
"""The function returned a non-serializable output."""
"""The function returned a non-serializable output.
Attributes:
result (Any): The result that was not serializable
"""

def __init__(self, result: Any) -> None:
"""Initialize the NonSerializableOutputError.
Expand All @@ -44,7 +65,11 @@ def __init__(self, result: Any) -> None:


class InvalidJsonError(OpenAIFunctionsError):
"""OpenAI returned invalid JSON for the arguments."""
"""OpenAI returned invalid JSON for the arguments.
Attributes:
response (str): The response that was not valid JSON
"""

def __init__(self, response: str) -> None:
"""Initialize the InvalidJsonError.
Expand All @@ -59,7 +84,12 @@ def __init__(self, response: str) -> None:


class BrokenSchemaError(OpenAIFunctionsError):
"""The OpenAI response did not match the schema."""
"""The OpenAI response did not match the schema.
Attributes:
response (JsonType): The response that did not match the schema
schema (JsonType): The schema that the response did not match
"""

def __init__(self, response: JsonType, schema: JsonType) -> None:
"""Initialize the BrokenSchemaError.
Expand Down
2 changes: 1 addition & 1 deletion openai_functions/functions/basic_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def find_function(self, function_name: str) -> OpenAIFunction:
for function in self.functions:
if function.name == function_name:
return function
raise FunctionNotFoundError(f"Function {function_name} not found")
raise FunctionNotFoundError(function_name)

def get_function_result(
self, function: OpenAIFunction, arguments: dict[str, JsonType]
Expand Down
2 changes: 1 addition & 1 deletion openai_functions/functions/togglable_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,5 +82,5 @@ def run_function(self, input_data: FunctionCall) -> FunctionResult:
if input_data["name"] == self.enable_function_name:
self.enable()
return FunctionResult(self.enable_function_name, None, True)
raise FunctionNotFoundError(f"Function {input_data['name']} not found")
raise FunctionNotFoundError(input_data["name"])
return super().run_function(input_data)
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "openai-functions"
version = "0.6.14"
version = "0.6.15"
description = "Simplifies the usage of OpenAI ChatGPT's function calling by generating the schemas and parsing OpenAI's responses for you."
authors = ["rizerphe <44440399+rizerphe@users.noreply.github.com>"]
readme = "README.md"
Expand Down

0 comments on commit cbeca90

Please sign in to comment.