Nelly-43 commited on
Commit
c99694c
·
1 Parent(s): d113d61

Add committment to value chain analysis

Browse files
Files changed (3) hide show
  1. app_web.py +1 -1
  2. src/prompts.py +52 -44
  3. src/query_engine.py +169 -1
app_web.py CHANGED
@@ -7,7 +7,7 @@ import streamlit as st
7
  from src.config_loader import load_config, get_api_key
8
  from src.ingest import get_chroma_collection, ingest_documents
9
  from src.kb_meta import load_kb_meta_brief
10
- from src.query_engine import understand_query, categorize_query, init_query
11
  from src.retriever import clear_collection_cache, retrieve
12
  from src.verifier import verify_and_respond
13
  from src.llm import list_models
 
7
  from src.config_loader import load_config, get_api_key
8
  from src.ingest import get_chroma_collection, ingest_documents
9
  from src.kb_meta import load_kb_meta_brief
10
+ from src.query_engine import understand_query, categorize_query, init_query, analyze_committment_to_vc
11
  from src.retriever import clear_collection_cache, retrieve
12
  from src.verifier import verify_and_respond
13
  from src.llm import list_models
src/prompts.py CHANGED
@@ -315,10 +315,9 @@ Search for budget allocations, expenditure allocations, projects, programs, or p
315
 
316
  Identify:
317
 
318
- A. Budget allocation during FY2020/2021 (or nearest baseline year)
319
 
320
- B. Budget allocation during FY2025/2026
321
- (or most recent available year)
322
 
323
  Extract:
324
 
@@ -335,29 +334,32 @@ If multiple values are found, report all candidate values and explain difference
335
 
336
  STEP 2: STRATEGIC COMMITMENT
337
 
338
- Across all supplied policy documents determine:
 
 
 
339
 
340
  1. Total number of documents examined
341
 
342
  2. Number of documents where the value chain is discussed
343
 
344
- 3. Whether the value chain is discussed in:
345
 
346
- a) Most recent National Development Plan
 
347
 
348
- b) Most recent Agricultural Development Strategy,
349
- Agricultural Sector Plan, Agricultural
350
- Transformation Strategy, or equivalent
351
 
352
- c) Standalone value chain strategy
353
 
354
- d) Flagship value chain project
 
355
 
356
  For each item provide:
357
 
358
- - YES
359
- - NO
360
- - NOT_FOUND
361
 
362
  and supporting evidence.
363
 
@@ -390,9 +392,8 @@ C. Dedicated ministry department,
390
 
391
  Return:
392
 
393
- YES
394
- NO
395
- NOT_FOUND
396
 
397
  for each category.
398
 
@@ -413,15 +414,20 @@ Coverage Weight Formula:
413
  documents_discussing_value_chain /
414
  documents_examined
415
 
 
 
 
 
 
416
  --------------------------------------------------------
417
 
418
  OUTPUT FORMAT
419
  --------------------------------------------------------
420
 
421
- {
422
  "value_chain": "",
423
 
424
- "financial_commitment": {
425
  "budget_start_year": "",
426
  "budget_start_value": "",
427
  "budget_end_year": "",
@@ -429,66 +435,68 @@ OUTPUT FORMAT
429
  "currency": "",
430
  "responsible_institution": "",
431
  "evidence": [
432
- {
433
  "quote": "",
434
  "source_document": "",
435
  "page_or_section": ""
436
- }
437
  ]
438
- },
439
 
440
- "strategic_commitment": {
441
  "documents_examined": 0,
442
  "documents_discussing_value_chain": 0,
443
  "coverage_weight": 0,
444
 
445
- "development_plan": {
446
  "value": "YES|NO|NOT_FOUND",
447
  "evidence": []
448
- },
449
 
450
- "agricultural_strategy": {
451
  "value": "YES|NO|NOT_FOUND",
452
  "evidence": []
453
- },
454
 
455
- "standalone_vc_strategy": {
456
  "value": "YES|NO|NOT_FOUND",
457
  "evidence": []
458
- },
459
 
460
- "flagship_project": {
461
  "value": "YES|NO|NOT_FOUND",
462
  "evidence": []
463
- }
464
- },
465
 
466
- "institutional_commitment": {
467
- "dedicated_agency": {
468
  "value": "YES|NO|NOT_FOUND",
469
  "evidence": []
470
- },
471
 
472
- "dedicated_research_institute": {
473
  "value": "YES|NO|NOT_FOUND",
474
  "evidence": []
475
- },
476
 
477
- "dedicated_ministerial_department": {
478
  "value": "YES|NO|NOT_FOUND",
479
  "evidence": []
480
- }
481
- }
482
- }
483
 
484
  """
485
 
486
- def build_vc_prompt(value_chain:str,
487
- domain:str
488
- ):
 
489
  return VALUE_CHAIN_PROMPT_TEMPLATE.format(
490
  domain=domain,
491
  value_chain=value_chain,
 
492
  )
493
 
494
  def dict_to_string(d, indent=0):
 
315
 
316
  Identify:
317
 
318
+ A. Budget allocation at least five years prior to current date
319
 
320
+ B. Current budget allocation (or in the most recent financial year)
 
321
 
322
  Extract:
323
 
 
334
 
335
  STEP 2: STRATEGIC COMMITMENT
336
 
337
+ Extract all national agricultural strategies, national development plans, donor strategies,
338
+ and value chain specific strategies in the last 10 years.
339
+
340
+ Across all supplied policy documents and identified strategies determine:
341
 
342
  1. Total number of documents examined
343
 
344
  2. Number of documents where the value chain is discussed
345
 
346
+ 3. Whether:
347
 
348
+ a) the value chain is identified as a priority
349
+ in the national development plan
350
 
351
+ b) the value chain is identified as a priority
352
+ in the most recent agricultural development strategy
 
353
 
354
+ c) there is a standalone value chain strategy
355
 
356
+ d) there is a flagship value chain project
357
+ (supported by donors/government, or co-financed between them)
358
 
359
  For each item provide:
360
 
361
+ - YES (if value chain is only mentioned with explicit reference)
362
+ - NO (if there is no mention or reference of the value chain for the respective category)
 
363
 
364
  and supporting evidence.
365
 
 
392
 
393
  Return:
394
 
395
+ - YES (if value chain is only mentioned with explicit reference)
396
+ - NO (if there is no mention or reference of the value chain for the respective category)
 
397
 
398
  for each category.
399
 
 
414
  documents_discussing_value_chain /
415
  documents_examined
416
 
417
+ CONTEXT (use ONLY this to answer)
418
+ --------------------------------------------------------
419
+ {context}
420
+ --------------------------------------------------------
421
+
422
  --------------------------------------------------------
423
 
424
  OUTPUT FORMAT
425
  --------------------------------------------------------
426
 
427
+ {{
428
  "value_chain": "",
429
 
430
+ "financial_commitment": {{
431
  "budget_start_year": "",
432
  "budget_start_value": "",
433
  "budget_end_year": "",
 
435
  "currency": "",
436
  "responsible_institution": "",
437
  "evidence": [
438
+ {{
439
  "quote": "",
440
  "source_document": "",
441
  "page_or_section": ""
442
+ }}
443
  ]
444
+ }},
445
 
446
+ "strategic_commitment": {{
447
  "documents_examined": 0,
448
  "documents_discussing_value_chain": 0,
449
  "coverage_weight": 0,
450
 
451
+ "development_plan": {{
452
  "value": "YES|NO|NOT_FOUND",
453
  "evidence": []
454
+ }},
455
 
456
+ "agricultural_strategy": {{
457
  "value": "YES|NO|NOT_FOUND",
458
  "evidence": []
459
+ }},
460
 
461
+ "standalone_vc_strategy": {{
462
  "value": "YES|NO|NOT_FOUND",
463
  "evidence": []
464
+ }},
465
 
466
+ "flagship_project": {{
467
  "value": "YES|NO|NOT_FOUND",
468
  "evidence": []
469
+ }}
470
+ }},
471
 
472
+ "institutional_commitment": {{
473
+ "dedicated_agency": {{
474
  "value": "YES|NO|NOT_FOUND",
475
  "evidence": []
476
+ }},
477
 
478
+ "dedicated_research_institute": {{
479
  "value": "YES|NO|NOT_FOUND",
480
  "evidence": []
481
+ }},
482
 
483
+ "dedicated_ministerial_department": {{
484
  "value": "YES|NO|NOT_FOUND",
485
  "evidence": []
486
+ }}
487
+ }}
488
+ }}
489
 
490
  """
491
 
492
+ def build_vc_analyzer_prompt(context:str,
493
+ value_chain:str,
494
+ domain:str
495
+ ):
496
  return VALUE_CHAIN_PROMPT_TEMPLATE.format(
497
  domain=domain,
498
  value_chain=value_chain,
499
+ context=context
500
  )
501
 
502
  def dict_to_string(d, indent=0):
src/query_engine.py CHANGED
@@ -6,7 +6,87 @@ import re
6
  from typing import Dict
7
 
8
  from src.llm import generate
9
- from src.prompts import build_query_understanding_prompt, build_categorizer_prompt, build_init_prompt
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
 
11
 
12
  def _load_sql_schema_summary(sql_db_dir: str) -> str:
@@ -168,6 +248,93 @@ def understand_query(
168
 
169
  return result
170
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
171
  def _parse_qinit_result(raw:str) -> Dict:
172
  parsed = None
173
 
@@ -197,6 +364,7 @@ def _parse_qinit_result(raw:str) -> Dict:
197
  }
198
 
199
  return parsed
 
200
  def _parse_qcat_result(raw:str) -> Dict:
201
  parsed = None
202
 
 
6
  from typing import Dict
7
 
8
  from src.llm import generate
