Skip to content

Commit 6f35f81

Browse files
Merge pull request #303 from SuffolkLITLab/llm-lazier-goal-seeking
Better version of GoalSeeking - looser, allows use of structured questions; less annoying
2 parents 4a86c28 + 0176e21 commit 6f35f81

File tree

5 files changed

+945
-11
lines changed

5 files changed

+945
-11
lines changed
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
---
2+
modules:
3+
- .llms
4+
- .misc
5+
---
6+
include:
7+
- display_template.yml
8+
---
9+
generic object: GoalOrientedQuestionList
10+
objects:
11+
- x[i].response_dict: DADict.using(auto_gather=False, gathered=True)
12+
---
13+
generic object: GoalOrientedQuestionList
14+
code: |
15+
x[i].question = x.get_next_question()
16+
---
17+
generic object: GoalOrientedQuestionList
18+
question: |
19+
% if isinstance(x[i].question, dict):
20+
${ x[i].question.get('question_text', 'Please provide more information') }
21+
% else:
22+
${ x[i].question }
23+
% endif
24+
subquestion: |
25+
${ collapse_template(x.show_current_progress) }
26+
fields:
27+
- code: |
28+
x[i].build_field_list()
29+
- Is there anything else you want to tell us? (optional): x[i].response
30+
datatype: area
31+
rows: 4
32+
required: False
33+
---
34+
generic object: GoalOrientedQuestionList
35+
code: |
36+
x.there_are_any = x.need_more_questions()
37+
---
38+
generic object: GoalOrientedQuestionList
39+
code: |
40+
x.there_is_another = x.need_more_questions()
41+
---
42+
generic object: GoalOrientedQuestionList
43+
template: x.show_current_progress
44+
subject: |
45+
Your questions and answers so far
46+
content: |
47+
Your initial response:
48+
> ${ x.initial_response_as_text() }
49+
50+
% for question in x.complete_elements():
51+
* ${ question.response_as_text() }
52+
% endfor
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
---
2+
include:
3+
- goal_oriented_question.yml
4+
---
5+
metadata:
6+
title: Legal Aid Intake - Goal-Oriented Questions Demo
7+
short title: Intake Questions Demo
8+
description: |
9+
This interview demonstrates how to use the GoalOrientedQuestionList
10+
to conduct a legal aid intake by asking follow-up questions until
11+
the intake worker has sufficient information about the client's goals.
12+
---
13+
objects:
14+
- divorce_intake: GoalOrientedQuestionList.using(rubric="The response is complete and gives clear guidance to the intake worker about the client's primary goals and circumstances for the divorce, including enough detail to understand the key issues before the initial meeting.", initial_question="Are you filing for no-fault divorce (for example, 'irretrievable breakdown' or 'separated for at least six months'), or do you believe you have a fault-based reason (for example, cruelty, adultery, desertion, substance abuse, etc.)?\n\nIf it's no-fault, please say when you and your spouse stopped living together (if you still live in the same home, please explain how things are separated — e.g., 'separate bedrooms, no financial sharing').\n\nIf it's fault-based, please give a short description of what happened and when the behavior occurred.", llm_assumed_role="intake worker", user_assumed_role="client")
15+
---
16+
mandatory: True
17+
code: |
18+
intro_screen
19+
divorce_intake.initial_draft
20+
divorce_intake.gather()
21+
final_response
22+
intake_summary
23+
---
24+
code: |
25+
if len(divorce_intake):
26+
final_response_default = divorce_intake.synthesize_draft_response()
27+
else:
28+
final_response_default = divorce_intake.initial_draft
29+
---
30+
continue button field: intro_screen
31+
question: |
32+
Welcome to Legal Aid Intake
33+
subquestion: |
34+
This demo shows how the **GoalOrientedQuestionList** can be used
35+
in a legal aid intake setting to gather complete information from clients.
36+
37+
#### Scenario
38+
39+
You are seeking help with a divorce case. An intake worker needs to understand
40+
your situation to determine if you qualify for services and to prepare for
41+
your initial consultation.
42+
43+
#### How it works:
44+
45+
1. You'll be asked an open-ended question about your divorce situation
46+
2. The AI intake assistant will evaluate your response to see if it provides enough detail
47+
3. If more information is needed, you'll get follow-up questions
48+
4. The assistant will continue asking questions (up to a limit) until it has sufficient information
49+
5. Your responses will be synthesized into a complete intake summary
50+
51+
This approach allows for a more natural conversation while ensuring the intake
52+
worker gets all the essential information before your first meeting.
53+
---
54+
question: |
55+
Tell us about your divorce situation
56+
subquestion: |
57+
To help us prepare for your consultation, please answer the following:
58+
59+
**Are you filing for no-fault divorce** (for example, "irretrievable breakdown"
60+
or "separated for at least six months"), **or do you believe you have a fault-based
61+
reason** (for example, cruelty, adultery, desertion, substance abuse, etc.)?
62+
63+
* If it's **no-fault**, please say when you and your spouse stopped living together.
64+
If you still live in the same home, please explain how things are separated
65+
(e.g., "separate bedrooms, no financial sharing").
66+
67+
* If it's **fault-based**, please give a short description of what happened and
68+
when the behavior occurred.
69+
70+
Don't worry if you're not sure about the legal terms—just tell us about your
71+
situation in your own words.
72+
fields:
73+
- Your response: divorce_intake.initial_draft
74+
datatype: area
75+
rows: 8
76+
---
77+
question: |
78+
Review your intake information
79+
subquestion: |
80+
% if len(divorce_intake):
81+
Based on your responses, we've prepared this summary of your situation.
82+
Please review it and make any corrections or additions before we finalize
83+
your intake information.
84+
85+
${ collapse_template(divorce_intake.show_current_progress) }
86+
% else:
87+
Here is the information you provided. You can make any edits before we finalize
88+
your intake.
89+
% endif
90+
fields:
91+
- Intake summary: final_response
92+
datatype: area
93+
rows: 10
94+
default: |
95+
${ final_response_default }
96+
---
97+
event: intake_summary
98+
question: |
99+
Intake completed
100+
subquestion: |
101+
Thank you for providing this information. Your intake summary is ready
102+
for the intake worker to review before your consultation.
103+
104+
#### Intake Summary
105+
106+
> ${ final_response }
107+
108+
% if len(divorce_intake):
109+
#### Your Conversation
110+
111+
${ collapse_template(divorce_intake.show_current_progress) }
112+
113+
% endif
114+
115+
#### Next Steps
116+
117+
An intake worker will review this information and contact you to schedule
118+
your initial consultation. They now have a clear understanding of your
119+
situation and can better prepare to help you.
120+
121+
---
122+
123+
#### About this demo
124+
125+
This demo used a **GoalOrientedQuestionList** with:
126+
127+
* **Question limit**: ${ divorce_intake.question_limit } follow-up questions maximum
128+
* **Follow-ups asked**: ${ len(divorce_intake) }
129+
* **Sufficient information gathered**: ${ "Yes" if divorce_intake.satisfied() else "Partially" }
130+
* **Model**: ${ divorce_intake.model }
131+
* **LLM role**: ${ divorce_intake.llm_assumed_role }
132+
* **User role**: ${ divorce_intake.user_assumed_role }
133+
134+
The AI asked follow-up questions until the response met this rubric:
135+
136+
> ${ divorce_intake.rubric }
137+
buttons:
138+
- Exit: exit
139+
- Restart: restart
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
---
2+
comment: |
3+
This file provides support for GoalOrientedQuestionList with structured initial questions.
4+
Use this when you want the initial question to use structured fields (radio, checkboxes, etc.)
5+
instead of an open-ended narrative response.
6+
---
7+
modules:
8+
- .llms
9+
- .misc
10+
---
11+
include:
12+
- display_template.yml
13+
- goal_oriented_question.yml
14+
---
15+
generic object: GoalOrientedQuestionList
16+
objects:
17+
- x.initial_draft_dict: DADict.using(auto_gather=False, gathered=True)
18+
---
19+
generic object: GoalOrientedQuestionList
20+
code: |
21+
# Generate the structured initial question fields
22+
x.initial_question_structure = x.generate_initial_question_fields()
23+
x.use_structured_initial_question = True
24+
---
25+
generic object: GoalOrientedQuestionList
26+
code: |
27+
# Mark the initial_draft_dict as gathered after the question is answered
28+
x.initial_draft_dict.gathered = True
29+
x._initial_structured_complete = True
30+
---
31+
generic object: GoalOrientedQuestionList
32+
question: |
33+
% if hasattr(x, 'initial_question_structure'):
34+
${ x.initial_question_structure.get('question_text', x.initial_question) }
35+
% else:
36+
${ x.initial_question }
37+
% endif
38+
field: x._initial_structured_complete
39+
fields:
40+
- code: |
41+
x.build_initial_field_list()
42+
- Is there anything else you want to tell us? (optional): x.initial_draft_response
43+
datatype: area
44+
rows: 4
45+
required: False
46+
---
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
---
2+
include:
3+
- goal_oriented_question_structured.yml
4+
---
5+
metadata:
6+
title: Legal Aid Intake - Structured Initial Question Demo
7+
short title: Structured Intake Demo
8+
description: |
9+
This interview demonstrates using GoalOrientedQuestionList with a
10+
structured initial question (using radio buttons, checkboxes, etc.)
11+
instead of an open-ended narrative response.
12+
---
13+
objects:
14+
- housing_intake: GoalOrientedQuestionList.using(rubric="The response provides complete information about the tenant's housing situation, including the type of issue, timeline, communication with landlord, and any immediate safety or habitability concerns.", initial_question="We need to understand your housing situation to determine how we can help. Please provide information about your housing issue.", llm_assumed_role="housing intake specialist", user_assumed_role="tenant seeking help")
15+
---
16+
mandatory: True
17+
code: |
18+
intro_screen
19+
# Trigger the initial structured question
20+
housing_intake._initial_structured_complete
21+
housing_intake.gather()
22+
final_response
23+
intake_summary
24+
---
25+
code: |
26+
if len(housing_intake):
27+
final_response_default = housing_intake.synthesize_draft_response()
28+
else:
29+
final_response_default = housing_intake.initial_response_as_text()
30+
---
31+
continue button field: intro_screen
32+
question: |
33+
Welcome to Housing Legal Aid Intake (Structured)
34+
subquestion: |
35+
This demo shows how the **GoalOrientedQuestionList** can use structured
36+
fields (radio buttons, checkboxes, etc.) for the initial question instead
37+
of requiring an open-ended narrative.
38+
39+
#### Scenario
40+
41+
You are seeking help with a housing issue. An intake worker needs to understand
42+
your situation using a structured form.
43+
44+
#### How it works:
45+
46+
1. The AI will generate structured fields for the initial question based on the rubric
47+
2. You'll answer using radio buttons, checkboxes, dates, etc. (not just a text area)
48+
3. The AI will then ask follow-up questions if more information is needed
49+
4. Your responses will be synthesized into a complete intake summary
50+
51+
This approach is useful when you want more structured data collection from the start.
52+
---
53+
question: |
54+
Review your intake information
55+
subquestion: |
56+
% if len(housing_intake):
57+
Based on your responses, we've prepared this summary of your situation.
58+
Please review it and make any corrections or additions before we finalize
59+
your intake information.
60+
61+
${ collapse_template(housing_intake.show_current_progress) }
62+
% else:
63+
Here is the information you provided. You can make any edits before we finalize
64+
your intake.
65+
% endif
66+
fields:
67+
- Intake summary: final_response
68+
datatype: area
69+
rows: 10
70+
default: |
71+
${ final_response_default }
72+
---
73+
event: intake_summary
74+
question: |
75+
Intake completed
76+
subquestion: |
77+
Thank you for providing this information. Your intake summary is ready
78+
for the intake worker to review before your consultation.
79+
80+
#### Intake Summary
81+
82+
> ${ final_response }
83+
84+
% if len(housing_intake):
85+
#### Your Conversation
86+
87+
${ collapse_template(housing_intake.show_current_progress) }
88+
89+
% endif
90+
91+
#### Next Steps
92+
93+
An intake worker will review this information and contact you to determine
94+
if we can help with your housing issue.
95+
96+
---
97+
98+
#### About this demo
99+
100+
This demo used a **GoalOrientedQuestionList** with structured initial question:
101+
102+
* **Initial question format**: Structured fields (generated by AI)
103+
* **Question limit**: ${ housing_intake.question_limit } follow-up questions maximum
104+
* **Follow-ups asked**: ${ len(housing_intake) }
105+
* **Sufficient information gathered**: ${ "Yes" if housing_intake.satisfied() else "Partially" }
106+
* **Model**: ${ housing_intake.model }
107+
* **LLM role**: ${ housing_intake.llm_assumed_role }
108+
* **User role**: ${ housing_intake.user_assumed_role }
109+
110+
The AI generated structured fields for the initial question and then asked follow-ups until the response met this rubric:
111+
112+
> ${ housing_intake.rubric }
113+
buttons:
114+
- Exit: exit
115+
- Restart: restart

0 commit comments

Comments
 (0)