[![Unit Tests](https://github.com/eyurtsev/kor/actions/workflows/test.yml/badge.svg?branch=main&event=push)](https://github.com/eyurtsev/kor/actions/workflows/test.yml)
[![Test Docs](https://github.com/eyurtsev/kor/actions/workflows/doc_test.yaml/badge.svg?branch=main&event=push)](https://github.com/eyurtsev/kor/actions/workflows/doc_test.yaml)
[![Release Notes](https://img.shields.io/github/release/eyurtsev/kor)](https://github.com/eyurtsev/kor/releases)
[![Downloads](https://static.pepy.tech/badge/kor/month)](https://pepy.tech/project/kor)
[![Open Issues](https://img.shields.io/github/issues-raw/eyurtsev/kor)](https://github.com/eyurtsev/kor/issues)
[![](https://dcbadge.vercel.app/api/server/6adMQxSpJS?compact=true&style=flat)](https://discord.com/channels/1038097195422978059/1170024642245832774)
# Kor
This is a half-baked prototype that "helps" you extract structured data from text using LLMs π§©.
Specify the schema of what should be extracted and provide some examples.
Kor will generate a prompt, send it to the specified LLM and parse out the
output.
You might even get results back.
So yes β itβs just another wrapper on top of LLMs with its own flavor of abstractions. πΈ
See [documentation](https://eyurtsev.github.io/kor/).
Integrated with the [LangChain framework π½π π¦π](https://python.langchain.com/en/latest/index.html).
## Kor vs. LangChain
There are 3 different approaches for extracting information using LLMs:
1. [prompt based/parsing](https://python.langchain.com/docs/use_cases/extraction/how_to/parse)
2. [function/tool calling](https://python.langchain.com/docs/use_cases/extraction/quickstart)
3. JSON mode
Please see the LangChain [extraction use case docs](https://python.langchain.com/docs/use_cases/extraction/) for an overview.
Kor has a pretty good implementation of the **parsing** approach. The approach works with all good-enough LLMs regardless
of whether they support function/tool calling or JSON modes.
Extraction quality is principally driven by providing good reference examples and good schema documentation.
Please see guidelines [here](https://python.langchain.com/docs/use_cases/extraction/guidelines) and [here](https://eyurtsev.github.io/kor/guidelines.html).
## Version 1.0.0 Release
* `kor` compatible with both pydantic v2 and v1.
* pydantic v2 had significant breaking changes w/ respect to v1, `kor` major
version bump was used as a precaution.
Main things to watch out for:
1. Use a `default` value for any Optional fields if using pydantic v2 for validation.
```python
class MusicRequest(BaseModel):
song: Optional[List[str]] = Field(
default=None,
description="The song(s) that the user would like to be played."
)
```
2. Kor schema is typed checked using pydantic. Pydantic v2 is stricter, and may
catch issues that were hiding in existing user code that was using the `kor`
library.
3. Serialization has not yet been implemented with pydantic v2.
## Kor style schema
```python
from langchain.chat_models import ChatOpenAI
from kor import create_extraction_chain, Object, Text
llm = ChatOpenAI(
model_name="gpt-3.5-turbo",
temperature=0,
max_tokens=2000,
model_kwargs = {
'frequency_penalty':0,
'presence_penalty':0,
'top_p':1.0
}
)
schema = Object(
id="player",
description=(
"User is controlling a music player to select songs, pause or start them or play"
" music by a particular artist."
),
attributes=[
Text(
id="song",
description="User wants to play this song",
examples=[],
many=True,
),
Text(
id="album",
description="User wants to play this album",
examples=[],
many=True,
),
Text(
id="artist",
description="Music by the given artist",
examples=[("Songs by paul simon", "paul simon")],
many=True,
),
Text(
id="action",
description="Action to take one of: `play`, `stop`, `next`, `previous`.",
examples=[
("Please stop the music", "stop"),
("play something", "play"),
("play a song", "play"),
("next song", "next"),
],
),
],
many=False,
)
chain = create_extraction_chain(llm, schema, encoder_or_encoder_class='json')
chain.invoke("play songs by paul simon and led zeppelin and the doors")['data']
```
```python
{'player': {'artist': ['paul simon', 'led zeppelin', 'the doors']}}
```
## Pydantic style schema
* See documentation here [pydantic](https://eyurtsev.github.io/kor/validation.html).
```python
class Action(enum.Enum):
play = "play"
stop = "stop"
previous = "previous"
next_ = "next"
class MusicRequest(BaseModel):
song: Optional[List[str]] = Field(
default=None,
description="The song(s) that the user would like to be played."
)
album: Optional[List[str]] = Field(
default=None,
description="The album(s) that the user would like to be played."
)
artist: Optional[List[str]] = Field(
default=None,
description="The artist(s) whose music the user would like to hear.",
examples=[("Songs by paul simon", "paul simon")],
)
action: Optional[Action] = Field(
default=None,
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"),
],
)
schema, validator = from_pydantic(MusicRequest)
chain = create_extraction_chain(
llm, schema, encoder_or_encoder_class="json", validator=validator
)
chain.invoke("stop the music now")["validated_data"]
```
```python
MusicRequest(song=None, album=None, artist=None, action=<Action.stop: 'stop'>)
```
## Compatibility
`Kor` is tested against python 3.8, 3.9, 3.10, 3.11.
## Installation
```sh
pip install kor
```
## π‘ Ideas
Ideas of some things that could be done with Kor.
* Extract data from text that matches an extraction schema.
* Power an AI assistant with skills by precisely understanding a user request.
* Provide natural language access to an existing API.
## π§ Prototype
Prototype! So the API is not expected to be stable!
## β¨ What does Kor excel at? π
* Making mistakes! Plenty of them!
* Slow! It uses large prompts with examples, and works best with the larger slower LLMs.
* Crashing for long enough pieces of text! Context length window could become
limiting when working with large forms or long text inputs.
The expectation is that as LLMs improve some of these issues will be mitigated.
## Limitations
Kor has no limitations. (Just kidding.)
Take a look at the section above and at the compatibility section.
## Got Ideas?
Open an issue, and let's discuss!
## πΆ Why the name?
Fast to type and sufficiently unique.
## Contributing
If you have any ideas or feature requests, please open an issue and share!
See [CONTRIBUTING.md](https://github.com/eyurtsev/kor/blob/main/CONTRIBUTING.md) for more information.
## Other packages
Probabilistically speaking this package is unlikely to work for your use case.
So here are some great alternatives:
* [Promptify](https://github.com/promptslab/Promptify)
* [MiniChain](https://srush.github.io/MiniChain/examples/stats/)
Raw data
{
"_id": null,
"home_page": "https://www.github.com/eyurtsev/kor",
"name": "kor",
"maintainer": null,
"docs_url": null,
"requires_python": "<4.0,>=3.9",
"maintainer_email": null,
"keywords": null,
"author": "Eugene Yurtsev",
"author_email": "eyurtsev@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/cf/27/1bff449058f94b3bd7f63cd3096ae6a4a28fc713bd1b4c374dc06f63f990/kor-3.0.0.tar.gz",
"platform": null,
"description": "[![Unit Tests](https://github.com/eyurtsev/kor/actions/workflows/test.yml/badge.svg?branch=main&event=push)](https://github.com/eyurtsev/kor/actions/workflows/test.yml)\n[![Test Docs](https://github.com/eyurtsev/kor/actions/workflows/doc_test.yaml/badge.svg?branch=main&event=push)](https://github.com/eyurtsev/kor/actions/workflows/doc_test.yaml)\n[![Release Notes](https://img.shields.io/github/release/eyurtsev/kor)](https://github.com/eyurtsev/kor/releases)\n[![Downloads](https://static.pepy.tech/badge/kor/month)](https://pepy.tech/project/kor)\n[![Open Issues](https://img.shields.io/github/issues-raw/eyurtsev/kor)](https://github.com/eyurtsev/kor/issues)\n[![](https://dcbadge.vercel.app/api/server/6adMQxSpJS?compact=true&style=flat)](https://discord.com/channels/1038097195422978059/1170024642245832774)\n\n\n# Kor\n\nThis is a half-baked prototype that \"helps\" you extract structured data from text using LLMs \ud83e\udde9.\n\nSpecify the schema of what should be extracted and provide some examples.\n\nKor will generate a prompt, send it to the specified LLM and parse out the\noutput.\n\nYou might even get results back.\n\nSo yes \u2013 it\u2019s just another wrapper on top of LLMs with its own flavor of abstractions. \ud83d\ude38\n\nSee [documentation](https://eyurtsev.github.io/kor/).\n\nIntegrated with the [LangChain framework \ud83d\ude3d\ud83d\udc97 \ud83e\udd9c\ud83d\udd17](https://python.langchain.com/en/latest/index.html).\n\n## Kor vs. LangChain\n\nThere are 3 different approaches for extracting information using LLMs: \n\n1. [prompt based/parsing](https://python.langchain.com/docs/use_cases/extraction/how_to/parse)\n2. [function/tool calling](https://python.langchain.com/docs/use_cases/extraction/quickstart)\n3. JSON mode\n\nPlease see the LangChain [extraction use case docs](https://python.langchain.com/docs/use_cases/extraction/) for an overview.\n\nKor has a pretty good implementation of the **parsing** approach. The approach works with all good-enough LLMs regardless\nof whether they support function/tool calling or JSON modes.\n\nExtraction quality is principally driven by providing good reference examples and good schema documentation.\n\nPlease see guidelines [here](https://python.langchain.com/docs/use_cases/extraction/guidelines) and [here](https://eyurtsev.github.io/kor/guidelines.html).\n\n## Version 1.0.0 Release\n\n* `kor` compatible with both pydantic v2 and v1.\n* pydantic v2 had significant breaking changes w/ respect to v1, `kor` major\n version bump was used as a precaution.\n\n\nMain things to watch out for:\n\n1. Use a `default` value for any Optional fields if using pydantic v2 for validation.\n\n```python\nclass MusicRequest(BaseModel):\n song: Optional[List[str]] = Field(\n default=None,\n description=\"The song(s) that the user would like to be played.\"\n )\n```\n\n2. Kor schema is typed checked using pydantic. Pydantic v2 is stricter, and may\n catch issues that were hiding in existing user code that was using the `kor`\n library.\n\n3. Serialization has not yet been implemented with pydantic v2.\n\n\n## Kor style schema\n\n```python\nfrom langchain.chat_models import ChatOpenAI\nfrom kor import create_extraction_chain, Object, Text\n\nllm = ChatOpenAI(\n model_name=\"gpt-3.5-turbo\",\n temperature=0,\n max_tokens=2000,\n model_kwargs = {\n 'frequency_penalty':0,\n 'presence_penalty':0,\n 'top_p':1.0\n }\n)\n\nschema = Object(\n id=\"player\",\n description=(\n \"User is controlling a music player to select songs, pause or start them or play\"\n \" music by a particular artist.\"\n ),\n attributes=[\n Text(\n id=\"song\",\n description=\"User wants to play this song\",\n examples=[],\n many=True,\n ),\n Text(\n id=\"album\",\n description=\"User wants to play this album\",\n examples=[],\n many=True,\n ),\n Text(\n id=\"artist\",\n description=\"Music by the given artist\",\n examples=[(\"Songs by paul simon\", \"paul simon\")],\n many=True,\n ),\n Text(\n id=\"action\",\n description=\"Action to take one of: `play`, `stop`, `next`, `previous`.\",\n examples=[\n (\"Please stop the music\", \"stop\"),\n (\"play something\", \"play\"),\n (\"play a song\", \"play\"),\n (\"next song\", \"next\"),\n ],\n ),\n ],\n many=False,\n)\n\nchain = create_extraction_chain(llm, schema, encoder_or_encoder_class='json')\nchain.invoke(\"play songs by paul simon and led zeppelin and the doors\")['data']\n```\n\n```python\n{'player': {'artist': ['paul simon', 'led zeppelin', 'the doors']}}\n```\n\n## Pydantic style schema\n\n* See documentation here [pydantic](https://eyurtsev.github.io/kor/validation.html).\n\n```python \nclass Action(enum.Enum):\n play = \"play\"\n stop = \"stop\"\n previous = \"previous\"\n next_ = \"next\"\n\n\nclass MusicRequest(BaseModel):\n song: Optional[List[str]] = Field(\n default=None,\n description=\"The song(s) that the user would like to be played.\"\n )\n album: Optional[List[str]] = Field(\n default=None,\n description=\"The album(s) that the user would like to be played.\"\n )\n artist: Optional[List[str]] = Field(\n default=None,\n description=\"The artist(s) whose music the user would like to hear.\",\n examples=[(\"Songs by paul simon\", \"paul simon\")],\n )\n action: Optional[Action] = Field(\n default=None,\n description=\"The action that should be taken; one of `play`, `stop`, `next`, `previous`\",\n examples=[\n (\"Please stop the music\", \"stop\"),\n (\"play something\", \"play\"),\n (\"play a song\", \"play\"),\n (\"next song\", \"next\"),\n ],\n )\n \nschema, validator = from_pydantic(MusicRequest) \nchain = create_extraction_chain(\n llm, schema, encoder_or_encoder_class=\"json\", validator=validator\n)\nchain.invoke(\"stop the music now\")[\"validated_data\"]\n```\n\n```python\nMusicRequest(song=None, album=None, artist=None, action=<Action.stop: 'stop'>)\n```\n\n\n\n## Compatibility\n\n`Kor` is tested against python 3.8, 3.9, 3.10, 3.11.\n\n## Installation\n\n```sh\npip install kor\n```\n\n## \ud83d\udca1 Ideas\n\nIdeas of some things that could be done with Kor.\n\n* Extract data from text that matches an extraction schema.\n* Power an AI assistant with skills by precisely understanding a user request.\n* Provide natural language access to an existing API.\n\n## \ud83d\udea7 Prototype\n\nPrototype! So the API is not expected to be stable!\n\n## \u2728 What does Kor excel at? \ud83c\udf1f\n\n* Making mistakes! Plenty of them!\n* Slow! It uses large prompts with examples, and works best with the larger slower LLMs.\n* Crashing for long enough pieces of text! Context length window could become\n limiting when working with large forms or long text inputs.\n\nThe expectation is that as LLMs improve some of these issues will be mitigated.\n\n## Limitations\n\nKor has no limitations. (Just kidding.)\n\nTake a look at the section above and at the compatibility section.\n\n## Got Ideas?\n\nOpen an issue, and let's discuss!\n\n## \ud83c\udfb6 Why the name?\n\nFast to type and sufficiently unique.\n\n## Contributing\n\nIf you have any ideas or feature requests, please open an issue and share!\n\nSee [CONTRIBUTING.md](https://github.com/eyurtsev/kor/blob/main/CONTRIBUTING.md) for more information.\n\n## Other packages\n\nProbabilistically speaking this package is unlikely to work for your use case.\n\nSo here are some great alternatives:\n\n* [Promptify](https://github.com/promptslab/Promptify)\n* [MiniChain](https://srush.github.io/MiniChain/examples/stats/)\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Extract information with LLMs from text",
"version": "3.0.0",
"project_urls": {
"Homepage": "https://www.github.com/eyurtsev/kor",
"Repository": "https://www.github.com/eyurtsev/kor"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "fef3169100160b3c92cbd5f0a135af4da43352fe84bc752870fa9addbed4db08",
"md5": "ca5e690d3b6561a6ce6ef8f34dc97a75",
"sha256": "550b3de5616c8a64780aca0dac64a5bb6fff8e7dcf5829dbe98f4866bba2fc4a"
},
"downloads": -1,
"filename": "kor-3.0.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "ca5e690d3b6561a6ce6ef8f34dc97a75",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<4.0,>=3.9",
"size": 31464,
"upload_time": "2024-09-16T17:26:14",
"upload_time_iso_8601": "2024-09-16T17:26:14.740679Z",
"url": "https://files.pythonhosted.org/packages/fe/f3/169100160b3c92cbd5f0a135af4da43352fe84bc752870fa9addbed4db08/kor-3.0.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "cf271bff449058f94b3bd7f63cd3096ae6a4a28fc713bd1b4c374dc06f63f990",
"md5": "f761a2c64fa97f3314c31106675dc86b",
"sha256": "2938b4c4004be692494a7b0629c401799b1e0cec70e6cbc5654cbb087cedf316"
},
"downloads": -1,
"filename": "kor-3.0.0.tar.gz",
"has_sig": false,
"md5_digest": "f761a2c64fa97f3314c31106675dc86b",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4.0,>=3.9",
"size": 27703,
"upload_time": "2024-09-16T17:26:15",
"upload_time_iso_8601": "2024-09-16T17:26:15.707983Z",
"url": "https://files.pythonhosted.org/packages/cf/27/1bff449058f94b3bd7f63cd3096ae6a4a28fc713bd1b4c374dc06f63f990/kor-3.0.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-09-16 17:26:15",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "eyurtsev",
"github_project": "kor",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "kor"
}