Structured Output Is All You Need!
LLMdantic is a powerful and efficient Python library that simplifies the integration of Large Language Models (LLMs) into your projects. Built on top of the incredible Langchain package and leveraging the power of Pydantic models, LLMdantic provides a seamless and structured approach to working with LLMs.
Features 🚀
- 🌐 Wide range of LLM support through Langchain integrations
- 🛡️ Ensures data integrity with Pydantic models for input and output validation
- 🧩 Modular and extensible design for easy customization
- 💰 Cost tracking and optimization for OpenAI models
- 🚀 Efficient batch processing for handling multiple data points
- 🔄 Robust retry mechanism for smooth and uninterrupted experience
Getting Started 🌟
Requirements
Before using LLMdantic, make sure you have set the required API keys for the LLMs you plan to use. For example, if you're using OpenAI's models, set the OPENAI_API_KEY environment variable:
export OPENAI_API_KEY="your-api-key"
If you're using other LLMs, follow the instructions provided by the respective providers in Langchain's documentation.
Installation
pip install llmdantic
Usage
1. Define input and output schemas using Pydantic:
- Use Pydantic to define input and output models with custom validation rules.
from pydantic import BaseModel, field_validator
class SummarizeInput(BaseModel):
text: str
class SummarizeOutput(BaseModel):
summary: str
@field_validator("summary")
def summary_must_not_be_empty(cls, v) -> bool:
"""Summary cannot be empty""" # Add docstring that explains the validation rule. This will be used as a prompt for the LLM.
if not v.strip():
raise
return v
@field_validator("summary")
def summary_must_be_short(cls, v) -> bool:
"""Summary must be less than 100 words""" # Add docstring that explains the validation rule. This will be used as a prompt for the LLM.
if len(v.split()) > 100:
raise
return v
2. Create an LLMdantic client:
- Provide input and output models, objective, and configuration.
from llmdantic import LLMdantic, LLMdanticConfig
from langchain_openai import ChatOpenAI
llm = ChatOpenAI()
config: LLMdanticConfig = LLMdanticConfig(
objective="Summarize the text",
inp_schema=SummarizeInput,
out_schema=SummarizeOutput,
retries=3,
)
llmdantic = LLMdantic(llm=llm, config=config)
Here's the prompt template generated based on the input and output models:
Objective: Summarize the text
Input 'SummarizeInput':
{input}
Output 'SummarizeOutput''s fields MUST FOLLOW the RULES:
SummarizeOutput.summary:
• SUMMARY CANNOT BE EMPTY
• SUMMARY MUST BE LESS THAN 100 WORDS
{format_instructions}
3. Generate output using the LLMdantic:
from llmdantic import LLMdanticResult
data = SummarizeInput(text="A long article about natural language processing...")
result: LLMdanticResult = llmdantic.invoke(data)
output: Optional[SummarizeOutput] = result.output
if output:
print(output.summary)
Here's the actual prompt sent to the LLM based on the input data:
Objective: Summarize the text
Input 'SummarizeInput':
{'text': 'A long article about natural language processing...'}
Output 'SummarizeOutput''s fields MUST FOLLOW the RULES:
SummarizeOutput.summary:
• SUMMARY CANNOT BE EMPTY
• SUMMARY MUST BE LESS THAN 100 WORDS
The output should be formatted as a JSON instance that conforms to the JSON schema below.
As an example, for the schema {"properties": {"foo": {"title": "Foo", "description": "a list of strings", "type": "array", "items": {"type": "string"}}}, "required": ["foo"]}
the object {"foo": ["bar", "baz"]} is a well-formatted instance of the schema. The object {"properties": {"foo": ["bar", "baz"]}} is not well-formatted.
Here is the output schema:
{"properties": {"summary": {"title": "Summary", "type": "string"}}, "required": ["summary"]}
- For batch processing, pass a list of input data.
data: List[SummarizeInput] = [
SummarizeInput(text="A long article about natural language processing..."),
SummarizeInput(text="A long article about computer vision...")
]
results: List[LLMdanticResult] = llmdantic.batch(data, concurrency=2)
for result in results:
if result.output:
print(result.output.summary)
4. Monitor usage and costs:
-
Use the
costattribute of the LLMdanticResult to track the cost of the request (currently available for OpenAI models). -
Use the
usageattribute of the LLMdantic to track the usage stats overall.
from llmdantic import LLMdanticResult
data: SummarizeInput = SummarizeInput(text="A long article about natural language processing...")
result: LLMdanticResult = llmdantic.invoke(data)
if result.output:
print(result.output.summary)
# Track the cost of the request (OpenAI models only)
print(f"Cost: {result.cost}")
# Track the usage stats
print(f"Usage: {llmdantic.usage}")
Cost: 0.0003665
Overall Usage: LLMdanticUsage(
inp_tokens=219,
out_tokens=19,
total_tokens=238,
successful_requests=1,
cost=0.000367,
successful_outputs=1
)
Advanced Usage 🛠
LLMdantic is built on top of the langchain package, which provides a modular and extensible framework for working with LLMs. You can easily switch between different LLMs and customize your experience.
Switching LLMs
from llmdantic import LLMdantic, LLMdanticConfig
from langchain_community.llm.ollama import Ollama
from langchain.llms.base import BaseLanguageModel
llm: BaseLanguageModel = Ollama()
config: LLMdanticConfig = LLMdanticConfig(
objective="Summarize the text",
inp_schema=SummarizeInput,
out_schema=SummarizeOutput,
retries=3,
)
llmdantic = LLMdantic(
llm=llm,
config=config
)
Contributing 🤝
Contributions are welcome! Whether you're fixing bugs, adding new features, or improving documentation, your help makes LLMdantic better for everyone. Feel free to open an issue or submit a pull request.
License 📄
LLMdantic is released under the MIT License. Feel free to use it, contribute, and spread the word!
Metadata
Release files for llmdantic 1.0.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| llmdantic-1.0.3.tar.gz | 1.9 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| llmdantic-1.0.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 1.9 MB
Release files / llmdantic-1.0.3.tar.gz
| Download URL | llmdantic-1.0.3.tar.gz |
|---|---|
| Size | 1.9 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
212ccc0d3be5d87ca9917ae9167285a5a570f1cc8d59e890425d10fa3c54e3ba
|
|
BLAKE2b-256 checksum How to use checksums |
f6ac1c486dc1186fe2829ece0423313f0ba410f949d6a961e3433281a333cb00
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
python-requests/2.31.0
|
Release files / llmdantic-1.0.3-py3-none-any.whl
| Download URL | llmdantic-1.0.3-py3-none-any.whl |
|---|---|
| Size | 14.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5eda31f32632b612704de5a0f40281adfb74a0a93be4ff7d6bd836c482b1dc88
|
|
BLAKE2b-256 checksum How to use checksums |
9d54610d6e43f971148ba611423660f7335c4ac4ad14e927cac1cea2a0d49d7c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
python-requests/2.31.0
|