Prompt "profiles": serializable bundles of system prompt + tools + schema
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 176
- Forks
- 28
- Avg merge
- 18h 42m
- Merged PRs (30d)
- 16
Description
Motivation
Simon Willison's llm has templates: YAML bundles of system prompt, prompt fragments, model options, tools, and schemas, invoked via llm -t name. This lets users package up a reusable "agent config" and share it as a file. chatlas has the pieces (interpolate()/interpolate_file() in chatlas/_interpolate.py, register_tool()/set_tools() and chat_structured(data_model=...) in chatlas/_chat.py, set_model_params()), but nothing that bundles them into one serializable, shareable unit. Pydantic AI has a related but narrower idea in reusable Agent instances, though those aren't declaratively serializable either.
Proposed approach
Introduce a Profile object — a thin, serializable bundle of the inputs to a Chat, not a new execution engine:
from chatlas import Profile, ChatOpenAI
profile = Profile(
system_prompt="You are a terse SQL assistant.\n{{ extra_instructions }}", # interpolate() template
data_model="myapp.schemas.SqlAnswer", # optional, import-path string
params={"temperature": 0.2},
)
chat = profile.create_chat(ChatOpenAI, variables={"extra_instructions": "Always cite the table."})
Profile.from_yaml(path)/Profile.to_yaml(path)(or TOML) for round-tripping.system_promptis rendered throughinterpolate()atcreate_chat()time, so the same template mechanics/variable-inference already in_interpolate.pyapply.data_modelandparamsmap directly ontochat_structured(data_model=...)andset_model_params().- Tools are the hard part. Functions aren't YAML-serializable. Two honest options: (a) store an import path string (
"myapp.tools:lookup_price") resolved viaimportlibat load time — simple, but ties the profile to code being importable in the same environment; (b) require a small in-app registry mapping names to callables that the profile references by name only. Given this complexity, the proposal is to ship the non-tool subset first (system prompt + data_model + params, dumpable/loadable), and treat tool bundling as a stretch goal / separate follow-up once the serialization approach is validated with users.
Alternatives / prior art
- ellmer has
interpolate()(string-only) and no bundling concept beyond that — this would be new territory for both projects, so getting the design right in chatlas first and porting later (as usual) seems reasonable. - Do nothing: users keep hand-rolling a
dict/module of prompt+schema+params, which works but isn't shareable as a file the wayllm's templates are. - A pure-YAML "recipe" that only ever produces kwargs for
ChatAuto(**kwargs)(no new class) is a lighter-weight alternative worth considering.
Open questions
- Is
create_chat()the right entry point, or should this be aChat*(profile=...)constructor kwarg instead (per the original ask)? - YAML vs TOML vs both?
- Should
Profilealso carry the provider/model string (à laChatAuto's"provider/model"), or stay provider-agnostic and let the caller pick theChat*class?
Drafted from a competitive review of llm / Pydantic AI / LangChain / LiteLLM (July 2026); filed via Claude Code on behalf of @cpsievert.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading chatlas/_interpolate.py and chatlas/_chat.py, especially interpolate(), chat_structured(), set_model_params(), and the tool methods. Resolve the open questions around serialization scope and the creation entry point, then verify that a Profile can round-trip its system_prompt, data_model, and params and create a Chat with interpolation. Tool bundling is outside the initial done criteria.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- backend-api-design
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100