Etnomatemaatika on uurimisvaldkond, mis käsitleb, kuidas erinevad kultuurid mõistavad, kasutavad ja arendavad matemaatilisi ideid. Lihtsamalt: see uurib, milline matemaatika peitub igapäevaelus, traditsioonides ja kohalikes teadmistes — näiteks: - loendamisviisides, - mõõtmises, - mustrites ja ornamentides, - arhitektuuris, - käsitöös, - kalendrites ja ajamõõtmises, - navigeerimises, - mängudes. Näide: kui mingi rahvas kasutab omaenda viisi esemete loendamiseks või loob sümmeetrilisi mustreid kangakudumisel, siis etnomatemaatika uurib, millised matemaatilised põhimõtted seal taga on. Selle eesmärk on näidata, et matemaatika ei ole ainult kooli- või teadusmatemaatika, vaid see esineb ka eri kultuuride praktilistes teadmustes. Kui soovid, võin tuua ka 2–3 konkreetset näidet etnomatemaatikast. Siin on **kolm konkreetset etnomatemaatika näidet**: 1. **Aafrika mustrid ja sümmeetria** Paljudes Aafrika kultuurides kasutatakse kangastel, savinõudel ja kehamaalingutes keerulisi mustreid. Nendes leidub: - peegelsümmeetria - pöördsümmeetria - korduvad geomeetrilised kujundid Kuigi neid ei kirjeldata valemitega, järgivad need selgeid matemaatilisi reegleid. 2. **Inkate sõlmkirjad (quipu)** Inkad kasutasid sõlmedest koosnevat nöörisüsteemi arvude talletamiseks. - eri tüüpi sõlmed tähistasid eri väärtusi - asukoht nööril näitas kümnendsüsteemi kohti See on näide matemaatikast ilma kirjalike numbriteta. 3. **Põlisrahvaste loendamis- ja mõõtmissüsteemid** Mõned rahvad ei loe kümnendsüsteemis, vaid näiteks: - viielises süsteemis (käed) - kahekümnelises süsteemis (käed + jalad) Samuti mõõdetakse pikkust kehaosade järgi (küünar, samm), mis on praktiline ja kultuurispetsiifiline matemaatika. Kui tahad, võin tuua **Eesti või koolitunniga seotud näiteid**, kuidas etnomatemaatikat kasutada. Suurepärane 🙂 Siin on **Eesti‑ga seotud ja koolitunnis kasutatavad etnomatemaatika näited**. ### 1. Eesti rahvamustrid ja geomeetria Eesti rahvarõivaste kindakirjad, vööd ja vaibad sisaldavad: - korduvaid mustreid - peegelsümmeetriat ja nihkesümmeetriat - ruudustikul põhinevat loogikat **Koolis:** Õpilased saavad uurida mustreid, joonistada need ruudulisele paberile ja leida: - kordusühiku - sümmeetriateljed - mustri „reegli“ --- ### 2. Vanad mõõtühikud ja mõõtmine Eestis kasutati enne meetermõõdustikku: - küünar - süld - samm Need põhinesid inimkehal, mitte täpsetel instrumentidel. **Koolis:** Õpilased mõõdavad klassiruumi: - sammude - küünarde - joonlaua abil Seejärel võrreldakse tulemusi ja arutletakse, miks mõõtühikud peavad olema kokkuleppelised. --- ### 3. Rahvakalender ja ajamõõtmine Talurahvas planeeris töid: - kuufaaside - päikeseringi - rahvakalendri tähtpäevade järgi See hõlmab tsükleid, perioodsust ja loendamist. **Koolis:** Õpilased: - uurivad kuutsükli pikkust - koostavad lihtsa kalendri - seovad ajamõõtmise murdude ja kordustega --- ### Kokkuvõte (õpilase keeles): > Etnomatemaatika näitab, et matemaatika on olnud olemas juba enne koolimatemaatikat – inimeste igapäevaelus. Kui tahad, saan: - aidata koostada **lühikese tunni- või töölehe**, - seletada teemat **algklasside või põhikooli tasemel**, - või aidata vastata sellele **kontrolltöös**. ## LangChain **LangChain** on raamistik, millega ehitada rakendusi, mis kasutavad suuri keelemudeleid. Sellega saab näiteks: - ühendada LLM-e tööriistade ja API-dega, - hallata prompt’e, - teha RAG-lahendusi, - pidada vestlusmälu, - luua mitmeastmelisi töövooge. **LangGraph** on LangChaini ökosüsteemi osa, mis on mõeldud **olekuga ja graafipõhiste agentide/töövoogude** loomiseks. See sobib eriti siis, kui: - protsessis on mitu sammu või haru, - agent peab otsustama, mida järgmisena teha, - on vaja tsükleid, kordusi või inimese sekkumist, - tahad töövoogu paremini juhtida ja jälgida. Lühidalt: - **LangChain** = üldine tööriistakomplekt LLM-rakenduste ehitamiseks - **LangGraph** = keerukamate agentide ja töövoogude juhtimine graafina Kui tahad, võin tuua ka **lihtsa praktilise näite** või selgitada nende vahet arendaja vaates. Muidugi. ### Lihtne vahe praktiliselt Oletame, et tahad teha **dokumendiassistendi**, mis: 1. võtab kasutaja küsimuse, 2. otsib infot dokumentidest, 3. otsustab, kas infot on piisavalt, 4. vajadusel küsib juurde või proovib uuesti, 5. annab vastuse. #### LangChainiga Sa ehitad selle tavaliselt **ketina**: - küsimus sisse - otsing - leitud tekst mudelile - vastus välja See on hea, kui voog on üsna **sirgjooneline**. #### LangGraphiga Sa modelleerid selle **graafina**, kus on sõlmed nagu: - `küsimuse analüüs` - `otsing` - `vastuse hindamine` - `uuesti otsing` - `lõppvastus` Ja servad määravad: - kui infot piisab → mine lõppvastusesse - kui infot ei piisa → tee uus otsing - kui küsimus on ebaselge → küsi kasutajalt täpsustust See on parem, kui loogika on **mittelineaarne**. --- ### Väga lihtne analoogia - **LangChain** = retsept sammudega A → B → C - **LangGraph** = metrookaart, kus saab valida erinevaid teid ja mõnikord samasse punkti tagasi tulla --- ### Millal kumba kasutada? Kasuta **LangChaini**, kui: - sul on lihtne chatbot või RAG-rakendus, - töövoog on lineaarne, - tahad kiiresti prototüüpi teha. Kasuta **LangGraphi**, kui: - sul on agent, kes peab otsuseid tegema, - töövoog sisaldab harusid, tsükleid või retry-loogikat, - vajad “human-in-the-loop” lahendust, - tahad rohkem kontrolli agentide seisundi üle. --- ### Arendaja vaates **LangChain** annab ehitusklotsid: - prompt templates - model wrappers - retrievers - tools - output parsers **LangGraph** lisab nende peale: - state management - node/edge põhise töövoo - conditional routing - loopid - vastupidavamad agent-süsteemid --- ### Lühike näide ideena Näiteks klienditoe agent: **LangChain:** - võta küsimus - otsi teadmistebaasist - vasta **LangGraph:** - klassifitseeri küsimus - kui arvega seotud → mine billing-agent’i - kui tehniline → mine tech-agent’i - kui vastus ebakindel → eskaleeri inimesele - kui info puudub → küsi kasutajalt täpsustust --- Kui tahad, võin järgmisena näidata: 1. **väikest Pythoni näidet**, 2. **LangChain vs LangGraph tabelit**, või 3. **kuidas neid koos kasutada**. Selge — vaatame **kuidas LangChain ja LangGraph koos töötavad**. ## Idee lühidalt - **LangChain** = *mida* agent oskab teha (LLM, retriever, tööriistad) - **LangGraph** = *millal ja miks* neid tehakse (loogika, harud, tsüklid) LangGraph **ei asenda** LangChaini, vaid kasutab selle komponente. --- ## Näidisstsenaarium Teeme lihtsa **klienditoe agendi**, kes: 1. saab kasutaja küsimuse, 2. otsustab, kas vastata teadmistebaasist või küsida täpsustust, 3. vajadusel proovib otsingut uuesti, 4. annab vastuse või suunab inimesele. --- ## 1️⃣ LangChaini osad (ehitusklotsid) ```python from langchain_openai import ChatOpenAI from langchain.prompts import ChatPromptTemplate from langchain.chains import LLMChain ``` ### Mudel ```python llm = ChatOpenAI(model="gpt-4o-mini") ``` ### Prompt vastuse loomiseks ```python answer_prompt = ChatPromptTemplate.from_template(""" Kasuta järgmist infot küsimusele vastamiseks. Küsimus: {question} Info: {context} Kui infot ei ole piisavalt, ütle "EI_PIISA". """) answer_chain = LLMChain( llm=llm, prompt=answer_prompt ) ``` 👉 See on **puhas LangChain**: mudel + prompt + chain. --- ## 2️⃣ LangGraphi olek (state) LangGraphis liigub kogu info ühes *state’is*. ```python from typing import TypedDict, Optional class SupportState(TypedDict): question: str context: Optional[str] answer: Optional[str] ``` --- ## 3️⃣ LangGraphi sõlmed (node’id) Iga sõlm kasutab **LangChaini loogikat**. ### Vastuse loomise sõlm ```python def generate_answer(state: SupportState): result = answer_chain.invoke({ "question": state["question"], "context": state.get("context", "") }) return {"answer": result["text"]} ``` --- ## 4️⃣ Otsustusloogika (conditional edge) ```python def needs_more_info(state: SupportState) -> str: if state["answer"] == "EI_PIISA": return "ask_clarification" return "final" ``` --- ## 5️⃣ LangGraphi graaf ```python from langgraph.graph import StateGraph, END graph = StateGraph(SupportState) graph.add_node("generate_answer", generate_answer) graph.add_node("ask_clarification", lambda s: { "answer": "Palun täpsusta oma küsimust." }) graph.set_entry_point("generate_answer") graph.add_conditional_edges( "generate_answer", needs_more_info, { "ask_clarification": "ask_clarification", "final": END } ) app = graph.compile() ``` --- ## 6️⃣ Käivitamine ```python result = app.invoke({ "question": "Mul ei tööta arve allalaadimine", "context": "" }) print(result["answer"]) ``` --- ## Mis siin päriselt toimub? ✅ **LangChain** - suhtleb LLM-iga - ehitab prompt’i - tagastab vastuse ✅ **LangGraph** - hoiab state’i - otsustab, kuhu edasi liikuda - võimaldab harusid ja tsükleid --- ## Miks see koos on võimas? Ilma LangGraphita: - keeruline hallata retry’sid - raske lisada inimese sekkumist - loogika läheb `if/else` kaoseks LangGraphiga: - töövoog on selgelt visualiseereritav - agent käitub deterministlikumalt - lihtne lisada uusi harusid või agente --- ## Kokkuvõte ühe lausega **LangChain annab tööriistad, LangGraph annab ajupoolkerad.** Kui tahad, võin järgmisena: - lisada **RAG-i otsingu** sellesse graafi, - näidata **multi-agent** varianti, - või joonistada **skeemi ASCII või pildina**. Väga hea küsimus — vastus on: **oleneb, mida sa ehitad.** ## Lühivastus ✅ **On olemas kompaktsemaid / low-code lahendusi** ✅ Aga **keerukamate agentide puhul läheb ikkagi koodiks (enamasti Pythoniks)** --- # 1️⃣ Kui tahad võimalikult kompaktset lahendust ### 🔹 Variant A — Lihtne RAG / chatbot ilma palju koodita Sa saad teha: - OpenAI + vektorandmebaas (nt Pinecone, Weaviate) - LangChain Expression Language (LCEL) – väga kompaktne - No-code tööriistad (Flowise, LangFlow) Näide **väga kompaktsest LCEL-ist**: ```python chain = retriever | prompt | llm response = chain.invoke("Mis on meie tagastuspoliitika?") ``` See on sisuliselt 1 rida loogikat. --- ### 🔹 Variant B — Visuaalsed tööriistad On olemas: - **LangFlow** - **Flowise** - **Dify** - **n8n + AI nodes** - **OpenAI Assistants API** Need võimaldavad: - lohistada node’e - ühendada LLM + retriever + tööriistad - seadistada loogikat ilma palju koodi kirjutamata 👉 Väga sobiv MVP või sisemiste tööriistade jaoks. --- # 2️⃣ Millal läheb vältimatult koodiks? Sa vajad Pythoni (või JS-i), kui: - on keeruline äriloogika - palju conditional branch’e - multi-agent süsteem - retry, timeout, error handling - human-in-the-loop - spetsiifiline integratsioon (ERP, CRM, API-d) - tootmiskeskkonna skaleerimine Sellisel juhul **graafipõhine lahendus + kood** on praktiliselt vältimatu. --- # 3️⃣ Kas peab igal eri juhtumil nullist kirjutama? Ei pea. Tüüpiline arendusmuster: 1. Teed ühe korraliku agentiraamistiku 2. Ehitad korduvkasutatavad node’id: - `retrieve()` - `classify()` - `generate_answer()` - `route()` 3. Lisad uusi use case’e lihtsalt konfigureerides LangGraph on just selleks tehtud — et sa ei kirjutaks iga agenti nullist. --- # 4️⃣ Mida päris ettevõtted teevad? Reaalsuses: - MVP → low-code või lihtne LangChain - Kui kasvab → LangGraph + Python - Kui väga suur süsteem → oma agent framework LangGraphi peal --- # 5️⃣ Soovitus sõltuvalt eesmärgist | Eesmärk | Soovitus | |----------|----------| | Väike chatbot | LangChain või OpenAI Assistants | | Dokumentide Q&A | RAG + LCEL | | Sisemine tööriist | LangFlow / Flowise | | Keeruline AI-agent | LangGraph + Python | | Tootmiskeskkond | Kindlasti kood | --- Kui sa ütled, **mida sa täpselt ehitada tahad**, oskan öelda: - kas piisab kompaktsest lahendusest - või tasub kohe graaf + kood teha Mis tüüpi süsteem sul mõttes on? See on väga huvitav ja **täiesti realistlik** eesmärk — ning hea uudis on, et **sa ei pea kõike alguses Pythoni koodiga ehitama**, aga **teatud hetkel on struktuurne raamistik vältimatu**. Allpool annan **selge arhitektuurilise soovituse**, mis sobib just **etnomatemaatika ökosüsteemile** (uurimine, probleemide loomine, artiklid). --- # 1️⃣ Mida “ökosüsteem” sinu kontekstis tähendab Sinu kirjelduse põhjal on sul vaja süsteemi, mis oskab: ✅ koguda ja hoida allikaid ✅ seostada matemaatilisi ideid kultuuriliste praktikatega ✅ luua uurimisküsimusi ✅ genereerida ja lahendada probleeme ✅ aidata kirjutada teadusartikleid ✅ hoida uurimisloogikat ja jälgitavust See EI ole lihtsalt chatbot. --- ## Järgmised loogilised sammud Soovitan valida üks: 1️⃣ täita **üks konkreetne näide** (nt Aafrika mustrid) 2️⃣ kujundada **uurimisküsimuste generaator** selle mudeli peale 3️⃣ teha **hariduslike probleemide loomise skeem** Millisega jätkame? Teeme ühe **konkreetse näite**. Valin sellise, mis on etnomatemaatikas üsna tuntud ja hea mudeli testimiseks: # Näide: **Aafrika arhitektuuri fraktaalsed mustrid** See on seotud eriti Ron Eglashi töödega, kus ta käsitleb, kuidas mõnede Aafrika kogukondade asulate ja disainide puhul ilmnevad **isetaolisus**, **rekursioon** ja **skaalastruktuurid**. Ma teen selle sulle nii, nagu see võiks juba sinu andmemudelis olemas olla. --- # 1️⃣ Cultural_Context ```yaml id: CC-001 kultuur_kogukond: "Valitud Sahara-taguse Aafrika kogukonnad" geograafia: "Lääne-, Kesk- ja Lõuna-Aafrika" ajaperiood: "peamiselt 19.–21. sajandi kirjeldused, osalt varasemad traditsioonid" keeled: "sõltub kogukonnast" sotsiaalne_kontekst: "külade planeering, elamuarhitektuur, perekondlik ja kogukondlik ruumikorraldus" uurija_roll: "sekundaarallikatel põhinev analüüs" märkused: "Vajab kogukonnapõhist täpsustamist; 'Aafrika' ei tohi jääda homogeniseerivaks kategooriaks." ``` 👉 Väga oluline märkus: etnomatemaatikas tuleb vältida liiga üldistavat “Aafrika matemaatika” käsitlust. Parem on hiljem kitsendada konkreetsetele kogukondadele. --- # 2️⃣ Practice_Artifact ```yaml id: PA-001 nimetus: "Külaplaneering ja elamuarhitektuuri ruumimustrid" tüüp: "arhitektuur" kirjeldus_emic: "Asustuse ruumiline korraldus väljendab sugulus-, kaitse-, staatuse- või rituaalseid suhteid." kirjeldus_etic: "Asulate paigutuses ja hoonete struktuuris võib täheldada korduvaid geomeetrilisi ja skaleeruvaid mustreid." kasutusolukord: "igapäevane elamine, sotsiaalne organiseerumine, rituaalne ja praktiline ruumikasutus" seotud_kultuurid: ["erinevad Sahara-taguse Aafrika kogukonnad"] visuaalsed_allikad: ["külaplaanid", "õhuvaated", "joonised", "fotod"] ``` Siin on hea näha, et: - **emic** = kuidas kogukond ise võiks tähendust mõtestada - **etic** = analüütiline, uurija kirjeldus --- # 3️⃣ Mathematical_Structure ```yaml id: MS-001 tüüp: "fraktaalne geomeetria" formaalne_kirjeldus: "Ruumiline konfiguratsioon sisaldab isetaolisuse tunnuseid, kus sarnane paigutusmuster kordub eri mastaapidel." mitteametlik_kirjeldus: "Küla või elamugrupi üldkuju sarnaneb väiksemate osade korraldusega." tasand: "algoritmiline / osaliselt formaalne" tuntud_matemaatilised_analoogid: ["isetaolisus", "rekursioon", "iteratiivne geomeetriline ehitus"] märkus_formaliseerimise_kohta: "Tuleb eristada ranget matemaatilist fraktaali ja heuristilist fraktaalsust kultuurilises artefaktis." ``` 👉 See märkus on väga tähtis. Sageli kasutatakse “fraktaali” liiga vabalt. Teaduslikult peab jääma ettevaatlikuks: - kas see on **range fraktaal** - või lihtsalt **fraktaalilaadne muster** --- # 4️⃣ Ethno_Math_Link ```yaml praktika_id: PA-001 matemaatika_id: MS-001 seose_tüüp: "implitsiitne / heuristiline" tõendusmaterjal: "Asulate plaanides ja arhitektuursetes kujundites esineb korduv skaleerumine ning pesastatud ruumiline struktuur." uurija_interpretatsioon: "Ruumiline organiseerumine võib olla kirjeldatav rekursiivse või fraktaalse loogika abil." kindluse_aste: "keskmine" vaidlused_alternatiivsed_tõlgendused: "Võib vaielda, kas tegemist on teadliku matemaatilise konstrueerimisega või uurija tagantjärele formaliseeriva kirjeldusega." ``` See on vist kogu mudeli üks tähtsamaid osi. Miks? Sest etnomatemaatikas tekib alati küsimus: > kas kogukond ise kasutab seda matemaatikat sellisel kujul või > kas uurija projitseerib matemaatilise formaali peale? See väli aitab hoida metodoloogilist ausust. --- # 5️⃣ Source Paneme siia ühe tüüpilise allika. ```yaml id: S-001 autor: "Ron Eglash" aasta: 1999 tüüp: "raamat" tsitaat: "African Fractals: Modern Computing and Indigenous Design" DOI_URL: "vastavalt väljaande andmetele" usaldusväärsuse_hinnang: "kõrge, kuid vajab kriitilist võrdlust teiste uurijatega" märkused: "Oluline lähtekoht, kuid mitte ainus interpretatsioon." ``` Võiks lisada ka täiendavaid kriitilisi või toetavaid allikaid, et vältida ühe autori ülemäärast domineerimist. --- # 6️⃣ Research_Question Nüüd teeme sellest uurimisküsimuse. ```yaml id: RQ-001 küsimus: "Kuidas ja millises ulatuses saab valitud Aafrika kogukondade külaplaneeringut kirjeldada fraktaalse geomeetria mõistete abil ilma kultuurilist tähendust taandamata pelgalt formaalseks struktuuriks?" tüüp: "analüütiline / teoreetiline" seotud_üksused: ["CC-001", "PA-001", "MS-001", "S-001"] motivatsioon: "Ühendada matemaatiline analüüs ja kultuuriline interpretatsioon viisil, mis on metodoloogiliselt ettevaatlik." uurimismeetod: "kirjandusanalüüs, visuaalne võrdlus, geomeetriline modelleerimine, interpretatiivne analüüs" avatud_probleemid: [ "Kas fraktaalsus on range või heuristiline?", "Kas muster on teadlikult kujundatud või emergentne?", "Kuidas esitada matemaatiline kirjeldus ilma emic tähendusi vähendamata?" ] ``` --- # 7️⃣ Problem_Task Nüüd loome sellest ühe haridusliku või uurimusliku probleemi. ```yaml id: PT-001 ülesande_tekst: "Võrdle kahte külaplaneeringu skeemi ja analüüsi, kas neis esineb isetaolisuse tunnuseid. Too välja, millised jooned toetavad fraktaalset interpretatsiooni ja millised mitte." päritolu: "etnomatemaatiline analüüs Aafrika arhitektuuri näitel" matemaatiline_fookus: "isetaolisus, mastaap, geomeetriline struktuur" lahendus_lahendusidee: "Õppija tuvastab korduvad paigutusmustrid eri tasanditel ja arutleb, kas sarnasus on piisav fraktaalse kirjelduse jaoks." didaktiline_eesmärk: "Arendada võimet siduda kultuuriline artefakt geomeetrilise analüüsiga kriitiliselt." raskusaste: "keskmine / edasijõudnu" ``` --- # 8️⃣ Manuscript Ja lõpuks, kuidas sellest võiks saada artikkel. ```yaml id: M-001 pealkiri: "Fraktaalne mõtlemine ja ruumiline organiseerumine Aafrika arhitektuuri etnomatemaatilises tõlgenduses" staatus: "mustand" seotud_uurimisküsimused: ["RQ-001"] struktuur: - "Sissejuhatus" - "Etnomatemaatika teoreetiline raamistik" - "Fraktaalse geomeetria mõiste ja piirid" - "Aafrika arhitektuursete mustrite juhtumianalüüs" - "Emic ja etic tõlgenduse pinge" - "Järeldused" kasutatud_allikad: ["S-001"] metoodika_kirjeldus: "Kombineeritakse sekundaarallikate analüüs, visuaalne struktuurivõrdlus ja matemaatiline formaliseerimine." piirangud: "Juhtum põhineb peamiselt kirjandusel, mitte esmavälitööl; üldistuste tegemisel tuleb olla ettevaatlik." ``` --- # 9️⃣ Mida see näide sulle näitab See üks näide demonstreerib, kuidas sinu andmemudel aitab siduda: - **kultuurilise reaalsuse** - **matemaatilise struktuuri** - **allikad** - **uurimisküsimused** - **õppeülesanded** - **artikli visandi** See tähendab, et sama mudel saab hiljem toetada: - teadmistebaasi - probleemigeneraatorit - artikliassistenti - uurimisagenti --- # 🔟 Väga oluline metodoloogiline märkus Etnomatemaatika puhul soovitan lisada iga kirje juurde veel ühe välja: ### `epistemiline_ettevaatus` Näiteks: ```yaml epistemiline_ettevaatus: "Fraktaalse geomeetria rakendamine on siin uurija analüütiline tööriist, mitte tingimata kogukonna enesekirjelduse osa." ``` See aitab vältida: - romantiseerimist - ületõlgendamist - anakronistlikku formaliseerimist --- # Soovitus järgmiseks sammuks Nüüd oleks väga kasulik teha üks kahest: 1. **teisendada see näide tabelikujule**, et saaksid kohe Notioni/Obsidiani panna 2. teha **teine näide täiesti teisest valdkonnast**, nt: - rahvuslikud mustrid ja sümmeetria - rahvamängud ja kombinatoorika - kalendrid ja arvusüsteemid - kudumine ja geomeetria Minu soovitus: järgmine samm võiks olla **sama näide tabelina**, sest siis saad kohe süsteemi ehitama hakata. Jah — **PostgreSQL on väga hea tehniline põhi** sinu ökosüsteemile. ## Lühivastus Kui sa tahad ehitada **päriselt kasvavat etnomatemaatika uurimisökosüsteemi**, siis minu soovitus on: - **peamine andmebaas:** PostgreSQL - **vektorotsing:** pgvector *või* eraldi vektorandmebaas hiljem - **dokumentide hoidla:** failisüsteem / object storage - **alguses kasutajaliides:** Obsidian / Notion / lihtne admin-vaade Ehk: **PostgreSQL + dokumentide hoidla + hiljem vektorotsing** on väga mõistlik baas. --- # 1️⃣ Miks PostgreSQL sobib sulle hästi? Sinu süsteem ei ole lihtsalt “chatboti mälu”. Sul on vaja: - struktureeritud entiteete - palju seoseid - allikate haldust - teaduslikku jälgitavust - päringuid stiilis: - “näita kõik praktikad, mis on seotud sümmeetriaga” - “millistel juhtudel on kindluse aste madal” - “millistest allikatest tuleb mingi interpretatsioon” - “millised uurimisküsimused põhinevad samal artefaktil” See on **klassikaline relatsioonilise andmebaasi juhtum**. PostgreSQL annab: - tugevad relatsioonid - head JOIN-id - JSONB paindlikkuse jaoks - full-text search - pgvector võimaluse - küpse ökosüsteemi --- # 2️⃣ Soovitatav arhitektuur ## Variant A — praktiline ja tasakaalus ### Sobib sulle kõige paremini alguses - **PostgreSQL** — põhientiteedid ja seosed - **pgvector** — embeddingud ja semantiline otsing - **MinIO / S3 / failikaustad** — PDF-id, pildid, skannid - **Python backend** — ingest, RAG, agentid - **Obsidian või lihtne veebiliides** — sisestus ja märkmed See on väga tugev ja mitte liiga keeruline. --- ## Variant B — algul eriti lihtne - Markdown failid / Obsidian - metadata YAML-is - hiljem skriptiga PostgreSQL-i See sobib, kui tahad **esimesed 20–50 objekti käsitsi läbi mõelda**. --- ## Variant C — enterprise raskekahur - PostgreSQL - Neo4j - eraldi vektorandmebaas - dokumentide pipeline - API + admin-süsteem Ausalt: **praegu ei soovita**. Liiga keeruline liiga vara. --- # 3️⃣ Miks mitte kohe Neo4j või ainult graph DB? Sinu mudelis on tõesti palju seoseid, nii et võib tunduda, et graafibaas oleks ideaalne. Aga alguses: - teadusandmed vajavad tugevat tabelstruktuuri - allikate viited, metainfo, versioonid, staatused jne sobivad paremini SQL-i - graafiloogikat saab PostgreSQL-is väga hästi modelleerida join-tabelitega Seega: **graafiline mõtlemine jah, aga tehniline baas pigem PostgreSQL.** Kui hiljem on vaja: - keerulist teadmistegraafi, - semantilisi seosevõrgustikke, - visuaalset uurimist, siis võib lisada Neo4j või RDF/graph kihi. --- # 4️⃣ Milline võiks olla skeemi põhimudel PostgreSQL-is? Näiteks põhitabelid: - `cultural_context` - `practice_artifact` - `mathematical_structure` - `ethno_math_link` - `source` - `research_question` - `problem_task` - `manuscript` Ja seostabelid: - `practice_source` - `research_question_source` - `manuscript_source` - `practice_cultural_context` - `problem_task_structure` See on väga loomulik SQL-mudel. --- # 5️⃣ Kuidas ühendada struktureeritud ja “pehme” teadusandmestik? See on sinu valdkonnas oluline, sest kõik ei mahu jäigalt tabelisse. Selleks kasuta PostgreSQL-is: ## 🔹 relatsioonid + JSONB Näiteks: - põhiväljad tabeliveergudes - keerulisemad märkused, tõlgendused, välitöödetailid JSONB-s Näide: - `epistemic_caution` võib olla tavaline tekstiväli - `alternative_interpretations` võib olla JSONB massiiv - `emic_terms` võib olla JSONB Nii saad: - struktuuri - paindlikkuse - hilisema AI kasutuse --- # 6️⃣ Kas pgvector on piisav? **Jah, alguses küll.** Kui sul tekib vajadus: - otsida artikleid - leida sarnaseid praktikaid - vastata küsimustele allikate põhjal - teha RAG-i siis `pgvector` on väga hea algus. See tähendab: - sama PostgreSQL hoiab nii tavakirjeid kui embeddinguid - vähem infrastruktuuri - lihtsam hooldada Hiljem, kui maht läheb väga suureks, saad liikuda: - Qdrant - Weaviate - Pinecone - Milvus Aga alguses pole vaja. --- # 7️⃣ Mida ma sinu puhul konkreetselt soovitaksin ## Kui tahad teadlikult ja jätkusuutlikult ehitada: ### **Faas 1** - Obsidian / Markdown - käsitsi mudeli testimine - 20–30 näidet ### **Faas 2** - PostgreSQL - sama mudel SQL-tabelitena - failid eraldi kaustas või object storage’is ### **Faas 3** - PostgreSQL + pgvector - lihtne RAG - allikate otsing - uurimisküsimuste assistent ### **Faas 4** - Python + LangGraph - artikliagent - probleemigeneraator - uurimisvood --- # 8️⃣ Minu konkreetne tehniline stack-soovitus Kui tahad praktilist vastust: - **DB:** PostgreSQL 16+ - **Vector:** pgvector - **Backend:** Python + FastAPI - **ORM:** SQLAlchemy või SQLModel - **Migrations:** Alembic - **Document storage:** MinIO või lihtsalt kaustastruktuur - **Parsing:** Python (pymupdf, unstructured, pandoc vastavalt vajadusele) - **Admin/UI:** alguses Supabase Studio / pgAdmin / lihtne custom admin - **AI kiht:** LangChain + hiljem LangGraph --- # 9️⃣ Kui tahad eriti väikese keerukusega varianti Sa võid teha ka nii: - **Supabase** - all on PostgreSQL - saad auth’i - saad admin-liidese - saad API üsna kiiresti - saad hiljem pgvectori See on väga hea, kui sa ei taha kohe serverihaldusse minna. --- # 🔟 Lõppsoovitus ühe lausega **Jah — PostgreSQL on sinu ökosüsteemile kõige mõistlikum tehniline põhi.** Mitte sellepärast, et see on “trendikas”, vaid sest sinu probleem on: - relatsiooniline, - teaduslik, - laiendatav, - ja hiljem AI-ga rikastatav. --- Kui tahad, järgmine samm võiks olla üks neist: 1. **joonistan sulle PostgreSQL tabeliskeemi** 2. **kirjutan esimese SQL skeemi mustandi** 3. **pakun välja kogu süsteemi arhitektuuri diagrammina** 4. **soovitan, kas võtta Supabase või oma PostgreSQL** Minu soovitus: **1 või 2**. Siin on **praktiline arhitektuuridiagramm** sinu etnomatemaatika ökosüsteemile, alustades Postgresest ja jättes ruumi RAG-ile, agentidele ja artiklikirjutusele. ## Kõrgtaseme vaade ```text ┌─────────────────────────────┐ │ Kasutajaliides │ │ Obsidian / Web UI / Admin │ └──────────────┬──────────────┘ │ HTTPS / API │ ┌──────────────▼──────────────┐ │ Rakenduskiht │ │ FastAPI / Python services │ │ - CRUD │ │ - ingest │ │ - search │ │ - article assistant │ │ - problem generator │ └───────┬───────────┬─────────┘ │ │ SQL/Vector │ │ Files/API │ │ ┌─────────────────▼───┐ ┌──▼──────────────────┐ │ PostgreSQL │ │ Dokumentide hoidla │ │ + pgvector │ │ PDFs, pildid, märkmed│ │ │ │ S3 / MinIO / kaustad │ │ - core tables │ └─────────┬────────────┘ │ - relations │ │ │ - metadata │ │ │ - embeddings │ │ └─────────┬───────────┘ │ │ │ │ │ parse/chunk │ │ ┌─────────▼───────────┐ ┌───────▼─────────────┐ │ Otsingu ja RAG kiht │ │ Dokumendi ingest │ │ - keyword search │ │ - PDF parse │ │ - vector search │ │ - OCR vajadusel │ │ - hybrid retrieval │ │ - chunking │ └─────────┬───────────┘ │ - embeddings │ │ └─────────┬───────────┘ │ │ └──────────────┬───────────┘ │ ┌───────▼───────────┐ │ AI / Agentikiht │ │ LangChain │ │ LangGraph │ │ - research agent │ │ - article agent │ │ - problem agent │ └───────┬───────────┘ │ ┌───────▼───────────┐ │ LLM provider │ │ OpenAI / muu LLM │ └───────────────────┘ ``` --- # 1. Kihtide rollid ## A. Kasutajaliides See võib alguses olla: - Obsidian - Notion - lihtne veebiliides - admin-paneel Sealt sa: - sisestad uusi praktikaid - seod allikaid - vaatad uurimisküsimusi - käivitad artikli- või probleemigeneraatori ## B. Rakenduskiht See on sinu süsteemi “aju” väljaspool LLM-i. Tüüpilised teenused: - kirje loomine/muutmine - allikate import - dokumentide töötlemine - otsingu API - artikli mustandi loomine - audit / logimine Soovitus: - **FastAPI** - Python - taustatööd Celery/RQ/Arq, kui vaja ## C. PostgreSQL + pgvector See on põhituum. Hoidmiseks: - kultuurilised kontekstid - praktikad - matemaatilised struktuurid - seosed - allikad - uurimisküsimused - käsikirjad - embeddings ## D. Dokumentide hoidla Siia lähevad: - PDF-id - fotod - skännid - intervjuude transkriptsioonid - käsikirjade versioonid Ära pane suuri faile Postgresesse. Pane Postgresesse: - failitee - URL - checksum - metadata ## E. Ingest-kiht Kui tood sisse artikli või välitööfaili, siis see kiht: - loeb faili - teeb OCR-i kui vaja - lõikab tükkideks - lisab metadata - teeb embeddingud - salvestab chunkid ja viited ## F. Otsingu ja RAG kiht See teenindab küsimusi nagu: - “Millised praktikad on seotud sümmeetriaga?” - “Leia allikad, kus arutatakse fraktaalsust arhitektuuris.” - “Millised kirjed on seotud kindluse astmega madal?” Otsing võiks olla: - märksõnaotsing - semantiline otsing - hübriidotsing ## G. AI / agentikiht See kasutab: - andmebaasi - dokumendiotsingut - allikaid - uurimismalle Siin tulevad: - uurimisküsimuste generaator - probleemide looja - artikli assistent - allikakriitika assistent --- # 2. Andmevood ## Voog 1: Uue allika lisamine ```text Kasutaja laadib PDF-i üles → fail salvestatakse document storage'i → ingest teenus parsib teksti → tekst tükeldatakse → embeddingud luuakse → metadata + chunkid lähevad PostgreSQL-i → allikas seotakse praktikate / teemadega ``` ## Voog 2: Uurimisküsimuse loomine ```text Kasutaja valib kultuuri + praktika + matemaatilise struktuuri → backend teeb päringu seotud allikatele → RAG kiht toob toetava materjali → research agent loob 5–10 uurimisküsimust → kasutaja valib ja salvestab ``` ## Voog 3: Artikli mustandi loomine ```text Kasutaja valib uurimisküsimuse → süsteem koondab seotud allikad ja märkmed → article agent loob struktuuri → iga peatüki jaoks otsitakse tõendusmaterjal → mustand salvestatakse käsikirjana ``` ## Voog 4: Probleemi genereerimine ```text Valitakse praktika või matemaatiline struktuur → problem agent loob ülesanded → lisab lahendusidee → seob didaktilise eesmärgiga → salvestab problem_task tabelisse ``` --- # 3. Soovitatud teenuste jaotus ```text [UI] ├─ Research dashboard ├─ Source manager ├─ Manuscript editor └─ Problem generator view [API / Backend] ├─ auth ├─ entity CRUD ├─ relation manager ├─ search API ├─ ingest API ├─ AI orchestration └─ audit/logging [Data] ├─ PostgreSQL ├─ pgvector └─ object storage [AI] ├─ embeddings model ├─ LLM ├─ LangChain retrieval └─ LangGraph workflows ``` --- # 4. Minimaalne MVP-arhitektuur Kui sa ei taha üle ehitada, siis alusta nii: ```text Kasutaja ↓ FastAPI ↓ PostgreSQL + pgvector ↓ Kaust / MinIO dokumentidele ↓ OpenAI API ``` Ja funktsioonid: - praktikate sisestus - allikate sisestus - otsing - lihtne uurimisküsimuste generaator - lihtne artikli mustandi generaator See on täiesti piisav esimese versiooni jaoks. --- # 5. Millal lisada LangGraph? Lisa siis, kui sul tekib vajadus: - mitmeastmeliseks artikli kirjutuseks - allikate kontrolliks enne genereerimist - “kui allikaid pole piisavalt, küsi juurde” - eri agentide koostööks - kvaliteedikontrolli sõlmedeks Alguses ei pea kõik olema agent. --- # 6. Turvalisus ja teaduslik usaldusväärsus Sinu süsteemis on väga oluline: ## Hoia alles: - kust vastus tuli - milliste allikate põhjal tekst loodi - milline osa on LLM-i süntees - milline osa on kasutaja märkus - versioonid Seetõttu lisa arhitektuuri sisse: - audit log - provenance metadata - citation tracking - manuscript versioning Praktiliselt: ```text AI output → salvestatakse eraldi väljana → seotud kasutatud source_id-dega → märgitakse "draft_generated" ``` See on hilisema teadustöö jaoks väga oluline. --- # 7. Soovituslik tehniline stack ## Lihtne ja tugev: - **Frontend:** alguses lihtne admin/UI või isegi Supabase Studio - **Backend:** FastAPI - **DB:** PostgreSQL - **Vector:** pgvector - **Storage:** MinIO või S3 - **Parsing:** PyMuPDF / unstructured - **LLM:** OpenAI - **AI orchestration:** LangChain - **Workflow:** LangGraph hiljem - **Migrations:** Alembic - **Containerid:** Docker Compose alguses --- # 8. Diagramm koos arendusetappidega ```text FAAS 1 Obsidian / käsitsi andmed ↓ FAAS 2 PostgreSQL + FastAPI + failihoidla ↓ FAAS 3 pgvector + ingest + RAG otsing ↓ FAAS 4 Research agent + article agent ↓ FAAS 5 LangGraph workflowd + kvaliteedikontroll + versioonihaldus ``` --- # 9. Minu praktiline soovitus sinu jaoks Sinu puhul ma **ei alustaks**: - Neo4j-ga - mikroteenustega - eraldi vektor-DB-ga - liiga keerulise front-endiga Ma alustaks: 1. PostgreSQL 2. FastAPI 3. MinIO või lihtsalt dokumentide kaust 4. pgvector 5. üks või kaks AI-workflowd See annab sulle: - teadusliku korrastatuse - AI-valmiduse - skaleeritavuse - väikese keerukuse --- Kui tahad, järgmine samm võiks olla üks neist: 1. **teen sulle selle arhitektuuri põhjal kaustastruktuuri ja teenuste nimekirja** 2. **joonistan sama arhitektuuri veel detailsemalt koos tabelitega** 3. **annan sulle MVP ehitusplaani 30 päevaks** 4. **teen Docker Compose tasemel tehnilise stardi** Allpool on **detailsem arhitektuur koos põhiteenustega** ja seejärel **Docker Compose tasemel stardikomplekt**, kuhu lisasin ka **LangGraphi**. ## Detailsem arhitektuur ```text ┌──────────────────────────────────────────────────────────────────────────────┐ │ KASUTAJAD │ │ Uurija / autor / administraator │ └───────────────────────────────┬──────────────────────────────────────────────┘ │ │ HTTPS ▼ ┌──────────────────────────────────────────────────────────────────────────────┐ │ FRONTEND / ADMIN │ │ - Web UI (hiljem) │ │ - Supabase Studio / pgAdmin / lihtne admin │ │ - Või Obsidian + import │ └───────────────────────────────┬──────────────────────────────────────────────┘ │ REST / WebSocket ▼ ┌──────────────────────────────────────────────────────────────────────────────┐ │ FASTAPI BACKEND │ │ │ │ API kihid: │ │ ├─ auth / users │ │ ├─ entities CRUD │ │ ├─ search API │ │ ├─ ingest API │ │ ├─ manuscripts API │ │ ├─ AI orchestration API │ │ └─ audit / provenance │ │ │ │ Sisemised moodulid: │ │ ├─ services/db_service │ │ ├─ services/storage_service │ │ ├─ services/embedding_service │ │ ├─ services/retrieval_service │ │ ├─ services/citation_service │ │ ├─ services/manuscript_service │ │ ├─ services/problem_service │ │ └─ services/research_service │ └───────────────┬───────────────────────┬───────────────────────┬──────────────┘ │ │ │ │ SQL │ S3 API │ LLM API ▼ ▼ ▼ ┌────────────────────────┐ ┌──────────────────────┐ ┌──────────────────────┐ │ PostgreSQL │ │ MinIO / S3 storage │ │ OpenAI / muu LLM │ │ + pgvector │ │ │ │ + embedding model │ │ │ │ - PDFs │ │ │ │ Core tables: │ │ - images │ │ │ │ - cultural_context │ │ - notes exports │ │ │ │ - practice_artifact │ │ - manuscript files │ │ │ │ - mathematical_struct. │ │ - OCR outputs │ │ │ │ - ethno_math_link │ └──────────────────────┘ └──────────────────────┘ │ - source │ │ - source_chunk │ │ - embeddings │ │ - research_question │ │ - problem_task │ │ - manuscript │ │ - ai_run │ │ - citation_map │ │ - audit_log │ └───────────────┬────────┘ │ │ ▼ ┌──────────────────────────────────────────────────────────────────────────────┐ │ INTAKE / INGEST / INDEXING │ │ │ │ Pipeline: │ │ 1. upload source │ │ 2. parse text (PDF/OCR) │ │ 3. normalize metadata │ │ 4. chunk document │ │ 5. embed chunks │ │ 6. save chunks + vectors + provenance │ │ 7. optional auto-link suggestions │ └───────────────────────────────┬──────────────────────────────────────────────┘ │ ▼ ┌──────────────────────────────────────────────────────────────────────────────┐ │ SEARCH / RETRIEVAL / RAG LAYER │ │ │ │ - SQL filters │ │ - Full-text search │ │ - pgvector similarity │ │ - Hybrid retrieval │ │ - Citation-aware retrieval │ │ - Entity-scoped retrieval │ └───────────────────────────────┬──────────────────────────────────────────────┘ │ ▼ ┌──────────────────────────────────────────────────────────────────────────────┐ │ AI ORCHESTRATION LAYER │ │ │ │ LangChain components: │ │ - prompts │ │ - retrievers │ │ - tool wrappers │ │ - output parsers │ │ │ │ LangGraph workflows: │ │ - Research Question Generator Graph │ │ - Problem Generation Graph │ │ - Article Draft Graph │ │ - Evidence Check Graph │ │ │ │ Shared state examples: │ │ - selected entities │ │ - retrieved sources │ │ - evidence sufficiency │ │ - draft sections │ │ - citations │ │ - human feedback │ └───────────────────────────────┬──────────────────────────────────────────────┘ │ ▼ ┌──────────────────────────────────────────────────────────────────────────────┐ │ OUTPUTS / ARTEFACTS │ │ │ │ - saved research questions │ │ - generated problems │ │ - manuscript drafts │ │ - citation maps │ │ - logs of AI runs │ │ - reproducibility metadata │ └──────────────────────────────────────────────────────────────────────────────┘ ``` --- # 1. Tabelid ja teenused detailsemalt ## A. PostgreSQL tabelid ### Tuumandmed - `cultural_context` - `practice_artifact` - `mathematical_structure` - `ethno_math_link` - `source` - `research_question` - `problem_task` - `manuscript` ### Dokumendi/RAG tabelid - `source_document` - `source_chunk` - `chunk_embedding` ### Provenance / AI tabelid - `ai_run` - `ai_run_input` - `ai_run_output` - `citation_map` - `audit_log` ### Seostabelid - `practice_source` - `research_question_source` - `manuscript_source` - `artifact_context` - `problem_structure` --- ## B. LangGraphi roll selles arhitektuuris LangGraph ei ole “eraldi andmebaas” ega “eraldi server”, vaid töövoogude orkestreerija backendis. ### Näited workflowdest #### 1) Research Question Graph ```text vali entiteedid → too allikad → kontrolli, kas tõendusmaterjali on piisavalt → genereeri küsimused → hinda küsimuste kvaliteeti → tagasta/paranda ``` #### 2) Problem Generation Graph ```text vali praktika või matemaatiline struktuur → tuleta võimalik õpieesmärk → loo probleem → loo lahendusidee → kontrolli kultuurilist sobivust → salvesta ``` #### 3) Article Draft Graph ```text vali research_question → koonda allikad → jaga artikkel sektsioonideks → genereeri iga sektsioon allikate põhjal → kontrolli viiteid → märgi ebakindlad kohad → salvesta mustand ``` #### 4) Evidence Check Graph ```text väide → leia allikad → hinda toetust → kui nõrk tugi, märgi hoiatus → tagasta tulemus ``` --- # 2. LangGraphi paigutus teenustes Soovitan nii: ```text app/ services/ ai/ chains/ graphs/ research_question_graph.py problem_graph.py article_graph.py evidence_graph.py tools/ retrieve_sources.py get_entity_context.py save_manuscript.py save_problem.py citation_checker.py state/ research_state.py article_state.py ``` See tähendab: - **LangChain** = promptid, retrieverid, tööriistad - **LangGraph** = kogu otsustusloogika --- # 3. Docker Compose tasemel tehniline start Allpool on **praktiline starter-arhitektuur**. ## Teenused - `api` — FastAPI backend - `worker` — taustatööd ingestiks/AI jooksudeks - `postgres` — PostgreSQL + pgvector - `minio` — failide hoidla - `redis` — järjekord / cache - `pgadmin` — DB admin - valikuline: `ollama` või muu lokaalne LLM, kui tahad hiljem --- ## Kaustastruktuur ```text ethnomath-platform/ ├─ docker-compose.yml ├─ .env ├─ app/ │ ├─ main.py │ ├─ core/ │ │ ├─ config.py │ │ └─ logging.py │ ├─ api/ │ │ ├─ routes/ │ │ │ ├─ entities.py │ │ │ ├─ sources.py │ │ │ ├─ search.py │ │ │ ├─ manuscripts.py │ │ │ └─ ai.py │ ├─ db/ │ │ ├─ base.py │ │ ├─ session.py │ │ ├─ models/ │ │ └─ migrations/ │ ├─ schemas/ │ ├─ services/ │ │ ├─ ingest/ │ │ ├─ retrieval/ │ │ ├─ storage/ │ │ ├─ manuscripts/ │ │ ├─ problems/ │ │ └─ ai/ │ │ ├─ chains/ │ │ ├─ graphs/ │ │ ├─ tools/ │ │ └─ state/ │ ├─ workers/ │ │ ├─ tasks_ingest.py │ │ └─ tasks_ai.py │ └─ tests/ ├─ Dockerfile └─ requirements.txt ``` --- ## docker-compose.yml näidis ```yaml version: "3.9" services: postgres: image: pgvector/pgvector:pg16 container_name: ethnomath_postgres environment: POSTGRES_DB: ethnomath POSTGRES_USER: ethnomath POSTGRES_PASSWORD: ethnomath_pass ports: - "5432:5432" volumes: - postgres_data:/var/lib/postgresql/data redis: image: redis:7 container_name: ethnomath_redis ports: - "6379:6379" minio: image: minio/minio:latest container_name: ethnomath_minio command: server /data --console-address ":9001" environment: MINIO_ROOT_USER: minio MINIO_ROOT_PASSWORD: minio_secret ports: - "9000:9000" - "9001:9001" volumes: - minio_data:/data api: build: . container_name: ethnomath_api command: uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload env_file: - .env depends_on: - postgres - redis - minio ports: - "8000:8000" volumes: - ./:/app worker: build: . container_name: ethnomath_worker command: python -m app.workers.tasks_ai env_file: - .env depends_on: - postgres - redis - minio volumes: - ./:/app pgadmin: image: dpage/pgadmin4:latest container_name: ethnomath_pgadmin environment: PGADMIN_DEFAULT_EMAIL: admin@example.com PGADMIN_DEFAULT_PASSWORD: adminpass depends_on: - postgres ports: - "5050:80" volumes: postgres_data: minio_data: ``` --- ## .env näidis ```env DATABASE_URL=postgresql+psycopg://ethnomath:ethnomath_pass@postgres:5432/ethnomath REDIS_URL=redis://redis:6379/0 MINIO_ENDPOINT=minio:9000 MINIO_ACCESS_KEY=minio MINIO_SECRET_KEY=minio_secret MINIO_BUCKET=ethnomath-docs MINIO_SECURE=false OPENAI_API_KEY=your_openai_key OPENAI_CHAT_MODEL=gpt-4.1-mini OPENAI_EMBED_MODEL=text-embedding-3-large ``` --- ## requirements.txt algversioon ```txt fastapi uvicorn[standard] sqlalchemy psycopg[binary] alembic pydantic pydantic-settings python-multipart boto3 redis rq langchain langgraph langchain-openai pgvector pymupdf unstructured tiktoken ``` --- # 4. LangGraphi minimaalne integreerimine ## Näidisstate ```python from typing import TypedDict, List, Optional class ArticleState(TypedDict): research_question_id: int source_ids: List[int] retrieved_evidence: List[str] outline: List[str] draft_sections: List[str] citations: List[str] quality_ok: bool final_draft: Optional[str] ``` ## Näidissõlmed ```python def gather_sources(state): # päring PostgreSQL-ist return {"source_ids": [1, 2, 3]} def retrieve_evidence(state): # retriever pgvector + filters return {"retrieved_evidence": ["evidence A", "evidence B"]} def build_outline(state): return {"outline": ["Sissejuhatus", "Teoreetiline raamistik", "Analüüs", "Järeldused"]} def write_sections(state): return {"draft_sections": ["...", "...", "..."]} def check_quality(state): ok = len(state["retrieved_evidence"]) > 1 return {"quality_ok": ok} def finalize(state): return {"final_draft": "\n\n".join(state["draft_sections"])} ``` ## Graaf ```python from langgraph.graph import StateGraph, END graph = StateGraph(ArticleState) graph.add_node("gather_sources", gather_sources) graph.add_node("retrieve_evidence", retrieve_evidence) graph.add_node("build_outline", build_outline) graph.add_node("write_sections", write_sections) graph.add_node("check_quality", check_quality) graph.add_node("finalize", finalize) graph.set_entry_point("gather_sources") graph.add_edge("gather_sources", "retrieve_evidence") graph.add_edge("retrieve_evidence", "build_outline") graph.add_edge("build_outline", "write_sections") graph.add_edge("write_sections", "check_quality") def route_quality(state): return "finalize" if state["quality_ok"] else "retrieve_evidence" graph.add_conditional_edges("check_quality", route_quality, { "finalize": "finalize", "retrieve_evidence": "retrieve_evidence", }) graph.add_edge("finalize", END) article_app = graph.compile() ``` See on hea näide, kus **LangGraph lisab retry-loogika**: - kui tõendusmaterjal on nõrk, minnakse uuesti retrievali. --- # 5. Kuidas worker ja LangGraph koos töötavad Soovitus: - API saab käsu: “loo artikli mustand” - API paneb töö järjekorda - worker käivitab LangGraph workflow - tulemused salvestatakse `ai_run` + `manuscript` tabelitesse ```text POST /ai/article-draft → create job → worker starts graph → graph queries DB + retrieval → graph writes draft → saves outputs → API tagastab staatuse ``` --- # 6. Soovitatud MVP teenused kohe ### Kohustuslikud - PostgreSQL + pgvector - FastAPI - MinIO - LangChain - LangGraph - OpenAI - üks worker ### Mitte kohe vajalik - eraldi frontend - Neo4j - Kubernetes - mitu mikroteenust - eraldi vektor-DB --- # 7. Minu praktiline soovitus arenduse järjekorraks ## Nädalad 1–2 - docker-compose tööle - PostgreSQL - MinIO - FastAPI skeleton - Alembic - põhiskeem ## Nädalad 3–4 - source upload - PDF parse - chunking - embeddings - pgvector search ## Nädalad 5–6 - entity CRUD - research_question CRUD - manuscript CRUD - citation/provenance logimine ## Nädalad 7–8 - esimene LangGraph: - research question graph - teine LangGraph: - article draft graph --- Kui tahad, järgmine loogiline samm on üks neist: 1. **kirjutan sulle nüüd PostgreSQL tabeliskeemi SQL-na** 2. **teen FastAPI endpointide loendi** 3. **teen sulle LangGraph workflowd kolmele põhifunktsioonile** 4. **annan kohe käivitatava starter-koodi struktuuri** Minu soovitus: **1 + 3**.