Lilypad¶
Project is in alpha phase
This means that things like the user interface, database schemas, etc. are still subject to change. We do not yet recommend fully relying on this project in production, but we've found it works quite well for local development in its current stage.
An open-source prompt engineering framework built on these principles:
- Prompt engineering is an optimization process, which requires...
- Automatic versioning and tracing
- Developer-centric prompt template editor
- Proper syncing between prompts and code
We're looking for early design partners!
We are also working on tooling for improved collaboration between technical and non-technical team members. This is particularly important for involving domain experts who may not have the technical chops to contribute to a code base.
If you're interested, join our community and DM William Bakst :)
There are limited spots.
30 Second Quickstart¶
Install Lilypad, specifying the provider(s) you intend to use, and set your API key:
Create your first synced prompt to recommend a book.
For example, you could use the prompt Recommend a fantasy book
:
Once you hit "Submit" you'll see the function run in your shell. Follow the link to see the version and trace in an interactive UI.
Next, try editing the function signature to take a genre: str
argument. When you run the function again it will open the editor and give you access to the {genre}
template variable (with autocomplete).
Features¶
Official SDK Usage¶
You can use the lilypad.llm_fn
decorator on any function that uses an LLM API to generate it's response. This function will then be versioned and traced automatically for you, all the way through the entire lexical closure:
import lilypad
from openai import OpenAI
client = OpenAI()
@lilypad.llm_fn()
def recommend_book(genre: str) -> str:
completion = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": f"Recommend a {genre} book"}],
)
return str(completion.choices[0].message.content)
output = recommend_book("fantasy")
print(output)
import lilypad
from anthropic import Anthropic
client = Anthropic()
@lilypad.llm_fn()
def recommend_book(genre: str) -> str:
message = client.messages.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": f"Recommend a {genre} book"}],
max_tokens=1024,
)
block = message.content[0]
return block.text if block.type == "text" else ""
output = recommend_book("fantasy")
print(output)
Synced LLM Function Usage¶
Setting synced=True
in the lilypad.llm_fn
decorator indicates that the decorated function should be synced. The result is that only the function definition / signature will be used and everything else that goes into calling the LLM API (i.e. the prompt) lives in the database.
Note that this is truly just a shim where everything lives externally -- down to the provider and model to be used.
You can also change the return type of the shim and it will be automatically handled: