Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Request: AI-Based Tagging, Note Optimization, and RAG-style Vector Search #4174

Closed
LiangWei88 opened this issue Dec 2, 2024 · 5 comments
Labels
enhancement New feature or request

Comments

@LiangWei88
Copy link

Describe the solution you'd like

First of all, I want to express how much I appreciate the software. It's lightweight, responsive, and works seamlessly across both mobile and web platforms. It's incredibly easy to use, and I’m really impressed by its performance.

That said, I would like to request the following features to further enhance the user experience:

AI-Based Tagging:
It would be great to have an AI that can either select appropriate tags from an existing list or suggest new ones based on the content of a note. This could help automate the organization process and save time.

AI-Powered Proofreading and Optimization:
An AI tool that can automatically proofread and optimize the phrasing, vocabulary, and logical flow of notes would be very useful. This would make the content more coherent and polished without manual editing.

RAG-style Vector Search:
A retrieval-augmented generation (RAG) based fuzzy vector search would be extremely beneficial. It would enable better search results and improve content discovery by utilizing semantic understanding.

Type of feature

User Experience (UX)

Additional context

I understand that some previous AI features were removed during the restructuring process. I would like to inquire if there are any plugin capabilities that would allow me to write and add such features myself.

Thank you very much for considering my request!

@LiangWei88 LiangWei88 added the enhancement New feature or request label Dec 2, 2024
@RyoJerryYu
Copy link
Contributor

RyoJerryYu commented Dec 2, 2024

Just wanted to chime in on your feature requests. I'm a user of Memos myself, not the developer.

I get that Memos is all about keeping things simple and user-friendly, and the AI features you're talking about might not be the right fit for the main app.

Memos does have Webhook support, though. You could totally write your own Webhook server to add those AI features you're interested in.

I've actually already a Webhook Server for my own use: https://github.com/RyoJerryYu/memos-webhook-py . It includes some LLM features where you can write prompts, use Zhipu AI, and update Memos with the AI's responses. That might cover your AI-based Tagging and AI-Powered Proofreading and Optimization needs.

The downside is that my Webhook server is a bit personalized, so you might need to fork it and tweak it to fit your needs.

Additionally, while Webhooks can effectively integrate Memos content into a vector database, they don't provide a search interface themselves. To utilize the RAG Search functionality, you might also need to implement a custom frontend interface.

@hxii
Copy link

hxii commented Dec 2, 2024

I just wanted to chime in and add that since API is also available, you can use something like n8n to implement all the LLM-based functionality you'll ever need, perhaps in even a better way than if it was added directly to Memos.

@LiangWei88
Copy link
Author

What you said is very reasonable.
I am currently studying solutions in the direction of webhooks and n8n.

Before, I switched to blinko because of these functions. Later, I found that the customizability there is not strong, but it is barely available. At the same time, the system resource consumption is higher than that of memos.

At present, I hope to implement combinations on the basis of memos.

If you have more example code, I am very happy to learn and refer to it, which makes my implementation process easier. Thank you very much.

@hxii
Copy link

hxii commented Dec 2, 2024

What you said is very reasonable. I am currently studying solutions in the direction of webhooks and n8n.

Before, I switched to blinko because of these functions. Later, I found that the customizability there is not strong, but it is barely available. At the same time, the system resource consumption is higher than that of memos.

At present, I hope to implement combinations on the basis of memos.

If you have more example code, I am very happy to learn and refer to it, which makes my implementation process easier. Thank you very much.

I can't give you anything concrete, since I didn't add Memos functionality to my TG assistant, but I would probably do something like this:
image

JSON For the workflow

