{"id":29571833,"url":"https://github.com/oceanbase/ai-workshop-2024","last_synced_at":"2025-07-19T04:36:17.531Z","repository":{"id":260209252,"uuid":"874535852","full_name":"oceanbase/ai-workshop-2024","owner":"oceanbase","description":"AI Workshop Project of OceanBase 2024 Product Launch","archived":false,"fork":false,"pushed_at":"2025-02-19T03:16:40.000Z","size":7464,"stargazers_count":45,"open_issues_count":0,"forks_count":18,"subscribers_count":1,"default_branch":"tongyi","last_synced_at":"2025-07-13T00:55:10.419Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://oceanbase-devhub.github.io/ai-workshop-2024/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/oceanbase.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-10-18T02:24:20.000Z","updated_at":"2025-06-13T06:30:35.000Z","dependencies_parsed_at":null,"dependency_job_id":"82593083-c281-4e62-9c04-cb4f6d2fd08f","html_url":"https://github.com/oceanbase/ai-workshop-2024","commit_stats":null,"previous_names":["oceanbase-devhub/ai-workshop-2024","oceanbase/ai-workshop-2024"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/oceanbase/ai-workshop-2024","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oceanbase%2Fai-workshop-2024","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oceanbase%2Fai-workshop-2024/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oceanbase%2Fai-workshop-2024/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oceanbase%2Fai-workshop-2024/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/oceanbase","download_url":"https://codeload.github.com/oceanbase/ai-workshop-2024/tar.gz/refs/heads/tongyi","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oceanbase%2Fai-workshop-2024/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265889155,"owners_count":23844539,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-07-19T04:36:16.768Z","updated_at":"2025-07-19T04:36:17.510Z","avatar_url":"https://github.com/oceanbase.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# OceanBase AI Workshop\n\n[中文版](./README_zh.md)\n\n## Introduction\n\nIn this workshop, we will build a RAG chatbot that answers questions related to OceanBase documentation. It uses open-source OceanBase documentation repositories as multi-modal data sources, converting documents into vectors and structured data stored in OceanBase. When users ask questions, the chatbot converts their questions into vectors and performs vector retrieval in the database. By combining the retrieved document content with the user's questions, it leverages Tongyi Qianwen's large language model capabilities to provide more accurate answers.\n\n### Components\n\nThe chatbot consists of the following components:\n\n1. A text embedding service that converts documents into vectors, using Tongyi Qianwen's embedding API\n2. A database that provides storage and query capabilities for document vectors and other structured data, using OceanBase 4.3.3\n3. Several LLM agents that analyze user questions and generate answers based on retrieved documents and questions, built with Tongyi Qianwen's large model capabilities\n4. A chat interface for user interaction, built with Streamlit\n\n### Interaction Flow\n\n![RAG Flow](./demo/rag-flow.png)\n\n1. User inputs a question in the Web interface and sends it to the chatbot\n2. The chatbot converts the user's question into a vector using a text embedding model\n3. Uses the vector converted from the user's question as input to retrieve the most similar vectors in OceanBase\n4. OceanBase returns the most similar vectors and their corresponding document content\n5. The chatbot sends the user's question and retrieved documents to the large language model and requests it to generate an answer\n6. The large language model returns the answer in chunks, streaming fashion\n7. The chatbot displays the received answer in chunks, streaming fashion on the Web interface, completing one round of Q\u0026A\n\n## Concepts\n\n### What is Text Embedding?\n\nText embedding is a technique that converts text into numerical vectors. These vectors can capture the semantic information of text, enabling computers to \"understand\" and process the meaning of text. Specifically:\n\n- Text embedding maps words or sentences to points in a high-dimensional vector space\n- In this vector space, semantically similar texts are mapped to nearby locations\n- Vectors typically consist of hundreds of numbers (e.g., 512 dimensions, 1024 dimensions)\n- Vector similarity can be calculated using mathematical methods (e.g., cosine similarity)\n- Common text embedding models include Word2Vec, BERT, BGE, etc.\n\nIn this project, we use Tongyi Qianwen's text embedding model to generate vector representations of documents, which will be stored in OceanBase database for subsequent similarity retrieval.\n\nFor example, when using an embedding model to convert \"apple\", \"banana\", and \"orange\" into 4-dimensional vectors, their vector representations might look like the diagram below. Note that we reduced the vector dimensions to 4 for easier visualization - in practice, text embedding vectors usually have hundreds or thousands of dimensions. For instance, the text-embedding-v3 model we use from Tongyi Qianwen produces 1024-dimensional vectors.\n\n![Embedding Example](./demo/embedding-example.png)\n\n### What is Vector Retrieval?\n\nVector retrieval is a technique for quickly finding the most similar vectors to a query vector in a vector database. Its key features include:\n\n- Search based on vector distance (e.g., Euclidean distance) or similarity (e.g., cosine similarity)\n- Typically uses Approximate Nearest Neighbor (ANN) algorithms to improve retrieval efficiency\n- OceanBase 4.3.3 supports the HNSW algorithm, which is a high-performance ANN algorithm\n- ANN can quickly find the most similar results approximately from millions or even billions of vectors\n- Compared to traditional keyword search, vector retrieval better understands semantic similarity\n\nOceanBase has added excellent support for \"vector\" as a data type in its relational database model, enabling efficient storage and retrieval of both vector data and conventional structured data in a single database. In this project, we use OceanBase's HNSW (Hierarchical Navigable Small World) vector index to implement efficient vector retrieval, helping us quickly find the most relevant document fragments for user questions.\n\nIf we use \"Fuji\" as a query text in an OceanBase database that already has embeddings for \"apple\", \"banana\", and \"orange\", we might get results like the diagram below, where the similarity between \"apple\" and \"Fuji\" is highest. (Assuming we use cosine similarity as the similarity measure)\n\n![Vector Search Example](./demo/vector-search-example.png)\n\n### What is RAG?\n\nRAG (Retrieval-Augmented Generation) is a hybrid architecture that combines retrieval systems with generative AI to improve the accuracy and reliability of AI responses. The workflow consists of:\n\n1. Retrieval Phase:\n\n- Convert user questions into vectors\n- Retrieve relevant documents from the knowledge base\n- Select the most relevant document fragments\n\n2. Generation Phase:\n\n- Provide retrieved documents as context to the large language model\n- Generate answers based on questions and context\n- Ensure answer sources are traceable\n\nKey advantages of RAG:\n\n- Reduces hallucination problems in large language models\n- Can utilize latest knowledge and domain-specific information\n- Provides verifiable and traceable answers\n- Suitable for building domain-specific Q\u0026A systems\n\nTraining and releasing large language models takes considerable time, and training data stops updating once training begins. While the amount of information in the real world continues to increase constantly, it's unrealistic to expect language models to spontaneously master the latest information after being \"unconscious\" for several months. RAG essentially gives large models a \"search engine\", allowing them to acquire new knowledge input before answering questions, which typically significantly improves the accuracy of generated responses.\n\n## Prerequisites\n\nNotes: If you are participating in the OceanBase AI Workshop, you can skip steps 1 ~ 4 below. All required software is already prepared on the machine. :)\n\n1. Install [Python 3.9+](https://www.python.org/downloads/) and [pip](https://pip.pypa.io/en/stable/installation/). If the version of Python on your machine is lower than 3.9, you can use Miniconda to create a new environment with Python 3.9. Refer to the [Miniconda installation guide](https://docs.anaconda.com/miniconda/install/) for details.\n\n2. Install [Poetry](https://python-poetry.org/docs/) with command `python3 -m pip install poetry`\n\n3. Install [Docker](https://docs.docker.com/engine/install/) (Optional, only required if you want to run OceanBase in a Docker container)\n\n4. Install MySQL client, using `yum install -y mysql` or `apt-get install -y mysql-client` (Optional, only required if you want to test database connection with MySQL client)\n\n5. Ensure your project code is up to date, recommended to run `git pull` in the project directory\n\n6. Register an [Alibaba Cloud Bailian](https://bailian.console.aliyun.com/) account, activate model service and obtain API Key\n\n![Activate Model Service](./demo/activate-models.png)\n\n![Confirm to Activate Model Service](./demo/confirm-to-activate-models.png)\n\n![Alibaba Cloud Bailian](./demo/dashboard.png)\n\n![Get Alibaba Cloud Bailian API Key](./demo/get-api-key.png)\n\n## Building the Chatbot\n\n### 1. Get an OceanBase Database\n\nFirst, we need to obtain an OceanBase database version 4.3.3 or above to store our vector data. You can get an OceanBase database through either of these two methods:\n\n1. Use the OB Cloud database free trial instances. For platform registration and instance creation, please refer to [OB Cloud Database 365-Day Free Trial](https://www.oceanbase.com/free-trial); (Recommended)\n2. Use Docker to start a standalone OceanBase database. (Alternative option, requires Docker environment, consumes more local resources)\n\n#### 1.1 Using OB Cloud Database Free Trial Version\n\n##### Register and Create an Instance\n\nVisit the [OB Cloud Database 365-Day Free Trial](https://www.oceanbase.com/free-trial) web page, click the \"Try Now\" button, register and log in to your account, fill in the relevant information, create an instance, and wait for creation to complete.\n\n##### Get Database Instance Connection Information\n\nGo to the \"Instance Workbench\" on the instance details page, click the \"Connect\"-\"Get Connection String\" button to obtain the database connection information. Fill the connection information into the .env file that will be created in subsequent steps.\n\n![Get Database Connection Information](./demo/obcloud-get-connection.png)\n\n##### Modify Parameters to Enable Vector Module\n\nGo to \"Parameter Management\" on the instance details page, and set the `ob_vector_memory_limit_percentage` parameter to 30 to enable the vector module.\n\n![Modify Parameters to Enable Vector Module](./demo/obcloud-modify-param.png)\n\n#### 1.2 Deploy an OceanBase Database with Docker\n\n##### Start an OceanBase Container\n\nIf this is your first time logging into the machine provided by the workshop, you need to start the Docker service with:\n\n```bash\nsystemctl start docker\n```\n\nThen you can start an OceanBase docker container with:\n\n```bash\ndocker run --name=ob433 -e MODE=mini -e OB_MEMORY_LIMIT=8G -e OB_DATAFILE_SIZE=10G -e OB_CLUSTER_NAME=ailab2024 -e OB_SERVER_IP=127.0.0.1 -p 127.0.0.1:2881:2881 -d quay.io/oceanbase/oceanbase-ce:4.3.3.1-101000012024102216\n```\n\nIf the command executes successfully, it will print the container ID:\n\n```bash\naf5b32e79dc2a862b5574d05a18c1b240dc5923f04435a0e0ec41d70d91a20ee\n```\n\n##### Check the bootstrap of OceanBase is complete\n\nAfter the container is started, you can check the bootstrap status of OceanBase with:\n\n```bash\ndocker logs -f ob433\n```\n\nThe initialization takes about 2-3 minutes. When you see the following message (the bottom `boot success!` is essential), the bootstrap is complete:\n\n```bash\ncluster scenario: express_oltp\nStart observer ok\nobserver program health check ok\nConnect to observer ok\nInitialize oceanbase-ce ok\nWait for observer init ok\n+----------------------------------------------+\n|                 oceanbase-ce                 |\n+------------+---------+------+-------+--------+\n| ip         | version | port | zone  | status |\n+------------+---------+------+-------+--------+\n| 172.17.0.2 | 4.3.3.1 | 2881 | zone1 | ACTIVE |\n+------------+---------+------+-------+--------+\nobclient -h172.17.0.2 -P2881 -uroot -Doceanbase -A\n\ncluster unique id: c17ea619-5a3e-5656-be07-00022aa5b154-19298807cfb-00030304\n\nobcluster running\n\n...\n\ncheck tenant connectable\ntenant is connectable\nboot success!\n```\n\nPress `Ctrl+C` to exit the log view.\n\n##### Test deployment (Optional)\n\nConnect to the OceanBase cluster with mysql client to check the deployment.\n\n```bash\nmysql -h127.0.0.1 -P2881 -uroot@test -A -e \"show databases\"\n```\n\nIf the deployment is successful, you will see the following output:\n\n```bash\n+--------------------+\n| Database           |\n+--------------------+\n| information_schema |\n| mysql              |\n| oceanbase          |\n| test               |\n+--------------------+\n```\n\n### 2. Install dependencies\n\nFirst of all, you need to change to the directory of the workshop project:\n\n```bash\ncd ~/ai-workshop-2024\n```\n\nWe use Poetry to manage the dependencies of the chatbot project. You can install the dependencies with the following command:\n\n```bash\npoetry install\n```\n\nIf you are using the machine provided by the workshop, you will probably see the following message because the dependencies are already installed in the machine:\n\n```bash\nInstalling dependencies from lock file\n\nNo dependencies to install or update\n```\n\n### 3. Set up environment variables\n\nWe prepare a `.env.example` file that contains the environment variables required for the chatbot. You can copy the `.env.example` file to `.env` and update the values in the `.env` file.\n\n```bash\ncp .env.example .env\n# Update the .env file with the correct values, especially the API_KEY and database information\nvi .env\n```\n\nThe content of `.env.example` is as follows, you only need to update the `API_KEY` and `OPENAI_EMBEDDING_API_KEY` with the value you get from the Bailian dashboard if you are following the workshop steps which will take LLMs from Tongyi Qwen. If you are using the OB Cloud instance, update the database-related environment variables starting with `DB_` accordingly. After updating the `.env` file, save and exit the editor.\n\n```bash\nAPI_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # Fill your API Key\nLLM_MODEL=\"qwen-turbo-2024-11-01\"\nLLM_BASE_URL=\"https://dashscope.aliyuncs.com/compatible-mode/v1\"\n\nHF_ENDPOINT=https://hf-mirror.com\nBGE_MODEL_PATH=BAAI/bge-m3\n\nOLLAMA_URL=\nOLLAMA_TOKEN=\n\nOPENAI_EMBEDDING_API_KEY= # Fill your API Key\nOPENAI_EMBEDDING_BASE_URL=\"https://dashscope.aliyuncs.com/compatible-mode/v1\"\nOPENAI_EMBEDDING_MODEL=text-embedding-v3\n\nUI_LANG=\"zh\"\n\n# If you are using the OB Cloud instance, update the following database-related environment variables accordingly\nDB_HOST=\"127.0.0.1\" \nDB_PORT=\"2881\"\nDB_USER=\"root@test\"\nDB_NAME=\"test\"\nDB_PASSWORD=\"\"\n```\n\n### 4. Connect to the Database\n\nYou can use our prepared script to try connecting to the database to ensure database-related environment variables are set correctly:\n\n```bash\nbash utils/connect_db.sh\n# If you successfully enter the MySQL connection, this verifies that the database-related environment variables are set correctly.\n```\n\n### 5. Prepare Document Data\n\nIn this step, we will clone the open-source documentation repositories of OceanBase components and process them to generate document vectors and other structured data, which will then be inserted into the OceanBase database we deployed in step 1.\n\n#### 5.1 Clone Document Repositories\n\nFirst, we'll use git to clone the documentation for the oceanbase project locally.\n\n```bash\ngit clone --single-branch --branch V4.3.4 https://github.com/oceanbase/oceanbase-doc.git doc_repos/oceanbase-doc\n# If your network is slow when accessing GitHub, you can use the following command to clone the repository from Gitee\ngit clone --single-branch --branch V4.3.4 https://gitee.com/oceanbase-devhub/oceanbase-doc.git doc_repos/oceanbase-doc\n```\n\n#### 5.2 Document Format Standardization\n\nSince some files in OceanBase's open-source documentation use `====` and `----` to represent level 1 and level 2 headings, in this step we'll convert them to the standard `#` and `##` representation.\n\n```bash\n# Convert document headings to standard markdown format\npoetry run python convert_headings.py doc_repos/oceanbase-doc/zh-CN\n```\n\n#### 5.3 Convert Documents to Vectors and Insert into OceanBase\n\nWe provide the `embed_docs.py` script which, when given a document directory and corresponding component, will traverse all markdown documents in the directory, split long documents into chunks, convert them into vectors using the embedding model, and finally insert the document chunk content, embedded vectors, and chunk metadata (in JSON format, including document title, relative path, component name, chunk title, cascading titles) together into the same table in OceanBase, ready for querying.\n\nIn order to save time, we will only process a few documents related to vector retrieval. After opening the chat interface in step 6, the questions you ask about vector retrieval functionality of OceanBase will receive more accurate answers.\n\n```bash\n# Generate document vectors and metadata\npoetry run python embed_docs.py --doc_base doc_repos/oceanbase-doc/zh-CN/640.ob-vector-search\n```\n\nWhile waiting for the text processing, we can examine the contents of `embed_docs.py` to see how it works.\n\nFirst, the file instantiates two objects: one is the embedding service `embeddings` responsible for converting text content into vector data; the other is OceanBase's LangChain Vector Store service, which encapsulates pyobvector (OceanBase's vector retrieval SDK) and provides simple, user-friendly interface methods. We've also established partition keys for OceanBase components to greatly improve efficiency when querying documents for specific components.\n\n```python\nembeddings = get_embedding(\n    ollama_url=os.getenv(\"OLLAMA_URL\") or None,\n    ollama_token=os.getenv(\"OLLAMA_TOKEN\") or None,\n    base_url=os.getenv(\"OPENAI_EMBEDDING_BASE_URL\") or None,\n    api_key=os.getenv(\"OPENAI_EMBEDDING_API_KEY\") or None,\n    model=os.getenv(\"OPENAI_EMBEDDING_MODEL\") or None,\n)\n\nvs = OceanBase(\n    embedding_function=embeddings, # Pass in embedding service, called immediately when inserting documents\n    table_name=args.table_name,\n    connection_args=connection_args,\n    metadata_field=\"metadata\",\n    extra_columns=[Column(\"component_code\", Integer, primary_key=True)],\n    partitions=ObListPartition(\n        is_list_columns=False,\n        list_part_infos=[RangeListPartInfo(k, v) for k, v in cm.items()]\n        + [RangeListPartInfo(\"p10\", \"DEFAULT\")],\n        list_expr=\"component_code\",\n    ),\n    echo=args.echo,\n)\n```\n\nNext, the script checks if the vector functionality module is enabled in the connected OceanBase cluster, and if not, enables it using SQL commands.\n\n```python\n# Check if vector module is enabled by querying ob_vector_memory_limit_percentage parameter\nparams = vs.obvector.perform_raw_text_sql(\n    \"SHOW PARAMETERS LIKE '%ob_vector_memory_limit_percentage%'\"\n)\n# ...\n\n# Enable vector module by setting ob_vector_memory_limit_percentage parameter to 30\nvs.obvector.perform_raw_text_sql(\n  \"ALTER SYSTEM SET ob_vector_memory_limit_percentage = 30\"\n)\n```\n\nFinally, we traverse the document directory, read and chunk the document content, and submit it to OceanBase Vector Store for embedding and storage.\n\n```python\nif args.doc_base is not None:\n    loader = MarkdownDocumentsLoader(\n        doc_base=args.doc_base,\n        skip_patterns=args.skip_patterns,\n    )\n    batch = []\n    for doc in loader.load(limit=args.limit):\n        if len(batch) == args.batch_size:\n            insert_batch(batch, comp=args.component)\n            batch = []\n        batch.append(doc)\n\n    if len(batch) \u003e 0:\n        insert_batch(batch, comp=args.component)\n```\n\n### 6. Start the Chat UI\n\nExecute the following command to start the chat UI:\n\n```bash\npoetry run streamlit run --server.runOnSave false chat_ui.py\n```\n\nVisit the URL displayed in the terminal to open the chatbot application UI.\n\n```bash\n  You can now view your Streamlit app in your browser.\n\n  Local URL: http://localhost:8501\n  Network URL: http://172.xxx.xxx.xxx:8501\n  External URL: http://xxx.xxx.xxx.xxx:8501 # This is the URL you can access from your browser\n```\n\n![Chat UI](./demo/chatbot-ui.png)\n\n## FAQ\n\n### 1. How to change the LLM model used for generating responses?\n\nYou can change the LLM model by updating the `LLM_MODEL` environment variable in the `.env` file, or by modifying the \"Large Language Model\" in the left sidebar of the chat interface. The default value is `qwen-turbo-2024-11-01`, which is a recently released model from Tongyi Qianwen with a relatively high free quota. Other available models include `qwen-plus`, `qwen-max`, `qwen-long`, etc. You can find the complete list of available models in the [Alibaba Cloud Bailian website](https://bailian.console.aliyun.com/)'s model marketplace. Please note the free quotas and pricing standards.\n\n### 2. Can I update document data after initial loading?\n\nOf course. You can insert new document data by running the `embed_docs.py` script. For example:\n\n```bash\n# This will embed all markdown files in the current directory, including README.md and LEGAL.md\npoetry run python embed_docs.py --doc_base .\n\n# Or you can specify the table to insert data into\npoetry run python embed_docs.py --doc_base . --table_name my_table\n```\n\nThen you can specify the `TABLE_NAME` environment variable before launching the chat interface to specify which table the chatbot will query:\n\n```bash\nTABLE_NAME=my_table poetry run streamlit run --server.runOnSave false chat_ui.py\n```\n\n### 3. How to see the SQL statements executed by the database during embedding and retrieval?\n\nWhen inserting documents yourself, you can set the `--echo` flag to see the SQL statements executed by the script:\n\n```bash\npoetry run python embed_docs.py --doc_base . --table_name my_table --echo\n```\n\nYou will see output like this:\n\n```bash\n2024-10-16 03:17:13,439 INFO sqlalchemy.engine.Engine\nCREATE TABLE my_table (\n        id VARCHAR(4096) NOT NULL,\n        embedding VECTOR(1024),\n        document LONGTEXT,\n        metadata JSON,\n        component_code INTEGER NOT NULL,\n        PRIMARY KEY (id, component_code)\n)\n...\n```\n\nYou can also set `ECHO=true` before launching the chat UI to see the SQL statements executed by the chat UI.\n\n```bash\nECHO=true TABLE_NAME=my_table poetry run streamlit run --server.runOnSave false chat_ui.py\n```\n\n### 4. Why don't changes to the .env file take effect after starting the UI service?\n\nIf you edit the .env file or code files, you need to restart the UI service for the changes to take effect. You can terminate the service with `Ctrl + C`, then run `poetry run streamlit run --server.runOnSave false chat_ui.py` again to restart the service.\n\n### 5. How to change the language of the chat UI?\n\nYou can change the language of the chat interface by updating the `UI_LANG` environment variable in the `.env` file. The default value is `zh`, which means Chinese. You can change it to `en` to switch to English. You need to restart the UI after updating for the changes to take effect.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foceanbase%2Fai-workshop-2024","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foceanbase%2Fai-workshop-2024","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foceanbase%2Fai-workshop-2024/lists"}