Sulaiman8 commited on
Commit
aa3aa09
Β·
verified Β·
1 Parent(s): 0bf9da7

Update recommender/graph_retrieval.py

Browse files
Files changed (1) hide show
  1. recommender/graph_retrieval.py +121 -100
recommender/graph_retrieval.py CHANGED
@@ -57,109 +57,130 @@ class Neo4jRetrievalTool(BaseTool):
57
  description: str = "Runs Cypher and builds FAISS on filtered cards."
58
 
59
  def generate_cypher(self, user_query: str, query_intent: bool, include_cobranded: bool) -> str:
60
- debug_print("TOOL", f"generate_cypher called with query: '{user_query}'")
61
- debug_print("TOOL", f"Parameters: query_intent={query_intent}, include_cobranded={include_cobranded}")
62
-
63
- model = genai.GenerativeModel("gemini-2.0-flash")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
 
65
- context_flags = f"""
66
- Contextual Flags:
67
- - FD Card intent: {query_intent}
68
- - Include co-branded cards: {include_cobranded}
 
 
 
 
 
 
 
 
 
 
 
69
  """
70
- prompt = """
71
- You are an expert Neo4j Cypher query generator.
72
-
73
- Given a user’s question, graph schema, and **contextual flags**, generate the correct Cypher query. The query should return only the card names`c.name as name`.
74
-
75
- ONLY output the Cypher query. Do NOT explain anything.
76
-
77
- ---
78
-
79
- Graph Schema:
80
- - Nodes:
81
- - (Card): Properties = name, bank_name, card_type, premium, co_branded
82
- - (Feature): Properties = name
83
- - Relationships:
84
- - (Card)-[:HAS_FEATURE]->(Feature)
85
-
86
- Feature Inclusion Rules:
87
- - Only include relevant features based on user query.
88
- - Forex markup fee and foreign transaction fee are the same.
89
- - If FD Card intent is true then include the features if the query contains any and also include β€œGeneral Cashback” or β€œGeneral Reward Points”
90
- - Don’t add β€œGeneral Cashback” or β€œGeneral Reward Points” if it is not required.
91
- - If fuel is mentioned, include both `Fuel Benefits` and `Fuel Surcharge Waiver`.
92
- - **ALWAYS** match features using: `f.name IN [...]` β€” even if there is only **one** feature.
93
-
94
- Valid values:
95
- - card_type: 'FD Card' or 'Regular'
96
- - premium: true (no concept of false β€” just include it if applicable)
97
- - co_branded: true (no concept of false β€” just include it if applicable)
98
-
99
- MANDATORY Condition Rules:
100
- - If FD Card intent is true β†’ include: `c.card_type = 'FD Card'`
101
- - Else β†’ include: `c.card_type = 'Regular'`
102
- - If the query is based on beginners or students or people with no or low credit history then use FD Card.
103
- - If the query uses words like "premium", "elite", "luxury", "exclusive", "infinia", "black", etc. β†’ include: `AND c.premium = true`
104
- - If the query includes low spending, without high spending or budget β†’ include: `(c.premium IS NULL OR c.premium = false)`
105
- - If include co-branded is false β†’ include: `AND (c.co_branded IS NULL OR c.co_branded = false)`
106
- - Use exact values for `bank_name` as in the database: ["SBI", "HDFC", "Axis", "ICICI", "YES", "HSBC", "IDFC", "American Express", "SMB", "Federal Bank", "AU Bank", "IDBI", "Kotak Mahindra Bank","IndusInd","RBL"]
107
-
108
- ---
109
-
110
- Available features:
111
- 'Fuel Surcharge Waiver','Insurance','Shopping Benefits','Airport Lounge Access','Co-Branded',
112
- 'Daily Spends (Grocery)','Dining Benefits','Domestic Travel Benefits','Entertainment',
113
- 'General Reward Points','Movie Benefits','Rupay Network Support','Student',
114
- 'UPI Transaction Support','Welcome Bonus','International Travel Benefits','premium',
115
- 'Flight Discounts','Hotel Benefits','Travel Benefits','Railway Benefits','Railway Lounge',
116
- 'Utility','Beginners (Entry Level)','E-commerce Platform Benefits','Air Miles',
117
- 'Jewellery Spends','Concierge Services','Food Delivery Benefits','Lifestyle & Luxury Perks',
118
- 'Spa Access Benefits','Golf Access & Perks','Super Premium','Frequent Flyer Benefits',
119
- 'Health Benefits','Rent Payment Benefits','Education','Lifetime Free','Roadside Assistance',
120
- 'EMI Conversion Options','No Forex Markup Fee','Secured FD Based','Cashback','Fuel Benefits','Business'
121
- ---
122
- Few-shot Examples:
123
-
124
- User Query: Show premium cards with airport lounge access
125
- Cypher:
126
- MATCH (c:Card)-[:HAS_FEATURE]->(f:Feature)
127
- WHERE f.name IN ["Airport Lounge Access"]
128
- AND c.card_type = 'Regular'
129
- AND c.premium = true
130
- RETURN DISTINCT c.name AS name
131
-
132
- User Query: I want FD cards with spa access and golf perks
133
- Cypher:
134
- MATCH (c:Card)-[:HAS_FEATURE]->(f:Feature)
135
- WHERE f.name IN ["Spa Access Benefits", "Golf Access & Perks"]
136
- AND c.card_type = 'FD Card'
137
- RETURN DISTINCT c.name AS name
138
-
139
- User Query: Cards that support UPI but are not co-branded
140
- Cypher:
141
- MATCH (c:Card)-[:HAS_FEATURE]->(f:Feature)
142
- WHERE f.name IN ["UPI Transaction Support"]
143
- AND c.card_type = 'Regular'
144
- AND (c.co_branded IS NULL OR c.co_branded = false)
145
- RETURN DISTINCT c.name AS name
146
-
147
- ---
148
-
149
- {context_flags}
150
-
151
- User Query: {user_query}
152
- Cypher:
153
- """
154
 
