-
Notifications
You must be signed in to change notification settings - Fork 583
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enforcing a conditional logic in responses #1457
Comments
I don't think that Pydantic exposes the kind of conditional logic that Json Schema supports. However, we can try a different approach by unrolling the conditional dependency using the Regex DSL. from outlines.types.dsl import Alternatives, String
information_query = "Enough information to categorize the post? "
conclusion = "Final coding of post "
choice = Alternatives([String("macroeconomics"), String("civil rights")])
template = information_query + ( ("No. " + conclusion + "OTHER") | ("Yes. " + conclusion + choice)) I apologize for the syntax, it is still a bit rough around the edges. Opened #1459 to correct this. |
This looks really helpful. Two, perhaps stupid questions if you have a moment:
|
|
My two cents here -- Remi's right that Pydantic doesn't support conditionals, so there's not really a great way to enforce the non-response you're looking for. One option is to try class Coding(BaseModel):
information: Information = Field(..., description="Enough information to categorize the post?")
conclusion: Optional[Code] = Field(..., description="Final coding of post") Your model may also be somewhat confused because the question asks whether or not there is enough information to assign a code, and then even if it says no it must choose a code which can include This is sadly not really an enforced output thing but it might help. If this were my project, I would ignore any codes where the |
Since this issue is about conditional logic, I figured I'd stick this in here for discussion. It doesn't seem like Outlines supports conditionals in JSON schemas (which may already be a known issue): import time
import outlines
from outlines import models, generate
from outlines_core.fsm.json_schema import build_regex_from_schema
from outlines.fsm.guide import RegexGuide
import json
from transformers import AutoTokenizer
model_name = "HuggingFaceTB/SmolLM2-135M"
model = models.transformers(
model_name,
device="auto",
)
tk = AutoTokenizer.from_pretrained(model_name)
schema = """
{
"type": "object",
"properties": {
"name": { "type": "string" },
"credit_card": { "type": "number" },
"billing_address": { "type": "string" }
},
"required": ["name"],
"dependentRequired": {
"credit_card": ["billing_address"]
}
}
"""
generator = generate.json(model, schema)
prompts = [
"Return a json of a person",
"Return a json of a person with a credit card",
"Return a json of a person without a credit card",
"Return a json of a person with a billing address",
"Return a json of a person without a billing address",
]
def template(thing):
return tk.apply_chat_template(
[
{"role": "user", "content": thing},
],
tokenize=False,
add_generation_prompt=True,
)
res = generator([template(prompt) for prompt in prompts])
for prompt, res in zip(prompts, res):
print(prompt)
print(res)
print() which yields
Any of these that include a credit card must include a billing address as per the schema, so seems it's not currently implemented. |
With the latest release you should be able to write: from outlines.types import either
information_query = "Enough information to categorize the post? "
conclusion = "Final coding of post "
choices = either("macroeconomics", "civil rights")
outline = information_query + either(
("No. " + conclusion + "OTHER"),
("Yes. " + conclusion + choices)
) |
I've been working on using this to categorize twitter posts into 1 of 7 categories. One issue I've had so far is that models seem to be overly willing to identify meaning in posts that don't have a lot of content. I thought about solving this by trying to use a chain-of-thought style approach where the prompt asks to first identify if there is enough information and then code the tweet if there is enough (and if there isn't enough it should return "OTHER").
The problem I'm having is that there doesn't seem to be an obvious way to force that requirement. So I will get posts identified as having not enough information and then a non-OTHER code applied.
Below is what I'm using. I'm afraid I might be missing something obvious.
I'll get output like:
The text was updated successfully, but these errors were encountered: