Spaces:
Running
Running
adding FAQ chatbot
Browse files
examples/LynxScribe FAQ Chatbot Builder.lynxkite.json
ADDED
@@ -0,0 +1,605 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"edges": [
|
3 |
+
{
|
4 |
+
"id": "LynxScribe FAQ to RAG 1 LynxScribe RAG Graph Chatbot Builder 1",
|
5 |
+
"source": "LynxScribe FAQ to RAG 1",
|
6 |
+
"sourceHandle": "output",
|
7 |
+
"target": "LynxScribe RAG Graph Chatbot Builder 1",
|
8 |
+
"targetHandle": "rag_graph"
|
9 |
+
},
|
10 |
+
{
|
11 |
+
"id": "LynxScribe RAG Graph Chatbot Builder 1 LynxScribe RAG Graph Chatbot Backend 1",
|
12 |
+
"source": "LynxScribe RAG Graph Chatbot Builder 1",
|
13 |
+
"sourceHandle": "output",
|
14 |
+
"target": "LynxScribe RAG Graph Chatbot Backend 1",
|
15 |
+
"targetHandle": "knowledge_base"
|
16 |
+
},
|
17 |
+
{
|
18 |
+
"id": "Chat processor 1 LynxScribe RAG Graph Chatbot Backend 1",
|
19 |
+
"source": "Chat processor 1",
|
20 |
+
"sourceHandle": "output",
|
21 |
+
"target": "LynxScribe RAG Graph Chatbot Backend 1",
|
22 |
+
"targetHandle": "chat_processor"
|
23 |
+
},
|
24 |
+
{
|
25 |
+
"id": "Truncate history 1 Chat processor 1",
|
26 |
+
"source": "Truncate history 1",
|
27 |
+
"sourceHandle": "output",
|
28 |
+
"target": "Chat processor 1",
|
29 |
+
"targetHandle": "processor"
|
30 |
+
},
|
31 |
+
{
|
32 |
+
"id": "LynxScribe RAG Graph Chatbot Backend 1 Test Chat API 1",
|
33 |
+
"source": "LynxScribe RAG Graph Chatbot Backend 1",
|
34 |
+
"sourceHandle": "output",
|
35 |
+
"target": "Test Chat API 1",
|
36 |
+
"targetHandle": "chat_api"
|
37 |
+
},
|
38 |
+
{
|
39 |
+
"id": "Input chat 1 Test Chat API 1",
|
40 |
+
"source": "Input chat 1",
|
41 |
+
"sourceHandle": "output",
|
42 |
+
"target": "Test Chat API 1",
|
43 |
+
"targetHandle": "message"
|
44 |
+
},
|
45 |
+
{
|
46 |
+
"id": "Test Chat API 1 View 1",
|
47 |
+
"source": "Test Chat API 1",
|
48 |
+
"sourceHandle": "output",
|
49 |
+
"target": "View 1",
|
50 |
+
"targetHandle": "input"
|
51 |
+
}
|
52 |
+
],
|
53 |
+
"env": "LynxScribe",
|
54 |
+
"nodes": [
|
55 |
+
{
|
56 |
+
"data": {
|
57 |
+
"__execution_delay": 0.0,
|
58 |
+
"collapsed": false,
|
59 |
+
"display": null,
|
60 |
+
"error": null,
|
61 |
+
"input_metadata": null,
|
62 |
+
"meta": {
|
63 |
+
"inputs": {},
|
64 |
+
"name": "LynxScribe FAQ to RAG",
|
65 |
+
"outputs": {
|
66 |
+
"output": {
|
67 |
+
"name": "output",
|
68 |
+
"position": "right",
|
69 |
+
"type": {
|
70 |
+
"type": "None"
|
71 |
+
}
|
72 |
+
}
|
73 |
+
},
|
74 |
+
"params": {
|
75 |
+
"faq_excel_path": {
|
76 |
+
"default": "uploads/organon_demo/organon_en_copy.xlsx",
|
77 |
+
"name": "faq_excel_path",
|
78 |
+
"type": {
|
79 |
+
"type": "<class 'str'>"
|
80 |
+
}
|
81 |
+
},
|
82 |
+
"scenario_cluster_distance_pct": {
|
83 |
+
"default": 30.0,
|
84 |
+
"name": "scenario_cluster_distance_pct",
|
85 |
+
"type": {
|
86 |
+
"type": "<class 'float'>"
|
87 |
+
}
|
88 |
+
},
|
89 |
+
"text_embedder_interface": {
|
90 |
+
"default": "openai",
|
91 |
+
"name": "text_embedder_interface",
|
92 |
+
"type": {
|
93 |
+
"type": "<class 'str'>"
|
94 |
+
}
|
95 |
+
},
|
96 |
+
"text_embedder_model_name_or_path": {
|
97 |
+
"default": "text-embedding-3-large",
|
98 |
+
"name": "text_embedder_model_name_or_path",
|
99 |
+
"type": {
|
100 |
+
"type": "<class 'str'>"
|
101 |
+
}
|
102 |
+
},
|
103 |
+
"vdb_collection_name": {
|
104 |
+
"default": "lynx",
|
105 |
+
"name": "vdb_collection_name",
|
106 |
+
"type": {
|
107 |
+
"type": "<class 'str'>"
|
108 |
+
}
|
109 |
+
},
|
110 |
+
"vdb_num_dimensions": {
|
111 |
+
"default": 3072.0,
|
112 |
+
"name": "vdb_num_dimensions",
|
113 |
+
"type": {
|
114 |
+
"type": "<class 'int'>"
|
115 |
+
}
|
116 |
+
},
|
117 |
+
"vdb_provider_name": {
|
118 |
+
"default": "faiss",
|
119 |
+
"name": "vdb_provider_name",
|
120 |
+
"type": {
|
121 |
+
"type": "<class 'str'>"
|
122 |
+
}
|
123 |
+
}
|
124 |
+
},
|
125 |
+
"type": "basic"
|
126 |
+
},
|
127 |
+
"params": {
|
128 |
+
"faq_excel_path": "uploads/organon_demo/organon_en_copy.xlsx",
|
129 |
+
"scenario_cluster_distance_pct": "30",
|
130 |
+
"text_embedder_interface": "openai",
|
131 |
+
"text_embedder_model_name_or_path": "text-embedding-3-large",
|
132 |
+
"vdb_collection_name": "lynx",
|
133 |
+
"vdb_num_dimensions": 3072.0,
|
134 |
+
"vdb_provider_name": "faiss"
|
135 |
+
},
|
136 |
+
"status": "done",
|
137 |
+
"title": "LynxScribe FAQ to RAG"
|
138 |
+
},
|
139 |
+
"dragHandle": ".bg-primary",
|
140 |
+
"height": 620.0,
|
141 |
+
"id": "LynxScribe FAQ to RAG 1",
|
142 |
+
"position": {
|
143 |
+
"x": -1180.0,
|
144 |
+
"y": -76.0
|
145 |
+
},
|
146 |
+
"type": "basic",
|
147 |
+
"width": 415.0
|
148 |
+
},
|
149 |
+
{
|
150 |
+
"data": {
|
151 |
+
"__execution_delay": 0.0,
|
152 |
+
"collapsed": false,
|
153 |
+
"display": null,
|
154 |
+
"error": null,
|
155 |
+
"input_metadata": null,
|
156 |
+
"meta": {
|
157 |
+
"inputs": {
|
158 |
+
"rag_graph": {
|
159 |
+
"name": "rag_graph",
|
160 |
+
"position": "left",
|
161 |
+
"type": {
|
162 |
+
"type": "<class 'inspect._empty'>"
|
163 |
+
}
|
164 |
+
}
|
165 |
+
},
|
166 |
+
"name": "LynxScribe RAG Graph Chatbot Builder",
|
167 |
+
"outputs": {
|
168 |
+
"output": {
|
169 |
+
"name": "output",
|
170 |
+
"position": "top",
|
171 |
+
"type": {
|
172 |
+
"type": "None"
|
173 |
+
}
|
174 |
+
}
|
175 |
+
},
|
176 |
+
"params": {
|
177 |
+
"node_types": {
|
178 |
+
"default": "intent_cluster",
|
179 |
+
"name": "node_types",
|
180 |
+
"type": {
|
181 |
+
"type": "<class 'str'>"
|
182 |
+
}
|
183 |
+
},
|
184 |
+
"scenario_file": {
|
185 |
+
"default": "uploads/lynx_chatbot_scenario_selector.yaml",
|
186 |
+
"name": "scenario_file",
|
187 |
+
"type": {
|
188 |
+
"type": "<class 'str'>"
|
189 |
+
}
|
190 |
+
},
|
191 |
+
"scenario_meta_name": {
|
192 |
+
"default": "scenario_name",
|
193 |
+
"name": "scenario_meta_name",
|
194 |
+
"type": {
|
195 |
+
"type": "<class 'str'>"
|
196 |
+
}
|
197 |
+
}
|
198 |
+
},
|
199 |
+
"position": {
|
200 |
+
"x": 1569.0,
|
201 |
+
"y": 528.0
|
202 |
+
},
|
203 |
+
"type": "basic"
|
204 |
+
},
|
205 |
+
"params": {
|
206 |
+
"node_types": "intent_cluster",
|
207 |
+
"scenario_file": "uploads/organon_demo/backend-scenarios-en.yaml",
|
208 |
+
"scenario_meta_name": "scenario_name"
|
209 |
+
},
|
210 |
+
"status": "done",
|
211 |
+
"title": "LynxScribe RAG Graph Chatbot Builder"
|
212 |
+
},
|
213 |
+
"dragHandle": ".bg-primary",
|
214 |
+
"height": 296.0,
|
215 |
+
"id": "LynxScribe RAG Graph Chatbot Builder 1",
|
216 |
+
"position": {
|
217 |
+
"x": -591.0,
|
218 |
+
"y": 86.0
|
219 |
+
},
|
220 |
+
"type": "basic",
|
221 |
+
"width": 547.0
|
222 |
+
},
|
223 |
+
{
|
224 |
+
"data": {
|
225 |
+
"__execution_delay": 0.0,
|
226 |
+
"collapsed": null,
|
227 |
+
"display": null,
|
228 |
+
"error": null,
|
229 |
+
"input_metadata": null,
|
230 |
+
"meta": {
|
231 |
+
"inputs": {
|
232 |
+
"chat_processor": {
|
233 |
+
"name": "chat_processor",
|
234 |
+
"position": "bottom",
|
235 |
+
"type": {
|
236 |
+
"type": "<class 'inspect._empty'>"
|
237 |
+
}
|
238 |
+
},
|
239 |
+
"knowledge_base": {
|
240 |
+
"name": "knowledge_base",
|
241 |
+
"position": "bottom",
|
242 |
+
"type": {
|
243 |
+
"type": "<class 'inspect._empty'>"
|
244 |
+
}
|
245 |
+
}
|
246 |
+
},
|
247 |
+
"name": "LynxScribe RAG Graph Chatbot Backend",
|
248 |
+
"outputs": {
|
249 |
+
"output": {
|
250 |
+
"name": "output",
|
251 |
+
"position": "top",
|
252 |
+
"type": {
|
253 |
+
"type": "None"
|
254 |
+
}
|
255 |
+
}
|
256 |
+
},
|
257 |
+
"params": {
|
258 |
+
"llm_interface": {
|
259 |
+
"default": "openai",
|
260 |
+
"name": "llm_interface",
|
261 |
+
"type": {
|
262 |
+
"type": "<class 'str'>"
|
263 |
+
}
|
264 |
+
},
|
265 |
+
"llm_model_name": {
|
266 |
+
"default": "gpt-4o",
|
267 |
+
"name": "llm_model_name",
|
268 |
+
"type": {
|
269 |
+
"type": "<class 'str'>"
|
270 |
+
}
|
271 |
+
},
|
272 |
+
"negative_answer": {
|
273 |
+
"default": "I'm sorry, but the data I've been trained on does not contain any information related to your question.",
|
274 |
+
"name": "negative_answer",
|
275 |
+
"type": {
|
276 |
+
"type": "<class 'str'>"
|
277 |
+
}
|
278 |
+
},
|
279 |
+
"retriever_limits_by_type": {
|
280 |
+
"default": "{}",
|
281 |
+
"name": "retriever_limits_by_type",
|
282 |
+
"type": {
|
283 |
+
"type": "<class 'str'>"
|
284 |
+
}
|
285 |
+
},
|
286 |
+
"retriever_max_iterations": {
|
287 |
+
"default": 3.0,
|
288 |
+
"name": "retriever_max_iterations",
|
289 |
+
"type": {
|
290 |
+
"type": "<class 'int'>"
|
291 |
+
}
|
292 |
+
},
|
293 |
+
"retriever_overall_chunk_limit": {
|
294 |
+
"default": 20.0,
|
295 |
+
"name": "retriever_overall_chunk_limit",
|
296 |
+
"type": {
|
297 |
+
"type": "<class 'int'>"
|
298 |
+
}
|
299 |
+
},
|
300 |
+
"retriever_overall_token_limit": {
|
301 |
+
"default": 3000.0,
|
302 |
+
"name": "retriever_overall_token_limit",
|
303 |
+
"type": {
|
304 |
+
"type": "<class 'int'>"
|
305 |
+
}
|
306 |
+
},
|
307 |
+
"retriever_strict_limits": {
|
308 |
+
"default": true,
|
309 |
+
"name": "retriever_strict_limits",
|
310 |
+
"type": {
|
311 |
+
"type": "<class 'bool'>"
|
312 |
+
}
|
313 |
+
}
|
314 |
+
},
|
315 |
+
"position": {
|
316 |
+
"x": 1280.0,
|
317 |
+
"y": 450.0
|
318 |
+
},
|
319 |
+
"type": "basic"
|
320 |
+
},
|
321 |
+
"params": {
|
322 |
+
"llm_interface": "openai",
|
323 |
+
"llm_model_name": "gpt-4o",
|
324 |
+
"negative_answer": "I'm sorry, but the data I've been trained on does not contain any information related to your question.",
|
325 |
+
"retriever_limits_by_type": "{\"faq_question\": [0, 0], \"faq_answer\": [3, 3]}",
|
326 |
+
"retriever_max_iterations": "3",
|
327 |
+
"retriever_overall_chunk_limit": "3",
|
328 |
+
"retriever_overall_token_limit": "30000",
|
329 |
+
"retriever_strict_limits": true
|
330 |
+
},
|
331 |
+
"status": "done",
|
332 |
+
"title": "LynxScribe RAG Graph Chatbot Backend"
|
333 |
+
},
|
334 |
+
"dragHandle": ".bg-primary",
|
335 |
+
"height": 382.0,
|
336 |
+
"id": "LynxScribe RAG Graph Chatbot Backend 1",
|
337 |
+
"position": {
|
338 |
+
"x": -427.131476508498,
|
339 |
+
"y": -465.1194966607713
|
340 |
+
},
|
341 |
+
"type": "basic",
|
342 |
+
"width": 791.0
|
343 |
+
},
|
344 |
+
{
|
345 |
+
"data": {
|
346 |
+
"display": null,
|
347 |
+
"error": null,
|
348 |
+
"input_metadata": null,
|
349 |
+
"meta": {
|
350 |
+
"inputs": {
|
351 |
+
"processor": {
|
352 |
+
"name": "processor",
|
353 |
+
"position": "bottom",
|
354 |
+
"type": {
|
355 |
+
"type": "<class 'inspect._empty'>"
|
356 |
+
}
|
357 |
+
}
|
358 |
+
},
|
359 |
+
"name": "Chat processor",
|
360 |
+
"outputs": {
|
361 |
+
"output": {
|
362 |
+
"name": "output",
|
363 |
+
"position": "top",
|
364 |
+
"type": {
|
365 |
+
"type": "None"
|
366 |
+
}
|
367 |
+
}
|
368 |
+
},
|
369 |
+
"params": {},
|
370 |
+
"position": {
|
371 |
+
"x": 1291.0,
|
372 |
+
"y": 718.0
|
373 |
+
},
|
374 |
+
"type": "basic"
|
375 |
+
},
|
376 |
+
"params": {},
|
377 |
+
"status": "done",
|
378 |
+
"title": "Chat processor"
|
379 |
+
},
|
380 |
+
"dragHandle": ".bg-primary",
|
381 |
+
"height": 200.0,
|
382 |
+
"id": "Chat processor 1",
|
383 |
+
"position": {
|
384 |
+
"x": 252.7291107206022,
|
385 |
+
"y": 81.86852349150202
|
386 |
+
},
|
387 |
+
"type": "basic",
|
388 |
+
"width": 200.0
|
389 |
+
},
|
390 |
+
{
|
391 |
+
"data": {
|
392 |
+
"display": null,
|
393 |
+
"error": null,
|
394 |
+
"input_metadata": null,
|
395 |
+
"meta": {
|
396 |
+
"inputs": {},
|
397 |
+
"name": "Truncate history",
|
398 |
+
"outputs": {
|
399 |
+
"output": {
|
400 |
+
"name": "output",
|
401 |
+
"position": "top",
|
402 |
+
"type": {
|
403 |
+
"type": "None"
|
404 |
+
}
|
405 |
+
}
|
406 |
+
},
|
407 |
+
"params": {
|
408 |
+
"max_tokens": {
|
409 |
+
"default": 10000.0,
|
410 |
+
"name": "max_tokens",
|
411 |
+
"type": {
|
412 |
+
"type": "<class 'int'>"
|
413 |
+
}
|
414 |
+
}
|
415 |
+
},
|
416 |
+
"position": {
|
417 |
+
"x": 1440.0,
|
418 |
+
"y": 936.0
|
419 |
+
},
|
420 |
+
"type": "basic"
|
421 |
+
},
|
422 |
+
"params": {
|
423 |
+
"max_tokens": 10000.0
|
424 |
+
},
|
425 |
+
"status": "done",
|
426 |
+
"title": "Truncate history"
|
427 |
+
},
|
428 |
+
"dragHandle": ".bg-primary",
|
429 |
+
"height": 200.0,
|
430 |
+
"id": "Truncate history 1",
|
431 |
+
"position": {
|
432 |
+
"x": 253.59374153502728,
|
433 |
+
"y": 386.4661577036063
|
434 |
+
},
|
435 |
+
"type": "basic",
|
436 |
+
"width": 200.0
|
437 |
+
},
|
438 |
+
{
|
439 |
+
"data": {
|
440 |
+
"__execution_delay": 0.0,
|
441 |
+
"collapsed": null,
|
442 |
+
"display": null,
|
443 |
+
"error": null,
|
444 |
+
"input_metadata": null,
|
445 |
+
"meta": {
|
446 |
+
"inputs": {},
|
447 |
+
"name": "Input chat",
|
448 |
+
"outputs": {
|
449 |
+
"output": {
|
450 |
+
"name": "output",
|
451 |
+
"position": "right",
|
452 |
+
"type": {
|
453 |
+
"type": "None"
|
454 |
+
}
|
455 |
+
}
|
456 |
+
},
|
457 |
+
"params": {
|
458 |
+
"chat": {
|
459 |
+
"default": null,
|
460 |
+
"name": "chat",
|
461 |
+
"type": {
|
462 |
+
"type": "<class 'str'>"
|
463 |
+
}
|
464 |
+
}
|
465 |
+
},
|
466 |
+
"position": {
|
467 |
+
"x": 449.0,
|
468 |
+
"y": 172.0
|
469 |
+
},
|
470 |
+
"type": "basic"
|
471 |
+
},
|
472 |
+
"params": {
|
473 |
+
"chat": "I had headache after taking the pill"
|
474 |
+
},
|
475 |
+
"status": "done",
|
476 |
+
"title": "Input chat"
|
477 |
+
},
|
478 |
+
"dragHandle": ".bg-primary",
|
479 |
+
"height": 204.0,
|
480 |
+
"id": "Input chat 1",
|
481 |
+
"position": {
|
482 |
+
"x": -1115.7774404622555,
|
483 |
+
"y": -747.1320865489535
|
484 |
+
},
|
485 |
+
"type": "basic",
|
486 |
+
"width": 552.0
|
487 |
+
},
|
488 |
+
{
|
489 |
+
"data": {
|
490 |
+
"__execution_delay": 0.0,
|
491 |
+
"collapsed": null,
|
492 |
+
"display": null,
|
493 |
+
"error": null,
|
494 |
+
"input_metadata": null,
|
495 |
+
"meta": {
|
496 |
+
"inputs": {
|
497 |
+
"chat_api": {
|
498 |
+
"name": "chat_api",
|
499 |
+
"position": "bottom",
|
500 |
+
"type": {
|
501 |
+
"type": "<class 'inspect._empty'>"
|
502 |
+
}
|
503 |
+
},
|
504 |
+
"message": {
|
505 |
+
"name": "message",
|
506 |
+
"position": "left",
|
507 |
+
"type": {
|
508 |
+
"type": "<class 'inspect._empty'>"
|
509 |
+
}
|
510 |
+
}
|
511 |
+
},
|
512 |
+
"name": "Test Chat API",
|
513 |
+
"outputs": {
|
514 |
+
"output": {
|
515 |
+
"name": "output",
|
516 |
+
"position": "right",
|
517 |
+
"type": {
|
518 |
+
"type": "None"
|
519 |
+
}
|
520 |
+
}
|
521 |
+
},
|
522 |
+
"params": {
|
523 |
+
"show_details": {
|
524 |
+
"default": false,
|
525 |
+
"name": "show_details",
|
526 |
+
"type": {
|
527 |
+
"type": "<class 'bool'>"
|
528 |
+
}
|
529 |
+
}
|
530 |
+
},
|
531 |
+
"position": {
|
532 |
+
"x": 937.0,
|
533 |
+
"y": 213.0
|
534 |
+
},
|
535 |
+
"type": "basic"
|
536 |
+
},
|
537 |
+
"params": {
|
538 |
+
"show_details": false
|
539 |
+
},
|
540 |
+
"status": "done",
|
541 |
+
"title": "Test Chat API"
|
542 |
+
},
|
543 |
+
"dragHandle": ".bg-primary",
|
544 |
+
"height": 200.0,
|
545 |
+
"id": "Test Chat API 1",
|
546 |
+
"position": {
|
547 |
+
"x": -131.54900620226195,
|
548 |
+
"y": -745.4660726292032
|
549 |
+
},
|
550 |
+
"type": "basic",
|
551 |
+
"width": 200.0
|
552 |
+
},
|
553 |
+
{
|
554 |
+
"data": {
|
555 |
+
"display": {
|
556 |
+
"dataframes": {
|
557 |
+
"df": {
|
558 |
+
"columns": [
|
559 |
+
"answer"
|
560 |
+
],
|
561 |
+
"data": [
|
562 |
+
[
|
563 |
+
"I'm not equipped to handle adverse events or other product-related queries. Your safety is important to us, and we want to ensure you receive the appropriate support. Please report any adverse events or concerns to our dedicated support team. They can be reached at [email protected]. If you have any questions related to contraceptives or women's health, please feel free to ask, and I'll provide you with the information you need.\n"
|
564 |
+
]
|
565 |
+
]
|
566 |
+
}
|
567 |
+
}
|
568 |
+
},
|
569 |
+
"error": null,
|
570 |
+
"input_metadata": null,
|
571 |
+
"meta": {
|
572 |
+
"inputs": {
|
573 |
+
"input": {
|
574 |
+
"name": "input",
|
575 |
+
"position": "left",
|
576 |
+
"type": {
|
577 |
+
"type": "<class 'inspect._empty'>"
|
578 |
+
}
|
579 |
+
}
|
580 |
+
},
|
581 |
+
"name": "View",
|
582 |
+
"outputs": {},
|
583 |
+
"params": {},
|
584 |
+
"position": {
|
585 |
+
"x": 1547.0,
|
586 |
+
"y": 222.0
|
587 |
+
},
|
588 |
+
"type": "table_view"
|
589 |
+
},
|
590 |
+
"params": {},
|
591 |
+
"status": "done",
|
592 |
+
"title": "View"
|
593 |
+
},
|
594 |
+
"dragHandle": ".bg-primary",
|
595 |
+
"height": 483.0,
|
596 |
+
"id": "View 1",
|
597 |
+
"position": {
|
598 |
+
"x": 540.6544350347407,
|
599 |
+
"y": -886.065865503576
|
600 |
+
},
|
601 |
+
"type": "table_view",
|
602 |
+
"width": 707.0
|
603 |
+
}
|
604 |
+
]
|
605 |
+
}
|
examples/LynxScribe RAG Chatbot.lynxkite.json
CHANGED
@@ -7,20 +7,6 @@
|
|
7 |
"target": "LynxScribe Text RAG Loader 1",
|
8 |
"targetHandle": "file_urls"
|
9 |
},
|
10 |
-
{
|
11 |
-
"id": "LynxScribe Text RAG Loader 1 LynxScribe RAG Graph Chatbot Builder 1",
|
12 |
-
"source": "LynxScribe Text RAG Loader 1",
|
13 |
-
"sourceHandle": "output",
|
14 |
-
"target": "LynxScribe RAG Graph Chatbot Builder 1",
|
15 |
-
"targetHandle": "rag_graph"
|
16 |
-
},
|
17 |
-
{
|
18 |
-
"id": "LynxScribe RAG Graph Chatbot Builder 1 LynxScribe RAG Graph Chatbot Backend 1",
|
19 |
-
"source": "LynxScribe RAG Graph Chatbot Builder 1",
|
20 |
-
"sourceHandle": "output",
|
21 |
-
"target": "LynxScribe RAG Graph Chatbot Backend 1",
|
22 |
-
"targetHandle": "knowledge_base"
|
23 |
-
},
|
24 |
{
|
25 |
"id": "Truncate history 1 Chat processor 1",
|
26 |
"source": "Truncate history 1",
|
@@ -62,6 +48,20 @@
|
|
62 |
"sourceHandle": "output",
|
63 |
"target": "View 1",
|
64 |
"targetHandle": "input"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
65 |
}
|
66 |
],
|
67 |
"env": "LynxScribe",
|
@@ -112,10 +112,6 @@
|
|
112 |
}
|
113 |
}
|
114 |
},
|
115 |
-
"position": {
|
116 |
-
"x": 530.0,
|
117 |
-
"y": 350.0
|
118 |
-
},
|
119 |
"type": "basic"
|
120 |
},
|
121 |
"params": {
|
@@ -210,10 +206,6 @@
|
|
210 |
}
|
211 |
}
|
212 |
},
|
213 |
-
"position": {
|
214 |
-
"x": 1048.0,
|
215 |
-
"y": 762.0
|
216 |
-
},
|
217 |
"type": "basic"
|
218 |
},
|
219 |
"params": {
|
@@ -237,70 +229,6 @@
|
|
237 |
"type": "basic",
|
238 |
"width": 290.0
|
239 |
},
|
240 |
-
{
|
241 |
-
"data": {
|
242 |
-
"display": null,
|
243 |
-
"error": null,
|
244 |
-
"input_metadata": null,
|
245 |
-
"meta": {
|
246 |
-
"inputs": {
|
247 |
-
"rag_graph": {
|
248 |
-
"name": "rag_graph",
|
249 |
-
"position": "left",
|
250 |
-
"type": {
|
251 |
-
"type": "<class 'inspect._empty'>"
|
252 |
-
}
|
253 |
-
}
|
254 |
-
},
|
255 |
-
"name": "LynxScribe RAG Graph Chatbot Builder",
|
256 |
-
"outputs": {
|
257 |
-
"output": {
|
258 |
-
"name": "output",
|
259 |
-
"position": "top",
|
260 |
-
"type": {
|
261 |
-
"type": "None"
|
262 |
-
}
|
263 |
-
}
|
264 |
-
},
|
265 |
-
"params": {
|
266 |
-
"node_types": {
|
267 |
-
"default": "intent_cluster",
|
268 |
-
"name": "node_types",
|
269 |
-
"type": {
|
270 |
-
"type": "<class 'str'>"
|
271 |
-
}
|
272 |
-
},
|
273 |
-
"scenario_file": {
|
274 |
-
"default": "uploads/lynx_chatbot_scenario_selector.yaml",
|
275 |
-
"name": "scenario_file",
|
276 |
-
"type": {
|
277 |
-
"type": "<class 'str'>"
|
278 |
-
}
|
279 |
-
}
|
280 |
-
},
|
281 |
-
"position": {
|
282 |
-
"x": 1451.0,
|
283 |
-
"y": 752.0
|
284 |
-
},
|
285 |
-
"type": "basic"
|
286 |
-
},
|
287 |
-
"params": {
|
288 |
-
"node_types": "intent_cluster",
|
289 |
-
"scenario_file": "uploads/lynx_chatbot_scenario_selector.yaml"
|
290 |
-
},
|
291 |
-
"status": "done",
|
292 |
-
"title": "LynxScribe RAG Graph Chatbot Builder"
|
293 |
-
},
|
294 |
-
"dragHandle": ".bg-primary",
|
295 |
-
"height": 208.0,
|
296 |
-
"id": "LynxScribe RAG Graph Chatbot Builder 1",
|
297 |
-
"position": {
|
298 |
-
"x": 245.0,
|
299 |
-
"y": 421.0
|
300 |
-
},
|
301 |
-
"type": "basic",
|
302 |
-
"width": 407.0
|
303 |
-
},
|
304 |
{
|
305 |
"data": {
|
306 |
"__execution_delay": 0.0,
|
@@ -393,10 +321,6 @@
|
|
393 |
}
|
394 |
}
|
395 |
},
|
396 |
-
"position": {
|
397 |
-
"x": 1658.0,
|
398 |
-
"y": 587.0
|
399 |
-
},
|
400 |
"type": "basic"
|
401 |
},
|
402 |
"params": {
|
@@ -404,7 +328,7 @@
|
|
404 |
"llm_model_name": "gpt-4o",
|
405 |
"negative_answer": "I'm sorry, but the data I've been trained on does not contain any information related to your question.",
|
406 |
"retriever_limits_by_type": "{\"information\": [1, 5], \"summary\": [0, 2], \"template_qna\": [1, 3], \"QnA question\": [0, 0]}",
|
407 |
-
"retriever_max_iterations": 3
|
408 |
"retriever_overall_chunk_limit": 20.0,
|
409 |
"retriever_overall_token_limit": 3000.0,
|
410 |
"retriever_strict_limits": true
|
@@ -448,10 +372,6 @@
|
|
448 |
}
|
449 |
},
|
450 |
"params": {},
|
451 |
-
"position": {
|
452 |
-
"x": 1742.0,
|
453 |
-
"y": 847.0
|
454 |
-
},
|
455 |
"type": "basic"
|
456 |
},
|
457 |
"params": {},
|
@@ -462,8 +382,8 @@
|
|
462 |
"height": 220.0,
|
463 |
"id": "Chat processor 1",
|
464 |
"position": {
|
465 |
-
"x":
|
466 |
-
"y":
|
467 |
},
|
468 |
"type": "basic",
|
469 |
"width": 387.0
|
@@ -494,10 +414,6 @@
|
|
494 |
}
|
495 |
}
|
496 |
},
|
497 |
-
"position": {
|
498 |
-
"x": 1991.0,
|
499 |
-
"y": 1042.0
|
500 |
-
},
|
501 |
"type": "basic"
|
502 |
},
|
503 |
"params": {
|
@@ -565,10 +481,6 @@
|
|
565 |
}
|
566 |
}
|
567 |
},
|
568 |
-
"position": {
|
569 |
-
"x": 2003.0,
|
570 |
-
"y": 1053.0
|
571 |
-
},
|
572 |
"type": "basic"
|
573 |
},
|
574 |
"params": {
|
@@ -618,10 +530,6 @@
|
|
618 |
}
|
619 |
}
|
620 |
},
|
621 |
-
"position": {
|
622 |
-
"x": 2012.0,
|
623 |
-
"y": 475.0
|
624 |
-
},
|
625 |
"type": "basic"
|
626 |
},
|
627 |
"params": {
|
@@ -683,10 +591,6 @@
|
|
683 |
}
|
684 |
}
|
685 |
},
|
686 |
-
"position": {
|
687 |
-
"x": 1238.0,
|
688 |
-
"y": 211.0
|
689 |
-
},
|
690 |
"type": "basic"
|
691 |
},
|
692 |
"params": {
|
@@ -715,7 +619,7 @@
|
|
715 |
],
|
716 |
"data": [
|
717 |
[
|
718 |
-
"The CEO of Lynx Analytics is Gyorgy Lajtai. He co-
|
719 |
]
|
720 |
]
|
721 |
}
|
@@ -736,10 +640,6 @@
|
|
736 |
"name": "View",
|
737 |
"outputs": {},
|
738 |
"params": {},
|
739 |
-
"position": {
|
740 |
-
"x": 1746.0,
|
741 |
-
"y": 232.0
|
742 |
-
},
|
743 |
"type": "table_view"
|
744 |
},
|
745 |
"params": {},
|
@@ -755,6 +655,80 @@
|
|
755 |
},
|
756 |
"type": "table_view",
|
757 |
"width": 995.0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
758 |
}
|
759 |
]
|
760 |
}
|
|
|
7 |
"target": "LynxScribe Text RAG Loader 1",
|
8 |
"targetHandle": "file_urls"
|
9 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
{
|
11 |
"id": "Truncate history 1 Chat processor 1",
|
12 |
"source": "Truncate history 1",
|
|
|
48 |
"sourceHandle": "output",
|
49 |
"target": "View 1",
|
50 |
"targetHandle": "input"
|
51 |
+
},
|
52 |
+
{
|
53 |
+
"id": "LynxScribe Text RAG Loader 1 LynxScribe RAG Graph Chatbot Builder 1",
|
54 |
+
"source": "LynxScribe Text RAG Loader 1",
|
55 |
+
"sourceHandle": "output",
|
56 |
+
"target": "LynxScribe RAG Graph Chatbot Builder 1",
|
57 |
+
"targetHandle": "rag_graph"
|
58 |
+
},
|
59 |
+
{
|
60 |
+
"id": "LynxScribe RAG Graph Chatbot Builder 1 LynxScribe RAG Graph Chatbot Backend 1",
|
61 |
+
"source": "LynxScribe RAG Graph Chatbot Builder 1",
|
62 |
+
"sourceHandle": "output",
|
63 |
+
"target": "LynxScribe RAG Graph Chatbot Backend 1",
|
64 |
+
"targetHandle": "knowledge_base"
|
65 |
}
|
66 |
],
|
67 |
"env": "LynxScribe",
|
|
|
112 |
}
|
113 |
}
|
114 |
},
|
|
|
|
|
|
|
|
|
115 |
"type": "basic"
|
116 |
},
|
117 |
"params": {
|
|
|
206 |
}
|
207 |
}
|
208 |
},
|
|
|
|
|
|
|
|
|
209 |
"type": "basic"
|
210 |
},
|
211 |
"params": {
|
|
|
229 |
"type": "basic",
|
230 |
"width": 290.0
|
231 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
232 |
{
|
233 |
"data": {
|
234 |
"__execution_delay": 0.0,
|
|
|
321 |
}
|
322 |
}
|
323 |
},
|
|
|
|
|
|
|
|
|
324 |
"type": "basic"
|
325 |
},
|
326 |
"params": {
|
|
|
328 |
"llm_model_name": "gpt-4o",
|
329 |
"negative_answer": "I'm sorry, but the data I've been trained on does not contain any information related to your question.",
|
330 |
"retriever_limits_by_type": "{\"information\": [1, 5], \"summary\": [0, 2], \"template_qna\": [1, 3], \"QnA question\": [0, 0]}",
|
331 |
+
"retriever_max_iterations": "3",
|
332 |
"retriever_overall_chunk_limit": 20.0,
|
333 |
"retriever_overall_token_limit": 3000.0,
|
334 |
"retriever_strict_limits": true
|
|
|
372 |
}
|
373 |
},
|
374 |
"params": {},
|
|
|
|
|
|
|
|
|
375 |
"type": "basic"
|
376 |
},
|
377 |
"params": {},
|
|
|
382 |
"height": 220.0,
|
383 |
"id": "Chat processor 1",
|
384 |
"position": {
|
385 |
+
"x": 907.3546850533578,
|
386 |
+
"y": 381.09754180073975
|
387 |
},
|
388 |
"type": "basic",
|
389 |
"width": 387.0
|
|
|
414 |
}
|
415 |
}
|
416 |
},
|
|
|
|
|
|
|
|
|
417 |
"type": "basic"
|
418 |
},
|
419 |
"params": {
|
|
|
481 |
}
|
482 |
}
|
483 |
},
|
|
|
|
|
|
|
|
|
484 |
"type": "basic"
|
485 |
},
|
486 |
"params": {
|
|
|
530 |
}
|
531 |
}
|
532 |
},
|
|
|
|
|
|
|
|
|
533 |
"type": "basic"
|
534 |
},
|
535 |
"params": {
|
|
|
591 |
}
|
592 |
}
|
593 |
},
|
|
|
|
|
|
|
|
|
594 |
"type": "basic"
|
595 |
},
|
596 |
"params": {
|
|
|
619 |
],
|
620 |
"data": [
|
621 |
[
|
622 |
+
"The CEO of Lynx Analytics is Gyorgy Lajtai. He is also a co-founder of the company and has a rich background in CRM, marketing automation, and systems."
|
623 |
]
|
624 |
]
|
625 |
}
|
|
|
640 |
"name": "View",
|
641 |
"outputs": {},
|
642 |
"params": {},
|
|
|
|
|
|
|
|
|
643 |
"type": "table_view"
|
644 |
},
|
645 |
"params": {},
|
|
|
655 |
},
|
656 |
"type": "table_view",
|
657 |
"width": 995.0
|
658 |
+
},
|
659 |
+
{
|
660 |
+
"data": {
|
661 |
+
"__execution_delay": 0.0,
|
662 |
+
"collapsed": null,
|
663 |
+
"display": null,
|
664 |
+
"error": null,
|
665 |
+
"input_metadata": null,
|
666 |
+
"meta": {
|
667 |
+
"inputs": {
|
668 |
+
"rag_graph": {
|
669 |
+
"name": "rag_graph",
|
670 |
+
"position": "left",
|
671 |
+
"type": {
|
672 |
+
"type": "<class 'inspect._empty'>"
|
673 |
+
}
|
674 |
+
}
|
675 |
+
},
|
676 |
+
"name": "LynxScribe RAG Graph Chatbot Builder",
|
677 |
+
"outputs": {
|
678 |
+
"output": {
|
679 |
+
"name": "output",
|
680 |
+
"position": "top",
|
681 |
+
"type": {
|
682 |
+
"type": "None"
|
683 |
+
}
|
684 |
+
}
|
685 |
+
},
|
686 |
+
"params": {
|
687 |
+
"node_types": {
|
688 |
+
"default": "intent_cluster",
|
689 |
+
"name": "node_types",
|
690 |
+
"type": {
|
691 |
+
"type": "<class 'str'>"
|
692 |
+
}
|
693 |
+
},
|
694 |
+
"scenario_file": {
|
695 |
+
"default": "uploads/lynx_chatbot_scenario_selector.yaml",
|
696 |
+
"name": "scenario_file",
|
697 |
+
"type": {
|
698 |
+
"type": "<class 'str'>"
|
699 |
+
}
|
700 |
+
},
|
701 |
+
"scenario_meta_name": {
|
702 |
+
"default": "scenario_name",
|
703 |
+
"name": "scenario_meta_name",
|
704 |
+
"type": {
|
705 |
+
"type": "<class 'str'>"
|
706 |
+
}
|
707 |
+
}
|
708 |
+
},
|
709 |
+
"position": {
|
710 |
+
"x": 1121.0,
|
711 |
+
"y": 813.0
|
712 |
+
},
|
713 |
+
"type": "basic"
|
714 |
+
},
|
715 |
+
"params": {
|
716 |
+
"node_types": "intent_cluster",
|
717 |
+
"scenario_file": "uploads/lynx_chatbot_scenario_selector.yaml",
|
718 |
+
"scenario_meta_name": ""
|
719 |
+
},
|
720 |
+
"status": "done",
|
721 |
+
"title": "LynxScribe RAG Graph Chatbot Builder"
|
722 |
+
},
|
723 |
+
"dragHandle": ".bg-primary",
|
724 |
+
"height": 297.0,
|
725 |
+
"id": "LynxScribe RAG Graph Chatbot Builder 1",
|
726 |
+
"position": {
|
727 |
+
"x": 328.41755532473496,
|
728 |
+
"y": 378.2277574498554
|
729 |
+
},
|
730 |
+
"type": "basic",
|
731 |
+
"width": 396.0
|
732 |
}
|
733 |
]
|
734 |
}
|
lynxkite-lynxscribe/src/lynxkite_lynxscribe/lynxscribe_ops.py
CHANGED
@@ -9,6 +9,7 @@ from enum import Enum
|
|
9 |
import asyncio
|
10 |
import pandas as pd
|
11 |
import joblib
|
|
|
12 |
|
13 |
import pathlib
|
14 |
from lynxscribe.core.llm.base import get_llm_engine
|
@@ -16,6 +17,7 @@ from lynxscribe.core.vector_store.base import get_vector_store
|
|
16 |
from lynxscribe.common.config import load_config
|
17 |
from lynxscribe.components.text.embedder import TextEmbedder
|
18 |
from lynxscribe.core.models.embedding import Embedding
|
|
|
19 |
|
20 |
from lynxscribe.components.rag.rag_graph import RAGGraph
|
21 |
from lynxscribe.components.rag.knowledge_base_graph import PandasKnowledgeBaseGraph
|
@@ -27,6 +29,7 @@ from lynxscribe.components.chat.processors import (
|
|
27 |
)
|
28 |
from lynxscribe.components.chat.api import ChatAPI
|
29 |
from lynxscribe.core.models.prompts import ChatCompletionPrompt
|
|
|
30 |
|
31 |
from lynxkite.core import ops
|
32 |
import json
|
@@ -53,6 +56,60 @@ class RAGVersion(Enum):
|
|
53 |
V2 = "v2"
|
54 |
|
55 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
56 |
@op("Cloud-sourced File Listing")
|
57 |
def cloud_file_loader(
|
58 |
*,
|
@@ -397,14 +454,102 @@ def ls_text_rag_loader(
|
|
397 |
return {"rag_graph": rag_graph}
|
398 |
|
399 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
400 |
@output_on_top
|
401 |
@op("LynxScribe RAG Graph Chatbot Builder")
|
402 |
-
@mem.cache
|
403 |
def ls_rag_chatbot_builder(
|
404 |
rag_graph,
|
405 |
*,
|
406 |
scenario_file: str = "uploads/lynx_chatbot_scenario_selector.yaml",
|
407 |
node_types: str = "intent_cluster",
|
|
|
408 |
):
|
409 |
"""
|
410 |
Builds up a RAG Graph-based chatbot (basically the loaded RAG graph +
|
@@ -422,11 +567,15 @@ def ls_rag_chatbot_builder(
|
|
422 |
# rag_graph = rag_graph[0]["rag_graph"] TODO: check why is it bad
|
423 |
rag_graph = rag_graph["rag_graph"]
|
424 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
425 |
# loading the scenarios
|
426 |
-
scenario_selector = ScenarioSelector(
|
427 |
-
scenarios=[Scenario(**scenario) for scenario in scenarios],
|
428 |
-
node_types=node_types,
|
429 |
-
)
|
430 |
|
431 |
# TODO: later we should unify this "knowledge base" object across the functions
|
432 |
# this could be always an input of a RAG Chatbot, but also for other apps.
|
@@ -554,7 +703,12 @@ async def test_chat_api(message, chat_api, *, show_details=False):
|
|
554 |
messages=[{"role": "user", "content": message["text"]}],
|
555 |
)
|
556 |
response = await chat_api.answer(request, stream=False)
|
557 |
-
|
|
|
|
|
|
|
|
|
|
|
558 |
if show_details:
|
559 |
return {"answer": answer, **response.__dict__}
|
560 |
else:
|
|
|
9 |
import asyncio
|
10 |
import pandas as pd
|
11 |
import joblib
|
12 |
+
from pydantic import BaseModel, ConfigDict
|
13 |
|
14 |
import pathlib
|
15 |
from lynxscribe.core.llm.base import get_llm_engine
|
|
|
17 |
from lynxscribe.common.config import load_config
|
18 |
from lynxscribe.components.text.embedder import TextEmbedder
|
19 |
from lynxscribe.core.models.embedding import Embedding
|
20 |
+
from lynxscribe.components.embedding_clustering import FclusterBasedClustering
|
21 |
|
22 |
from lynxscribe.components.rag.rag_graph import RAGGraph
|
23 |
from lynxscribe.components.rag.knowledge_base_graph import PandasKnowledgeBaseGraph
|
|
|
29 |
)
|
30 |
from lynxscribe.components.chat.api import ChatAPI
|
31 |
from lynxscribe.core.models.prompts import ChatCompletionPrompt
|
32 |
+
from lynxscribe.components.rag.loaders import FAQTemplateLoader
|
33 |
|
34 |
from lynxkite.core import ops
|
35 |
import json
|
|
|
56 |
V2 = "v2"
|
57 |
|
58 |
|
59 |
+
class RAGTemplate(BaseModel):
|
60 |
+
"""
|
61 |
+
Model for RAG templates consisting of three tables: they are connected via scenario names.
|
62 |
+
One table (FAQs) contains scenario-denoted nodes to upsert into the knowledge base, the other
|
63 |
+
two tables serve as the configuration for the scenario selector.
|
64 |
+
Attributes:
|
65 |
+
faq_data:
|
66 |
+
Table where each row is an FAQ question, and possibly its answer pair. Will be fed into
|
67 |
+
`FAQTemplateLoader.load_nodes_and_edges()`. For configuration of this table see the
|
68 |
+
loader's init arguments.
|
69 |
+
scenario_data:
|
70 |
+
Table where each row is a Scenario, column names are thus scenario attributes. Will be
|
71 |
+
fed into `ScenarioSelector.from_data()`.
|
72 |
+
prompt_codes:
|
73 |
+
Optional helper for the scenario table, may contain prompt code mappings to real prompt
|
74 |
+
messages. It's enough then to use the codes instead of the full messages in the
|
75 |
+
scenarios table. Will be fed into `ScenarioSelector.from_data()`.
|
76 |
+
"""
|
77 |
+
|
78 |
+
model_config = ConfigDict(arbitrary_types_allowed=True)
|
79 |
+
|
80 |
+
faq_data: pd.DataFrame
|
81 |
+
scenario_data: pd.DataFrame
|
82 |
+
prompt_codes: dict[str, str] = {}
|
83 |
+
|
84 |
+
@classmethod
|
85 |
+
def from_excel_path(
|
86 |
+
cls,
|
87 |
+
path: str,
|
88 |
+
faq_data_sheet_name: str,
|
89 |
+
scenario_data_sheet_name: str,
|
90 |
+
prompt_codes_sheet_name: str | None = None,
|
91 |
+
) -> "RAGTemplate":
|
92 |
+
"""Spawn a from an Excel file containing the two needed (plus one optional) sheets."""
|
93 |
+
|
94 |
+
def transform_codes(prompt_codes: pd.DataFrame) -> dict[str, str]:
|
95 |
+
"""Check and transform prompt codes table into a code dictionary."""
|
96 |
+
if (len_columns := len(prompt_codes.columns)) != 2:
|
97 |
+
raise ValueError(
|
98 |
+
f"Prompt codes should contain exactly 2 columns, {len_columns} found."
|
99 |
+
)
|
100 |
+
return prompt_codes.set_index(prompt_codes.columns[0])[
|
101 |
+
prompt_codes.columns[1]
|
102 |
+
].to_dict()
|
103 |
+
|
104 |
+
return cls(
|
105 |
+
faq_data=pd.read_excel(path, sheet_name=faq_data_sheet_name),
|
106 |
+
scenario_data=pd.read_excel(path, sheet_name=scenario_data_sheet_name),
|
107 |
+
prompt_codes=transform_codes(pd.read_excel(path, sheet_name=prompt_codes_sheet_name))
|
108 |
+
if prompt_codes_sheet_name
|
109 |
+
else {},
|
110 |
+
)
|
111 |
+
|
112 |
+
|
113 |
@op("Cloud-sourced File Listing")
|
114 |
def cloud_file_loader(
|
115 |
*,
|
|
|
454 |
return {"rag_graph": rag_graph}
|
455 |
|
456 |
|
457 |
+
@op("LynxScribe FAQ to RAG")
|
458 |
+
@mem.cache
|
459 |
+
async def ls_faq_to_rag(
|
460 |
+
*,
|
461 |
+
faq_excel_path: str = "uploads/organon_demo/organon_en_copy.xlsx",
|
462 |
+
vdb_provider_name: str = "faiss",
|
463 |
+
vdb_num_dimensions: int = 3072,
|
464 |
+
vdb_collection_name: str = "lynx",
|
465 |
+
text_embedder_interface: str = "openai",
|
466 |
+
text_embedder_model_name_or_path: str = "text-embedding-3-large",
|
467 |
+
scenario_cluster_distance_pct: int = 30,
|
468 |
+
):
|
469 |
+
"""
|
470 |
+
Loading a text-based RAG graph from saved files (getting pandas readable links).
|
471 |
+
"""
|
472 |
+
|
473 |
+
# getting the text embedder instance
|
474 |
+
llm_params = {"name": text_embedder_interface}
|
475 |
+
llm = get_llm_engine(**llm_params)
|
476 |
+
text_embedder = TextEmbedder(llm=llm, model=text_embedder_model_name_or_path)
|
477 |
+
|
478 |
+
# getting the vector store
|
479 |
+
if vdb_provider_name == "chromadb":
|
480 |
+
vector_store = get_vector_store(name=vdb_provider_name, collection_name=vdb_collection_name)
|
481 |
+
elif vdb_provider_name == "faiss":
|
482 |
+
vector_store = get_vector_store(name=vdb_provider_name, num_dimensions=vdb_num_dimensions)
|
483 |
+
else:
|
484 |
+
raise ValueError(f"Vector store name '{vdb_provider_name}' is not supported.")
|
485 |
+
|
486 |
+
# building up the RAG graph
|
487 |
+
rag_graph = RAGGraph(
|
488 |
+
PandasKnowledgeBaseGraph(vector_store=vector_store, text_embedder=text_embedder)
|
489 |
+
)
|
490 |
+
|
491 |
+
# loading the knowledge base from the FAQ file
|
492 |
+
rag_template = RAGTemplate.from_excel_path(
|
493 |
+
path=faq_excel_path,
|
494 |
+
faq_data_sheet_name="scenario_examples",
|
495 |
+
scenario_data_sheet_name="scenario_scripts",
|
496 |
+
prompt_codes_sheet_name="prompt_dictionary",
|
497 |
+
)
|
498 |
+
|
499 |
+
faq_loader_params = {
|
500 |
+
"id_column": "scenario_example_ID",
|
501 |
+
"timestamp_column": "last_modified_timestamp",
|
502 |
+
"validity_column": "valid_flg",
|
503 |
+
"question_type_contents_id": ["faq_question", "faq_question", "q_{id}"],
|
504 |
+
"answer_type_contents_id": ["faq_answer", "{faq_question}\n\n{faq_answer}", "a_{id}"],
|
505 |
+
"question_to_answer_edge_type_weight": ["qna", 1.0],
|
506 |
+
}
|
507 |
+
|
508 |
+
nodes, edges = FAQTemplateLoader(**faq_loader_params).load_nodes_and_edges(
|
509 |
+
rag_template.faq_data
|
510 |
+
)
|
511 |
+
|
512 |
+
await rag_graph.kg_base.upsert_nodes(*nodes)
|
513 |
+
rag_graph.kg_base.upsert_edges(edges)
|
514 |
+
|
515 |
+
# Generating scenario clusters
|
516 |
+
question_ids = [_id for _id in nodes[0] if _id.startswith("q_")]
|
517 |
+
stored_embeddings = rag_graph.kg_base.vector_store.get(
|
518 |
+
question_ids, include=["embeddings", "metadatas"]
|
519 |
+
)
|
520 |
+
embedding_vals = pd.Series([_emb.value for _emb in stored_embeddings], index=question_ids)
|
521 |
+
labels = pd.Series(
|
522 |
+
[_emb.metadata["scenario_name"] for _emb in stored_embeddings], index=question_ids
|
523 |
+
)
|
524 |
+
temp_cls = FclusterBasedClustering(distance_percentile=scenario_cluster_distance_pct)
|
525 |
+
temp_cls.fit(embedding_vals, labels)
|
526 |
+
df_tempclusters = temp_cls.get_cluster_centers()
|
527 |
+
|
528 |
+
# Adding the scenario clusters to the RAG Graph
|
529 |
+
df_tempclusters["template_id"] = "t_" + df_tempclusters.index.astype(str)
|
530 |
+
df_tempclusters["embedding"] = df_tempclusters.apply(
|
531 |
+
lambda row: Embedding(
|
532 |
+
id=row["template_id"],
|
533 |
+
value=row["cluster_center"],
|
534 |
+
metadata={"scenario_name": row["control_label"], "type": "intent_cluster"},
|
535 |
+
),
|
536 |
+
axis=1,
|
537 |
+
)
|
538 |
+
embedding_list = df_tempclusters["embedding"].tolist()
|
539 |
+
rag_graph.kg_base.vector_store.upsert(embedding_list)
|
540 |
+
|
541 |
+
return {"rag_graph": rag_graph}
|
542 |
+
|
543 |
+
|
544 |
@output_on_top
|
545 |
@op("LynxScribe RAG Graph Chatbot Builder")
|
546 |
+
# @mem.cache
|
547 |
def ls_rag_chatbot_builder(
|
548 |
rag_graph,
|
549 |
*,
|
550 |
scenario_file: str = "uploads/lynx_chatbot_scenario_selector.yaml",
|
551 |
node_types: str = "intent_cluster",
|
552 |
+
scenario_meta_name: str = "",
|
553 |
):
|
554 |
"""
|
555 |
Builds up a RAG Graph-based chatbot (basically the loaded RAG graph +
|
|
|
567 |
# rag_graph = rag_graph[0]["rag_graph"] TODO: check why is it bad
|
568 |
rag_graph = rag_graph["rag_graph"]
|
569 |
|
570 |
+
parameters = {
|
571 |
+
"scenarios": [Scenario(**scenario) for scenario in scenarios],
|
572 |
+
"node_types": node_types,
|
573 |
+
}
|
574 |
+
if len(scenario_meta_name) > 0:
|
575 |
+
parameters["get_scenario_name"] = lambda node: node.metadata[scenario_meta_name]
|
576 |
+
|
577 |
# loading the scenarios
|
578 |
+
scenario_selector = ScenarioSelector(**parameters)
|
|
|
|
|
|
|
579 |
|
580 |
# TODO: later we should unify this "knowledge base" object across the functions
|
581 |
# this could be always an input of a RAG Chatbot, but also for other apps.
|
|
|
703 |
messages=[{"role": "user", "content": message["text"]}],
|
704 |
)
|
705 |
response = await chat_api.answer(request, stream=False)
|
706 |
+
if len(response.choices) == 0:
|
707 |
+
answer = "The following FAQ items are similar to the question:\n"
|
708 |
+
for item in response.sources:
|
709 |
+
answer += f"------------------------------------------------------ \n{item.body}\n\n"
|
710 |
+
else:
|
711 |
+
answer = response.choices[0].message.content
|
712 |
if show_details:
|
713 |
return {"answer": answer, **response.__dict__}
|
714 |
else:
|