9
+ from src.prompts import (build_query_understanding_prompt,
10
+ build_categorizer_prompt, build_init_prompt, build_vc_analyzer_prompt)
11
+
12
+ def analyze_committment_to_vc(value_chain:str,
13
+ cfg:Dict,):
14
+ domain = cfg.get("chatbot", {}).get("domain", "research")
15
+
16
+ prompt = build_vc_analyzer_prompt(value_chain, domain)
17
+
18
+ try:
19
+ raw = generate(
20
+ "",
21
+ prompt,
22
+ cfg,
23
+ max_tokens=512,
24
+ )
25
+ return _parse_vc_analyzer_result(raw)
26
+ except Exception:
27
+ # LLM failure: fall back to raw query
28
+ return {
29
+ "value_chain": None,
30
+
31
+ "financial_commitment": {
32
+ "budget_start_year": "",
33
+ "budget_start_value": "",
34
+ "budget_end_year": "",
35
+ "budget_end_value": "",
36
+ "currency": "",
37
+ "responsible_institution": "",
38
+ "evidence": [
39
+ {
40
+ "quote": "",
41
+ "source_document": "",
42
+ "page_or_section": ""
43
+ }
44
+ ]
45
+ },
46
+
47
+ "strategic_commitment": {
48
+ "documents_examined": 0,
49
+ "documents_discussing_value_chain": 0,
50
+ "coverage_weight": 0,
51
+
52
+ "development_plan": {
53
+ "value": "NOT_FOUND",
54
+ "evidence": []
55
+ },
56
+
57
+ "agricultural_strategy": {
58
+ "value": "NOT_FOUND",
59
+ "evidence": []
60
+ },
61
+
62
+ "standalone_vc_strategy": {
63
+ "value": "NOT_FOUND",
64
+ "evidence": []
65
+ },
66
+
67
+ "flagship_project": {
68
+ "value": "NOT_FOUND",
69
+ "evidence": []
70
+ }
71
+ },
72
+
73
+ "institutional_commitment": {
74
+ "dedicated_agency": {
75
+ "value": "NOT_FOUND",
76
+ "evidence": []
77
+ },
78
+
79
+ "dedicated_research_institute": {
80
+ "value": "NOT_FOUND",
81
+ "evidence": []
82
+ },
83
+
84
+ "dedicated_ministerial_department": {
85
+ "value": "NOT_FOUND",
86
+ "evidence": []
87
+ }
88
+ }
89
+ }
90
 
91
 
92
  def _load_sql_schema_summary(sql_db_dir: str) -> str:
 
248
 
249
  return result
250
 
251
+ def _parse_vc_analyzer_result(raw:str) -> Dict:
252
+ parsed = None
253
+
254
+ # Try direct parse
255
+ try:
256
+ parsed = json.loads(raw)
257
+ except (json.JSONDecodeError, TypeError):
258
+ pass
259
+
260
+ # Fallback: scan for the first valid JSON object using raw_decode
261
+ if parsed is None:
262
+ decoder = json.JSONDecoder()
263
+ for i, ch in enumerate(raw):
264
+ if ch == '{':
265
+ try:
266
+ parsed, _ = decoder.raw_decode(raw, i)
267
+ break
268
+ except json.JSONDecodeError:
269
+ continue
270
+
271
+ # Unparseable: fall back to raw query
272
+ if not isinstance(parsed, dict):
273
+ return {
274
+ "value_chain": None,
275
+
276
+ "financial_commitment": {
277
+ "budget_start_year": "",
278
+ "budget_start_value": "",
279
+ "budget_end_year": "",
280
+ "budget_end_value": "",
281
+ "currency": "",
282
+ "responsible_institution": "",
283
+ "evidence": [
284
+ {
285
+ "quote": "",
286
+ "source_document": "",
287
+ "page_or_section": ""
288
+ }
289
+ ]
290
+ },
291
+
292
+ "strategic_commitment": {
293
+ "documents_examined": 0,
294
+ "documents_discussing_value_chain": 0,
295
+ "coverage_weight": 0,
296
+
297
+ "development_plan": {
298
+ "value": "NOT_FOUND",
299
+ "evidence": []
300
+ },
301
+
302
+ "agricultural_strategy": {
303
+ "value": "NOT_FOUND",
304
+ "evidence": []
305
+ },
306
+
307
+ "standalone_vc_strategy": {
308
+ "value": "NOT_FOUND",
309
+ "evidence": []
310
+ },
311
+
312
+ "flagship_project": {
313
+ "value": "NOT_FOUND",
314
+ "evidence": []
315
+ }
316
+ },
317
+
318
+ "institutional_commitment": {
319
+ "dedicated_agency": {
320
+ "value": "NOT_FOUND",
321
+ "evidence": []
322
+ },
323
+
324
+ "dedicated_research_institute": {
325
+ "value": "NOT_FOUND",
326
+ "evidence": []
327
+ },
328
+
329
+ "dedicated_ministerial_department": {
330
+ "value": "NOT_FOUND",
331
+ "evidence": []
332
+ }
333
+ }
334
+ }
335
+
336
+ return parsed
337
+
338
  def _parse_qinit_result(raw:str) -> Dict:
339
  parsed = None
340
 
 
364
  }
365
 
366
  return parsed
367
+
368
  def _parse_qcat_result(raw:str) -> Dict:
369
  parsed = None
370