reorganized documentation (#77)
diff --git a/content/en/docs/tutorial-ai/Lesson0/Lezione_0.txt b/content/en/docs/tutorial-ai/Lesson0/Lezione_0.txt new file mode 100644 index 0000000..f1540a3 --- /dev/null +++ b/content/en/docs/tutorial-ai/Lesson0/Lezione_0.txt
@@ -0,0 +1,150 @@ +Hello everyone, and welcome to the course application development with LLM Open using Apache Open Serverless. +A mileage title worthy of Wartmuller, but it's the Mastro GPT course for friends. +The first step is start the environment, environment that at this moment I have already started. +You can do it by simply going here on GitHub, slash Mastro GPT, and you will find +Here the slide shows it, it says to go to GitHub, Mastro GPT. +You will find the starter, and from here you have to press the code button and launch the code space. +So you see, go to Mastro GPT, launch the starter. +Here is this code button, and here it appears to make a button, this one, create code space on main. +I have already launched it because otherwise it takes a while to start. +So you see that this is already active, it's what I'm working with. +It's not the only job option so you don't have to. +You are not obliged to use the code space on the web because not everyone likes to work in the cloud like I'm doing. +However, but it is convenient then both for training and for other reasons. +For this reason, for this reason I use it and I recommend you to use it too because it saves you a lot. +A lot of time to configure the things but if you want you can configure yours as you want. +So at this point, once launched, all this will start, and above all you will have to have. +These, icons, which I'm matting here at the beginning. +The icon with the little cloud, which actually starts this. +This extension which has the main functions of the, and the first button is the login button so the first step is to login. +To open serverless so the first step is to write your name, your username and password, and login. +And then you should see this message, you successfully logged in. +You can now use open serverless. +Here is the message in all. +Therefore, first step, actually this this I am paying for is not the first lesson, it is the pre-lesson, the zero module. +To initialize to verify that everything works and understand if everything is okay in short. +So if everything is fine you will see the extension, you will see the logins. +And you can login and start working. +Let's take a tour of the environment. +So it is important in addition to the little cloud this other icon, the test tube. +Who? +It must also show the tests. +Therefore, the tests that are there, however, for everything so you should see. +By clicking on the cloud icon, the extension, clicking on the icon of the test tube, you will see the tests. +And then there is one more thing to see this lesson here, you will have to go to the docs icon. +On the documents icon, you will see the list of all the documents. +Under lessons you can find this text, which is the slide. +You only see the source, but actually just click on preview. +And you can see the slide, real already, rendering. +And we also use the source because sometimes we take and use the sources to take the exercises, etc. +So it's convenient to have the slide in markdown, in source. +So this slide, it recapitulates the various parts, document, test, research. +Research is useful, for example. +To find points in the source where you need to intervene to do the exercises. +Ok then. +So recapping documents, search, testing, the open serverless icon. +And here are the buttons to perform the tests. +The first step is to deploy then. +Go to the deploy icon. +That if you don't deploy, you can't run the tests. +So now he's taking the initial code and is installing it. +Here. +Now you can go here and run the test. +And therefore everything works because the test passes. +Ok, now when you work you don't deploy. +But go into development mode, which also allows you to see the user interface. +So now let's also try this other feature, which is on devil. +We'll open here too. +The deployment window. +And now some of you will even see an open button in browser. +If you don't see it. +This is a bit hidden, it is explained in the slide. +In the slide this small detail is explained which is a bit hidden. +There is this antenna below. +This antenna below simply shows the doors. +The doors of the service is launched. +Then devil launches a web server to run the user interface. +So you simply have to click here. +It opens and to see at this icon of the globe also hidden. +But there is the slide that explains it. +And here you can log in. +Then you can log in and since you are Mastro GPT reference to Mastro Geppetto. +We have called the user interface with great effort of imagination Pinocchio. +So you can log in Pinocchio. +The default password is already Geppetto. +The initial password is Pinocchio or Geppetto anyway. +We change it immediately so no problem. +Obviously she immediately tells me that she is not sure. +In fact now I'll show you how to change it. +Here in part of the user interface. +So here I am going to give you a tour. +Then this is user interface. +So all the resort will use Python as a programming language. +But we have developed a user interface that serves as a front end for the applications. +That we will use to make the course but then you don't have to modify it +because this will remain more or less fixed. +You will simply develop chats. +So this is the multi chat application. +So the first chat just to see if everything works is called hello +and does nothing but say hello to whatever you write to him. +Then hello Michelle. +Mirella hello Mirella etc. +And then here there is a chat a little more interesting which is instead the demo +of the characteristics of Pinocchio of this interface. +So basically that this interface can display code. +See you can also close this side view. +So when something is produced that it is interesting part of the side view to view it +or you can view HTML or a chess board here. +Therefore the support for. +So if I ask form shows me a form and I write on it because it's good. +We use this in the exercises CEO etc. +And here it gives me the result of the form. +This is fine. +So you understand that here there is an extendable menu. +This is the menu and there is another thing which is the upload of documents. +So here you can choose a document to upload it. +I'll show you this later. +How to use it. +The side display is customizable so you can powerful extend it with your own displays +and the side view that can be open and closed. +And with this we have seen. +This sums up the features of our interface. +Last step the terminal because we will use a lot of terminal. +Because many many commands are command line and therefore for this reason. +Let's start immediately to show the command line commands and as a command I show you immediately. +The terminal opens in various ways. +The easiest way is to go here terminal new terminal and this opens a terminal. +Okay here. +Let's do a command right away to change the password. +Then the password is actually stored here master GPT packages master GPT login users. +But as you can see it is encrypted so it is not easy to change. +So if I now decide to change the password. +Therefore I give this command OBS AI user update Pinocchio. +And I put another password here I changed it. +Here I changed my password. +Here the login is customizable so instead of using the file you can use anything a database an external system whatever you want. +And of course the easy implementation is that as I increase users of the interface are in the file that we can change which we have changed. +But when we change the users we also have to redeploy so second command is upside. +Deploy master GPT login. +So now he deploys an action to me. +This is to show that you can otherwise you could have gone here do deploy and we deployed them all. +This serves to make it clear which also exist. +Many command line commands that are used to do the most advanced things when you work a lot with the command line. +Then for those who use code space let me give you a note here on GitHub a piece of advice. +Go here go to settings here are code space and here I recommend you to change. +Eventually the timeout because there are 120 hours free so you really do a lot but it puts you the auto off time at 5 or 10 minutes maximum because otherwise it consumes 30 minutes each time and if you forget it you quickly run out of credit. +You can also decide to use and instead of visual studio on the web as I did you can use the local one so you can change this option in reality it is possible. +Also do not use the environment in the cloud but use everything locally with Docker so you can also install new Valaris locally instead of use what we offer regarding all these things for those who are interested. +We can do an ad hoc lesson in which I show how to install in a different way. +For the course we have provided this environment ultra simplified which should allow everyone to start with practically zero effort then course support what is available. +First of all as a support to the new Valaris course enterprise available to everyone with a free account which is you can see includes several services. +So it includes Redis understands Minio includes PostgreSQL although in this course I don't think I'll use it. +You can deploy on AWS G Cloud Azure Akamai on physical servers we for example use Hezner on Ubuntu on Red Hat OpenShift so you to get an account on the our open serverless environment where you can practice. +Gain ask now so if you have already written account we are already preparing it for you or you can go to the master gpt.com website where there is a chatbot and you can ask for it here. +Or you can contact us on LinkedIn and there you send a message on LinkedIn or you can install it yourself on the open serverless site where there is all the documentation for the installation. +So how to install it etc as for support there is discord. +I ask you and I recommend you to use that so go to discord and here we are there are already the first people this is a brand new server. +This is the second lesson so come and this is where we offer support possibly use the Italian channel because the language and then there's always read it. +There is also read it which is a forum and here you can ask your questions and discuss etc so these are the course support options we offer the next step. +And with this I conclude the first module even in reality this is mentioned is lesson zero then we will do the first real lesson go still on the extension then therefore here you see click on the lessons and here simply. +Click on the first lesson so here is downloading all the lessons downloaded the lessons and so we are ready to start and move on to the next lesson.
diff --git a/content/en/docs/tutorial-ai/Lesson0/_index.md b/content/en/docs/tutorial-ai/Lesson0/_index.md new file mode 100644 index 0000000..2465831 --- /dev/null +++ b/content/en/docs/tutorial-ai/Lesson0/_index.md
@@ -0,0 +1,210 @@ +--- +title: Lesson 0 +weight: 10 +draft: true +--- + +# TO BE REVIEWED! + +# ๐ Welcome to the Course: Application Development with LLM Open and Apache Open Serverless + +A mileage title worthy of Wertmüller — but for friends, it's simply the **Mastro GPT Course**. + +--- + +## ๐ Step 1: Start the Environment + +To start working, launch the development environment. + +### ๐ข Recommended: GitHub Codespace +1. Go to **GitHub → Mastro GPT**: https://github.com/mastrogpt +2. Click the **"Code"** button. +3. Select **"Create codespace on main"**. +4. Wait for it to start (takes some time the first time). + +> This is the environment used for the course. It's convenient and preconfigured for both training and development. + +--- + +## โ๏ธ Step 2: Explore the Interface Icons + +Once your Codespace is running, take note of these key icons in the sidebar: + +- โ๏ธ **Cloud icon**: Opens the Open Serverless extension. +- ๐งช **Test tube icon**: Opens the list of tests. +- ๐ **Docs icon**: Opens course documents and slides. +- ๐ **Search icon**: Lets you search in your code and documents. + +--- + +## ๐ Step 3: Login to Open Serverless + +1. Click the **Cloud icon**. +2. Press the **Login** button. +3. Enter your **username and password**. +4. You should see the message: + +You have successfully logged in. You can now use Open Serverless. + +yaml +Copy +Edit + +This concludes the initial setup. This is **Lesson Zero**, a pre-lesson to verify that everything works. + +--- + +## ๐งช Step 4: Deploy and Run Tests + +To ensure your setup is working: + +1. Click the **Deploy icon** inside the extension. +2. This will install the starter project. +3. Once deployed, go to the **Test Tube icon**. +4. Run the tests. If the test passes, your environment is working correctly. + +--- + +## ๐งฐ Step 5: Use Development Mode + +Switch to development mode to run the web interface: + +1. Click **Dev Mode** in the Open Serverless extension. +2. This starts a local web server. + +If you don’t see the **Open in browser** button: + +- Look for the ๐ก **Antenna icon** at the bottom bar. +- Click the ๐ **Globe icon** to open the UI in a browser. + +--- + +## ๐ค Step 6: Meet "Pinocchio" — The User Interface + +The web frontend is named **Pinocchio**, a reference to Mastro Geppetto. + +### Default login credentials: +- **Username**: Pinocchio +- **Password**: Geppetto (or vice versa) + +> You’ll be prompted to change it. Here’s how. + +--- + +## ๐ Step 7: Change the Password (via Terminal) + +1. Open the terminal: +Terminal → New Terminal + +2. Run the following command: + +bash +obs ai user update Pinocchio +Enter your new password. + +Redeploy the login service: + +bash +Copy +Edit +obs deploy mastrogpt-login +This shows how command-line tools can be used instead of the GUI for advanced operations. + +๐ง๐ป Step 8: Tour the Interface Features +Pinocchio is a multi-chat UI developed in Python. You won't need to change the UI — you'll build backend logic for chat apps. + +Available chats: +hello: Responds with a greeting. + +demo: Demonstrates Pinocchio’s interface features: + +Code rendering + +HTML view + +Chessboard display + +Forms and form submissions + +Document uploads + +Custom side views + +Everything is extendable and customizable. + +๐งช Step 9: View the Slides +To view this lesson's materials: + +Click the ๐ Docs icon. + +Navigate to the lessons/ folder. + +Open the lesson markdown file. + +Use the Preview tab to view the slide. + +Use Source to copy exercises or commands. + +๐ก Step 10: Tips for Codespaces +To avoid wasting free hours: + +Go to GitHub → Settings → Codespaces. + +Set Auto-off timeout to 5–10 minutes. + +Optionally switch from VS Code web to VS Code desktop. + +Alternatively, install and run everything locally using Docker. + +We can organize a dedicated lesson on local installation if needed. + +โ๏ธ Step 11: Open Serverless Services +Your environment includes: + +Redis + +MinIO + +PostgreSQL (not required for this course) + +You can deploy apps on: + +AWS + +Google Cloud + +Azure + +Akamai + +Hetzner + +Ubuntu + +OpenShift + +๐ Step 12: Get Support +You can request your free account or support via: + +๐ Website: https://mastrogpt.com + +๐ฌ Chatbot on the website + +๐ผ LinkedIn: Send us a message + +๐ป Discord: Primary support (use the Italian channel if preferred) + +๐ฃ๏ธ Reddit: Ask questions and join the discussion + +โถ๏ธ Step 13: Start Lesson 1 +Now that everything is set up: + +Go back to the Cloud icon. + +Click Lessons. + +Select Lesson 1. + +All lesson files will be downloaded automatically. + +You're now ready to start building! \ No newline at end of file
diff --git a/content/en/docs/Ai Tutorial/Lesson0/_index.md b/content/en/docs/tutorial-ai/Lesson0/_index.md.orig similarity index 100% rename from content/en/docs/Ai Tutorial/Lesson0/_index.md rename to content/en/docs/tutorial-ai/Lesson0/_index.md.orig
diff --git a/content/en/docs/tutorial-ai/Lesson1/Lezione_1.txt b/content/en/docs/tutorial-ai/Lesson1/Lezione_1.txt new file mode 100644 index 0000000..aad7e31 --- /dev/null +++ b/content/en/docs/tutorial-ai/Lesson1/Lezione_1.txt
@@ -0,0 +1,74 @@ +Hello everyone. To access the lesson, after starting, the environment and after configuring it, you must be logged in. +The first step is to select here. The first lesson, which is the one that we are about to see and hear all the files of the lesson are downloaded. +If we go and see now, the files you see that there is a new lesson that we can open and we can do the preview of this. +And this is the new lesson. Here, then, this is the first real lesson of the course. +While what you have already seen was lesson zero, which explains how to configure the environment. +Now let's talk about the integrated services. Who are supplied with the system and we show you some examples, which we call hello. +Exercising the various services available. And these are useful both as a code example that one can look at to try out the various services are useful in themselves because they are used for example for debugging for interact with the cache with the database and to do tests. +So the first step is to see these examples. Then I'll show you the tool command line that are even more useful because when you work, you use them extensively and so will end the second module. +Then the third module is that of the exercise in which I show you step by step how implement a simple service, which in this case will not use LLMs. +But it is still used for variations with the environment. And it is the exercise that we will ask you to do even with some modifications in the exercise. +And so we complete the lesson. Well, let's proceed. Downloading the lesson. Hello package was downloaded. +This package contains all the various examples. So an example to exercise the cache that is redis, an example to exercise the store that is milvis, the database, an example to exercise streaming, and an example to exercise the LLM, which is allama, etc. +And there are also two tests, trivial ones that fail that serve to try to correct them and check if the testing system works. Therefore, after downloading, if you go to see the tests and eventually it may take a refresh to see them if you don't see them, here they are. +You see, these are all the tests. We launch them and verify that all services work so now. Let's check that everything goes. The two tests deliberately fail precisely to verify that. Everything works. Then check that everything works by failing some tests and then correcting it. +Okay, here, all the tests work except the two that we have deliberately left broken. So the first exercise you should do to will correct the tests. Then let's go to look for the string to do that says where and we find here the wrong test. The output should be hello and the string high. So I suppose it is understood that it is not this. So we change the string and save it. +Now notice this. If I now perform the test happen that one passes by and is the test unitary because the unitary test. It only requires the code, but the integration test that requires deployment on the system does not pass because we have not deployed it. So what we have to do is go here and do the deploy. +And at this point, the integration test should also pass. So we deploy what now the integration test also passes. So so there is practice with the test performer. In general, it is better put develop mode devil so the development mode has the advantage that it immediately deploys the code. +As soon as you change it, and we will see this when we do the actual exercise. So now let's move on. Let's see the examples. We deployed together with the test. Also all the examples that we can go to see. So when you do the deploy, it also tells you the URL of where the environment is in production. +So each of you will have a different access. So he deployed on the environment and you will have to use the password that you have put before and that I changed. That's it. Good. Now there are new services. Stream, Redis, Olamai, etc. And now we see them one by one. So we realize what is available in the environment. +So first of all, there is obviously the LLM. Since this is a private AI development course, we will use Alma, where we deployed the Alma model, 3.18 billions. But you will find that it is very powerful. In fact, it is remarkable what it can do and is sufficient for for the course objectives. +We'll actually also use a vision model for image recognition and an embed model to do the ending that is used for the RAG. These are things that we will address during the course. So if we click on Alma, here gives us a welcome message. I ask him, who are you? Here's his answer. He says he's an artificial intelligence. +I can also ask questions in Italian. What is the capital of Italy? It is an absolutely remarkable model for what it manages to do. However small, because it is performed on a small GPU that costs quite little. Yet it really does so much. +In fact, the course will purely use this model, although nothing prevents you from using other larger ones and even connect to AI such as open AI, Claude, etc. +If you go and see the code, you will also see the code of the LLM, which is of devastating simplicity. So this is all you need to connect. +Moving on, then the next thing to test is the streamer. +Here, if I write to him, hi, how are you? It does the streaming, that is, it basically takes the string it sends and it tells you the ASCI characters separating them one second from each other to demonstrate how streaming works. +So we also have streaming support. We will see it this one too. +In the next lessons, here too, you can look at the code to understand how streaming works. Now let's see the cache. Redis works with commands. +So the logical thing was to select Redis and be able to talk to him. So for example, I can ask info and gives me all the info or I can ask for the keys that are available and shows them to me. +Etc. It's okay. Then, moving on, the next step is file storage. Then, so this is called S3, but this is not Amazon's S3. That's embedded in Nuvularis. +So this is to list the files that are in the storage. I can also create one plus hello equal world. +Here you see, now I can also list by substring and I can also delete them or upload like this. I now take a file and I upload it. And so if I now make star, here it is, it has arrived. +I did the upload. Then of course, once uploaded, move on to the LLM to process it. Then, last but not least is the vector database. +The vector database is what you need to insert the documents. In our case, Nimbus. +Therefore, I simply write a few things. For example, asterisk test and I look for everything that uses test. Obviously, first I have to insert some texts. So this is a test test. This is another test. I am testing the system. +Okay, now if I do the search with an asterisk test will look for me tests in order of distance, which is an essential concept for research vector, which is practically used to find in documents of the phrases relevant to what you are asking. +So this concept of vector search is essential. This allows you to test. So you are telling me that if I search for the word test, I found some phrases of which the first is the closest to all. +So it's a kind of search for relevance that however, with LLMs is done in a particular way using a technique called embedding, which we will discuss in detail in the lesson relevant our so far we have seen the user interface. And now let's talk about the command line tools. +So there are many command line tools. They are all documented and the tool is called oops. Here, there is explained everything he does. There is also the reference of all the components that there are, which are available. Therefore, are divisions into tools and tasks. +The tools begin with the hyphen and the tasks on the other hand are the things that are normally used of the many available. We will basically focus on ID tasks and on AI tasks, basically a sub command that has many sub commands. Therefore, here we take an example how oops works creating an action and then and then removing it. +So practice I repeat by hand what we did with the extension. And so you better understand how it works. Take lesson one. And I perform this piece of code. Instead of copying it, I run it directly from the example. Now I'm going to give you an introduction to the main commands of oops. The first ops action list is used to list the actions, which are the functions, the components of our applications. +Then we can create an action. I have here added a simple example action of a single file. Usually the actions we use are many when it is a single file you have to package it. But this is done by the other tools when you have an action of only one file you can create it on the fly. +You can invoke it with an input. You can get a URL. By default, the action. It is. So if you try to use it, you will get an error requires permission. But you can make it public. Then you can make an update and put a parameter on it. So this made it public. Now we get a URL. Now we can invoke it directly and pass parameters directly to it using curl, etc. +And finally the possible delete delete. And now we see that it is no longer there. Okay. All right. This is to give you an idea of how it works. But all the other things you can simply see by doing oops minus T and lists all the various action invokers URL logs and then the plugins. +AI IDE admin configuration setup. All this serves to install it. There is really a lot of stuff. So you should go and see the documentation for details. Normally, however, this is what you need. And these are a bit low level, because almost everything is done using IDE actions instead. That are the ones that are here. +So what does the login that you have already seen so I can redo the login. So it's HTTP open serverless point dev. So here I can redo the login instead of using this. Can I deploy, which is the same thing as pressing here, I can deploy only one action. +So if you don't want to redeploy everything every time and you want to deploy one just write oops IDE deploy hello LLM. The difference that there is between the deployment with this tool and the creation of the action is that this manages the packaging of shares and a whole host of extra things that you would otherwise have to do by hand. +It is explained in the documentation how it is done, but this automates it so basically using these tools do now and do it even sooner. Using devil that pretty much throws everything. Pack it up and you can write the code and deploy it on the fly. +Well, last thing that clean, which is useful because there are temporary files and sometimes pieces remain. So it's better to do a clean because it is incremental. So if an old file remains, then you may have some problems and then the clean comes to your rescue. +Okay, so these are the development tools and finally there's a specific plugin for the course that oops AI, which provides a number of fight on specific tools. So Ops AI lesson is used to download the lessons of the course. +Then oops AI user, you saw it. It is used to add and create user. Then there's Ops AI chat, which is very nice because it's a command line version of the chat you saw here. So for example, I can do Ops AI chat hello LLM and I can talk with AI as I did before. Who are you from the command line. +So now I'm talking to llama or I can call the store. Okay, so asterisk that lists the files. I can also upload them like this at tests. Master GPT test hello here. And then AI CLI. This is immensely useful when you do development. In fact, I will use it because it is a Python interpreter. +And finally, Ops AI new that creates you a new service. You have to give it a parameter. In fact, now we will use it in the exercise. All right. So here I am. Summarize the things I have said. So then exercise. Now let's put together everything we have seen doing an exercise. Therefore, preview, I take the exercise. +The exercise consists of implementing a simple chat that in this serves to reverse the text then. So let's go here. Let's go to Alma and write how do I invert the string s in Python. +And told us code to reverse the string. They're going to use this thing to invert the string. Then the goal is to create a new service. And so here we will execute this command, which I can do immediately because as I told you, oops AI to a wizard new reverse and usually makes a package that is called as the action in this case I give him the package mine and I call it reverse messiah. +So I do mine lapels in my pack ag. So if I now go to the packages, you see that there is messiah. So there is a messiah package. There is a reverse service that ready to use for deployment using all the conventions of the environment. +And there are also two tests. Therefore, you see that under Mashiab there is unit reverse testing and integration testing. So if you try to run the tests you will find out right away that the unit integration test passes. +So now I'm going to refresh. Here you are. If I do the integration test passes, but I have the unitary text. No, indeed it had passed because had already been filed before. I try to remove this problem. +So we send it back to the terminal and I do oops action. Delete Mashiab. Reverse. He was not supposed to pass, but unfortunately he remained from the previous time. Then as soon as you create the integration test it should fail because has not been deployed. +Therefore, or deploy it. Everything or just that service. The best thing is to deploy everything. Deploy and then passes the test integration of a service empty practically, which simply it echoes what it writes. So that's it done the deploy. +Let's rerun the integration test and default pass. OK, so now we have a new service that we can use. The nice thing is that we can immediately add this service to the other services simply going here as the slide says, add it to the index. +So there is an index under packages. Mastro GPT index. There are two files. You can create a third file or just edit this one and put the new service on it. Then reverse Mashiab reverse. +OK, good. And now if we go to the user interfaces in M Sahab, we recharge it. +Pinocchio. Gepetto. Login. I realized that I had to deploy also in the index. So OBS I deploy master GPT index. Here this here I had to deploy it. +Here is the reverse, which is trivial because whatever we say to him always tells us the reverse, but it is a starting point right now. Let's implement the actual reverse and go to do the code. +Now here I use Python programmer techniques. So I put the command line here. I take the code of reverse, then packages Mashiab reverse here. +Here you see that there is always a main that calls a function and the function is this. So here we need to implement a. I will explain in the next lessons how it works. +The mechanism, however, sustainably the functionals take an input and return an output. So the thing I do is in equals args get input. And it is better to put this one here, which also gives a default. +Then I write if in equals zero because the first time he start the conversation with a message blank, then please provide an input. So I the answer I will return without and only if I am P is different from empty will out equal to the inverse in practice. +Here is a very simple exercise. It's interesting. When you develop it, put it in devil mode. So as you write the code, he deploys it on the fly. So now. +Okay, if I try to ask him now to redo reverse here, you see that the first time I activate a chat, he sends an empty input and he replied. If I now say Pippo, he gives it to me inverted, adapting it to show you how you can edit. +I now give it an output with an asterisk at the beginning and in the end, just to show you see that he immediately updated everything. +So if I now I try it again, instead he interprets it as italics. If I put the double asterisk instead as bold here, this is a simple exercise, but it allows you to familiarize yourself with the system and to understand how easy it is to create new actions to extend it since we will create many of them. +So I recommend you do it. With this I am finished. Goodbye.
diff --git a/content/en/docs/tutorial-ai/Lesson1/_index.md b/content/en/docs/tutorial-ai/Lesson1/_index.md new file mode 100644 index 0000000..655bdff --- /dev/null +++ b/content/en/docs/tutorial-ai/Lesson1/_index.md
@@ -0,0 +1,216 @@ +--- +title: Lesson 1 +weight: 10 +draft: true +--- + +# TO BE REVIEWED! + + +# ๐ Lesson 1 – Integrated Services & First Exercise + +Welcome! After launching and configuring your environment, ensure you're **logged in** to begin. + +--- + +## ๐ฅ Downloading the Lesson + +1. In the extension, select **Lesson 1** from the sidebar. +2. This will automatically download all lesson files. +3. You can preview the new lesson by selecting the markdown file under `lessons/`. + +> โ _Lesson 0_ was the environment setup. _Lesson 1_ is the **first real lesson** of the course. + +--- + +## ๐งฐ Included "Hello" Examples + +The `hello` package includes small examples demonstrating system services: + +| Service | Description | +|-------------|------------------------------------------| +| Redis | Cache operations (info, keys, etc.) | +| Milvus | Vector DB search using embedding | +| Streamer | ASCII-based output streaming | +| LLM (Alma) | Query small language model | +| S3 Storage | Store, list, upload & delete files | +| Tests | 2 failing tests to practice debugging | + +> These examples are useful for testing, debugging, and learning the system APIs. + +--- + +## โ Running and Fixing Tests + +1. Run the tests (๐งช Tests tab). +2. Two tests **intentionally fail**. +3. Locate the `TODO` in the broken test. +4. Example fix: change `"Hi"` to `"Hello"` and save. + +### Why Tests Still Fail After Fix? + +- โ **Unit test** will pass immediately. +- โ **Integration test** will still fail — it requires deployment! + +### Fix Integration Tests + +```bash +# Deploy the fixed code +obs deploy + +# Or just redeploy the specific action +obs ide deploy hello-llm +``` + +> Enable **Dev Mode** (Devil) for automatic deploy on save. + +--- + +## ๐ Using the Deployed Examples + +After deployment, you’ll get a **custom URL**. Login with your user credentials. + +### Example Services Overview + +#### 1. ๐ค Alma (LLM) + +- Powered by a 3.18B parameter model +- Works in Italian and English +- Example: + - Ask: `What is the capital of Italy?` + - Response: `Rome` + +#### 2. ๐ Streamer + +- Demonstrates streaming via slow ASCII output +- Example: `Hi, how are you?` → streamed char-by-char + +#### 3. โก Redis + +- Supports CLI-like interaction +- Examples: + ```bash + info + keys * + ``` + +#### 4. ๐๏ธ Object Storage (MinIO) + +- S3-compatible local storage +- Commands: list, insert (`+ key = value`), search, delete +- Supports file upload via UI + +#### 5. ๐ Vector DB (Milvus) + +- Supports semantic search +- Example: + ```text + This is a test + Another test + ``` + Then search: `*test` → shows ranked results by similarity + +--- + +## ๐ง Command-Line Tools (OBS CLI) + +Use `obs` or `oops` for CLI actions. Common subcommands: + +```bash +obs ai lesson # download lessons +obs ai user # manage users +obs ai chat <svc> # chat with an LLM from CLI +obs ide deploy <action> # deploy a single action +obs action delete <svc> # delete an action +obs clean # cleanup temp files +``` + +> `obs ai chat` is a terminal version of the web chat. + +--- + +## โจ Creating a New Service: Reverse Text + +### Step-by-step: "Reverse Text" Chat App + +1. Ask Alma: _"How do I reverse a string in Python?"_ +2. Create the service: + +```bash +obs ai new reverse -p messiah +``` + +This creates: + +``` +packages/ + messiah/ + reverse/ # your new action + __tests__/ + reverse.unit.test.py + reverse.int.test.py +``` + +3. Run the tests → Integration test should fail initially +4. Deploy: + +```bash +obs deploy +``` + +5. Add to UI: + - Edit `packages/mastrogpt/index/index.py` + - Add: + ```python + reverse("messiah/reverse") + ``` +6. Redeploy the index: + +```bash +obs ide deploy mastrogpt-index +``` + +7. Try it in the web UI: + Log in → Select `Reverse` → Input: `hello` → Output: `olleh` + +--- + +## ๐ง Edit Logic in Code + +File: `packages/messiah/reverse/main.py` + +```python +def main(args): + inp = args.get("input", "") + if inp == "": + return {"output": "Please provide an input"} + else: + out = inp[::-1] + return {"output": f"**{out}**"} # bold markdown +``` + +Use **Dev Mode** to auto-deploy as you edit. + +--- + +## โ Summary + +You now: + +- Downloaded your first real lesson +- Ran & fixed tests (unit + integration) +- Explored system services: Redis, Alma, MinIO, Milvus, Streamer +- Built and deployed a custom chat service +- Learned how to modify and extend the UI + +--- + +## ๐ง๐ซ Up Next + +Next lessons will: + +- Dive deeper into LLM usage +- Cover vision models and embeddings +- Show full-stack app development using Open Serverless + +Happy hacking! ๐งช๐ค
diff --git a/content/en/docs/Ai Tutorial/Lesson1/_index.md b/content/en/docs/tutorial-ai/Lesson1/_index.md.orig similarity index 100% rename from content/en/docs/Ai Tutorial/Lesson1/_index.md rename to content/en/docs/tutorial-ai/Lesson1/_index.md.orig
diff --git a/content/en/docs/tutorial-ai/Lesson2/Lezione_2.txt b/content/en/docs/tutorial-ai/Lesson2/Lezione_2.txt new file mode 100644 index 0000000..aa79a72 --- /dev/null +++ b/content/en/docs/tutorial-ai/Lesson2/Lezione_2.txt
@@ -0,0 +1,265 @@ +Welcome to the second lesson of the OpenLLM course with Apache Open Serverless, +for friends the course of Mastro GPT for Private AI. +We start immediately by going to the Mastro GPT site, then GitHub, Mastro GPT, +here you will find the starter, as explained in the first lesson, which we can launch. +This way you will have the environment pointing to our Mastro GPT Stator Repository, +on which you obviously do not have right permissions. So you should fork, that is, +create a copy of the environment and choose your account. This way you can write all your changes +and save them without depending on the original, so you can save everything using the Git version +control tool. Here I have already made a fork as you can see and I have launched the code space. +I repeat that you can also use the local environment, but simply for this course. +We will use the code space that allows you to work quickly, +without too much effort and without having to configure by hand. +Then click on create code space and you will see this screen. +You should see the speech bubble which is our extension that allows you to log in. +Using the parameters we gave you in the first lesson, you can log into the open serverless +environment that we provide. At this point you see the starter files basically empty. +By selecting the lessons you can select the files of the second lesson. +In this way we are downloading all the files of the second lesson. Each lesson is independent of +the others so you don't have to have the files of the first lesson to be able to use those of +the second. In the second lesson you will find the lesson both in markdown format and in PDF +format for ease of reading, so that you can also consult it by downloading the local. +So this is the second lesson and we are going to talk about how to start actually talking to +LLMs by creating an LLM chat in which we will implement an important feature that is streaming, +which is the ability to see what the LLM produces along the way without having to wait until everything +has been completely generated and this makes interaction with these systems much more immediate +instead of waiting until the end for everything to come. +We will also address a series of related topics so the plan of this lesson will be +first of all how to access the LLM and then we will learn how to manage the secrets that +allow you to access it then we will embark on streaming then we will put everything together +by accessing the LLM in streaming mode basically having you implement it with an exercise before +starting since I will use a lot of a trick which is to copy lines and texts from a file +opened in the editor directly from the terminal to repeat the experience I recommend you to +configure a key in my case control enter which allows you to copy the text from a file to the +terminal this is a feature present in studio code only that it is not normally enabled by default +so to enable it you have to go to settings i.e. the wheel in the bottom left select the keyboard +shortcuts and we'll try run selected text in active terminal this one you click on it and +set your preferred sequence for example I set control enter which allows me to copy the text +of the file into the terminal it is truly extremely comfortable and I recommend it now +let's start talking about how to access the LLM to access the LLM we need the credentials +the credentials we need are stored in environment variables then I will explain +exactly how they get there and how to use them however these credentials are in the environment +variables olima host which is the URL and for AUTH we use the credentials in reality the credentials +are the same ones that are used to log in to the environment open serverless so the LLM is protected +with the same credentials as open serverless let's see it right away we do it by opening a +terminal and at the terminal we type this command OBS AI CLI which launches an interactive phyton +environment and now I use the trick I was talking about I copy these commands which are used to +read the environment variables so as a first step I import the O s module I tie the olima host +variable and AUTH this one you see that we will use to access olima host now using these credentials +you can get a URL to access the olima server where we can invoke the LLMs in particular we will use +these commands ie host note that here I am doing a technique which is the one you have to follow +in the code ie every definitive function in open serverless receives addiction called args I will +always look for the secret parameters in args and if I don't find them I search the environment +this is a technique that is used to be able to write code that takes secrets both in the test +environment and in the production environment so these are the three commands to give and I'm +going to give them like this so let's set the empty args to simulate in the command line what is done +in test I take the host I take the off and I compose a URL simply by putting the HTTPS prefix +on it using the key as username and password and at host our this URL that we have called base +is the URL we need to access to olima password protected so if I invoke beware of this exclamation +mark which allows me to run while I'm in the shell command editor without having to exit the shell +and re-enter and I can use variables so I basically run curl and in this way I invoked the URL to +access olima and you can see that I got this message olima is running now we see that the +credentials are correct now let's always see at the command line how to access olima therefore +we have to use a simple API that basically uses JSON messages that specify the template +the prompt the stream false because we start immediately by disabling the streaming which +is easier and we get the whole complete answer so let's set the llama as a model llama 3.1.8 +billions which is a model made by meta small enough to fit into the gpt we have as input we ask you +who are you and let's compose this message at this point using that URL the base API +slash generate we can invoke it we invoke it by executing a post therefore here now I import the +request another python library which allows you to make HTTP calls and I make a post to the +request using the URL I composed and the message I composed and extract the result in JSON now from +here the result will be the answer to my request who are you so this is basically the generic way +you interact with olima with its API there are also libraries that allow you to avoid composing +messages but generally it is convenient to know how to do it and in many cases it is not needed +you just need when the requests become complex then I always teach the essential information +and then complicate it with library when it becomes necessary so we can try running this +code right away let's set the model first let's set the input let's compose a message let's +compose the URL using the base we prepared before and so now we have a full URL and a full message +to make the request to olima asking him to use the llama 3.1.8b template with this prompt without +streaming so now I do a post then we import requests we make a request he performed all +the result without streaming so now I get this item here res which is all the complete answer +that has various information of this one I am only interested in extracting the answer that I can +print that's it like this I was able to quickly create a call and then we can write our first +function now I'll show you the code I made put inside the code of a function so we simply open it +the code is what we saw before let's take the secrets then we compose a message being careful +that the input is not empty and we invoke it at this point we make the request we return the result +with boy and output as we have seen the previous time now we will do another somewhat magical thing +we'll expressly create the action from the file and pass the parameters directly to it so one +and two don't do that because this is to understand how it works below because there is actually a +feature that is there in the deploy that automatically implements this feature but as you see when you +create a function or update so for this you can use update even if the function does not exist +it creates it in this package using a single file and these parameters are enough for him +obviously instead of doing this directly we will use the deploy command which does a series of more +complex actions that I will now explain to you this is to understand what are the steps necessary +to do the deployment now this can be tried actually now since you need to deploy everything else +you also need the front end and so on I now perform a complete deployment and go to see +here we have that simple action that allows you to converse without streaming so now it takes +a while with llama so we learned how to create a simple llm without streaming at the moment +but we have already made some steps forward by learning all the steps necessary to build our +system that will become seems more complex now we have stumbled over the secrets which are necessary +to be able to pass the information to allama and also to the other services for this modification +we would have to answer some questions where do the allama host and auth variables come from +in reality they come from many places the main source is the configuration that is loaded when +you log in here comes a whole series of information that is made available both to the test environment +and to the deployment environment they are not available in shell for this reason I use it directly +from the cli which instead sees them this information can be overwritten i.e. you can add your own by +creating an env file or you can further create a packages env file that puts additional variables +but valid only for deployment and an additional env which instead applies only to the if we go to +check we see that there are values i try to read these two variables then i try to look for them +i make grep and you see that i find llama new valeris.io if instead i do the grep of the test +i see that different words in general these values are different because the variables +for the tests they are used to perform tests in a test environment while the default variables are +used for production therefore in the new valeris deployment environment so the cli looks at the +test ones not those of production but if someone goes to look at these variables which are available +he realizes that auth is not in any of the env so if one tries to make this command by looking for +it in this case there is no output because because the information is actually in the config that we +can read with the command oops config dump which lists them all let's make a nice grep and we see +only the ones we want to look for and in fact there is off so off we have it and we can pass it +this one is actually generally used to access all the features of your open serverless in particular +it is used to access allama how are secrets propagated to actions the way in which secrets +propagate to actions is simply to pass on a command line as i did before but it is quite +an inconvenient thing because in practice you would have to write a rather long command line +each time to pass these operations by the way this command can only be done from the cli because +these variables are not visible from the shell then the problem is solved simply with these +annotations that begin with a sharp dash dash which basically allow you to specify in the action +the arguments to pass to the command line so if i go and see the simple code you can see +that above i have these three annotations that are used to specify the parameters and these +annotations are able to read the environment variables of the configuration as well to use +just use ops id deploy all or just one function note that here i deploy a function that is composed +of its own file and here i have to specify the extension alternatively if i have a directory +i specify the directory and it is zipped so in this case i do the deploy and you see that the +deploy has composed the action by passing all the parameters that are in the config in this way +from the login the secrets are prepaid to the actions in practice i have revealed almost all +the tricks of the secrets keep in mind that the tests and cli see the configuration on +env and the test env while the deployment sees configuration env and packages +that the cli only sees test env it makes sense because it is normally used to develop tests +and not production if you want to see what happens in production write an integration test that +doesn't need access to the variables as a rule to follow always use secrets from the args and get +a default by taking the equivalent value on the environment this way you are able to have code +that works both in production and in testing note that you need to add the perms in the main file +of an action when it is a single file or in underscore underscore main when an action is +multi file then deploy with ops id deploy and you will have all the parameters passed for this +reason it is never advisable to use the creation of actions directly except for special cases when +you have to debug here's a few things about what ops id deploy does it's built on top of ops actions +and packages it currently supports python node and php we will also support other create packages +for the actions create zip for multi file actions resolves dependencies so a requirement of packages +json or the php composer it extracts annotations and is used to propagate secrets and also integrates +with the ops id devil by doing an interactive incremental deploy every time you change something +it only redeploys the function you changed with this we have finished the discussion of secrets +now let's focus on the other topic of this lesson which is streaming how do you do streaming +let's try streaming from the command line right away let's import the libraries to invoke now here +i have created a url in a quick way because i am in a test environment don't do this do as i told +you in general i create a message and pass it to him note that this time the stream is true for this +reason if i now execute the result i will be given a streamed answer what is a stream in python it's +an iterator so now i get an ideator from the answer this is a particular object called a generator +that can be executed with a four cycle if i now execute the before you see that it produces not +one but several answers so the iterator is iterated each piece of response that the streamer is +returning is extracted so the requests from alama are streamed note that the format of each request +has this format remember this because we will use it in the exercise when you stream an alama request +he returns a sequence of juns that have the model response and the done flag until the last one says +done equals true and puts a series of additional information including context duration and other +information so here we have seen the iteration now let's make a function that whole let's create +for simplicity an iterator that counts to zero by waiting for a second then count to zero i give it +n puts a second pause between one request and another this is to show the streaming that i +can try so if i now simply copy this code in the environment here i can test it and see that it +counts down to zero see this is a dummy iterator that we can use to test streaming and since we +write in tests for everything we do then we will use a socket to do the streaming the problem is this +the actions when they are performed are asynchronous so they are managed in a rather +complex serverless environment so they lose contact with the web server because the serverless system +is quite complex so to do the steaming that is only useful in special cases there is a component +called streamer that invokes the action and passes it a socket to receive the intermediate results +the socket is passed in two parameters stream host and stream port by the way the door is +always changing so it is necessary so to do the streaming you will take the parameters stream host +and stream port you will have a socket and you will connect to this socket and then along the way +when you produce the output you send the result to this socket this is the full streaming feature +that you can use with minor tweaks that depend on what you're streaming with this function +you receive an iterator and send it to the stream that was passed through the arguments +most of the time you can copy it like this i collect the result and return it at the end +all concatenated even though i have gradually sent the intermediate steps but testing something +like this is not easy that's why we have a mock something called a stream mock that's able to +simulate what's happening on the stream so you can write code that uses the stream and test it +locally to see what effect it has so that when you send it to production it's already been tested +so using the mock everything is prepared args is created the mock is created then both +executes the stream you simply need to pass the args the args are located where the stream is +created from the mock so the code is the same both in production and in testing and then the +mock stops and you see the results so now i'll show you how it works in the command line amount +this is necessary because it is used to refund the stream because it is in the test folder import +a stream mock and i'll give you the args you see this created me a host stream is a random +stream port that change every time and then using these arguments i create the mock now he is +practically listening something he will receive okay this is normal because the mock wait five +seconds and then and then stops therefore so we have to do it quickly so now i'll show you how +the streamer works first of all i take this stream function and put it in the command line +so now i have this stream function and i can use the mock be careful because the mock is +a bit impatient because it waits five seconds and then finishes this serves to prevent the texts +from getting caught in fact if i start and i don't do anything the mock times out and it dies +because it waits five seconds at most however now i do it again because if there were no this time +out the mock could remain stuck indefinitely so now let's do the test we have to hurry because +we have five seconds so i now i launched the mock i take the generator and launch the stream here it +is it's steaming count to zero so it'll be 10 seconds there there you go you're done now i can +stop the mock and see the result so you see that it produced the various results nine eight seven +five four three this is to understand how the mock basically simulates what the streamer does in +production now i'll show you the actual test code and test it then let's open the countdown and +countdown test code this is a countdown function this is the iterator this is the streaming function +then here is the main which is usual reads and input gives default messages if there is no +in pot it does a conversion of the input into a number and then executes take the iterator and +it does the streaming a very important thing is that when you write a function you have to return +streaming equals true in this way the first response sustainably did not stream but if you +return streaming equals true the client and in particular pinocchio he knows he needs to do the +streaming and so he will reinvoke the request to the streamer so instead of calling the normal url +it will call a special url that is used to do the streaming now let's see the test code which is +similar to the one before the difference is that you create the mock and then run the two functions +count to zero and stream in such a way as to see if it works if i now go to the tests i run it +you see that the test passes because it is able to test a streamed code with a mock +so now if i go to see countdown i can now write three he does two one zero we put 10 and it makes +nine eight seven it is implementing the streamed and tested feature we put everything we've learned +into practice and create an llm stream we have three exercises to do for the first exercise look for +to do e2 1 and here you have to add the parameters to access and authorize allama so see here the +point where you need to complete the code and to add the secrets then the second exercise +is to fix the streaming because if you watch the streaming feature at the moment it is written to +work with the countdown and does not handle the format that instead returns allama so you have +to decode the object i return allama extract the part one i'm interested in an estimate only that +part the third exercise is to modify the application which will be a chat that accesses the llm in +streaming and adds a model switcher that is a command that allows you to change the model from +llama to deep seek and there is also a correction to be made because deep seek produces a think +that is not readable you need to make a modification so that thing is readable by writing in square +brackets and instead of staples now if you want to try do it otherwise i will solve the exercises +in the rest of the video so exercise number one let's add the secrets so i'm going here +here it is the solution is obviously to add perm allama host and then we have to add here +off args get allama host args get off here right now as exercise says the result of this changes +that the test url passes but the stream test does not so the url test before did not pass +i forgot to run it it was read so much so that if we deduce an error for example to see we put out +one if i put this the test breaks because you can't access allama if on the other hand +it takes the right parameter the test passes the streaming tests instead do not pass we have to +correct exercise two says to correct the streaming here it is fixed streaming now if you remember +in this code we're accessing allama using the code we used with an iterator what is produced +at each step is no longer a simple 1098 but is an object so what we have to do here is +decode the object then i do deck equals json loads which is the function that decodes a json +object among other things the streamer returns it to me like this so i have to transform it into +a string utfa decoder and i get an item that i have to extract response and by default let's put +error if it does not find it at this point i can return to this deck and i can add to the final +result this is what we have to do to properly implement streaming when we access allama which +returns to me that sequence of objects that we only care about a part not everything so now +the streaming test should pass now i run the test stream and it passes here we have corrected and we +can deploy and now if we go here on the chat i say who are you and here he is answering me in an +exhausted way list the capitals of united states here it is this is the list is giving it to me +in streamed mode now last finesse this is the third exercise test the model switch so now simply +let us to do e 2 3 and let's add a if to manage the model switch so if i write if imp equals +llama model equals llama and i change the input so that it changes the model and makes it say who +are you if the input is deep seek the model is this and i make him say who are you so in this +way i basically added the functionality of switch of the models being able to change from llama to +deep seek and others if we want now we deploy always diloy also that i could do it incrementally +with devil and let's see the result now i'm going to pinocchio again calling the chat here now i +write deep seek to him it is taking a while because it is carrying out the change of model and therefore +it is loading the model here is if i write llama here now i change to llama here what about slope +okay do you see this empty space this blank space is actually due to the fact that it says what it +thinks but you can't see it so a subtlety is going to modify this code and when i reverse engineer it +i do so if i ask what about china deep seek this changes deep seek tell me about the meaning of +life universe and everything banning of life universe epic see that's thinking sometimes +it begins to think and does not come out anymore so it goes into a loop however the execution +it ends after a timeout that you can change with the action parameters so usually it seems to me +that it is three minutes and after that he stops it when he begins to loop in his infinite thoughts +and in fact if he doesn't loop on a question of this kind i don't know what else can send him +into a loop here is his endless answer about life the universe and everything else okay that's it +because there is a limit that how can be changed with the parameters of the duration of an execution +for this reason it stopped when it took too long okay thank you for your attention and with this +we finish the second lesson
diff --git a/content/en/docs/tutorial-ai/Lesson2/_index.md b/content/en/docs/tutorial-ai/Lesson2/_index.md new file mode 100644 index 0000000..434031e --- /dev/null +++ b/content/en/docs/tutorial-ai/Lesson2/_index.md
@@ -0,0 +1,8 @@ +--- +title: Lesson 2 +weight: 10 +draft: true +--- + +# TO BE REVIEWED! +
diff --git a/content/en/docs/Ai Tutorial/Lesson2/_index.md b/content/en/docs/tutorial-ai/Lesson2/_index.md.orig similarity index 100% rename from content/en/docs/Ai Tutorial/Lesson2/_index.md rename to content/en/docs/tutorial-ai/Lesson2/_index.md.orig
diff --git a/content/en/docs/tutorial-ai/Lesson3/Lezione_3.txt b/content/en/docs/tutorial-ai/Lesson3/Lezione_3.txt new file mode 100644 index 0000000..20cb31d --- /dev/null +++ b/content/en/docs/tutorial-ai/Lesson3/Lezione_3.txt
@@ -0,0 +1,211 @@ +Welcome to the third lesson of the private AI course with open serverless. +Let's start right away. +If you remember the previous lessons you should go to your fork of the starter so that you keep all the changes. +But now there is an update, because changes have been made to the starter and you need to update it so in your fork +you will almost certainly find this comment, a commit behind, which says that you are behind one commit. +So if you don't want to have problems before doing anything do an update then go to synk fork, +lower it and do an update which will update the starter to the changes that have been made, +but keeping your code unless you have also modified the starter code. +At this point we can launch the code space. +You should delete what is there but be careful if you delete it you lose any changes +so be careful if there is this uncommitted change. +In this case if you want to keep the changes you have made go there and update. +At this point you can delete the code space, although it should update it automatically, +however for safety it is better to delete it and start it again so that you will get a fresh and +updated environment that you can use for lesson three, which is independent of the other two, +so you are able to run the code regardless of whether there is code from lesson one of lesson two. +Now let's wait a minute. +Notice here that it is downloading. +You can also see that there are different components here that I will explain later. +After loading everything our speech bubble appeared. +First we log into Open Serverless using the credentials you have already been given +and we can take the new lesson. +So let's select and take lesson number three. +Okay we can start the lesson of the day. +Let's open the slide which is in PDF format here. +Let's also open in markdown format to make references. +In this lesson we will deal with form and display management, i.e. +the ability to create structured inputs with forms and also a structured output with the display, +thus substantially enhancing the input and output of your artificial intelligence applications. +In addition, we will also begin to do prompt engineering, that is, +build prompts no longer based on user input but based on forms and other types of information +that will be provided. +As I said before, wait to update the branch because the starter is updated and therefore +you may be left behind. +First topic is authentication, which concerns the important aspect of information security. +You will say, but isn't it already protected? +Actually not entirely. +On Pinocchio, the interface that we have provided you and that we will use, +there is a password that protects the user interface but in reality the actions to be +invoked by Pinocchio must be public because they must be web action and therefore they are not +protected. +For this reason it is necessary to add an ad hoc authentication layer, +the one I will explain in this lesson, but before going into detail I will explain how +open serverless authentication works normally. +When you want to create actions in open serverless, these are normally not directly accessible. +The access must be mediated through a key that is stored in the whisk props file, +which one can read and use for his own purposes. +However, the actions can also be public, so they can be used by anyone and this is true +when they are web actions and are deployed with the web true flag. +The problem is that when we use Pinocchio we have to use only web actions and therefore +all actions by default are not authenticated and therefore can be accessed by anyone. +But there is a way to protect, which is what we are going to talk about now, +which is a custom authentication ready to use and available in the provided GPT master +infrastructure with Pinocchio and with the back end functions that are already provided. +But now I'll explain some things and to do so I also have to use some shell tricks that not +everyone knows. +When you log in the login information is found in this file. +There's this string off and this stinging API host. +This string off is the key, which is composed of a UID. +Here that is basically the user and a secret here after. +So it can be considered a username and a colon password. +And then there's the AP host pointing to our server. +I can load these values into the shell with the command source ID point isk props +so that it becomes an environment variable that I can use. +This is convenient to be able to work with the environment. +Now to take an action I do UPS URL master GPT index. +See the problem is that this command however gives me this okay here it's annoying. +Then I can remove it with tail plus two and I get only this and I can catch everything +when with the syntax dollar bracket bracket. +Then assign a variable all this to say that I did a command that takes the URL of an +action that I extracted directly because I will use this thing to do verifications. +Now I'll show you in practice how protected actions are and how to access them. +I now open the code of this action which by default is protected because it does not have +web true. If I now deploy and I have not specified web true this is protected by default. +So if I take the URL with the technique I outlined before and invoke it it will tell me +that it is protected because the action cannot be invoked without the key by default +because as I said this is a normal action that does not have web true. +Instead I'll show you how I can use it by loading the off +this one which is now the key that I use it as a user username and password basically to invoke +that action but it is also important to pass these flags because otherwise it becomes asynchronous. +So basically the command to invoke the action will be off we'll use a post and add these +additional flags to it this is all the way open serverless actions are normally invoked under +the floor by doing so the action is invoked correctly and is accessed. So this is how you +invoke actions that are protected by default but in order to use them with a user interface like +Pinocchios we have to make them unprotected so for example an auth action that is normally +public has web true and the result is that I can invoke it now I deploy it I take the URL +and I invoke it you're authenticated because in because there's actually no protection when +their web actions which can be a problem if you log in LLMs but there is a way to hook them to the +same authentication this one there is an easy way to hook it to this authentication that we +have provided and that is what I will explain to you in fact Pinocchio supports an authentication token +so let's look at Pinocchio and now put it in devil mode thus we can realize what happens +and modify along the way okay watch what happens carefully I now invoke off and he tells me that +you are authenticated actually this function here if we go to see the logs it prints me a token +which is what is created when you log in and that you can use to protect your actions +in fact if I go to see what's inside redis here inside the cache I can inspect the keys +do you see this it's your prefix then there's token and that's the logged in user if I do get +msib token messiah I get this secret here which coincidentally it's just the secret that was +printed here so it practically happens that every time you log in Pinocchio will send you this token +at every request to allow me to authenticate users so practically you have to accept requests only +from those who present you with this token which is random of course and is always different +so to prevent someone from sniffing it this token is kept in a cookie and is passed to each request +and you must verify with this code that follows you simply have to add and here is an example +you simply need to disable this if unauthorized return you are not authenticated in practice +with this command unauthorized you can check if one is logged into Pinocchio or not the code here +is this in practice takes the token goes to see if the secret that has passed coincides with the +one on redis and in this way it is sure that the user has logged in so you simply have to add this +function here and check if you are authenticated or not so now activating this function now if I go +to the auth I am always authenticated because I am turning on via Pinocchio but if I call it directly +as I did before taking the URL differently now it says that I am no longer authenticated +so now the actions can only be invoked after one has logged into Pinocchio here this is basically +the point I realized that the topic is a bit intricate however in the end it's basically a +matter of adding this code here is checking who if unauthorized to verify that it is a logged +in or not on each service that is public as all those with web true are normally +let's go ahead and continue the discussion let's now analyze an interesting topic that is the forms +and we will do it by writing a post generator what is a post generator it is this post gen +see I clicked on post gen and this form appears and I say to him CEO because it solves +all the problems of kubernetes difficulty okay and here I say it's formal so he generates me +a promotional post for Apache open serverless and asks me what information I want to provide +so I send it and now he will make a post that if you read it has a formal tone follows the +instructions I gave etc or I can try to make another one for example I say I'm a developer +because it is cool and it must have an informal tone now it will generate me see the post depends +on the input so I did this thing by generating a formula and then building an ad hoc prompt based +on the form so this is an example of prompt in geniring before going into the details of how +it works let's clarify how to define a field so a form as you see here is a field has a description +the kind that can be a text input a radio button a text area etc and then it has a name +and a description which are essentially the fields explained here the description the name if it is +required what type text text area checkbox radio file if it is a radio what are the options if it +is a file there is also the file option it allows you to upload even an image in 64 format +so you know this to analyze when you want to make a form you have to do something like this +a form is an area of these fields described in this way so if I go and see the code of the post +generator you see that in the code I created this area of records and each record defines the form +so to get effect basically I have to go back remember that it is mandatory to always return +output we said it in the first lesson and in the second lesson we said that we have to return +streaming if we want to enable streaming and if now they want to produce a form we have to +return a form that is an object that is a list of records as before so looking at the code I +realized that if the input is null at the first request it produces residential form equals form +that is in the request dictionary the form field is the form you saw before in this way you get the +effect that when I select the form or request for a form is returned and Pinocchio displays it +the whole form and so far we have seen how to request an input the next step is how to request +the output and how to process the form when you produce a form in response an object is sent as +input that is of type dictionary and has a form field whose values are the fields of the form +that I can process therefore using the values of the form I build a prompt so basically I'm +replacing the input so instead of writing an ad hoc input I write a prompt that corresponds to the +fields of the form so I ask you to generate me a form that promotes a patchy open serverless +your job role is job the reason you are using it is why and the tone of the post must be according +to this tone that's all it takes return the form when it is required and when you receive the form +data you process it produce a prompt and return the result like this that's all you need you have +the ready example of how to make a chat that asks for information when it is required okay soon we +will do an exercise that uses this but before doing this exercise let's see another important +topic the display now I'll show you a display which is Pinocchio's ability to display content that +depends on the output of the LLM or from other sources in this case I show that Pinocchio is +able to visualize a chessboard but it is an example because it can display anything there are those +who have used it to view PDFS those who have used it to visualize circuits so only the sky is the +limit because the mechanism of the display is completely extensible and worked like this +simply every time the invocation of a function returns an object that has unknown keys which +are not one of the ones that are processed that are currently three output state and form are +forwarded to Mastro GPT display which is an extensible viewer now I'll show you in practice how it +works by making command line calls so I now launch the CLI I'll show you how it works by +showing below what this demo does this demo does just that it displays a chessboard now I'll show +you what happens under invoking it if I do so I invoke the demo with chess input and as output +you see that it produces me this additional value this additional key chess with output and state +could also produce a form it produces this chess then when there is something this is +forwarded to the display so I now grab it and save it on a file so I caught it on the chess +jason file now I forward it to the display so now I take this output and invoke the display with +the value that was returned to me from the input it's practically a chain the input is not good +forwards it and passes it to the display the result is what you see it also produced me a +whole realization of a chessboard so the details of how it does it you can see in the display +function but basically there is the code that uses it to produce an svg that displays that chessboard +and that's it so if now you have gone to see how the puzzle generator works now let's see the puzzle +viewer let's use the display to make a chess puzzle generator for example we go here on puzzle and +write puzzles and now it will happen that we ask for an llm who is quite good with chess which will +generate a chess puzzle which is displayed here because in the output there is and I expressly +requested it this string which is called the fen string is a string that is used in the game of +chess to describe the position for example if we go to this site we see that we can explore well +known chess puzzles and here is reported the string fen of a certain position so much so that if I +write fen and the location he reports it to me identical based on the description I have given +instead the puzzle generator requires to the llm a chess puzzle and then extracts the fen +string from the code and forwards it to the display the code that does all this is quite +simple if I say puzzle then I make the request to it generates a chess puzzle in fen format chat +after which I extract the fen string from the output and return it as an additional value +of the answer so that the display will grab it and display it the extraction of the fen string +is done via a regular expression that a very standard technique it basically takes the output +dlllm searches for a strina that conforms to a certain situation and displays it so the technique +of extracting output with regular expressions is ubiquitous so it's a worthwhile thing use however +you don't have to go crazy with regular expressions because usually the lllm helps you a lot to build +it's one of the things it does quite well if we now look at the code for a moment we understand +how it works here it is the codex you ask for how to input puzzles creates a request that you want +to generate a chess puzzle in fen format chat with lllm extracts the fen string and if fen +stings it there is the includes as the key chess at this point the value will be propagated by +pinocchio who will take care of making the visualization the same works when you make the +fen request in this case simply take the request from the input instead of the output and display +it directly again the code is pretty simple and so it should be clear how to accomplish +now the exercise of which this time I will not provide the solution but I will let you realize +it step by step you have to do the following you have to modify the puzzle in such a way that +instead of providing me with a generic puzzle it provides me with a specific puzzle so you have +to ask the lllm not to generate a chess puzzle in fen format but you have to produce a form that +asks for the format of the puzzle a simple form like this with a queen with a rook with a knight +with an ensign our check boxes and you have to if for example you select queen and bishop +produce an output generates a chess puzzle fen that has a queen that has a knight so based on +what you have chosen I don't give you the solution I don't do it I'll let you see it but I tell you +how to get the solution easily obviously after you have tried you can extract the solution like +this with this command by default the command is not available but if you do so extracts the +solution you find here so puzzle upload here is the solution so you can do something as trivial +as a select for compare comparison compare with selected and see the difference practically +what I did to achieve and the result is something like this now I copy it and paste it deploy it +once you've deployed the puzzle generator with form you should see something like this then +puzzle when I write puzzles this one should appear to me here and I say with a queen and with a knight +send and he has to produce a puzzle for me who has a queen and a horse so now you should see +here you see he produced me a puzzle which is exactly what I asked him a puzzle with the queen +and a horse all right then thank you very much and see you in the next exercise we'll see how +you got on with this exercise
diff --git a/content/en/docs/tutorial-ai/Lesson3/_index.md b/content/en/docs/tutorial-ai/Lesson3/_index.md new file mode 100644 index 0000000..02ad5fb --- /dev/null +++ b/content/en/docs/tutorial-ai/Lesson3/_index.md
@@ -0,0 +1,9 @@ +--- +title: Lesson 3 +weight: 10 +draft: true +--- + +# TO BE RERGANIZED AND REVIEWED! + +
diff --git a/content/en/docs/tutorial-ai/Lesson4/Lezione_4.txt b/content/en/docs/tutorial-ai/Lesson4/Lezione_4.txt new file mode 100644 index 0000000..5ce57c5 --- /dev/null +++ b/content/en/docs/tutorial-ai/Lesson4/Lezione_4.txt
@@ -0,0 +1,371 @@ +Welcome to Lesson 4 of the AI, Private with a PACE Open Serverless. +To begin with, let's go to your starter. +I remind you to do a synchronization, then go here to syncfork if you see Update, +to update it in case there have been any changes to the starter, +and let's start immediately by launching the code space, +which contains the development environment for the course. +By launching the code space we will get to this point, +where there is the starter, which is empty, +and once it has been initialized we can go to the extension, +and download lesson 4. +So first let's log in. +Okay, and then we can choose lesson number 4. +These are the files of lesson number 4. +Let's start immediately by opening the PDF of lesson 4. +We also open the markdown, which we will use to copy commands. +So in lesson 4, we'll talk about how to create an assistant. +In reality, an assistant is simply a chat that remembers what you said before, +maybe you haven't noticed it so far, but I'll tell you right away. +All the chats we have implemented so far are stateless, that is, +you can practically only interact with the request you make at the moment, +the chat does not remember anything. +From this version, however, we introduce assistants that are stateful, +that is, they remember all the conversation that has been performed, +and therefore you will have to memorize the conversation somewhere. +To implement this state, we will start using an API. +Now Universal, which is the API, by OpenAI, to access the LLMs. +It's actually not just for OpenA. +But it works with practically all LLMs, including the one we use, which is Alima. +The program of the lesson will be first of all to see how this API +works and to study it a little. +After that, we will create a class that wraps around this OpenA. +I, which basically allows you to interact in a simple way using a class in Python +for the first time, so I will also explain a little bit about the classes. +Now I don't explain Python in this course, +so I invite you to learn more about how to program objects in Python. +I assume that you already know object programming in some way. +To store the information and the history of interactions, we will use Redis. +So let's explore a little bit also how Redis works, +and we will also implement a class that maintains a history, +and we will put everything together, creating a stateful assistant, +an assistant that actually remembers what you said before +and interacts in a stateful way by carrying out a real conversation. +The first step is to see the API. +By OpenAI. +The A. I have OpenAI. +Was the first that was developed? +When it is. +ChatGPT was also made available in API, +a library that defines some ways of interacting with LLMs. +This mode of interaction has become the de facto standard. +So much so that using the OpenA. +I library, it is actually possible to use practically any other LLM +because practically all of them implement an API at least partially compatible. +So if you write an application that uses an LLM using these API, +you can practically hook up to any provider by changing parameters +such as the URL and the access key. +Now let's introduce the OpenAI. +AI specifically to start interacting more richly with the LLMs. +The first step to use this API is to create a connection. +So it is a matter of using this OpenAI builder by passing the two parameters. +One is base URL and the other is the API key. +The base URL is the access point of the call and the API key is used to authorize. +So we will use the A. B. I have OpenAI compatible that is inside Alima. +In fact, we will use the keys from before used to build the access URL. +Now let's try this mode immediately by opening a terminal. +And let's try it right away. +Let's launch a CLI and see how it works right away. +First of all, OpenAI has to import and I take the host and the key +after which I compose the URL using the API key and the host. +Attention with Alima authentication takes place on the basis of URL +and the API key is irrelevant. +So you basically have to put what we call the API key as username and password. +And that of the URL and the value of the API key is completely unused in this case +because the protection is done at the URL base level, but this is accidental. +In general, if you use another provider, +you almost certainly have to specify both the API key and the base URL. +So in the example we do, we specify both so we get a client. +This client object here is the one that allows you to access OpenAI's API. +Now let's see how to interact. +In practice, every request to OpenAI requires a list of messages. +Not one, but a list. +And these messages represent the conversation that we have had so far with LLM. +Each message has a role and you have to provide not only your requests, +but also the answers that the LLM has given to obtain a coherent result. +So you have to keep track of both what you said and what the assistant said. +So there are two important roles, user, which is you who are interacting, +and the assistant, which are the answers. +In addition, it is also possible to have another role, +which is that of the system, which is basically a configuration of requests. +So what you have to do is create a list of these messages and pass it to them. +So now in this example, I'll show you how to interact. +I now create a message. +I specify the model here. +In this case, we are always with Olima. +The message list in this case contains only one message, but it is still a list. +And to get the answer, I invoke this. +Chat client completion create. +I basically use the client to connect and then call this chat completion create +to create a conversation completion. +In practice, the LLM takes the list of all the things that have been said before and adds a new one. +This is the answer. +Rez, which is quite structured, contains many fields and can actually produce multiple answers +because it is part of the ability of LLMs to respond differently. +But in general, I take the first available option, +take the returned message and take the content. +So if I asked him, what is the capital of Italy? +He replied to me. +In this way, you see how I interacted with open AI and you should have understood. +So create this list of messages, each message has a role and content and pass it on to them +to the client that you initialized with the key and the initial URL. +This is therefore the essential part of how open AI is API works, +which allow you to create assistance sequences of interactions with the LLM. +For our purposes, it is important that the API also supports streaming. +Then you can return the answer step by step. +So to get the stream, you have to add stream true to the request. +The answer will be a generator in Python that can be iterated to extract content that is called delta. +So now I take the next step. +I call the a pie. +I re-execute the request by specifying stream equals true. +Here is this time I get back a stream object, +which I can iterate and this will iterate it and show it step by step. +It sends it to the end. +So now I can put it here, for example, and equals. +And so I see it all below. +I have to re-execute the request. +I execute the request. +If instead I perform it like this, you have it all in a row. +But you have seen that in reality, the answers are returned one piece at a time in streamed mode. +So now you've seen how streaming works with open AI. +Now we have all the tools we need to encapsulate all of this into a class. +It's the first time we've seen a class in Python. +First, I'll give you a super crash course of how classes are made in Python. +I won't explain object programming, but assuming you know what a class is, +in Python you define a class with a name you specify methods, +a particular method that underscore underscore. +Is the constructor, all methods require you to explicitly pass a self parameter, +which is the object you are pointing to and the characteristic of Python, +is that the changes of an object are dynamic. +So they are created when needed using self value. +And they are always accessed using this self parameter that is present in every method. +So in practice, this is a very trivial counterclass, +which is created with an initial value every time +that you call the counter method returns the current value and then increments it by one. +So for those who already knew about programming objects in some other language, +it should be enough to write classes. +If it is not enough, I suggest you study it because otherwise it will be a bit difficult +to understand the mechanism, but assuming you know object programming. +Here I have defined this class counter C. +Now that I have created this counter class, +so I can create an instance of this class with counter C equals counter. +Okay, and then I invoke the half counter, and then you see that it goes on. +I'm assuming you know programming objects, I realize. +So if you don't know it, probably these things that I have done, +as simple as they are, can be difficult. +In this case, I have to invite you to deepen the programming of objects +because the rest of the course and this lesson will use it. +Now I'm going to show you how to write a class that basically encapsulates OpenAI's API. +I'll first show you how it works and then I'll explain how it's done, +which allows you to create a chat. +To add a request, complete it, add another, complete it, add, complete it, etc. +So if I go here now, and I try this line is used to access the classes. +Here is now this chat object that I create and initialize without arguments, +so it will practically take the default arguments. +But anyway, this object is actually accessing Olima using OpenAI's API, +and I'll show you the code later. +But in the meantime, let's see how it works. +In this object, I can add a request, add, you see. +I wrote all the requests with this syntax, i.e. +Role, request. +Do you remember that all messages have a role? +For convenience, I put the role as a prefix, +so all requests are of type role two message points. +Now I have added a message to the chat and I tell him to complete. +Since the role is system, the completion is null. +If it doesn't respond, it's like AE saying, okay, it's fine. +But I configured it to say that I tell you the nation and you tell me the capital. +And so if I now add another message, Italy, +then it is as if I had written Italy on the chat, +and I tell him to complete, he will answer me Rome. +Now you see that you already remember? +He remembered that I told you to tell me the capital. +If I now give another interaction like France, he will answer Paris. +I can also go and see what is underneath. +I see that this class actually created a whole bunch of posts, +every time I added one and completed it. +He memorized it and therefore did all the history. +So basically simulating what happens when you guarantee with the LLM. +Now let's see the code as it is done. +I advise you to study it, it should not be difficult to understand. +Here is the builder. +In the constructor, I initialize the client to access. +These are the usual codes that are used to access Alima, +and here I initialize a field that accesses open AI, +and then it creates a list of messages for me, +and I initialize it with the role. +Then every time I do the add, I take that two-point message role message +and turn it into a content role object instead as required by the API. +Finally, it completes and does nothing but take the messages +and send them to open AI, returning the result and adding it to the history. +This is important. +What we have seen so far is enough to create a chat with which to interact. +Now let's move on. +Now an exercise. +Your exercise is to implement streaming to this class, +because if I deploy it now, as it is you will notice that it does not stream. +If I open it now, I go here I see that there is the open AI one. +If I try to use it you see that I wonder something is there a bit, +and then it answers you because there is no streaming. +Then the first exercise is to implement it. +There are various steps to take, here you are guided. +Search for, to do, and for one. +And here are the various points that you have to implement. +You have to follow these tips here they are also written in the code, +add a stream function, then retrieve the stream function, +adapt it because you have to adapt it to the answer that open AI gives. +Save arguments when you initialize the class, request a stream when. +Make the request, stream the response, and finally turn on streaming. +It's pretty easy. +I'll be clearer to familiarize you. +With the development of classes. +If you want to have the solution, Ops AI's lesson for. +Assistant minus minus solution. +So you can download the solution. +So here you can see the solution, now I simply use it, I copy it. +Here in such a way that you have the result. +I take the solution here, and I copy it here, +and the result once done you will see that the chat becomes streamed. +So here basically in the exercise is to invent a class of streamable chat +that you can obviously use for your programs. +All right. +The next step now is to save the state. +This one here is still stateless. +You don't remember anything because even though we used the AI. +By open AI. +We have to memorize the history somewhere. +And in fact now what we are going to talk about is precisely this, +how to memorize the history. +We'll use Redis. +We have already seen it. +When we discussed. +Now let's introduce what Redis does for a moment. +Redis stands for remote dictionary server. +It is a cache of data structures. +So strings but also list maps and much more. +And it is for server applications and all microservices applications. +Usually the backbone because it allows the various functions to communicate +or to remember information become full states using Redis. +Here we see for a moment how it works. +So now I launched the CLI. +Important warning. +Redis has a somewhat strange way of doing multi user. +Basically it is as if it were. +A single user even if the various users cannot access each other. +But they can see the keys on one side. +In fact this is a collaborative multi user. +One cannot read but can see what keys others have. +Each user must use a prefix that is assigned to them. +It is possible to do otherwise but in open serverless we have a single Redis +shared among the various users. +So each user must use the prefix. +So now let's try Redis right away. +As before we import it. +Let's read the prefix. +We read the Redis URL and access Redis with this object. +RD which is a client and allows you to interact. +Now let's see what can be done. +Here are a couple of examples where I can read and write a value key and then another +example where I create a list and then read it. +So there you have it. +Right now I set a key and I read it. +Note that there is this B that says that it is a ready byte and therefore must be +decoded when you want to convert it back to a string. +Redis stores only ready bytes and not strings. +Instead I make a push a light push in a list. +Another light push and then I'll iterate. +That's it. +And here instead I. +Piscotto 2 and then I iterated them. +So in this case I saw how they are managed. +Individual values and how to manage them. +In reality there are many other data structures that I mentioned now only for completeness. +There are hashes which are basically tables. +There are sets which are unordered sets. +Then there are the sorted sets which are ordered sets instead. +And there are many others bitmaps streams hyper logs. +There are a fair number of them so Redis is quite rich in these components. +Now let's put it all together and create an assistant using Redis to store the history +and then using the chat class we saw earlier. +So the first thing we do is create a historic class. +This historic class is the one we'll use to store state in Redis. +In practice it works that every time I create a history +a unique key is generated that is unique every time one connects to a history +and it will be kept in a conversation carrying this key with it. +In practice it is used to create a list on Redis where a list of conversations is created. +Each list is identified by a unique key. +We carry this unique key with us on the user interface +on Pinocchio as the state of a single conversation though. +In addition in order not to fill Redis with information +all conversations are deleted after a day. +So let's see how it is done in practice. +The calls used are these. +Use it to generate the UID key which is a Python standard library +which generates a unique unique identifier. +So so I'm sure each conversation has an ID that doesn't conflict with any other. +So you see this here generates it for me. +This will be the key where I go to store a list of objects and a list of conversations. +So here I add one then I set the expire so that after a day from the moment it is created +it is deleted. +So the system will basically create a new key every time a conversation starts +and after a day it will delete it. +The code of this class is quite simple and I'll show you it. +I suggest you study it and then I'll show you how to use it. +So when we initialize them it reads. +The prefix and keys in such a way as to find it to connect to Redis +and if there is no queue it creates it. +So practically every time I create this class without specifying the ID it creates a new ID +if it sees specific the ID it reuses it. +So the ID is returned by this method and then we have two methods. +Save which saves a history and load which reloads it. +Using this class and the chat class we implement an assistant that remembers the history of conversations. +Now we practically test this class immediately. +So I'll show you what's in the history. +So a history it is a chat. +So first I create the history then high and historical object and save it a message. +I basically tell him to tell me that when I ask him the country he replies with the capital +and I get the ID. +See now since here when I initialized it I did not specify any ID he created a new one for me. +Now let's make sure we're in a later conversation. +Now I recreate the history from scratch but this time I pass him the previous ID. +Now I can save Rome. +So I said to him when I tell you in the nation you tell me the capital. +If I tell him Italy he should tell me Rome. +Now the nice thing is that it hooks up to the chat so now it creates a chat +and I make you upload the messages and here are the messages. +See? +So we have a history class that is capable of saving a sequence of messages to Redis. +Now let's try it in practice. +Let's perform this sequence. +First of all let's create a new history. +Initially it is empty. +I initialize it by giving it a command if I tell you the nation you tell me the capital. +This one if I read it gives me the ID. +Since when I connect to the chat for the first time he creates a new history +he creates a new key and carries this key with him to remember the history. +The next time you can load the history from Redis. +This is a later time I loaded the history specifying the ID. +I create the history. +Now I tell him I tell you the nation you tell me the capital and he saves a further message. +The characteristic of this history is that if I pass him a chat he is able to load the list of +messages. If I go to see the messages in the chat I will see a history. +Putting everything together I can implement a full chat state like this. +I load the history and then I create a chat and load the history into the chat. +At this point I create a message with the user role taking from the input. +I add it to the chat and save the result. +At this point I interact with the chat and tell him to complete it and save his answer. +All this. +I remember it the next time returning to the state. +La next time the state will be called by the args. +So when this is initialized it will be able to work again. +As an exercise I tell you to add history to the stateless chat by transforming the stateless +into stateful. Then you have to reload the history from Redis, view the chat for the history, +save the replies to return the ID as status. +So if you do the search and 4.2 it tells you where you have to go to enter the specified +steps of the message. This is already the solution, already ready, so if I deploy it now we would +have the chat state full already working. Okay. So if I open it now. Open. Okay. +We go to the full state class, so now I tell him I tell you the country and you tell me the +capital, well. There is no streaming. I tell him Italy. Now France. United States. See? +By implementing the chat with history you have obtained a state full assistant, that is, +a chat that is able to remember to converse, maintaining the state on Redis in a temporary +way because after a day it is forgotten and cleaned. Okay. Thank you for your attention and see you at +the next lesson.
diff --git a/content/en/docs/tutorial-ai/Lesson4/_index.md b/content/en/docs/tutorial-ai/Lesson4/_index.md new file mode 100644 index 0000000..632e866 --- /dev/null +++ b/content/en/docs/tutorial-ai/Lesson4/_index.md
@@ -0,0 +1,7 @@ +--- +title: Lesson 4 +weight: 10 +draft: true +--- + +# TO BE RERGANIZED AND REVIEWED!
diff --git a/content/en/docs/tutorial-ai/Lesson5/Lezione_5.txt b/content/en/docs/tutorial-ai/Lesson5/Lezione_5.txt new file mode 100644 index 0000000..1408e82 --- /dev/null +++ b/content/en/docs/tutorial-ai/Lesson5/Lezione_5.txt
@@ -0,0 +1,178 @@ +Hello everyone and welcome to the lesson of the Private AI course with Apache Open Serverless. +Let's start immediately by starting the code space from your starter, which in this case I have +already started, then you will see this screen login and after logging in you can choose the +lesson in this case lesson number five. Now let's open the PDF of the lesson. In this lesson we +talk about computer vision that can be done with LLMs and file storage which is closely related +to the vision itself. The plan of the course is to learn how to analyze images using open source +LLMs, in particular we will use in this case Lama's vision model which is the model we mainly use. +Then we will see how to create actions that generate a form to load images. At this point we +deepen the storage using the s3 standard which is used precisely to save objects. They are called +this and are actually files inside a web file system and then we do an action that will use to +apply the vision the objects that have been loaded into this storage. So first step, let's analyze +the images. Let's see how it's done. To analyze an image using the Lama vision model we need to +connect to Halama and call this endpoint chat API in the Halama URL. So as a first step I create a +URL to access it and then to test the system we load an image from a file and transform it into +base 64 format which is necessary because it is the way you send information in JSON format +to the LLM using the Halama APIs. To analyze an image you must first choose a model that is capable +of making vision. Then you must send a message that specifies precisely this model and among the +various parameters it sends a message that contains a list of images in basic 64 format +as in this example. At this point you can make a post at the right endpoint asking to analyze the +image and the result is a stream. In fact you see here that I explore the result to see what if there +is in this stream but in reality the steam must be unrolled so you have to take all the pieces +one by one and collect the result to see the response of the LLM. Let's see it in practice with an +example. Let's try to execute step by step the code we have seen. First of all let's import these +libraries and compare the URL we need to work. So we can see this screen. Now let's load the image +in base 64 so if the printout we see the sequence of characters which is basically the textual +representation of a binary file. Now we can analyze the image then we build the message. Here it is +so you see the message specify the model specify the role specify a request what's in this image +and attach an array images in this case it's only one i.e. the image we uploaded from the file. +So now we can send the request to the LLM. The result is a generator so of a stream. +Let's see the first piece of the stream so this next line that allows you to read one. See he +replied duh so the first touch returned is duh to see them all we have to unroll the stream +with this code and so let's see the rest. I'll show you that it's in the image I uploaded. +The image represents an Abyssinian cat. +Moving on. So far we have seen how to use the vision with Halima. Now let's do an action that +uses it. We see it in this example. It uses a form that allows you to upload a file once the +file is uploaded it is passed to the LLMs for analysis and the return value is displayed so +that they can also see the image that we asked them to analyze and the result of the analysis. +In particular in this action we will use a form of type file whose format is this so you have to +specify file type the name of the file and the label then you have to extract the result by +verifying that the form has returned a dictionary and from this you can be the pick field which +represents the image already queued in base 64. To display the image we have returned we will +produce a piece of html using the base 64 encoding that is already present in html that is it is +possible to have a base 64 image to display it by building a tag in which source there is this +string here data image png and then the base 64 image in this way since Pinocchio's display is +able to display pieces of html simply by returning this html we are able to display the image +so now let's see the action code that we have written analyze it for a moment and then see it +in action let's take the action code first i wrote the class a vision class that encapsulates +access to the url see here it reads the yards and creates the url to access them after which the +decode method creates that famous message you saw before makes a call to the llm and iterates it +and then calls a collect function that collects everything this feature basically unrolls the +stream collecting the results step by step here it should actually put the streaming but for +simplicity i avoided streaming and i collected the data so as not to complicate the code so if we +open the test we see how this code works i first import the image of before that of the cat it creates +a vision object since it is a test the default values are taken from the environment variables +and then uses the test configuration and then i call decode which is calling the llm to understand +what is in the image if you print this image contains an abyssinian cat etc etc so the +test confirms that the class i created works at this point let's look at the actual code of the form +so do you remember that here i create a form that asks for an ipet and the code decodes the form +so if there is a form it extracts the image then creates a vision object and then decodes it and +as a final step the display of an html returns that will display with the url that i explained +before the image in base 64 so now i'll try to run our example i log in here it is here is the form +when i activated do you see that a form is displayed here at this point i simply choose a +file then take this which is an image again and send it right now it has been uploaded and is +processing it see there is an egg in the image and displayed image let's try another i choose +for example a parrot here a parrot that is on the branch has been updated and has updated the +display so here you have seen how this simple function that is able to do vision works now +let's complicate things a bit and learn how to manage how to store files in the open serverless +s3 cloud file system be careful because here you can get confused because there are three different +s3 endpoints endpoints are the access points of s3 there is an internal one which is used +when deployment is done so it is the one actually used by functions when they are production to +access this endpoint which is internal to the new velaris class so it is not public you use the s3 +host and s3 port variables which are provided by the system when you log in and are the famous +psychrists that are automatically provided by the system but when you do the tests there is +another one that is configured instead in the test env variables because in the test environment +there is another s3 because since the open serverless s3 is not directly accessible to do the tests +there is another one that is started together with the container and the editor and is accessible +using the parameters that are stored on test point env but then when we use the system to view images +we will need to export externally that is with a public url therefore accessible via web to images +so we would have to modify the internal url has an external url and this is the production +external endpoint which is pointed to by the s3 ap url we will see that to use this we will make +the modification to the internal one to make it external so let's be careful because being between +the different cases you can easily get confused we are not confused if we think that the internal +deployment is normally managed for production the test endpoint is managed when we do the tests +and the external one is used when internal images must be waited for externally here it had to be +clarified well because otherwise you can lose so now let's take a good look at these endpoints +endpoints are the access points of the s3 service where images are read and written +let's take some examples i import the os library and initialize the args now i open the host +i extract the port and build the url here it is this is the url which in this case is actually +the internal url that is used for testing from this i extract the bucket the bucket is a kind +of collection of let's clarify what we are talking about the s3 has an endpoint that is basically a +url that is used to read and write inside an s3 server there is an initial path which is called +a bucket and basically serves as an area that is different and separate for each user we now +extract the bucket that will be used in practically all calls because each file ends up in a different +bucket another thing we take is then the external url which has not been defined because it is not +there in the test environment so we will explain it when we do the tests you can verify that the +secrets to access the internal s3 are these the bucket is called msiab data the host is internal +and the external url is it's this one the external access point when we would like to make internal +information accessible externally instead the test values are these you see s3 host minio s3 +port etc the keys are also different and the url is different so as you can see the internal and +external values are different now let's try to log in to create the to create the client in addition +to the url that we have configured by taking those various parameters we also require a key and a +secret in practice a username and a password which are called so which are also provided as +environment variables and there is also the region which however in the case of s3 of open +serverless is fake there is only one region we always use the us east one one because s3 is +basically a standard defined by amazon but everyone uses it because we use a system compatible with +that amazon has various regions and the first us east one region is the default one in reality you +could put anything it would not change anything after that we got a client that allows us to access +s3 now let's see how it is possible to read and write these additional steps show the reading from +s3 so i'll take a file and i read it so body contains the file not encoded in base 64 just +the file as it is and i write it there you have it he gave me an answer that basically tells me +that the writing went well let's check simply by doing lend body and you tell me that we have +practically loaded 494356 bytes okay now let's try to read it note the key so pretty much in the +file will be called cat jpg now i'll read it again here and now i take the data and if i +now do lend data i realize that the value is the same so in practice the reading and writing were +successful so then so we saw the direct features and a now there are other features that we mention +one is the one that is used to listed so list objects which will return an object of which you +must specify contents and delete which is used to remove the object instead so now let's take the +list of the content object is not empty in fact it is a list of dictionaries that give us a series +of information including one of this is the name of the file and then there is also other information +now i can delete it then i perform a delete here you see and with this delete if i now rerun the +list now contents is false because the bucket is empty it returned a false value because it has no +content so we also used the ancillary features of listing the contents of a bucket and deleting bucket +objects with this new knowledge of how to manipulate objects we create another function that does the +same things with the added possibility of doing visualization on objects that are loaded therefore +we're going to do a function like this where we're going to use the of upload which instead of +displaying a form that asks for an input and instead he has a instead it has a button that +allows you to upload directly to s3 you can list the files that have been found and you can apply +the vision by simply selecting with the prefix add one of the the vision is read and carried out +and it is also displayed and the display will be done using a public url on s3 so it's a more +evolved and more sophisticated version of the viewer we saw before so let's go into detail +the important thing to know is that now in order to show an object to show an image and make it +public you need to generate a signed url what is a signed url it is a temporary url that has a +very specific lifetime and that has a whole series of keys that are used temporarily to +access a file until the lifetime which in this case is one hour has passed so it is a feature +that allows you to export to the public temporarily and make it readable to everyone without permission +for a limited time of the objects so if you want to display an image externally you have to create +a signed url and set a limited lifetime since the signed urls are generated by internal access +we have to do this trick here so that the url is accessible from the outside because open serverless +has both an internal access and an external access but to use the external access you have to change +the url because for photos the url is produced with the internal url now let's see the code of +this action that uploads the visualization if i go to see the code first of all i'll show you the +bucket this class here basically encapsulates all the bucket management features so let's +see how this class initializes all the parameters to access s3 here there is the right method that +is used to write here is the read method that is used to read here is the remove method that it is +used to delete the file in fact this deletes a series of files with a prefix this is the +external method that it generates the signed url i mentioned and then modifies it so that it can be +used from the outside here there is a method to see the size of a file and a method to search for +it so it looks for files as a prefix so this is a slight evolution of what i explained to you before +we can try everything so let's test all of this first of all let's upload the bucket and let's +make sure that there is nothing then we read the file again that of the cat and write it okay he gave +me an okay answer so it was successful now let's look if there's a file named cat so we found one +which keeps substringing cat and we assert that the length is one in fact there should only be one +let's take its size and verify that it is greater than zero now let's read it again and assert that +the length is equal to the length of the file we wrote and initialize a vision we decode it to base +64 and we invoke the llm to analyze it now the answer is obviously that it looks like an abyssinian +cat as before let's check that in the description there is precisely cat we remove it let's see that +we have removed one and make sure that now there is no more cat here this test allows you to verify +that the whole system is working so once we have verified the test we can focus on on the actual +action you see it has a use that involves use asterisk to do searches the shield point to remove +files the at to interpret the files then searches through the files that are there and applies +the description the upload is done directly from Pinocchio and the code is now extremely simple +so if the request begins with an asterisk it does a search if the search begins with the +exclamation mark makes a removal if the search instead begins with the at the matter becomes +more complicated after because first it searches for the file if it finds it it says i'm looking at +this file and here it reads the file from the bucket it codents it in base 65 passes it to the +vision decodes it and returns the result and in addition it creates an external url to be able +to view it and passes it as a fragment of html for visualization all this put together gives us the +sto store here it is inside there are already some things loaded we can load for example or the egg +very well if i write asterisk now i see that now there is also the egg now i use the at egg at this +point a search is done and it is passed to the llm and tells me that this allows you to interpret +the image i uploaded or if i do at galaxy he will make me the analysis of the warranty usually even +longer and more detailed there you go you see so it is also possible to delete them the removal +is more precise so it doesn't want a substring but a prefix that way i can specifically delete +just one here now i deleted the extra file that i had uploaded okay with this we are done i leave you +with an exercise which is to put the two things together so the exercise is to modify the form +that we said uploads the files and have the file saved on s3 if and then applying then the encode +in base 64 the view using the external url in this slide the steps to follow to solve the exercise +are suggested all right thank you all and see you next lesson
diff --git a/content/en/docs/tutorial-ai/Lesson5/_index.md b/content/en/docs/tutorial-ai/Lesson5/_index.md new file mode 100644 index 0000000..75b8d4b --- /dev/null +++ b/content/en/docs/tutorial-ai/Lesson5/_index.md
@@ -0,0 +1,9 @@ +--- +title: Lesson 5 +weight: 10 +draft: true +--- + +# TO BE RERGANIZED AND REVIEWED! + +
diff --git a/content/en/docs/tutorial-ai/Lesson6/Lezione_6.txt b/content/en/docs/tutorial-ai/Lesson6/Lezione_6.txt new file mode 100644 index 0000000..fb61c0e --- /dev/null +++ b/content/en/docs/tutorial-ai/Lesson6/Lezione_6.txt
@@ -0,0 +1,149 @@ +Hello everyone and welcome to the sixth lesson of the private AI course. +In this lesson, we will talk about vector databases. +Let's start immediately from your fork. I recommend that you update if you notice that +your fork is not updated from here, after which, as always, launch your code space using the extension +log and then we can start taking the lesson number six. Here it is. We have downloaded the lesson. +Let's open, as always, the text of the version. In this lesson, we talk about the vector database. +One thing closely related to the reader database that is embedding, which is the transformation +of text into vectors, and I will now explain what it is, the search for vectors and finally the +import of PDFS from which we will extract text for import. Material databases are the foundation +for doing the RAG, the retrieval augmented generation that we will see in the next lesson, +which will conclude this first edition of the course. Let's talk about vector databases. +As vector databases, we use Milvus. Milvus is a no-SQL vector database optimized for vector +searches. In fact, it is said to be a vector database. What is a vector search? It is a search +that finds similarities in a set of data regarding their numerical representation. +Vector research is important when trying to instruct LLMs by taking information from texts. +You look for sentences that are similar to a given sentence, typically a question you ask an LLM. +To do this, it is necessary to encode all the text you want to search for in numerical format that +represents it semantically, and this is done by LLMs that make a transformation of the text into +a series of numbers that are organized by semantic similarities. For example, the word cat and the +word dog are closer between the word cat and the word orange. So when you are searching for this +information that is semantically similar is extracted such that the LLM is instructed with +the relevant information when you do an augmented generation. We will see this better in the next +lesson, for now we limit ourselves to embedding the text and extracting it by similarity. +Milvus is a multiple database, each database has multiple collections. You can think of the +collection with a table. Just like the tables for each collection, you can assign a schema, i.e. +a structure and indexes. Let's try it right away. We need some information to access it, +so the host, i.e. where it is located, the key, the token, and the name of the database. So with +this information we can access Python by creating an instance of the Milvus client class. At this +point we can operate on the database. I'll show you. So we import libraries as an operating system +is Milvus, so here I take the URL to access, here I take the token and here I take the database, +and it comes to an instance of the Milvus client. With the client I can do operations such as listing +the collections, see here I have. Listed the collection that were there and I found one, +I remove it. Now the collection looks a lot like a table, you can recognize that you have fields, +so title, title vector, i.e. that the vectorized version transformed into title numbers, links, +other information. In a collection there are so many entities that are the records, +so how do the records in a database change? Let's see how to create a schema. We choose +to use the collection and we also choose the dimension which is the size of a vector which +is important because it's also the default size produced by the embedding template that I need +to use, so it has to be that number there. The one we're going to use produces outputs in that +format there. With that information we go create a schema, we add an ID field, just like in relational +databases a common concept is the auto ID, that is, the automatic assignment which means that the ID, +if you create a record is automatically generated. Let's add a text field where we will put text in +text format, the one we are used to, and an embedding field that will instead contain the text +transformed into numbers, and you see that the size of this vector is the one we have chosen, +so this is the minimum to be able to make a collection that contains text and with associated +embedding on which to do vector searches. It is also advisable to associate an index, +so that searches are speeded up. Then we'll create an index that indexes the embedding field. +The vector search can be done with many functions that calculate the distance. +There are several, the most common being IP, but there are many others that we will see in detail +later. Practically it is a distance that measures the proximity of the points of one vector to the +other vector, but other metrics may be more appropriate in particular cases. Once we have +index schema we can create the collection with that schema. Here I import the data type. The +collection will be called test, the size will be 1024. I create a schema object, create a first ID +field, a second text field, an embedding field, and then we define the schema. Now I'll create an +index. I add an index of type autoindex with that type of metric which is a way of, index, +and find the distances. Find the distances with the vectors contained in the, in the, +now we can create the collection. We have created a. One operation we can do is obviously the +insertion of texts. I also have to associate a vector representation of that text. At this moment +we can't do it because we have to learn how to do the embedding. Let's do it later, so for the +moment we put a sequence of numbers, but only to show how to do the insert and once they have +done the insert I'll show you how to extract them then the global search, i.e. we consider all records +then we will do a more appropriate search using a vector search. So going back to the text hello +world for example, a vector that is a simple sequence of numbers of 1024 numbers exclusively +for demonstration purposes. Here you see I have included it in the collection. Now I can extract +it, I create an iterator, all the records of a record extracting the text field. So I take a record +of this object I can extract the value, so you see we inserted a record and we retrieved it. +Now we can deepen the discussion by addressing embedding. What is embedding? Embedding is the +transformation of text into numbers with a semantic structure as I had done the example dog and cat +are closer between dog and orange. A numerical vector representation could be imagined as points +in a hyperspace as internally LLMs represent the information they process. To transform this text +into this series of numbers you need to have it done by an LLM. To do the embedding we have to +use a model that does the embedding, a model like the LLM-ACCS, with the difference that instead of +producing the answer to a question as it usually does an LLM produces a series of numbers that +are a semantically meaningful representation of these words, then transforms the text into a series +of concepts grouped by proximity. Using this we connect the LLM exactly like the other cases, +but we will use embedding as the call. So I get the name of them spy embed large model. +We want to embed hello word we keep the URL and build a message exactly as we have done +all the other times to connect to Olima and make the request. Here. Now let's extract the output +and see that the output is precisely a numerical representation that is suitable for vector searches +for similarity. Therefore, let's now proceed by embedding a few texts. So I'll show you how +similarity works. Therefore, I will use this class vector DB of which I will show you that it is able +to write an embed after that I proceed to insert some text into it and then I will do a vector search +and show you that the result is words that are close to the word we searched for. I use this +vector DB class. It's a class that encapsulates what we did before. So the setup does the +initialization and here is an insert that you see that does the embed first and the embed is +the same procedure I did before. So with this class, I'm able to easily insert text embedding +together into the records of our vector database. I import this class. I get a vector database and +here I insert this is a test. This is another test and testing. I also put hello word so it's a +complete example. Now I'm doing the vector search. As a text I have test. I embed it because the +vector search is done between embedded text and other embedded texts. I perform a search. I perform +a search. You see, this is a vector search in which I specify the type and the metric i.e. how it +calculates the distance between my numerical representation and the numerical representations +that are there. The field on which I do the vector search. The lookup data and output. I compare +the numerical distance but then it is with the text because that interests us. So if I now try to +iterate the result, see, I tried testing and found me testing first which has a distance of 271 which +is closer than this is a test and always the word test that is closer. This is another test +while the word hello world is rather distant. See? 97. By the way, if I repeat the same thing and +write hello hello as text instead, I repeat the procedure, embeddo and redo the search and now +you see that hello came first because it is closer for him. This came far because in reality this +was the representation that I put with random numbers so for him it means nothing. You have +understood how vector representation helps you find information associated with what you are +talking about. Now let's put everyone together with this action load there should be nothing, +it's empty. Now I write this is a test, this is another test, hello world, testing the system +and then asterisk test and find me this is a test, this is another test hello world. +If instead I do asterisk hello, I find hello first and then the rest so see how it allows you to +load databases with textual information. It is inconvenient to digital everything when by hand +we can use scripts. So if you see the example you can invoke it from the command line. So I enter a +text and you can also invoke the command line search and found me first for open serverless. +So I entered the text open serverless. I did the search and it found me first open serverless +etc. So taking advantage of this ability that can be used both from the command line and from the +user interface we will make an importer which I will show you in the next section in the meantime +let's explore the code. So as you can see this is the class that you have already seen before +that allows you to manage the vector database. There is also a feature that allows you to delete +data. And this is the action so if the input starts with an asterisk it does a search. If it +starts with an exclamation mark it does a removal otherwise it makes a database insert using the +vector db class. Well we have everything and now we close the round by entering the database data +importing a pdf. To do it I'll show you how to do it. We will use the paimu pdf library. We have +a file. I took a pdf at random. I took the bitcoin white paper which is an open source document and +I extract the page after which the page must be broken into sentences because it works if it has +many small pieces and for this I will use another feature. There will be another library capable +of analyzing the data and dividing them into sentences this other. I'll show you how it always +works from the command line. Now I'll show you how it works. I take the document and I can extract +the text of the first page. See this is the first page test. Obviously it is generally too long. +You can insert an embed although the embedding can also compress it but it comes out badly +so it's better to break it into sentences so I now use this library that uses a tokenizer. +This tokenizes the phrase second sentence. See here we took a pdf we extracted all the pages +we broke each page into sentences and now we know how to do it. Of course we would have to +import it into the database sentence by sentence. We do this work to a script since it is a frequent +job. I added to the opsai plugin because ops is the tool opsai is the plugin a loader that is +capable of importing documents which is capable of transforming them into text and then importing +them one by one so now I'll show you how to do it opsai has a new command which is loader +so opsai loader loader is the one that does the action using a data file so now I take +lessons bitcoin pdf and now he has it at and converted it so if I go to open it now we will see +all the text contained in that pdf this is the bitcoin pdf and this is the text contained in +this document now loader I can also specify an action to execute which is what we did vdb load +therefore we can export it and see the result and now we can specify an action that will pass +each sentence as input so vdb load here now is taking after converting and breaking into sentences +the vdb is loading all the sentences one by one since it already has to stop the +temporaries it shows you the files it is uploading and in this way we upload the whole document to +the vector database directly from a pdf now let's see what we have uploaded we see that if I do the +search for bitcoin it has come up with a whole sentence related to bitcoin or we choose merkle +and we will have phrases related to merkle tree which are a format used by bitcoin so we basically +loaded and vectorized the information ready to do some research and be used for the llm applications +that use it now I conclude the lesson with an exercise the exercise is to modify the loader +to be able to import content from the web directly online so if you write http something url you +should extract the content you should extract the test using the beautiful soap library and then I +recommend you to break using regular expressions and not that tokenizer because it is heavy instead +you can do it using an example that is demonstrated in that link in stack overflow thank you very much +and see you next time
diff --git a/content/en/docs/tutorial-ai/Lesson6/_index.md b/content/en/docs/tutorial-ai/Lesson6/_index.md new file mode 100644 index 0000000..69e9f1c --- /dev/null +++ b/content/en/docs/tutorial-ai/Lesson6/_index.md
@@ -0,0 +1,7 @@ +--- +title: Lesson 6 +weight: 10 +draft: true +--- + +# TO BE RERGANIZED AND REVIEWED!
diff --git a/content/en/docs/tutorial-ai/Lesson7/Lezione_7.txt b/content/en/docs/tutorial-ai/Lesson7/Lezione_7.txt new file mode 100644 index 0000000..3a2f959 --- /dev/null +++ b/content/en/docs/tutorial-ai/Lesson7/Lezione_7.txt
@@ -0,0 +1,205 @@ +Hello everyone and welcome to the last lesson of this first edition of the Private AI course. +Let's start right away by going to the fork of our starter before starting I recommend you as +usual to update your fork because there can be updates on the starter and I also recommend that +you save all the data on git and delete the code space because there may be changes so it's better +to start with a clean environment. At this point we launched the code space. +Let's log in. Let's select lesson seven. This is lesson number seven. In this lesson we'll talk +about how to create a RAG system. This lesson is different from the others because it has many +examples and code already done. I will also show you the code but basically it closes and completes +what we have explained in the previous lessons putting it into practice to create a system that +has its own intrinsic utility which you can modify, extend and generalize for your personal uses. +We will talk about how to implement a RAG system, what exactly it means, how to load data into the +vector database including PDF documents and then a chat that is multi-document and multi-LLM to explore +data contained in the vector database, individual documents or other types of data. Let's start +by looking at what a RAG is and how it is implemented. In the world of programming for +artificial intelligence we talk about RAG as retrieval augmented generation that is we talk +about LLMs to which requests are made by increasing the context to which the request is made with +so-called context information which is automatically provided together with the request that is made +to the RAG. Basically you make questions and these questions are used to find the relevant +content to provide the answer. So the mechanism of embeddings is used because vectors that represent +questions in a format that also has semantic content so if I say dog there is the concept of +animal and therefore content related to other animals can be extracted in context and vector +search is used to extract the semantic content from data sources. Let's see in practice with an +example how this mechanism works and we do it by initializing a vector database. Now we're going +to take an example on the command line to see how this mechanism of RAG works. Let's follow +preliminary commands to access the code. In this example we will use the vector database class that +we used last time. If you know in lesson 6 there is explained how this vector class works. It has +actually been slightly modified to be able to specify the collection but basically it works +the same as the previous time. So now I create a vector database, clean it, even if it is actually +empty but to be safe I remove all the contents and insert three statements related to Lisa, +Steve Jobs' daughter. So, Lisa is the first daughter of Steve Jobs, her name Lisa Brennan, +the name Lisa was used for what was supposed to be his masterpiece, the Apple Lisa, which then +actually failed and it is supposed that Lisa's name is inspired by the Mona Lisa, Leonardo's masterpiece. +I uploaded a series of statements to the vector database to be able to do some research. +Using this content we create a context that is a series of additional information that +enriches any requests related to Lisa. Let's see how we create this context. +Let's do the vector search. See? I go to inspect it and I see that using the word Lisa they are +chosen for me. In the example they were all words related to Lisa but in general doing a victory +search you find what is somehow related to the searched word. Using this context I now concatenate +and create what will be a context that is an additional piece of information that I give +to the LLM. I tell him consider this text that Lisa's name is inspired by Mona Lisa, +that Lisa is the name of Steve Jobs' first daughter. That Steve Jobs called his masterpiece +like Lisa etc. This is the background information which at this point I can use to pass them to +the LLM. So now we use an LLM function similar to functions that we have already seen in previous +lessons so I won't repeat it and I try to ask questions without context and with context. +If I now choose the Llama 38 Billions model if I try to ask the question who is Lisa. Without +context the LLM thinks for a moment and will give me an answer but one without additional +information. So he lists a series of Lisa, generic Lisa because he doesn't have specific +information. But if instead I add that string of context to the context and ask him the question +he replies that there are two different Lisa, Mona Lisa and Steve Jobs' daughter. He says +the answer is likely to be Lisa Brennan, Steve Jobs' daughter. This is how context has completely +changed the response and the LLM is able to respond by giving appropriate answers to context +information that it does not already know. This important that he does not already know and +that therefore we have increased his knowledge with a specific context. This is the fundamental +mechanism of RAG systems. In reality, there is a lot to be said. There are a few things to watch +out for. First of all, the context information must be small pieces, so called, chunks, that +should be significant. Now empirically the size of these chunks should be between 500 and 800 words, +so approximately around 4000 characters, considering an average of 5 characters per word +which is the typical number for the English language. It's hard to achieve, but the best thing +is that these chunks are semantically related, so they should ideally be sections or paragraphs +with content from a book or other source. Actually this is quite difficult to achieve, +so in this example we will settle for chunks which are blocks of text of about 4000 characters. +This is not ideal but it is the easiest way you can go about it. There is actually a lot to do +and it takes a lot of content engineering to get great results which we will not address here, +however, it is important to understand this concept. In addition, the dimensions are also +important. A request that is made to an LLM has a size that depends on the model. There are templates +that can handle even 2 million characters. The size that can support the main model we will use, +which is Llama 3 is 128000, which means that approximately the maximum size is 30 chunks +to leave some room for any questions as well. So I was saying that we used blocks of about +4000 characters and each question increased it with about 30 relative conks. However, +it is generally essential to provide structured information for best results. +You can also get results with information that is not particularly structured, +but the quality of the result expires and this will soon be noticed in the examples we will do. +Okay, so far we have seen the theory and now we put it into practice by showing the system we +have used. Basically we have created a loader, which is an action, a chat, which can also be +used by external tools to import information. The feature of this loader is to manage multiple +collections, to set different limits, to do searches and to be able to delete contents and +collections. So with this loader we could load more collections of content and do research tests +and possibly be able to do maintenance by cleaning up. It allows direct input from the content also +automated, in fact I will also show you an automated loader and allows you to try searches +manually. We will now see this in practice. This is the loader. So let's see that if I write. +I list the collections, I can change the collection, if I write asterisk basically +does a search for what is in the collection. Asterisk and test does a search based on what +I asked it, then I can also delete part of the text. So if I write exclamation mark test, +it deletes two records. So if I do it again now it tells me that there is test with three elements, +I can also delete the entire collection and so on. So it's pretty much a simple loader that is +used to manage collections and load multiple contents. Multiple contents that can also be loaded +by hand. So if I now write test again and then I write this is a test and then I write this is +another test again testing it all and then hello and hello world. Okay, this should give you an idea +of how the loader works. However, the charger alone does not do all the work. The loader is good +at loading data manually, which is convenient for checking the collections that are there for adding +information, etc. But this is used as a counterpart to a better command line loader, which is allows +you to load text from PDFS and then extract texts in blocks, which by default are 4000 characters. +The syntax is what you see, it specifies the action to be used to load the size of the chunks, +the name of the collection where to load and the action to be imported. So minus less action loader +is needed to load, while less less collection is needed to specify the collection to be used. +I'll show you now how I am out. Here I had already imported Bitcoin. Now I select it and +delete it. You see that I no longer have the text of Bitcoin because I deleted it. Now I'll show you +how to upload the text of a document. For example, we download it from the internet. +Bitcoin org slash Bitcoin PDF. We download the document from the internet and import it. So oops +AI loader. The action to load is RAG loader. We put it in a collection that we call Bitcoin again. +And we specify the Bitcoin PDF file. Now the loader takes the document, breaks it up, +turns it into text and loads it. The text is quite short, so he took it into four pieces of about +4,000 characters. In reality, it breaks it into sentences until it does not exceed 4,000 characters. +If we now go back to the collections, we see that now there is the Bitcoin collection. I select it +and now I try to ask something about Bitcoin, Bitcoin, and I extract some text. Actually, +I can select the size of the searches. The default is 30. So if I look for Bitcoin, now I get only +one, the most relevant, but still a block of 4,000 characters. All right. In reality, +using Bitcoin is not very useful because these are things that the LLM already knows, so it is +better to use more specific information. To give a more significant example, we will use the CDI +a little more relevant information. In this case, I made an importer who imports all my linked in +contacts. Obviously, these are my private data. And I did this because in this way I show you that +you can do interesting things with data that are not known because if you try to upload any document, +someone tries to download from the internet, you will realize that he already knows it. +Because these LLMs have already been instructed with practically all the internet that is publicly +accessible. So data such as any PDF that you can easily download generally does not give significant +results because it is information because it is information that in some way the LLM already knows. +You have to use private data to get results that are not exactly obvious. +Now I upload a file that contains my linked in connections. Okay. This file is obtained by going +to LinkedIn, exporting my data and gives you this file in separate comma value format. In which there +are all the contacts. For example, if I ask grep DeGiro Lamo connection CSV, I get this information. +I use this name because I had permission to publish it. Obviously, this is not a particularly +convenient format to use. So I wrote a script that converts to a text format. So I do a I run ops. +This code is part of the lesson. So if you want, you can see it connection, +here this file is converting all my connections into an easier to import text format that the +LLM choose better. It is converting all the contents. There are many. +There we go. So if we now grep on TXT, you see that it has produced a text. So I transform that +file that was in comma separate value into a more textual format that is better handled by the LLM. +And now I import it. So ops a I less collection loader RAG collection less collection linked in. +And here we give him the connections TXT aisle. Here now he takes and begins to load the data +in blocks of 4000 characters each. Right now, let's go and inspect. We actually see that we +have it linked in. And we can do some research. He is telling me that there are more than 1000, +because in order not to weigh down too much, the search limits it to 100 chunks. +One. So if I look for CEO, the problem is that in this way, the contents are divided into blocks +and therefore in practice, if I write CEO, it takes all related things and not necessarily +relevant. This is just a generic example because the system would be very refined. Actually, +transforming into smaller chunks or creating larger information or extracting information by +scraping data from linked in. It is only an initial example, however, to give you an idea +of what such a system can do. Surely this is not the optimal way to manage data like this, +but it was a quick way to show how the system works. Now let's take a look at the loader code. +We use for most of the features the vector DB class that we have already implemented last time, +of which I basically show the. So we have methods that do insert, remove. +Therefore, it is slightly modified compared to the example of the previous lesson because here we +can specify a collection so it handles multiple collections, but with an extra method to remove +a collection and an extra method to count the elements. But apart from fairly simple changes +the vector DB class is the same that we showed in lesson six. The magazine uses it. First of all, +here I read a status. The status is basically a stinga in which it chooses the current collection +and the current length of searches after which if I use the at I changed the current collection. +If I use the sharp, I change the current limit of the search. If I use the insert, I search on the +vector database. Finally, with the double exclamation mark, I remove a collection and with the single +exclamation point, I remove a part of the records per substring. This is how the loader works, +which is a modified and improved version of the loader we saw in the previous lesson. +Now let's conclude the tour by showing a query action, which works substantially as you saw at +the beginning, but in a function. So even the RAG query has the ability to extract text from +the database and do searches with LLM. It supports multiple LLMs, variable context sizes, and multiple +collections. So in this way, using a collection in which I have uploaded data, I can ask questions +using different sets of content using different LLMs. In this case, I put llama, phi and deep seek. +Now to make it convenient, I ask questions and I can use it by enriching the content with +contexts from different collections using different LLMs. Another thing is that it is expected. +The abbreviation so as not to have to write long names. So to be able to choose the collection +from which to enrich, I can simply use a prefix. So even a letter is enough to identify the right +collection. So let's see it in practice. I show how we can use the system. In practice, we take +the available collections. For example, we take jobs collection. Here I said some information +about Lisa. So now I go to the RAG and if I say who is Lisa, it will give me some generic information. +As before, if I specify at jobs, you see that this that allows me to select the LLM and I ask +him who is Lisa. Here you are. And now he replies because I add the context of the jobs collection +that I had chosen before. And here by default, it uses llama. But for example, I can use phi for +writing it, phi, then the syntax is explained here. At LPM allows you to select an LLM. +Then I can specify the size of the context, which by default is 30. And then the name of the +collection that I can abbreviate. We have done this to allow you to easily and quickly ask questions +by changing LLM or changing collection. If I write it PJ, now he is telling me to use phi for as an +LLM with the jobs collection. And I say who is Lisa. Right now I'm asking the same question, +though I'm using another LLM. This has expanded it a bit, you see, the behavior of +phi for and llama is slightly different. Now let's try with Mistrol. Here you see, +here instead I used Mistrol, who also replied to me at the same time. Now we can try to use +particular data instead. For example, using the one that begins with L, that is the LinkedIn one +that I uploaded. And now I can write it L and say list all the contacts with the role of CEO. +Now it's going to do a database search and it's listing me in my view of content, +those he finds as CEO, or I try to ask at L list all the contacts in a developer role. +And so instead he will take some data and list the people who he thinks have a developer role, +list all the contacts who works in software engineering. This is also very dependent on how +the model interprets vector searches. And as mentioned, this example is absolutely not optimal +because the data should be structured better, certainly not in this way, but grouped in different +ways and probably we need to choose better the way to do searches. But I still wanted to show +this example to show how the system is very suitable for manipulating private data. Obviously, +it must be optimized. Now let's see the code of the RAG. As you can see, it's pretty simple. +Basically, there is a function that scans that query in that particular format that I am now +showing you. Then it does a search in the vector database and creates a prompt exactly as I said +before to ask it questions. From the practical point of view, it is all here. The only particular +thing is this parser, which takes this string that is used to select which collection we want to use +in such a way that we can ask questions about different documents. But other than that, it is +basically a selection and here is a regular expression that is extracts and decides which +template to use, how much to use, which collection to use, and what content to provide. Other than +that, the rest are things we've already seen, such as connecting to an LLM, streaming, and all +things we've already seen in previous lessons. So there is no great news from a practical point of +view. This basically brings together quite a few things that we have seen in previous lessons. +So this closes the course and we close it with a relatively complex exercise, +which will be to implement a RAG on images. Here I give a few details. You will have to modify +the database to accept an image, upload images that you can upload with a form or upload them to +the S3, process it, and then make a RAG of the image description information so that you can make +a RAG in which you describe the image you want to use and you will find groups of images that you +have loaded based on the description, then make an LLM of the images using image recognition that +will produce descriptions. So the final exercise is basically to do a RAG of images. Okay, thank you +for following the course so far and for the moment we have concluded with this. We will continue with +open source projects and new more enriched editions of the course. For the moment, thank you all and +see you next time.
diff --git a/content/en/docs/tutorial-ai/Lesson7/_index.md b/content/en/docs/tutorial-ai/Lesson7/_index.md new file mode 100644 index 0000000..dabb421 --- /dev/null +++ b/content/en/docs/tutorial-ai/Lesson7/_index.md
@@ -0,0 +1,8 @@ +--- +title: Lesson 7 +weight: 10 +draft: true +--- + +\ +# TO BE RERGANIZED AND REVIEWED!
diff --git a/content/en/docs/Ai Tutorial/_index.md b/content/en/docs/tutorial-ai/_index.md similarity index 100% rename from content/en/docs/Ai Tutorial/_index.md rename to content/en/docs/tutorial-ai/_index.md