{
  "name": "[TOOL] Memos",
  "nodes": [
    {
      "parameters": {},
      "type": "n8n-nodes-base.executeWorkflowTrigger",
      "typeVersion": 1,
      "position": [
        -200,
        0
      ],
      "id": "ae2e1c97-b9e9-4d09-ae2c-3008a44b3e95",
      "name": "Execute Workflow Trigger"
    },
    {
      "parameters": {},
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [
        -420,
        -180
      ],
      "id": "db884151-b619-4e43-8697-fd8eec59b200",
      "name": "When clicking ‘Test workflow’"
    },
    {
      "parameters": {},
      "type": "n8n-nodes-globals.globalConstants",
      "typeVersion": 1,
      "position": [
        120,
        -180
      ],
      "id": "cf7c91b0-f335-4e11-ae16-38aea6afb1d6",
      "name": "Global Constants",
      "credentials": {
        "globalConstantsApi": {
          "id": "YiZ3y54TW3iUeYnc",
          "name": "Global Constants account"
        }
      }
    },
    {
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "leftValue": "={{ $json.command }}",
                    "rightValue": "getall",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "getall"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "9fd61451-e4c0-4f76-8fa6-464915dd1ddc",
                    "leftValue": "={{ $json.command }}",
                    "rightValue": "get",
                    "operator": {
                      "type": "string",
                      "operation": "equals",
                      "name": "filter.operator.equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "get"
            }
          ]
        },
        "options": {
          "allMatchingOutputs": true
        }
      },
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3.2,
      "position": [
        300,
        -180
      ],
      "id": "d5c0f960-e155-4bd2-9ec6-3da121aab250",
      "name": "Switch",
      "alwaysOutputData": false
    },
    {
      "parameters": {
        "url": "={{ $json.constants.memos_uri }}/api/v1/memos",
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "pageSize",
              "value": "100"
            }
          ]
        },
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "=Bearer {{ $('Global Constants').item.json.constants.memos_token }}"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        580,
        -200
      ],
      "id": "bc3458fa-6692-4bb9-9bbc-8e1a20c6883c",
      "name": "Get All Memos"
    },
    {
      "parameters": {
        "url": "={{ $json.constants.memos_uri }}/api/v1/memos/{{ $json.arguments.id }}",
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "pageSize",
              "value": "100"
            }
          ]
        },
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "=Bearer {{ $('Global Constants').item.json.constants.memos_token }}"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        580,
        -20
      ],
      "id": "cce3d5b0-1fbe-43d4-9b81-d7351d5186ce",
      "name": "Get Specific Memo"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "9e2f3dd0-93dc-43d7-b093-82022ee57d27",
              "name": "command",
              "value": "get",
              "type": "string"
            },
            {
              "id": "236d2f5e-f375-43ce-bb92-d83eb0320b2b",
              "name": "arguments",
              "value": "{'id':'3'}",
              "type": "object"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        -200,
        -180
      ],
      "id": "f4584bce-4357-4575-ba71-04aa70d89b64",
      "name": "Test Params"
    }
  ],
  "pinData": {},
  "connections": {
    "When clicking ‘Test workflow’": {
      "main": [
        [
          {
            "node": "Test Params",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Global Constants": {
      "main": [
        [
          {
            "node": "Switch",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Execute Workflow Trigger": {
      "main": [
        [
          {
            "node": "Global Constants",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Switch": {
      "main": [
        [
          {
            "node": "Get All Memos",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Get Specific Memo",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Test Params": {
      "main": [
        [
          {
            "node": "Global Constants",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "ea21b937-0f09-436d-bb13-9571ee971a47",
  "meta": {
    "instanceId": "bc5203f69c8f3fd7c5d69eb8bfb4301d2a24ea6f4c3598b007ffc921d39b239f"
  },
  "id": "wp0Z2UkgZC5WPE22",
  "tags": []
}

Edit: I just found this https://github.com/laxtiz/n8n-nodes-memos

@LiangWei88
Copy link
Author

What you said is very reasonable. I am currently studying solutions in the direction of webhooks and n8n.
Before, I switched to blinko because of these functions. Later, I found that the customizability there is not strong, but it is barely available. At the same time, the system resource consumption is higher than that of memos.
At present, I hope to implement combinations on the basis of memos.
If you have more example code, I am very happy to learn and refer to it, which makes my implementation process easier. Thank you very much.

I can't give you anything concrete, since I didn't add Memos functionality to my TG assistant, but I would probably do something like this: image

JSON For the workflow

{
  "name": "[TOOL] Memos",
  "nodes": [
    {
      "parameters": {},
      "type": "n8n-nodes-base.executeWorkflowTrigger",
      "typeVersion": 1,
      "position": [
        -200,
        0
      ],
      "id": "ae2e1c97-b9e9-4d09-ae2c-3008a44b3e95",
      "name": "Execute Workflow Trigger"
    },
    {
      "parameters": {},
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [
        -420,
        -180
      ],
      "id": "db884151-b619-4e43-8697-fd8eec59b200",
      "name": "When clicking ‘Test workflow’"
    },
    {
      "parameters": {},
      "type": "n8n-nodes-globals.globalConstants",
      "typeVersion": 1,
      "position": [
        120,
        -180
      ],
      "id": "cf7c91b0-f335-4e11-ae16-38aea6afb1d6",
      "name": "Global Constants",
      "credentials": {
        "globalConstantsApi": {
          "id": "YiZ3y54TW3iUeYnc",
          "name": "Global Constants account"
        }
      }
    },
    {
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "leftValue": "={{ $json.command }}",
                    "rightValue": "getall",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "getall"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "9fd61451-e4c0-4f76-8fa6-464915dd1ddc",
                    "leftValue": "={{ $json.command }}",
                    "rightValue": "get",
                    "operator": {
                      "type": "string",
                      "operation": "equals",
                      "name": "filter.operator.equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "get"
            }
          ]
        },
        "options": {
          "allMatchingOutputs": true
        }
      },
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3.2,
      "position": [
        300,
        -180
      ],
      "id": "d5c0f960-e155-4bd2-9ec6-3da121aab250",
      "name": "Switch",
      "alwaysOutputData": false
    },
    {
      "parameters": {
        "url": "={{ $json.constants.memos_uri }}/api/v1/memos",
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "pageSize",
              "value": "100"
            }
          ]
        },
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "=Bearer {{ $('Global Constants').item.json.constants.memos_token }}"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        580,
        -200
      ],
      "id": "bc3458fa-6692-4bb9-9bbc-8e1a20c6883c",
      "name": "Get All Memos"
    },
    {
      "parameters": {
        "url": "={{ $json.constants.memos_uri }}/api/v1/memos/{{ $json.arguments.id }}",
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "pageSize",
              "value": "100"
            }
          ]
        },
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "=Bearer {{ $('Global Constants').item.json.constants.memos_token }}"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        580,
        -20
      ],
      "id": "cce3d5b0-1fbe-43d4-9b81-d7351d5186ce",
      "name": "Get Specific Memo"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "9e2f3dd0-93dc-43d7-b093-82022ee57d27",
              "name": "command",
              "value": "get",
              "type": "string"
            },
            {
              "id": "236d2f5e-f375-43ce-bb92-d83eb0320b2b",
              "name": "arguments",
              "value": "{'id':'3'}",
              "type": "object"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        -200,
        -180
      ],
      "id": "f4584bce-4357-4575-ba71-04aa70d89b64",
      "name": "Test Params"
    }
  ],
  "pinData": {},
  "connections": {
    "When clicking ‘Test workflow’": {
      "main": [
        [
          {
            "node": "Test Params",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Global Constants": {
      "main": [
        [
          {
            "node": "Switch",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Execute Workflow Trigger": {
      "main": [
        [
          {
            "node": "Global Constants",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Switch": {
      "main": [
        [
          {
            "node": "Get All Memos",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Get Specific Memo",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Test Params": {
      "main": [
        [
          {
            "node": "Global Constants",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "ea21b937-0f09-436d-bb13-9571ee971a47",
  "meta": {
    "instanceId": "bc5203f69c8f3fd7c5d69eb8bfb4301d2a24ea6f4c3598b007ffc921d39b239f"
  },
  "id": "wp0Z2UkgZC5WPE22",
  "tags": []
}

Edit: I just found this https://github.com/laxtiz/n8n-nodes-memos

This has helped me see the direction clearly. I will see how to implement it on this basis. Thank you very much.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants