virginialevy commited on
Commit
9f10b9b
·
verified ·
1 Parent(s): bf186f5

Upload 2 files

Browse files
Files changed (2) hide show
  1. README.md +403 -11
  2. requirements.txt +6 -0
README.md CHANGED
@@ -1,14 +1,406 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
- title: Lexie
3
- emoji: 🏃
4
- colorFrom: purple
5
- colorTo: purple
6
- sdk: gradio
7
- sdk_version: 5.44.1
8
- app_file: app.py
9
- pinned: false
10
- license: mit
11
- short_description: Agentic AI to verify compliance with GDPR and AI Act.
 
 
 
 
 
 
 
 
 
12
  ---
13
 
14
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ### Lexie – Legal Compliance Assistant (base)
2
+
3
+
4
+
5
+ **Setup**
6
+
7
+ -----
8
+
9
+ pip install -r requirements.txt
10
+
11
+ \# for analysis:
12
+
13
+ pip install openai
14
+
15
+ \# Windows PowerShell:
16
+
17
+ setx OPENAI\_API\_KEY "sk-..."
18
+
19
+
20
+
21
+ Commands
22
+
23
+ --------
24
+
25
+ python main.py build-index
26
+
27
+ python main.py test-retriever
28
+
29
+ python main.py analyze-demo
30
+
31
+
32
+
33
+
34
+
35
+
36
+
37
+ **🧠 Design Principles**
38
+
39
+
40
+
41
+ **Lexie** was built with a modular and agentic mindset, inspired by emerging best practices in AI-assisted development. Rather than relying on monolithic prompting or magic workflows, Lexie applies strategic separation of concerns and methodical orchestration. Key principles include:
42
+
43
+
44
+
45
+ * Context-First Setup: Each task is approached like briefing a junior developer — with clear structure, expected behavior, and explicit constraints before any generation occurs.
46
+
47
+
48
+
49
+ * Test-by-Design: The logic of Lexie is enforced by validations and controlled outputs (e.g., maximum number of citations, placeholder filtering), reducing ambiguity and maximizing reliability.
50
+
51
+
52
+
53
+ * Rule-Based Core: A centralized configuration (config.py) and logic definitions (postprocess.py) act as an internal operating system, guiding how the system behaves and responds.
54
+
55
+
56
+
57
+ * Unified Workspace: All modules operate within a coherent and tightly scoped folder structure (lexie/), ensuring clarity, traceability, and easy collaboration.
58
+
59
+
60
+
61
+ * Model Mixing Strategy: Lexie combines small open-source models (e.g. for chunking and embedding with MiniLM) with powerful LLMs (GPT-4) for legal reasoning and summarization. This approach balances speed, cost, and analytical depth.
62
+
63
+
64
+
65
+ * Iterative, Human-in-the-Loop Development: Every feature is tested incrementally, reviewed critically, and refined through live interactions and error tracing.
66
+
67
+
68
+
69
+ Lexie is not a “prompt wrapper” — it’s a real-world application of AI as a reasoning assistant. The focus is on clarity, control, and meaningful outputs.
70
+
71
+
72
+
73
  ---
74
+
75
+
76
+
77
+ **🤝 Collaborative AI Development**
78
+
79
+
80
+
81
+ Lexie was developed in close collaboration with ChatGPT (GPT-4 and 5), used not merely as a coding assistant but as a reasoning partner throughout the project lifecycle. From architectural decisions to prompt engineering, from debugging complex errors to refining user-facing outputs, ChatGPT served as a real-time co-designer, especially valuable during early-stage prototyping and iterative testing.
82
+
83
+
84
+
85
+ The collaboration was guided by clear instructions, step-by-step validation, and a critical mindset: ChatGPT’s outputs were always reviewed, edited, and validated by a human before being integrated into the codebase.
86
+
87
+
88
+
89
+ This project stands as an example of human-in-the-loop agentic development, where AI tools are treated as powerful collaborators, not autopilots. The result is a system that reflects both technical coherence and creative decision-making.
90
+
91
+
92
+
93
  ---
94
 
95
+
96
+
97
+ 🧪 **Testing in Lexie**
98
+
99
+
100
+
101
+ Lexie includes a dedicated tests/ folder to ensure stability and prevent regressions as the project evolves. The goal is not bureaucracy, but trust and speed:
102
+
103
+
104
+
105
+ * Regression safety: whenever you update a file, you can run pytest and immediately see if something broke.
106
+
107
+
108
+
109
+ * Architecture clarity: all test cases are kept separate from the main code, but close enough for quick checks.
110
+
111
+
112
+
113
+ * Professional credibility: showing a reproducible test suite proves Lexie is a serious, production-ready tool.
114
+
115
+
116
+
117
+ **📂 Test structure**
118
+
119
+
120
+
121
+ lexie/
122
+
123
+   main.py
124
+
125
+   call\_agent.py
126
+
127
+   pdf\_reporter.py
128
+
129
+   tools/
130
+
131
+   requirements.txt
132
+
133
+   requirements-dev.txt
134
+
135
+   tests/
136
+
137
+   fixtures/
138
+
139
+   iubenda.pdf
140
+
141
+ &nbsp; iubenda\_snapshot.normalized.txt <-- golden reference
142
+
143
+ &nbsp; info\_breve.pdf
144
+
145
+ &nbsp; dpa\_bozza.pdf
146
+
147
+ &nbsp; helpers/
148
+
149
+ &nbsp; pdf\_extract.py
150
+
151
+ &nbsp; run\_cli.py
152
+
153
+ &nbsp; test\_pdf\_snapshot.py
154
+
155
+ &nbsp; test\_postprocess\_rules.py
156
+
157
+ &nbsp; test\_free\_text\_smoke.py
158
+
159
+ &nbsp; conftest.py
160
+
161
+
162
+
163
+
164
+
165
+ * tests/fixtures/ → input documents and golden snapshots.
166
+ * tests/helpers/ → utilities to extract and normalize PDF text, and to run the CLI.
167
+ * tests/test\_pdf\_snapshot.py → snapshot test for iubenda.pdf and smoke test for short documents.
168
+ * tests/test\_free\_text\_smoke.py → smoke test for free-text input.
169
+ * tests/test\_postprocess\_rules.py → unit tests for post-process rules.
170
+
171
+
172
+
173
+ **🔎 Types of tests**
174
+
175
+
176
+
177
+ 1. **Snapshot test (golden)**
178
+
179
+
180
+
181
+ * Compares the PDF generated from iubenda.pdf with the reference file iubenda\_snapshot.normalized.txt.
182
+
183
+
184
+
185
+ * Purpose: catch invisible regressions in layout or content.
186
+
187
+
188
+
189
+ * Rule: if the diff is a bug �� fix the code; if it’s an intended change → update the golden file.
190
+
191
+
192
+
193
+ **2. Smoke tests**
194
+
195
+
196
+
197
+ * Run on a short document (info\_breve.pdf) and on free-text input.
198
+
199
+
200
+
201
+ * Check that the generated PDF always includes:
202
+
203
+
204
+
205
+ &nbsp; - risk/score header
206
+
207
+
208
+
209
+ &nbsp; - key sections: Violations, Recommendations, Citations
210
+
211
+
212
+
213
+ **3. Unit tests (post-process)**
214
+
215
+
216
+
217
+ * Verify that the normalization and consistency rules are respected:
218
+
219
+
220
+
221
+ &nbsp; - Multi-hit on the same article is allowed.
222
+
223
+
224
+
225
+ &nbsp; - Title/article mismatch generates a warning, not an error.
226
+
227
+
228
+
229
+ &nbsp; - Citation cap is enforced if configured.
230
+
231
+
232
+
233
+ **📌 Golden file explained**
234
+
235
+
236
+
237
+ A golden file is a frozen output used as reference.
238
+
239
+ For Lexie, the golden is iubenda\_snapshot.normalized.txt.
240
+
241
+
242
+
243
+ How it works:
244
+
245
+
246
+
247
+ * First run: Lexie processes iubenda.pdf, the normalized text is saved as golden.
248
+
249
+
250
+
251
+ * Future runs: the test compares the new output against the golden.
252
+
253
+
254
+
255
+ * If they match → stable.
256
+
257
+
258
+
259
+ * If they differ:
260
+
261
+
262
+
263
+ &nbsp; - Bug → fix the pipeline.
264
+
265
+
266
+
267
+ &nbsp; - Intended change → overwrite the golden with the new output.
268
+
269
+
270
+
271
+ This acts as a **photograph** of the expected behavior.
272
+
273
+
274
+
275
+ **⚡ How to run tests**
276
+
277
+
278
+
279
+ Install dependencies:
280
+
281
+
282
+
283
+ pip install -r requirements.txt # runtime
284
+
285
+ pip install -r requirements-dev.txt # dev \& test
286
+
287
+
288
+
289
+
290
+
291
+ Run the full suite:
292
+
293
+
294
+
295
+ pytest tests/ -q
296
+
297
+
298
+
299
+
300
+
301
+ Run a single test:
302
+
303
+
304
+
305
+ pytest tests/test\_pdf\_snapshot.py::test\_iubenda\_snapshot -q
306
+
307
+
308
+
309
+
310
+
311
+ &nbsp; ┌──────────────────────────────────────────┐
312
+
313
+ &nbsp; │ LEXIE PIPELINE │
314
+
315
+ &nbsp; │ route → retrieve → analyze → postprocess │
316
+
317
+ &nbsp; │ → pdf\_reporter │
318
+
319
+ &nbsp; └───────────────┬───────────────┬─────────┘
320
+
321
+ &nbsp; │ │
322
+
323
+ &nbsp; (document) (free-text)
324
+
325
+ &nbsp; │ │
326
+
327
+ &nbsp; input .pdf input string
328
+
329
+ &nbsp; │ │
330
+
331
+ &nbsp; ▼ ▼
332
+
333
+ &nbsp; ┌─────────────────────────────┐
334
+
335
+ &nbsp; │ NORMALIZED PDF TEXT │
336
+
337
+ &nbsp; └─────────────────────────────┘
338
+
339
+
340
+
341
+
342
+
343
+ **Test Levels**
344
+
345
+
346
+
347
+ \[1] SNAPSHOT (GOLDEN) ──────────────────────────────────────────────────────────
348
+
349
+ &nbsp; Input: tests/fixtures/iubenda.pdf
350
+
351
+ &nbsp; Check: compare normalized PDF text ⇆ iubenda\_snapshot.normalized.txt
352
+
353
+ &nbsp; Outcome:
354
+
355
+ &nbsp; = pass → behavior stable
356
+
357
+ &nbsp; ≠ diff → bug OR intended change → update golden
358
+
359
+
360
+
361
+ \[2] SMOKE (DOCUMENT) ───────────────────────────────────────────────────────────
362
+
363
+ &nbsp; Input: tests/fixtures/info\_breve.pdf
364
+
365
+ &nbsp; Check: "risk:" + "score:" + sections {violations, recommendations, citations}
366
+
367
+
368
+
369
+ \[3] SMOKE (FREE-TEXT) ──────────────────────────────────────────────────────────
370
+
371
+ &nbsp; Input: "We collect facial images without consent."
372
+
373
+ &nbsp; Check: same header + same sections as document smoke
374
+
375
+
376
+
377
+ \[4] UNIT (POST-PROCESS) ────────────────────────────────────────────────────────
378
+
379
+ &nbsp; Target: tools/postprocess.enforce\_rules(...)
380
+
381
+ &nbsp; Checks:
382
+
383
+ &nbsp; - multi-hit same article = allowed
384
+
385
+ &nbsp; - title/article mismatch → WARNING (non-blocking)
386
+
387
+ &nbsp; - citations cap respected (if configured)
388
+
389
+
390
+
391
+ **Golden Update Flow**
392
+
393
+
394
+
395
+ Run snapshot → diff?
396
+
397
+ &nbsp; ├─ No → done
398
+
399
+ &nbsp; └─ Yes
400
+
401
+ &nbsp; ├─ Bug → fix code → rerun
402
+
403
+ &nbsp; └─ Intended change → overwrite iubenda\_snapshot.normalized.txt → rerun
404
+
405
+
406
+
requirements.txt ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ gradio>=4.44
2
+ reportlab>=4.1
3
+ pdfminer.six>=20231228
4
+ PyYAML>=6.0.1
5
+ openai>=1.40
6
+ numpy>=1.26