You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

270 lines
10 KiB

import re
from _arango import arango
from _llm import LLM
from pprint import pprint
from pprint import pprint
from langchain_text_splitters import CharacterTextSplitter
import multiprocessing
class Interrogation:
def __init__(self, interrogation):
self.interrogation = interrogation
self.llm = LLM(chat=True)
self.llm_checker = LLM(chat=False)
self.text = interrogation['text']
# Info to collect
self.sexual_content = None
self.sexual_info = []
self.sexual_content_description = None
self.sexual_content_date = None
self.self_experience = None
self.self_involvement = None
self.self_involvement_type = None
self.heard_about = None
self.heard_from = None
self.sexual_chunk = None
self.sexual_summary = None
self.self_heard_from_id = None
self.text_splitter = CharacterTextSplitter(
separator="\n\n",
chunk_size=3000,
chunk_overlap=0,
length_function=len,
is_separator_regex=False,
)
self.chunks = self.text_splitter.split_text(self.text)
if 'mentioned_persons' in interrogation:
q = f'''for doc in persons filter doc._id in ["{'","'.join(interrogation["mentioned_persons"])}"] return doc'''
print(q)
self.mentioned_persons = list(arango.db.aql.execute(q))
self.mentioned_in_interrogation = [i['name'] for i in self.mentioned_persons]
self.mentioned_in_interrogations_dict = {i['name']: i['_id'] for i in self.mentioned_persons}
print(self.mentioned_in_interrogation)
else:
self.mentioned_in_interrogation = None
def find_sexual_content(self, chunk, check_text=False):
prompt = f'''
Texten nedan är en del av ett polisförhör.
TEXT:
"""{chunk}"""
Jag vill veta om någonting i förhöret handlar om eller anspelar på något av:
- Sexuella olämpligheter
- Sexuella inviter
- Övergrepp
- Pedofili
- Grooming
Svara med "JA" eller "NEJ".
Svar:
'''
if check_text:
response = self.llm_checker.generate(prompt)
else:
response = self.llm.generate(prompt)
if 'JA' in response:
sexual_content = True
elif 'NEJ' in response:
sexual_content = False
else:
sexual_content = None
if check_text:
return sexual_content
self.sexual_content = sexual_content
if sexual_content:
self.sexual_chunk = chunk
prompt = f'''Beskriv det sexuella innehållet i förhöret.'''
self.sexual_content_description = self.llm.generate(prompt)
self.extract_sexual_info(chunk)
prompt = f'''Ungefär när i tiden hände det som personen berättar om?'''
self.sexual_content_date = self.llm.generate(prompt)
def find_self_experience(self):
prompt = f'Har personen som förhörs själv varit med om något av det som beskrivs? Svara ENBART med "JA" eller "NEJ".'
response = self.llm.generate(prompt)
if 'JA' in response:
self.self_experience = True
elif 'NEJ' in response:
self.self_experience = False
else:
self.self_experience = None
def find_self_involvement(self):
prompt = f'Har personen som förhörs själv varit inblandad på något sätt? Svara ENBART med "JA" eller "NEJ".'
response = self.llm.generate(prompt)
if 'JA' in response:
self.self_involvement = True
prompt = f'''På vilket sätt har personen som förhörs varit inblandad?'''
self.self_involvement_type = self.llm.generate(prompt)
elif 'NEJ' in response:
self.self_involvement = False
else:
self.self_involvement = None
def find_heard_about(self):
prompt = f'''Har personen hört talas om något av det som beskrivs? Svara ENBART med "JA" eller "NEJ".'''
response = self.llm.generate(prompt)
if 'JA' in response:
self.heard_about = True
self.find_heard_from()
elif 'NEJ' in response:
self.heard_about = False
else:
self.heard_about = None
def find_heard_from(self):
prompt = f'Av vem har personen hört det som beskrivs? Svara bara med namnet på personen, eller vad personen kallas.'
heard_from = self.llm.generate(prompt)
if self.mentioned_in_interrogation:
mentioned_in_interrogation = '\n'.join(self.mentioned_in_interrogation)
prompt = f'''Jag behöver identifiera vem {heard_from} är, verkar {heard_from} vara någon av följande personer:\n
{mentioned_in_interrogation}
Svara ENBART med med namnet på personen det skulle kunna vara. Om du inte vet svara "Jag vet inte".
'''
heard_from_answer = self.llm.generate(prompt)
if heard_from_answer in self.mentioned_in_interrogation:
self.heard_from = heard_from_answer
self.self_heard_from_id = self.mentioned_in_interrogations_dict[heard_from_answer]
else:
mentioned_info = '\n\n'.join([f'{i["name"].upper()}\n{i["info"]}' for i in self.mentioned_persons])
prompt = f'''Här är mer information om möjliga personer:\n
{mentioned_info}\n
Kan du utifrån den säga vem {heard_from} är? Svara BARA med namnet på personen ur listanÄr du inte säker så svara "Jag vet inte".
'''
heard_from_answer_info = self.llm.generate(prompt)
if heard_from_answer_info in self.mentioned_in_interrogation:
self.heard_from = heard_from_answer_info
self.self_heard_from_id = self.mentioned_in_interrogations_dict[heard_from_answer_info]
if not self.heard_from:
self.heard_from = heard_from
def create_arango_doc(self):
return {
'_key': self.interrogation['_key'],
'sexual_content': self.sexual_content,
'sexual_content_description': self.sexual_content_description,
'self_experience': self.self_experience,
'self_involvement': self.self_involvement,
'self_involvement_type': self.self_involvement_type,
'heard_about': self.heard_about,
'heard_from': self.heard_from,
'interrogation_date': self.interrogation['date'],
'sexual_content_date': self.sexual_content_date,
'sexual_info': '\n'.join(self.sexual_info),
'sexual_summary': self.sexual_summary,
}
def extract_sexual_info(self, chunk):
sexual_content = self.find_sexual_content(chunk, check_text=True)
if sexual_content:
prompt = f'''
Jag samlar uppgifter ur ett polisförhör och är intresserad av uppgifter som har att göra med eller anspelar på något av följande:
- Sexuella olämpligheter
- Sexuella inviter
- Övergrepp
- Pedofili
- Grooming
Texten nedan är nästa del i förhöret.\n
TEXT:
"""{chunk}"""\n
Om det finns något i texten som har att göra med listan ovan så sammanfatta dessa uppgifter så detaljerat som möjligt. Det behöver inte vara konkret fakta, jag är även intressserad av anspelningar och rykten.
Var noga med detaljer som namn, platser, tider och händelser. Se också till att få med vem som är inblandad och hur och vem som sagt vad, samt hur personer är relaterade till varandra.
Lägg inte till någon egen information, fokusera bara på texten.
'''
self.sexual_info.append(self.llm.generate(prompt))
def collect_sexual_info(self):
chunk = self.sexual_chunk
index_of_chunk = self.chunks.index(chunk)
if index_of_chunk != len(self.chunks)-1:
remaining_chunks = self.chunks[index_of_chunk+1:]
for chunk in remaining_chunks:
self.extract_sexual_info(chunk)
sexual_info_string = '\n'.join(self.sexual_info)
prompt = f'Nedan är innehåll som samlats in ur förhöret:\n\n"""{sexual_info_string}"""\n\nSammanfatta innehållet på ett detaljerat vis.'
self.sexual_summary = self.llm.generate(prompt)
def add_to_arango(self):
arango_doc = self.create_arango_doc()
db.collection('rumors').insert(arango_doc, overwrite=True, keep_none=False)
if arango_doc['sexual_content']:
pprint(arango_doc)
def process_interrogation(interrogation_data):
interrogation = Interrogation(interrogation_data)
for chunk in interrogation.chunks:
interrogation.find_sexual_content(chunk)
if not interrogation.sexual_content:
continue
if interrogation.sexual_content:
interrogation.find_self_experience()
if interrogation.self_experience:
interrogation.find_self_involvement()
if interrogation.self_involvement:
pass
else:
interrogation.find_heard_about()
else:
interrogation.find_heard_about()
interrogation.collect_sexual_info()
interrogation.add_to_arango()
break
if not interrogation.sexual_content:
interrogation.add_to_arango()
if __name__ == "__main__":
db = arango.db
q = 'for doc in interrogations return doc'
interrogations = list(db.aql.execute(q))
# Filter out interrogations that have their _key in the rumors collection
q = 'for rumor in rumors return rumor._key'
rumors = list(db.aql.execute(q))
interrogations = [interrogation for interrogation in interrogations if interrogation['_key'] not in rumors]
print('Number of interrogations to process:', len(interrogations))
for i in interrogations:
process_interrogation(i)
exit()
with multiprocessing.Pool() as pool:
pool.map(process_interrogation, interrogations)