NL → GoalSpec Interpreter#
LangGOAP’s GoalInterpreter converts natural language requests into formal
GoalSpec objects using any LangChain chat model that supports structured output.
"Generate a report under $5"
↓
GoalInterpreter.interpret()
↓
GoalSpec(conditions={"report_complete": True},
constraints=(ConstraintSpec(key="cost_usd", max=5.0),))
This notebook demonstrates the interpreter in isolation — no GOAP execution.
Setup#
Define a simple action catalog and create the interpreter.
from langchain_openai import ChatOpenAI
from langgoap import ActionSpec, GoalInterpreter
# Define available actions — the interpreter uses these to ground its output
actions = [
ActionSpec(
name="fetch_data",
preconditions={"has_source": True},
effects={"data_fetched": True},
resources={"cost_usd": 0.5, "api_calls": 1},
metadata={"description": "Fetch raw data from the configured source"},
),
ActionSpec(
name="clean_data",
preconditions={"data_fetched": True},
effects={"data_clean": True},
resources={"cost_usd": 0.1},
metadata={"description": "Validate and clean the raw data"},
),
ActionSpec(
name="generate_report",
preconditions={"data_clean": True},
effects={"report_complete": True},
resources={"cost_usd": 1.0, "tokens": 500},
metadata={"description": "Generate a formatted report from clean data"},
),
]
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
interpreter = GoalInterpreter(
llm=llm,
actions=actions,
)
Basic Interpretation#
Convert a simple request into a GoalSpec.
goal = interpreter.interpret("Generate a report from the data")
print(f"GoalSpec: {goal}")
print(f"Conditions: {dict(goal.conditions)}")
print(f"Constraints: {goal.constraints}")
print(f"Objectives: {goal.objectives}")
GoalSpec: GoalSpec(conditions={'report_complete': True})
Conditions: {'report_complete': True}
Constraints: ()
Objectives: None
With Budget Constraints#
Budget language like “under $5” is extracted as a ConstraintSpec.
goal = interpreter.interpret("Generate a report, keeping costs under $5")
print(f"Conditions: {dict(goal.conditions)}")
print(f"Constraints: {goal.constraints}")
for c in goal.constraints:
print(f" {c.key}: max={c.max}, min={c.min}, weight={c.weight}")
Conditions: {'report_complete': True}
Constraints: (ConstraintSpec(key='cost_usd', max=5.0, min=None, weight=1.0, level='hard'),)
cost_usd: max=5.0, min=None, weight=1.0
With Optimization Objectives#
Language like “cheapest” or “minimize cost” is extracted as an optimization objective.
goal = interpreter.interpret("Generate the cheapest possible report")
print(f"Conditions: {dict(goal.conditions)}")
print(f"Objectives: {dict(goal.objectives) if goal.objectives else None}")
Conditions: {'report_complete': True}
Objectives: {'cost_usd': <ObjectiveDirection.MINIMIZE: 'minimize'>}
Debugging with interpret_raw()#
interpret_raw() returns the InterpretedGoal with the LLM’s reasoning
field preserved — useful for debugging and transparency.
raw = interpreter.interpret_raw("Generate a detailed report under $5, minimizing token usage")
print(f"Reasoning: {raw.reasoning}")
print(f"Conditions: {raw.conditions}")
print(f"Constraints: {raw.constraints}")
print(f"Objectives: {raw.objectives}")
Reasoning: The request specifies generating a detailed report while ensuring the total cost does not exceed $5 and aims to minimize token usage.
Conditions: {'report_complete': True}
Constraints: [InterpretedConstraint(key='cost_usd', max=5.0, min=None, weight=1.0, level='hard')]
Objectives: [InterpretedObjective(metric='tokens', direction='minimize')]
Custom System Prompt#
Override the default system prompt for domain-specific interpretation.
The template must contain {action_catalog} and {world_state} placeholders.
custom_prompt = """\
You are interpreting user requests for a data pipeline system.
Available pipeline steps:
{action_catalog}
Current pipeline state:
{world_state}
Extract the user's desired end-state as **conditions** (key-value pairs using
the condition keys from the action effects above), any budget constraints, and
optimization preferences.
"""
custom_interpreter = GoalInterpreter(
llm=llm,
actions=actions,
system_prompt=custom_prompt,
)
goal = custom_interpreter.interpret("Generate a complete report from the data")
print(f"GoalSpec: {goal}")