Introducing Mindwave: Building AI-Powered Features in Laravel Made Easy

What is Mindwave?

Mindwave is a Laravel package that lets you easily build AI-powered Chatbots, Agents, and Document (Q&A) functionality into your own Laravel projects.

How is it architected?

Manager Pattern for configurable components

The major parts of the package use the Manager pattern. Specifically, the LLM, Embeddings, and Vectorstore components can be configured with config files. Each component has several implementations (drivers) similarly to how the database configuration in Laravel works.

If you want to use the OpenAI Complete model (text-davinci-003) instead of the Chat model (gpt-3.5_turbo), you can simply change the configuration, and you're done.

Similarly, if you want to use Weaviate or Milvus as your vectorstore instead of Pinecone, you are free to do so. All the drivers implement a common interface, allowing you to swap them out seamlessly.

You can also provide your own driver by extending the package and writing your own implementation.

<?php

namespace Mindwave\Mindwave\Contracts;

interface Vectorstore
{
    public function fetchById(string $id): ?VectorStoreEntry;
    public function fetchByIds(array $ids): array;
    public function insertVector(VectorStoreEntry $entry): void;
    public function upsertVector(VectorStoreEntry $entry): void;
    public function insertVectors(array $entries): void;
    public function upsertVectors(array $entries): void;
    public function similaritySearchByVector(EmbeddingVector $embedding, int $count = 5): array;
}

Here is how the VectorstoreManager is implemented:

<?php

namespace Mindwave\Mindwave\Vectorstore;

class VectorstoreManager extends Manager
{
    public function getDefaultDriver()
    {
        return $this->config->get('mindwave-vectorstore.default');
    }

    public function createFileDriver(): Vectorstore
    {
        return new File(
            path: $this->config->get('mindwave-vectorstore.vectorstores.file.path')
        );
    }

    // etc...
}

And you would configure this with the mindwave-vectorstore.php config file like this:

<?php

return [
    'default' => env('MINDWAVE_VECTORSTORE', 'pinecone'),
    'vectorstores' => [
        'array' => [
            // Has no configuration, used for testing
        ],

        'file' => [
            'path' => env('MINDWAVE_VECTORSTORE_PATH', storage_path('mindwave/vectorstore.json')),
        ],

        // etc...
    ],
];

The same concept applies to the LLM (Large Language Model). If you

had a custom LLM inference API that your company has created, you can simply extend the LLMManager like this in your AppServiceProvider:

<?php

namespace App\Providers;

use App\LLM\CustomLLM;
use Illuminate\Support\ServiceProvider;
use Mindwave\Mindwave\Facades\LLM;

class AppServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        LLM::extend("custom-llm", function($app) {
            return new CustomLLM(env("CUSTOM_LLM_API_KEY"));
        });
    }
}

And have your LLM implementation implement the interface like this (just an example):

<?php

namespace Mindwave\Mindwave\LLM\Drivers;

use Illuminate\Support\Facades\Http;
use Mindwave\Mindwave\Contracts\LLM;

class CustomLLM implements LLM
{
    protected string $apiKey;

    public function __construct(string $apiKey)
    {
        $this->apiKey = $apiKey;
    }

    public function predict(string $prompt): ?string
    {
        return Http::withToken($this->apiKey)
            ->get("https://my-custom-llm.com/predict", [
                "prompt" => $prompt,
            ])
            ->json("response.text");
    }
}

What is the goal?

Laravel Lambo ¯\_(ツ)_/¯

Nah, just kidding.

The goal is to build a solid foundation that allows the Laravel community to easily build meaningful AI features into their applications. This includes not just chatbots, but also AI Agents that can be used to automate tasks or retrieve information in real-world applications.

Personally, I am going to use it to build an AI-Powered "knowledge base" where I can upload a lot of historical documents related to the Home Owners Association (HoA) I am a part of (and the Chairman of). I also plan on connecting it to our shared Gmail account to:

  1. Make it easier to look up specific information, such as when a building was renovated, when the wall was painted, or how much a certain project ended up costing.
  2. Draft email responses to residents who ask specific questions about rules, regulations, or any other information related to the HoA.
  3. Automatically create reports, meeting notes, and other useful content that helps the HoA Board with their work.
  4. Summarize content and create task lists in external systems based on information received from residents, meeting notes etc.

It's one of those "spend 20 hours automating a 5-minute task" sort of things, but why do something when you can build a new library, right...?

relevant xkcd

Approach: Documentation-First?

When it comes to building Mindwave, I am taking an unconventional approach.

Instead of diving straight into writing code, I've begun creating the documentation and a demo application that will showcase its usage.

This approach allows me to get a clear picture of how the library should operate and which configuration and APIs I need for the library to be actually useful.

In line with the saying, "Write the code you want, then make the code work" (Jeffrey Way),

So far, this approach has been quite effective.

However, I've encountered some challenges along the way, particularly in abstracting and naming components in a way that accurately reflects their purpose and functionality (I started out calling "Documents" for "Knowledge," which made sense until I tried pluralizing it...).

I won't hide the fact that Mindwave draws heavy inspiration from LangChain.

However, as Mindwave progresses, it will gradually diverge from the LangChain-way to carve its own path that is better suited for the PHP language and Laravel ecosystem.

You can read the Documentation (WIP)

The documentation for the package is still a work in progress, but you can browse around and take a look at how I am envisioning this working.

You can find the docs on Mindwave.no.

I might change to another TLD later, but the .ai, .com, .app, .dev, .co were taken, and mindwave.io was $9000... soooo, deal with it :^)

When can I use it?

I've made some good progress so far in developing the boilerplate and sketched out the "core" of how Mindwave will work, and I am happy with the results so far.

However, there is still a lot of work to do before this can be used in a production application.

A generous estimate is that it might be ready to be used by the public in 3-5 weeks.

Until then, I will focus on refining how Agents and Tools should work, and I'm looking into how to make it easy to integrate your Eloquent models and data into Mindwave.

I am imagining a similar approach to how Laravel Scout works, where you add a Trait and interface to your models, and then you can start "consuming" the data in your database into the "Brain." The Brain will chunk and split the data into smaller fragments so it can be uploaded and indexed in a vectorstore. Later, it can be queried and used as context for your LLM Prompts.

However, time will tell how it will look like in the end.

A note on the importance of Branding

You might notice that I have no working package to release, but I have a logo, color scheme, and a beautiful documentation site.

You may wonder: Why not spend all the effort on building the thing?

It's because: Appearances matter.

It has to look polished, the documentation has to make sense, and it needs to cover both the basics, the real-world use cases, and the more complicated aspects.

Have you ever read through the routing documentation for Yii2? Back in my Craft CMS website-slinging days, I tried to figure out how this worked multiple times. Sure, I am a dummy, but to this day, I have no clue how any of it works.

Compare this with this. Which one do you prefer?

That is all for now.