155
- cypher_prompt = prompt.format(context_flags=context_flags, user_query=user_query)
156
- debug_print("TOOL", f"Calling Gemini to generate Cypher query, prompt length: {len(cypher_prompt)}")
157
-
158
- cypher_code = model.generate_content(cypher_prompt).text.strip()
159
- cleaned_cypher = cypher_code.strip("`").replace("cypher", "").strip()
160
-
161
- debug_print("TOOL", f"Generated Cypher query: {cleaned_cypher}")
162
- return cleaned_cypher
163
 
164
  def _run(
165
  self,
 
57
  description: str = "Runs Cypher and builds FAISS on filtered cards."
58
 
59
  def generate_cypher(self, user_query: str, query_intent: bool, include_cobranded: bool) -> str:
60
+ debug_print("TOOL", f"generate_cypher called with query: '{user_query}'")
61
+ debug_print("TOOL", f"Parameters: query_intent={query_intent}, include_cobranded={include_cobranded}")
62
+
63
+ model = genai.GenerativeModel("gemini-2.0-flash")
64
+
65
+ context_flags = f"""
66
+ Contextual Flags:
67
+ - FD Card intent: {query_intent}
68
+ - Include co-branded cards: {include_cobranded}
69
+ """
70
+ prompt = """
71
+ You are an expert Neo4j Cypher query generator.
72
+
73
+ Given a user’s question, graph schema, and **contextual flags**, generate the correct Cypher query. The query should return only the card names`c.name as name`.
74
+
75
+ ONLY output the Cypher query. Do NOT explain anything.
76
+
77
+ ---
78
+
79
+ Graph Schema:
80
+ - Nodes:
81
+ - (Card): Properties = name, bank_name, card_type, premium, co_branded
82
+ - (Feature): Properties = name
83
+ - (Partner): Properties = name
84
+ - Relationships:
85
+ - (Card)-[:HAS_FEATURE]->(Feature)
86
+ - (Card)-[:PARTNER_WITH]->(Partner)
87
+
88
+ Feature Inclusion Rules:
89
+ - Only include relevant features based on user query.
90
+ - Forex markup fee and foreign transaction fee are the same.
91
+ - If FD Card intent is true then include the features if the query contains any and also include β€œGeneral Cashback” or β€œGeneral Reward Points”
92
+ - Don’t add β€œGeneral Cashback” or β€œGeneral Reward Points” if it is not required.
93
+ - If fuel is mentioned, include both `Fuel Benefits` and `Fuel Surcharge Waiver`.
94
+ - **ALWAYS** match features using: `f.name IN [...]` β€” even if there is only **one** feature.
95
+
96
+ Partner Inclusion Rules:
97
+ - If the user query mentions any available partner brand names, include:
98
+ MATCH (c)-[:PARTNER_WITH]->(p:Partner)
99
+ AND p.name IN [<matched partner names>]
100
+ - Always use `p.name IN [...]` β€” even if there is only one partner.
101
+
102
+ Valid values:
103
+ - card_type: 'FD Card' or 'Regular'
104
+ - premium: true (no concept of false β€” just include it if applicable)
105
+ - co_branded: true (no concept of false β€” just include it if applicable)
106
+
107
+ MANDATORY Condition Rules:
108
+ - If FD Card intent is true β†’ include: `c.card_type = 'FD Card'`
109
+ - Else β†’ include: `c.card_type = 'Regular'`
110
+ - If the query is based on beginners or students or people with no or low credit history then use FD Card.
111
+ - If the query uses words like "premium", "elite", "luxury", "exclusive", "infinia", "black", etc. β†’ include: `AND c.premium = true`
112
+ - If the query includes low spending, without high spending or budget β†’ include: `(c.premium IS NULL OR c.premium = false)`
113
+ - If include co-branded is false β†’ include: `AND (c.co_branded IS NULL OR c.co_branded = false)`
114
+ - Use exact values for `bank_name` as in the database: ["SBI", "HDFC", "Axis", "ICICI", "YES", "HSBC", "IDFC", "American Express", "SMB", "Federal Bank", "AU Bank", "IDBI", "Kotak Mahindra Bank","IndusInd","RBL"]
115
+
116
+ ---
117
+
118
+ Available features:
119
+ 'Fuel Surcharge Waiver','Insurance','Shopping Benefits','Airport Lounge Access','Co-Branded',
120
+ 'Daily Spends (Grocery)','Dining Benefits','Domestic Travel Benefits','Entertainment',
121
+ 'General Reward Points','Movie Benefits','Rupay Network Support','Student',
122
+ 'UPI Transaction Support','Welcome Bonus','International Travel Benefits','premium',
123
+ 'Flight Discounts','Hotel Benefits','Travel Benefits','Railway Benefits','Railway Lounge',
124
+ 'Utility','Beginners (Entry Level)','E-commerce Platform Benefits','Air Miles',
125
+ 'Jewellery Spends','Concierge Services','Food Delivery Benefits','Lifestyle & Luxury Perks',
126
+ 'Spa Access Benefits','Golf Access & Perks','Super Premium','Frequent Flyer Benefits',
127
+ 'Health Benefits','Rent Payment Benefits','Education','Lifetime Free','Roadside Assistance',
128
+ 'EMI Conversion Options','No Forex Markup Fee','Secured FD Based','Cashback','Fuel Benefits','Business'
129
+
130
+ Available partners:
131
+ "Marriott Bonvoy", "Accor", "Taj", "ITC", "The Postcard", "Indigo", "United Airlines", "Emirates", "Etihad", "Club Vistara", "Air India", "Turkish airlines"
132
+
133
+ ---
134
+ Few-shot Examples:
135
+
136
+ User Query: Show premium cards with airport lounge access
137
+ Cypher:
138
+ MATCH (c:Card)-[:HAS_FEATURE]->(f:Feature)
139
+ WHERE f.name IN ["Airport Lounge Access"]
140
+ AND c.card_type = 'Regular'
141
+ AND c.premium = true
142
+ RETURN DISTINCT c.name AS name
143
+
144
+ User Query: I want FD cards with spa access and golf perks
145
+ Cypher:
146
+ MATCH (c:Card)-[:HAS_FEATURE]->(f:Feature)
147
+ WHERE f.name IN ["Spa Access Benefits", "Golf Access & Perks"]
148
+ AND c.card_type = 'FD Card'
149
+ RETURN DISTINCT c.name AS name
150
+
151
+ User Query: Cards that support UPI but are not co-branded
152
+ Cypher:
153
+ MATCH (c:Card)-[:HAS_FEATURE]->(f:Feature)
154
+ WHERE f.name IN ["UPI Transaction Support"]
155
+ AND c.card_type = 'Regular'
156
+ AND (c.co_branded IS NULL OR c.co_branded = false)
157
+ RETURN DISTINCT c.name AS name
158
 
159
+ User Query: Cards partnered with Indigo and Vistara that offer flight benefits
160
+ Cypher:
161
+ MATCH (c:Card)-[:PARTNER_WITH]->(p:Partner)
162
+ MATCH (c)-[:HAS_FEATURE]->(f:Feature)
163
+ WHERE f.name IN ["Flight Discounts"]
164
+ AND p.name IN ["Indigo", "Vistara"]
165
+ AND c.card_type = 'Regular'
166
+ RETURN DISTINCT c.name AS name
167
+
168
+ ---
169
+
170
+ {context_flags}
171
+
172
+ User Query: {user_query}
173
+ Cypher:
174
  """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
175
 
176
+ cypher_prompt = prompt.format(context_flags=context_flags, user_query=user_query)
177
+ debug_print("TOOL", f"Calling Gemini to generate Cypher query, prompt length: {len(cypher_prompt)}")
178
+
179
+ cypher_code = model.generate_content(cypher_prompt).text.strip()
180
+ cleaned_cypher = cypher_code.strip("`").replace("cypher", "").strip()
181
+
182
+ debug_print("TOOL", f"Generated Cypher query: {cleaned_cypher}")
183
+ return cleaned_cypher
184
 
185
  def _run(
186
  self,