Skip to content

Latest commit

 

History

386 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Dynamic Learning Model

PyPI version Python Version License: MIT

Overview

The Dynamic Learning Model (DLM) is a hybrid, domain-specific AI system designed to learn, adapt, and respond intelligently to user queries. It combines natural language understanding with structured reasoning, continually improving as it is trained.

Important Architecture Note: DLM acts as a backend engine, not a standalone chatbot. It processes queries and returns the answer, the thought process (if requested), and other structured information in a Python dictionary. It is the responsibility of the implementor to build the application loop, handle these states, interact with the user, and pass training data back to the bot via the teach_memory() and teach_compute() methods.

Key capabilities include:

  • FAQ Handling - Learns and responds to frequently asked questions based on the knowledge it has been trained on.
  • Advanced Math & Chain-of-Thought (CoT) - Performs clear, step-by-step logic to solve numerical arithmetic, unit conversions, and advanced symbolic math (algebra, calculus, integrals) using SymPy and LangGraph.
  • Custom Knowledge Integration - DLM is fully extensible. You can initialize it with an empty SQL database and train it with your domain-specific knowledge.
  • Local Privacy - DLM runs 100% locally utilizing the Ollama inference engine, keeping all your data secure.

Table of Contents

Prerequisites & Installation

CRITICAL PREREQUISITE: This package utilizes local LLM inference to ensure complete data privacy and requires an external engine to run. Before installing DLM, you must install the Ollama engine for your operating system from ollama.com.

DLM will automatically handle booting the background server and downloading the required neural network models (llama3.2 and nomic-embed-text) upon its first run.

Once Ollama is installed on your machine, install DLM via pip:

pip install dynamic-learning-model

Requirements: Python 3.12.0 or higher is required. SpaCy's en_core_web_lg vector model will automatically download itself on first launch if not found.

Initialization & Parameters

The constructor requires passing in up to two parameters:

  1. Bot Mode
    • "train_memory" - Enables teaching capabilities for factual questions. The engine will request training when it encounters unknown queries.
    • "train_compute" - Enables teaching capabilities for the math engine. It allows you to correct the symbolic Python/SymPy formulas generated by the LLM.
    • "apply" - Deployment mode. The bot seamlessly hybrid-routes between its compute and memory models using auto-routing but will not prompt for database updates.
  2. Database Path (Optional)
    • Absolute path to your SQLite database. This is optional; DLM automatically creates and uses ~/.dlm/dlm_database.db and ~/.dlm/dlm_compute_model.db in the user's home directory if not specified.

ask() method parameters:

  • query - The question you want DLM to answer (passed as a string).
  • display_thought - Whether or not you want DLM to return its internal Chain-of-Thought (passed as a boolean).

Response Architecture

Calling bot.ask(query, display_thought=True) does not print directly to the console. It returns a structured Python dictionary that the implementor must handle.

Expected Dictionary Keys:

  • status (str): The output state of the interaction (resolved, needs_teaching, confirm_memory, confirm_compute, or refused).
  • thought (str): The step-by-step thought process of the DLM bot. Empty if display_thought is False.
  • answer: (str): The final formulated answer, computation result, or fallback prompt.
  • context: (dict): Metadata needed for database insertion (e.g., special_stripped_query, generalized_query, var_num).

Implementation Examples

Below are the standard application loops an implementor should use to handle the states returned by DLM.

1. Training Factual Memory ("train_memory" mode)

from dlm import DLM

# Initialize in memory training mode
bot = DLM("train_memory") 

while True:
    query = input("\nAsk a factual question: ")
    response = bot.ask(query, display_thought=True)

    if response["thought"]:
        print(response["thought"])

    # State Routing
    if response["status"] == "needs_teaching":
        answer = input(f"\nI don't know the answer. Please teach me: ")
        category = input("What category does that answer belong to? ")
        
        # Pass the extracted context to the memory training API
        bot.teach_memory(response["context"]["special_stripped_query"], answer, category)
        print("Knowledge base updated!")

    elif response["status"] == "confirm_memory":
        print(f"\n{response['answer']}")
        verify = input("Is my answer correct? Press enter to accept, or type the correct answer: ")
        
        if verify != "":
            category = input("What category does that new answer belong to? ")
            bot.teach_memory(response["context"]["special_stripped_query"], verify, category)
            print("Knowledge base updated with correction!")

    elif response["status"] in ["resolved", "refused"]:
        print(f"\n{response['answer']}")

2. Training the Math Engine ("train_compute" mode)

from dlm import DLM

# Initialize in compute training mode
bot = DLM("train_compute") 

while True:
    query = input("\nEnter a math or calculus problem: ")
    response = bot.ask(query, display_thought=True)

    if response["thought"]:
        print(response["thought"])

    if response["status"] in ["confirm_compute", "needs_teaching"]:
        verify = input("\nIs this calculation correct? (Y/N): ")
        
        if verify.lower() == 'n':
            print(f"Extracted Variables: {response['context']['var_num']}")
            corrected = input("Enter the correct Python/SymPy formula using [x] variables (e.g., sp.diff([x0]*x, x)): ")
            
            # Pass the extracted context and new formula to the compute training API
            bot.teach_compute(response["context"]["generalized_query"], response["context"]["var_num"], corrected)
            print("Compute database permanently updated!")
            
    elif response["status"] in ["resolved", "refused"]:
        print(f"\n{response['answer']}")

3. Deployment ("apply" mode)

from dlm import DLM

# Initialize in deployment mode
bot = DLM("apply")

while True:
    query = input("\nAsk anything (facts or math): ")
    response = bot.ask(query, display_thought=True)

    if response["thought"]:
        print(response["thought"])

    # In apply mode, the system auto-routes and does NOT ask the user for training data
    print(f"\n{response['answer']}")

4. Complete Implementation Example

from DLM import DLM

def test_dlm_architecture():
    """Example Implementation."""

    print("\n\n=========================================")
    print("TRAIN_MEMORY TEST")
    print("=========================================\n\n")

    dlm_train_mem = DLM(mode="train_memory", db_filename="college_knowledge.db")

    query = input("MEMORY TRAINING: ")
    print(f"\n[QUERY]: {query}")
    result = dlm_train_mem.ask(query, display_thought=True)
    print("\n\nStatus: ", result['status'], "\n\nAnswer: ", result['answer'], "\n\nThought: ", result['thought'], "\n\nContext: ", result['context'], "\n\n")

    print("\n\n=========================================")
    print("TRAIN_COMPUTE TEST")
    print("=========================================\n\n")

    dlm_train_comp = DLM(mode="train_compute", db_filename="college_knowledge.db")

    query = input("COMPUTE TRAINING: ")
    print(f"[QUERY]: {query}")
    result = dlm_train_comp.ask(query, display_thought=True)
    print("\n\nStatus: ", result['status'], "\n\nAnswer: ", result['answer'], "\n\nThought: ", result['thought'], "\n\nContext: ", result['context'], "\n\n")

    print("\n\n=========================================")
    print("APPLY (PRODUCTION) TEST")
    print("=========================================\n\n")

    dlm_apply = DLM(mode="apply", db_filename="college_knowledge.db")

    query = input("APPLY MODE: ")
    print(f"[QUERY]: {query}")
    result = dlm_apply.ask(query, display_thought=True)
    print("\n\nStatus: ", result['status'], "\n\nAnswer: ", result['answer'], "\n\nThought: ", result['thought'], "\n\nContext: ", result['context'], "\n\n")

def implementor_testing():
    print("========================================= IMPLEMENTOR INTERFACE =========================================")
    mode = input("\n\nMode (A = Apply, M = Train_Memory, C = Train_Compute): ").strip().lower()

    if mode == "a":
        mode = "apply"
    elif mode == "m":
        mode = "train_memory"
    elif mode == "c":
        mode = "train_compute"

    dlm_bot = DLM(mode, "college_knowledge.db")

    while True:
        q = input("ASK: ")
        response = dlm_bot.ask(q, True)

        match response["status"].lower():
            case "resolved":
                print("\n\nTHOUGHT: ", response['thought'], "\n\nANSWER: ", response['answer'])
            case "refused":
                print("\n\nANSWER: ", response['answer'])
            case "confirm_memory":
                print("\n\nTHOUGHT: ", response['thought'])
                print("\n\nPROPOSED ANSWER: ", response['answer'])
                
                feedback = input("\nIs this the right answer? (Y/N): ").strip().upper()
                if feedback == 'N':
                    print("\n[MEMORY CORRECTION MODE]")
                    correct_ans = input("E\nnter the correct answer: ").strip()
                    category = input("\nEnter the category (e.g., generic, yesno, definition): ").strip()
                    
                    # Grab the cleanly stripped query we saved in the context dict
                    query_to_teach = response['context'].get('special_stripped_query')
                    
                    success = dlm_bot.teach_memory(query_to_teach, correct_ans, category)
                    if success:
                        print("\n[SYSTEM LOG]: Memory successfully updated.")
                    else:
                        print("\n[SYSTEM LOG]: Failed to update memory.")
                        
            case "confirm_compute":
                print("\n\nTHOUGHT: ", response['thought'])
                print(f"\n\nFORMULA USED: {response['context'].get('formula')}")
                print(f"\nCALCULATED ANSWER: {response['context'].get('answer')}")
                
                feedback = input("\nIs this calculation correct? (Y/N): ").strip().upper()
                if feedback == 'N':
                    print("\n[COMPUTE CORRECTION MODE]")
                    
                    # Pull variables from context to show the user what [x] maps to what number
                    var_num = response['context'].get('var_num', [])
                    mapping = ", ".join(f"[x{i}] = {v}" for i, v in enumerate(var_num))
                    print(f"Extracted Variables: {mapping}")
                    
                    corrected_template = input("Enter the correct Python formula using [x] variables (e.g., [x0] * 9/5 + 32): ").strip()
                    generalized_query = response['context'].get('generalized_query')
                    
                    # Send it back to the compute engine to overwrite the database and recalculate
                    new_state = dlm_bot.teach_compute(generalized_query, var_num, corrected_template)
                    
                    print(f"\nCorrected Final Answer: {new_state.get('answer')}")
                    print("[SYSTEM LOG]: Compute database permanently updated with your correction.")
                    
            case "needs_teaching":
                print("\n\nTHOUGHT: ", response['thought'])
                print("\n[SYSTEM LOG]: The bot does not know the answer to this query.")
                
                # Defaulting to memory teaching when stumped
                correct_ans = input("Enter the expected answer: ").strip()
                category = input("Enter the category (e.g., generic, location, deadline): ").strip()
                
                query_to_teach = response['context'].get('special_stripped_query')
                
                success = dlm_bot.teach_memory(query_to_teach, correct_ans, category)
                if success:
                    print("\n[SYSTEM LOG]: New knowledge successfully added to memory.")
                else:
                    print("\n[SYSTEM LOG]: Failed to update memory.")

if __name__ == "__main__":
    # test_dlm_architecture()
    implementor_testing()

Training Guidelines

DLM's natural language generation relies on categorizing knowledge. When teaching the bot via bot.teach_memory(), the implementor must provide clean, raw facts and assign them to a specific category.

DLM wraps these raw facts in dynamic templates. If you include conversational filler in your training data (e.g., training it with "The deadline is December 15th" instead of just "December 15th"), the bot will output grammatically awkward sentences.

Expected Formats by Category:

Category What to Train (Expected Format) Example Training Input Example Bot Output
yesno Start directly with "Yes" or "No", followed by the reason. Yes, because of Rayleigh scattering. "Absolutely, yes, because of Rayleigh scattering."
process A list of steps separated strictly by semicolons. Get bread; add peanut butter; eat it. "First, get bread. Next, add peanut butter. Lastly, eat it."
definition The raw, objective definition of the subject. The process plants use to make food. "By definition, it is the process plants use to make food."
deadline The specific date, time, or timeframe. December 15th. "The deadline is December 15th."
location A place, building, or directional instruction. At the center of campus. "You can find it at the center of campus."
eligibility The specific conditions or prerequisites required. you have a GPA over 3.5. "You qualify only if you have a GPA over 3.5."

Important Notices

  1. Training data quality matters. DLM's accuracy in learning modes depends entirely on the consistency and clarity of the question/answer pairs it's trained with. Inconsistent category labeling can produce corrupted responses later.
  2. Database files are local and untracked. DLM stores all trained knowledge in local SQLite files (dlm_database.db and dlm_compute_model.db). Back up these files regularly - there is no built-in cloud sync or recovery mechanism.
  3. Model loading behavior. Underlying NLP and vector models (en_core_web_lg, llama3.2) are lazy-loaded and shared across instances. The first call in a session may take longer due to model loading into RAM; subsequent calls may be significantly faster (depending on your computer's specs).
  4. SymPy Compute Integration. The compute engine utilizes the sympy library within a localized eval() environment to perform calculus, integration, and algebraic solving. Ensure corrected formulas in train_compute mode utilize standard sp. prefixes (e.g., sp.solve(), sp.diff()).

License

This project is licensed under the MIT License - see the LICENSE file for details.

Disclaimer

Dynamic Learning Model (DLM) is provided "as-is", without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose, and noninfringement. In no event shall the author be liable for any claim, damages, or other liability arising from the use of this software.

DLM may produce inaccurate, incomplete, or unexpected responses, particularly for ambiguous queries or insufficiently trained knowledge bases. Do not rely on DLM's output for decisions involving safety, legal, medical, or financial consequences without independent verification.

All data provided to DLM (training queries, database contents) is processed and stored locally on the host machine. DLM does not transmit user data externally, except for any underlying third-party model downloads required on the first run, which are subject to those providers' own terms.

About

The Dynamic Learning Model (DLM) is a hybrid AI system designed to learn, adapt, and intelligently respond to user queries. It combines natural language understanding with structured reasoning, continually improving as it is trained.

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages