Description
Sometimes outside of getting a structured output for the final answer, you might want to get the intermediate output by LLM and reference them in a later stage. Together with #1407 (and related #1434 #1480) here a interface of doing is is proposed.
Using a named variable it could be possible to pass value forward, e.g. for a simple example to count number of r in the word 'strawberry':
thinking_pattern = (
String("First, listing all letters in the word strawberry: ") +
Capture(repeat(char + optional(whitespace), 8, 11), "letters") +
newline
)
Then each letters in Capture
can be parsed into a list
letters_list = parse_capture("letters", list, [])
letters_list = [letter for letter in letters_list]
letter_count = len(letters_list)
And then create pattern using a loop so to emulate the effect of a for loop without LLM output
counting_items = []
for i in range(letter_count):
counting_items.append(
String(f" Checking letter {i+1}: ") +
String(letters_list[i]) +
String(" Is it 'r'? ") +
(String("Yes") | String("No")) +
String(".") +
optional(String(" Running count: ") + Capture(digit, f"count_{i}")) +
newline
)
Alternatively one can also capture a value e.g. String("Integer: ") + capture(integer, "integer_value")
, then parse it using int_val = parse_value("integer_value", int)
to cast into python type with
capture_pattern = (
String("Let's extract different data types:") + newline +
String("Integer: ") + capture(integer, "integer_value") + newline +...
)
def process_values():
int_val = parse_value("integer_value", int, 0)
store_value("int_squared", int_val ** 2)
return (
String("Processing results:") + newline +
String(f"Integer squared: {int_val}² = {int_val ** 2}") + newline +...
output = create_dynamic_pipeline(
model=model,
prompt="Extract different data types and perform operations on them.",
patterns=[capture_pattern, process_values...
Here is my prototype of the implementation: https://github.com/903124/outlines/tree/capture
Looking forward to any suggestion or enhancement!