Skip to content

Instantly share code, notes, and snippets.

@edanweis
Created March 10, 2024 03:04
Show Gist options
  • Select an option

  • Save edanweis/571acfea31599827a02fb4e31bd7bf52 to your computer and use it in GitHub Desktop.

Select an option

Save edanweis/571acfea31599827a02fb4e31bd7bf52 to your computer and use it in GitHub Desktop.
A partial snippet of LMQL prompt for causal graph (causal loop diagram) generation
# This code is incomplete
def modifyNode(id,new_name,c=None):
try:
for node in clds['nodes']:
if node['id'] == id:
node['name'] = new_name
except Exception as e:
new_row = pd.DataFrame([{'error': e, 'modification': f"modifyNode({id}, {new_name})"}])
global error_df
error_df = pd.concat([error_df, new_row], ignore_index=True)
pass
def modifyEdge(id, new_label, reason):
try:
for edge in cld['edges']:
e = re.sub(r'\D', '', id)
if edge['id'] == e:
edge['label'] = new_label
edge['reason'] = reason
except Exception as e:
new_row = pd.DataFrame([{'error': e, 'modification': f"modifyEdge({e}, {new_label}, {reason})"}])
global error_df
error_df = pd.concat([error_df, new_row], ignore_index=True)
pass
async def conditional(answer, rule):
rules = {
"positive": "Please where possible, rewrite the node in a more 'positive' sense, For example, the concept of 'Growth' increasing or decreasing is clearer than an increase or decrease in 'Contraction'",
"quantities": """. Please rewrite them to represent quantities that can vary over time. Eg: it does not make sense to say that "State of Mind" increases or decreases. A term like "Happiness" on the other hand, can vary.""",
"perceived-actual":"Distinguishing between perceived and actual states, such as 'Perceived Quality' versus 'Actual Quality' is important. Perceptions often change slower than reality does, and mistaking the perceived status for current reality can be misleading and create undesirable results.",
"reason": "Please provide a reason for the edge, with 'because' in it. Eg: 'The RAI Maturity Model increases Complexity because it evaluates multiple dimensions",
"intermediate":"Redefine the node labels or insert an intermediate term. Eg: the relationship between 'Demand' and 'Quality' may be more obvious when a 'Production Pressure' node is inserted between them.",
"rate_to_level_or_info": "Reconnect the edges so that they are not rate-to-level or 'flows'. Because a net rate is the aggregation of an inflow and an outflow, it is not possible to decide whether a net rate-to-level link is a positive influence or a negative one. Eg: If net births per year is positive, births add to population and the loop is a positive loop; conversely, if net births per year is negative, net births subtract from population and the loop is a negative loop identical to a population/deaths loop. Net births will decrease population only if the number declines far enough to be negative, in which case the loop is not positive, but negative.",
}
try:
answer = answer.strip("\n '.").lower()
if answer=='no':
broken_rules[rule] = True
return rules[rule]
else:
broken_rules[rule] = False
return "\n\n"
except:
return ''
def getQuestion(q):
questions = {
"quantities": "Do all nodes represent quantities that can vary over time?",
"positive": "Are all node variables worded in a 'positive' sense? eg: Growth instead of contraction",
"perceived-actual": "Are all nodes clearly worded as perceived or actual rates/levels/states?",
"intermediate": "Are all edges between two nodes clear, or do they require a lot of explanation to be clear?",
"reason": "Do all edges provide a reason, with 'because' in them?",
"rate_to_level_or_info": "Are all edges information relations? rather than worded as rate-to-level or 'flows'?"
}
return questions[q]
@lmql.query(model='openai/gpt-3.5-turbo-instruct', max_len=3900, openai_nonstop=True, cache="lmql_cache", verbose=False, output_writer=lmql.stream("MODIFICATION"))
def createCausalGraph(pattern, con, benefits, drawbacks, type_of_pattern, type_of_objective, target_users, impacted_stakeholders, solution):
'''lmql
"""
A causal loop diagram (CLD) is a directed graph with self-loops and parallel relationships that describes variables in a system whose values change over time and are causally interrelated. Closed loops, or causal feedback loops, in the diagram are very important features of CLDs. Feedback loops have either positive (reinforcing) or negative (balancing) polarity. A reinforcing loop is a cycle in which the effect of a variation in any variable propagates through the loop and returns to reinforce the initial deviation (ie. if a variable increases in a reinforcing loop the effect through the cycle will return an increase to the same variable and vice versa). A balancing loop is the cycle in which the effect of a variation in any variable propagates through the loop and returns to the variable a deviation opposite to the initial one (i.e. if a variable increases in a balancing loop the effect through the cycle will return a decrease to the same variable and vice versa). Balancing loops are typically goal-seeking, or error-sensitive, processes and are presented with the variable indicating the goal of the loop. Reinforcing loops are typically vicious or virtuous cycles.
Instructions:
Your task is to create a causal loop diagram to help define the causal edges connecting nodes:
- An "S" edge label "same" is when an increase in X results in a value of Y which is greater than it would have been had X not changed.
- An "O" edge label "opposite" is when X has a negative effect on Y if X subtracts from Y, or if a change in X results in a change in Y in the opposite direction.
You must use adjectival phrases which can increase or decrease instead of merely nouns, or stakeholders. For example in the case of an edge between node names "RAI risk committee" and "AI Projects" with reason, "The RAI risk committee ensures that all AI projects are reviewed and approved, leading to enforced internal governance." The name "AI Projects" should instead be "enforcement of internal governance" which is a quality or quantity that can increase or decrease.
Include a "reason" property on edges to explain and justify the causal connection citing the context given. The reason MUST absolutely have a "because" in it. (avoid repeating the node names in the reason)
Include a boolean "delay" property on edges if there is typically a delay in that particular cause-effect relationship.
Here is an example causal loop diagram in JSON format: {{ "nodes": [[{{"id": 1, "name": "Untrustworthy AI", "type": "level"}}, {{"id": 2, "name": "Poor RAI Standards", "type": "level"}} ]], "edges": [[{{"id": 1, "start": 2, "end": 1, "label": "S", "delay": false, "reason": "Inadequate RAI standards lead to less trust in AI systems" }}]] }}
Here is some context for the Causal loop diagram (use them to inform the cld, but do not include them in the JSON)
Pattern: {pattern}
Context: {con}
Solution: {solution}
Pattern type: {type_of_pattern}
Objective: {type_of_objective}
Benefits: {benefits}
Drawbacks: {drawbacks}
Now create a causal loop diagram to help define the causal edges connecting nodes following instructions above. Remember to use adjectival phrases that express a quantifiable factors that can increase or decrease. This task is vital to my career, and I greatly value your thorough analysis. Let's think this through step by step:
1. Firstly, write an excellent first draft of this in JSON (No breakdown or explanation required)
JSON schema:
node keys: id, type, name
edge keys: id, start, end, label, reason, delay
"""
"""
cld =
"nodes": [NODES]""" where STOPS_AT(NODES, "],")
"""
"edges": [EDGES]""" where STOPS_AT(EDGES, "]")
"""
2. Now let's examine and revise our answer:
"""
for q in ['positive', 'quantities', 'perceived-actual', 'intermediate', 'rate_to_level_or_info', 'reason']:
question = await getQuestion(q)
"Q: {question}\n"
"A: The answer is '[TERM]\n" where STOPS_AT(TERM, "'")
rule = await conditional(TERM, q)
broken_rules[q] = False if q.strip("\n '.").lower()=='no' else True
"{rule}"
if any(broken_rules.values()):
"""
Write Python code that modifies the node names and edge labels as per the suggestions above. Only modify if they are different. You must still apply the correct "S" or "O" edge labels. Eg, if you created variables with negative wording, you can modify them to be positive by changing using the function modifyNode(id: int, new_name: str)
```Python
modifyNode(1, "trust-worthiness")
modifyNode(2, "RAI Standards compliance")
```
Edge labels and reasons can be similarly modified
```
modifyEdge(1, "S", "Trust-worthiness from AI systems can be assured by compliance with RAI standards because users can trust the AI systems that meet the standards.")
```
but only if they are inconsistent after nodes/edges are modified. Finish your code with # End python
# Following the above suggestions, we only need to modify *n* nodes and *e* edges, where n = [N_MODIFY] and e = [E_MODIFY]""" where INT(N_MODIFY) and INT(E_MODIFY)
"""# No indents, Begin Python\n[MODIFICATION]"""
'''
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment