├── .github └── workflows │ ├── banned_file_changes_pr.yml │ ├── cla.yml │ ├── license_audit.yml │ ├── release-zip-file.yml │ ├── repolinter.yml │ └── sonarcloud.yml ├── .gitignore ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── README_autonomous.md ├── README_ords.md ├── README_rag.md ├── SECURITY.md ├── data ├── commands_opensearch.txt ├── fake_patient_data.pdf ├── generated_data.json ├── janedoe.json ├── nursing_best_practices.pdf ├── opensearch_data.json └── questions_llm_rag.txt ├── img ├── agent.PNG ├── agents_autonomous.png ├── answer_1.PNG ├── answer_2.PNG ├── answer_3_1.PNG ├── answer_3_2.PNG ├── answer_4.PNG ├── arch.PNG ├── chat_autonomous_1.png ├── chat_autonomous_2.png ├── chat_patient_1.png ├── chat_patient_2.png ├── chat_with_model.png ├── christopher_jordan.PNG ├── connection_strings.png ├── connections_menu.png ├── create_bucket.png ├── create_connection.png ├── create_connection_end.png ├── create_par.png ├── create_par_output.png ├── create_subnet.png ├── create_vcn.png ├── crontabguru_output.PNG ├── data_source_1.PNG ├── data_source_2.PNG ├── data_source_new.png ├── data_source_old.PNG ├── database_config.png ├── database_creation_1.png ├── database_creation_2.png ├── database_creation_3.png ├── database_details.png ├── databases_menu.png ├── dg_details.png ├── dynamic_group_create.png ├── embeddings_result.png ├── endpoint.PNG ├── extra_info.PNG ├── generate_api_key.png ├── ingestion_job.png ├── key_creation.png ├── knowledge_base.png ├── knowledge_base_autonomous.png ├── knowledge_base_opensearch.png ├── knowledge_bases.png ├── launch_agent.PNG ├── new_agent.png ├── new_agent_autonomous.png ├── new_landing_page.png ├── ords │ ├── 1sqlworkshop.png │ ├── 2restfulservices.png │ ├── 3modules.png │ ├── 4moduledefinition.png │ ├── 5resourcetemplate.png │ └── 6resourcehandler.png ├── output_model.PNG ├── policy_details.png ├── private_db_ip.png ├── private_ip.PNG ├── reference_1.png ├── reference_2.png ├── result_end.PNG ├── sql_worksheet.png ├── step_1.png ├── step_2.png ├── step_3.png ├── table_contents.png ├── uploaded_pdf.png ├── validate_connection.png ├── validate_result.png ├── vault_creation.png └── vcn_creation.png ├── license_policy.yml ├── ords_redo.md ├── release_files.json ├── repolinter.json ├── requirements.txt ├── scripts ├── consume_ords.py ├── data_converter.py └── data_generator.py └── sonar-project.properties /.github/workflows/banned_file_changes_pr.yml: -------------------------------------------------------------------------------- 1 | name: Banned file changes (PR) 2 | on: 3 | # pull_request: 4 | # branches: [ "**/*" ] 5 | pull_request_target: 6 | 7 | jobs: 8 | check_for_banned_file_changes: 9 | name: Look for unsupported (banned) file modifications on PRs 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: 'Get number of git commits' 13 | uses: oracle-devrel/action-git-num-commits@v0.1-alpha6 14 | id: num_commits 15 | with: 16 | pull_url: ${{ github.event.pull_request.url }} 17 | - name: 'Checkout repo' 18 | uses: actions/checkout@v2 19 | with: 20 | ref: ${{ github.event.pull_request.head.ref }} 21 | repository: ${{ github.event.pull_request.head.repo.full_name }} 22 | fetch-depth: ${{ steps.num_commits.outputs.fetch_depth }} 23 | - name: Get file changes 24 | uses: oracle-devrel/action-git-files-changed@v0.1-alpha2 25 | id: files 26 | with: 27 | pull_url: ${{ github.event.pull_request.url }} 28 | - name: Look for changes to .github 29 | if: contains(steps.files.outputs.all_files_changed, '.github') 30 | run: | 31 | echo 'Changes to files in .github are not allowed.' 32 | - name: Comment if .github changed 33 | if: contains(steps.files.outputs.all_files_changed, '.github') 34 | uses: mshick/add-pr-comment@v1 35 | with: 36 | message: | 37 | :no_entry: **Banned Files Modified** 38 | Changes to files in `.github` are not permitted. Please revert your changes and re-submit a new PR. Simply changing the file back to its original state and re-committing won't work (you must revert the changes made to it). 39 | repo-token: ${{ secrets.GITHUB_TOKEN }} 40 | - name: Look for changes to license_policy.yml 41 | if: contains(steps.files.outputs.all_files_changed, '"license_policy.yml"') 42 | run: | 43 | echo 'Changes to license_policy.yml are not allowed.' 44 | - name: Comment if license_policy.yml changed 45 | if: contains(steps.files.outputs.all_files_changed, '"license_policy.yml"') 46 | uses: mshick/add-pr-comment@v1 47 | with: 48 | message: | 49 | :no_entry: **Banned Files Modified** 50 | Changes to `license_policy.yml` are not permitted. Please revert your changes and re-submit a new PR. Simply changing the file back to its original state and re-committing won't work (you must revert the changes made to it). 51 | repo-token: ${{ secrets.GITHUB_TOKEN }} 52 | - name: Look for changes to repolinter.json 53 | if: contains(steps.files.outputs.all_files_changed, '"repolinter.json"') 54 | uses: mshick/add-pr-comment@v1 55 | with: 56 | message: | 57 | :no_entry: **Banned Files Modified** 58 | Changes to `repolinter.json` are not permitted. Please revert your changes and re-submit a new PR. Simply changing the file back to its original state and re-committing won't work (you must revert the changes made to it). 59 | repo-token: ${{ secrets.GITHUB_TOKEN }} 60 | - name: Comment if repolinter.json changed 61 | if: contains(steps.files.outputs.all_files_changed, '"repolinter.json"') 62 | run: | 63 | echo 'Changes to repolinter.json are not allowed.' 64 | - name: Look for changes to sonar-project.properties 65 | if: contains(steps.files.outputs.all_files_changed, '"sonar-project.properties"') 66 | uses: mshick/add-pr-comment@v1 67 | with: 68 | message: | 69 | :no_entry: **Banned Files Modified** 70 | Changes to `sonar-project.properties` are not permitted. Please revert your changes and re-submit a new PR. Simply changing the file back to its original state and re-committing won't work (you must revert the changes made to it). 71 | repo-token: ${{ secrets.GITHUB_TOKEN }} 72 | - name: Comment if sonar-project.properties changed 73 | if: contains(steps.files.outputs.all_files_changed, '"sonar-project.properties"') 74 | run: | 75 | echo 'Changes to sonar-project.properties are not allowed.' 76 | - name: Fail on banned file changes 77 | if: contains(steps.files.outputs.all_files_changed, '.github') || contains(steps.files.outputs.all_files_changed, '"license_policy.yml"') || contains(steps.files.outputs.all_files_changed, '"repolinter.json"') || contains(steps.files.outputs.all_files_changed, '"sonar-project.properties"') 78 | run: | 79 | exit 1 -------------------------------------------------------------------------------- /.github/workflows/cla.yml: -------------------------------------------------------------------------------- 1 | name: "CLA Assistant" 2 | on: 3 | issue_comment: 4 | types: [created] 5 | pull_request_target: 6 | types: [opened,closed,synchronize] 7 | 8 | jobs: 9 | CLAssistant: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: "CLA Assistant" 13 | if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target' 14 | # Beta Release 15 | uses: cla-assistant/github-action@v2.1.2-beta 16 | env: 17 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 18 | # the below token should have repo scope and must be manually added by you in the repository's secret 19 | PERSONAL_ACCESS_TOKEN : ${{ secrets.PERSONAL_ACCESS_TOKEN }} 20 | with: 21 | # for per-repo CLA-acceptance: 22 | # path-to-signatures: 'signatures/oca-20210504/${{ github.repository }}' 23 | # for per-GHO CLA-acceptance: 24 | path-to-signatures: 'signatures/oca-20210504/oracledevrel' 25 | path-to-document: 'https://github.com/oracledevrel/devrel-oca-mgmt/blob/main/oca-20210504.md' # e.g. a CLA or a DCO document 26 | # branch should not be protected 27 | branch: 'main' 28 | allowlist: bot* 29 | 30 | #below are the optional inputs - If the optional inputs are not given, then default values will be taken 31 | remote-organization-name: "oracledevrel" # enter the remote organization name where the signatures should be stored (Default is storing the signatures in the same repository) 32 | remote-repository-name: "devrel-oca-mgmt" # enter the remote repository name where the signatures should be stored (Default is storing the signatures in the same repository) 33 | #create-file-commit-message: 'For example: Creating file for storing CLA Signatures' 34 | #signed-commit-message: 'For example: $contributorName has signed the CLA in #$pullRequestNo' 35 | #custom-notsigned-prcomment: 'pull request comment with Introductory message to ask new contributors to sign' 36 | #custom-pr-sign-comment: 'The signature to be committed in order to sign the CLA' 37 | #custom-allsigned-prcomment: 'pull request comment when all contributors has signed, defaults to **CLA Assistant Lite bot** All Contributors have signed the CLA.' 38 | #lock-pullrequest-aftermerge: false - if you don't want this bot to automatically lock the pull request after merging (default - true) 39 | #use-dco-flag: true - If you are using DCO instead of CLA 40 | -------------------------------------------------------------------------------- /.github/workflows/license_audit.yml: -------------------------------------------------------------------------------- 1 | name: Audit licenses 2 | on: 3 | pull_request_target: 4 | 5 | jobs: 6 | run_scancode_toolkit: 7 | name: Get inventory of licenses used in project 8 | runs-on: ubuntu-latest 9 | container: 10 | image: ghcr.io/oracledevrel/scancode-toolkit:v21.3.31 11 | credentials: 12 | username: ${{ github.actor }} 13 | password: ${{ secrets.GHCR_PAT }} 14 | steps: 15 | - name: 'Checkout repo' 16 | uses: actions/checkout@v2 17 | with: 18 | ref: ${{ github.event.pull_request.head.ref }} 19 | repository: ${{ github.event.pull_request.head.repo.full_name }} 20 | - name: Run Scancode-toolkit 21 | run: | 22 | scancode -l --ignore licenses.json --ignore .github/**/* --ignore license_policy.yml --license-policy license_policy.yml --only-findings --summary --json-pp licenses.json * 23 | echo "\n\nHere is the licenses.json:\n" 24 | echo $(cat licenses.json) 25 | - name: Look for non-approved licenses 26 | uses: oracle-devrel/action-license-audit@1.0.2 27 | id: analysis 28 | with: 29 | licenses_file: '/github/workspace/licenses.json' 30 | - name: Analysis results 31 | run: echo "${{ steps.analysis.outputs.unapproved_licenses }}" 32 | - name: Comment if analysis finds unapproved licenses 33 | if: steps.analysis.outputs.unapproved_licenses == 'true' 34 | uses: mshick/add-pr-comment@v1 35 | with: 36 | message: | 37 | :no_entry: **License Inspection** 38 | Requires manual inspection. There are some licenses which dictate further analysis and review. 39 | repo-token: ${{ secrets.GITHUB_TOKEN }} 40 | - name: Halt pipeline on unapproved licenses 41 | if: steps.analysis.outputs.unapproved_licenses == 'true' 42 | run: exit 1 43 | -------------------------------------------------------------------------------- /.github/workflows/release-zip-file.yml: -------------------------------------------------------------------------------- 1 | name: Release ZIP file packaging 2 | 3 | on: 4 | release: 5 | types: [published] 6 | 7 | jobs: 8 | create_zip: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: 'Checkout repo' 12 | uses: actions/checkout@v2 13 | - name: 'Make (and upload) ZIP file(s)' 14 | uses: oracle-devrel/action-release-zip-maker@v0.5 15 | id: zip_maker 16 | with: 17 | github_token: ${{ secrets.GITHUB_TOKEN }} 18 | -------------------------------------------------------------------------------- /.github/workflows/repolinter.yml: -------------------------------------------------------------------------------- 1 | name: Repolinter 2 | on: 3 | pull_request_target: 4 | jobs: 5 | run_repolinter: 6 | name: Run Repolinter on pull request 7 | runs-on: ubuntu-latest 8 | container: 9 | image: ghcr.io/oracledevrel/repolinter:v0.11.1 10 | credentials: 11 | username: ${{ github.actor }} 12 | password: ${{ secrets.GHCR_PAT }} 13 | steps: 14 | - name: 'Checkout repo' 15 | uses: actions/checkout@v2 16 | with: 17 | ref: ${{ github.event.pull_request.head.ref }} 18 | repository: ${{ github.event.pull_request.head.repo.full_name }} 19 | - name: Run Repolinter 20 | run: | 21 | set +e 22 | bundle exec /app/bin/repolinter.js lint --format json --rulesetFile repolinter.json . > repolinter_results.json 23 | echo "\n\nHere is the repolinter_results.json:\n" 24 | echo $(cat repolinter_results.json) 25 | exit 0 26 | - name: Analyze the Repolinter results 27 | uses: oracle-devrel/action-repolinter-audit@v0.1-alpha2 28 | id: analysis 29 | with: 30 | json_results_file: '/github/workspace/repolinter_results.json' 31 | - name: Overall analysis results 32 | run: | 33 | echo "Passed: ${{ steps.analysis.outputs.passed }}" 34 | echo "Errored: ${{ steps.analysis.outputs.errored }}" 35 | - name: Comment if analysis finds missing disclaimer 36 | if: steps.analysis.outputs.disclaimer_found == 'false' 37 | uses: mshick/add-pr-comment@v1 38 | with: 39 | message: | 40 | :no_entry: **FAILURE: Missing Disclaimer** 41 | The standard Oracle Disclaimer seems to be missing from the readme. Please add it: 42 | 43 | ORACLE AND ITS AFFILIATES DO NOT PROVIDE ANY WARRANTY WHATSOEVER, EXPRESS OR IMPLIED, FOR ANY SOFTWARE, MATERIAL OR CONTENT OF ANY KIND CONTAINED OR PRODUCED WITHIN THIS REPOSITORY, AND IN PARTICULAR SPECIFICALLY DISCLAIM ANY AND ALL IMPLIED WARRANTIES OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. FURTHERMORE, ORACLE AND ITS AFFILIATES DO NOT REPRESENT THAT ANY CUSTOMARY SECURITY REVIEW HAS BEEN PERFORMED WITH RESPECT TO ANY SOFTWARE, MATERIAL OR CONTENT CONTAINED OR PRODUCED WITHIN THIS REPOSITORY. IN ADDITION, AND WITHOUT LIMITING THE FOREGOING, THIRD PARTIES MAY HAVE POSTED SOFTWARE, MATERIAL OR CONTENT TO THIS REPOSITORY WITHOUT ANY REVIEW. USE AT YOUR OWN RISK. 44 | 45 | Details: 46 | ${{ steps.analysis.outputs.disclaimer_details }} 47 | repo-token: ${{ secrets.GITHUB_TOKEN }} 48 | - name: Comment if analysis finds missing readme 49 | if: steps.analysis.outputs.readme_file_found == 'false' 50 | uses: mshick/add-pr-comment@v1 51 | with: 52 | message: | 53 | :no_entry: **FAILURE: Missing README** 54 | The README file seems to be missing. Please add it. 55 | 56 | Details: 57 | ${{ steps.analysis.outputs.readme_file_details }} 58 | repo-token: ${{ secrets.GITHUB_TOKEN }} 59 | - name: Comment if analysis finds missing license 60 | if: steps.analysis.outputs.license_file_found == 'false' 61 | uses: mshick/add-pr-comment@v1 62 | with: 63 | message: | 64 | :no_entry: **FAILURE: Missing LICENSE** 65 | The LICENSE file seems to be missing. Please add it. 66 | 67 | Details: 68 | ${{ steps.analysis.outputs.license_file_details }} 69 | repo-token: ${{ secrets.GITHUB_TOKEN }} 70 | - name: Comment if analysis finds copyright notice missing 71 | if: steps.analysis.outputs.copyright_found == 'false' 72 | uses: mshick/add-pr-comment@v1 73 | with: 74 | message: | 75 | :warning: **WARNING: Missing Copyright Notice(s)** 76 | It's a good idea to have copyright notices at the top of each file. It looks like at least one file was missing this (though it might be further down in the file - this might be a false-positive). 77 | 78 | Details: 79 | ${{ steps.analysis.outputs.copyright_details }} 80 | repo-token: ${{ secrets.GITHUB_TOKEN }} 81 | - name: Halt pipeline if README is missing 82 | if: steps.analysis.outputs.readme_file_found == 'false' 83 | run: exit 1 84 | - name: Halt pipeline if LICENSE is missing 85 | if: steps.analysis.outputs.license_file_found == 'false' 86 | run: exit 1 87 | - name: Halt pipeline if disclaimer is missing 88 | if: steps.analysis.outputs.disclaimer_found == 'false' 89 | run: exit 1 90 | -------------------------------------------------------------------------------- /.github/workflows/sonarcloud.yml: -------------------------------------------------------------------------------- 1 | name: SonarCloud Scan 2 | on: 3 | pull_request_target: 4 | jobs: 5 | sonarcloud: 6 | name: SonarCloud 7 | runs-on: ubuntu-latest 8 | steps: 9 | - name: Checkout repo 10 | uses: actions/checkout@v2 11 | with: 12 | ref: ${{ github.event.pull_request.head.ref }} 13 | repository: ${{ github.event.pull_request.head.repo.full_name }} 14 | fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis 15 | - name: SonarCloud Scan 16 | uses: SonarSource/sonarcloud-github-action@master 17 | env: 18 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any 19 | SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # General 2 | .DS_Store 3 | .AppleDouble 4 | .LSOverride 5 | 6 | # Icon must end with two \r 7 | Icon 8 | 9 | 10 | # Thumbnails 11 | ._* 12 | 13 | # Files that might appear in the root of a volume 14 | .DocumentRevisions-V100 15 | .fseventsd 16 | .Spotlight-V100 17 | .TemporaryItems 18 | .Trashes 19 | .VolumeIcon.icns 20 | .com.apple.timemachine.donotpresent 21 | 22 | # Directories potentially created on remote AFP share 23 | .AppleDB 24 | .AppleDesktop 25 | Network Trash Folder 26 | Temporary Items 27 | .apdisk 28 | 29 | # ignore common security keys 30 | .key 31 | .crt 32 | .csr 33 | .pem 34 | 35 | # ignore auth.yaml file with sensitive information 36 | auth.yaml 37 | 38 | # ignore some data files 39 | data/laps_db.json 40 | data/opensearch_redbull_data.json 41 | data/redbull_data.json -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to this repository 2 | 3 | We welcome your contributions! There are multiple ways to contribute. 4 | 5 | ## Opening issues 6 | 7 | For bugs or enhancement requests, please file a GitHub issue unless it's 8 | security related. When filing a bug remember that the better written the bug is, 9 | the more likely it is to be fixed. If you think you've found a security 10 | vulnerability, do not raise a GitHub issue and follow the instructions in our 11 | [security policy](./SECURITY.md). 12 | 13 | ## Contributing code 14 | 15 | We welcome your code contributions. Before submitting code via a pull request, 16 | you will need to have signed the [Oracle Contributor Agreement][OCA] (OCA) and 17 | your commits need to include the following line using the name and e-mail 18 | address you used to sign the OCA: 19 | 20 | ```text 21 | Signed-off-by: Your Name 22 | ``` 23 | 24 | This can be automatically added to pull requests by committing with `--sign-off` 25 | or `-s`, e.g. 26 | 27 | ```text 28 | git commit --signoff 29 | ``` 30 | 31 | Only pull requests from committers that can be verified as having signed the OCA 32 | can be accepted. 33 | 34 | ## Pull request process 35 | 36 | 1. Ensure there is an issue created to track and discuss the fix or enhancement 37 | you intend to submit. 38 | 1. Fork this repository. 39 | 1. Create a branch in your fork to implement the changes. We recommend using 40 | the issue number as part of your branch name, e.g. `1234-fixes`. 41 | 1. Ensure that any documentation is updated with the changes that are required 42 | by your change. 43 | 1. Ensure that any samples are updated if the base image has been changed. 44 | 1. Submit the pull request. *Do not leave the pull request blank*. Explain exactly 45 | what your changes are meant to do and provide simple steps on how to validate. 46 | your changes. Ensure that you reference the issue you created as well. 47 | 1. We will assign the pull request to 2-3 people for review before it is merged. 48 | 49 | ## Code of conduct 50 | 51 | Follow the [Golden Rule](https://en.wikipedia.org/wiki/Golden_Rule). If you'd 52 | like more specific guidelines, see the [Contributor Covenant Code of Conduct][COC]. 53 | 54 | [OCA]: https://oca.opensource.oracle.com 55 | [COC]: https://www.contributor-covenant.org/version/1/4/code-of-conduct/ 56 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2024 Oracle and/or its affiliates. 2 | 3 | The Universal Permissive License (UPL), Version 1.0 4 | 5 | Subject to the condition set forth below, permission is hereby granted to any 6 | person obtaining a copy of this software, associated documentation and/or data 7 | (collectively the "Software"), free of charge and under any and all copyright 8 | rights in the Software, and any and all patent rights owned or freely 9 | licensable by each licensor hereunder covering either (i) the unmodified 10 | Software as contributed to or provided by such licensor, or (ii) the Larger 11 | Works (as defined below), to deal in both 12 | 13 | (a) the Software, and 14 | (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if 15 | one is included with the Software (each a "Larger Work" to which the Software 16 | is contributed by such licensors), 17 | 18 | without restriction, including without limitation the rights to copy, create 19 | derivative works of, display, perform, and distribute the Software and make, 20 | use, sell, offer for sale, import, export, have made, and have sold the 21 | Software and the Larger Work(s), and to sublicense the foregoing rights on 22 | either these or other terms. 23 | 24 | This license is subject to the following condition: 25 | The above copyright notice and either this complete permission notice or at 26 | a minimum a reference to the UPL must be included in all copies or 27 | substantial portions of the Software. 28 | 29 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 30 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 31 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 32 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 33 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 34 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 35 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # OCI Retrieval-Augmented Generations (RAG) with Generative AI Agents Service 2 | 3 | [![License: UPL](https://img.shields.io/badge/license-UPL-green)](https://img.shields.io/badge/license-UPL-green) [![Quality gate](https://sonarcloud.io/api/project_badges/quality_gate?project=oracle-devrel_oci-rag-vectordb)](https://sonarcloud.io/dashboard?id=oracle-devrel_oci-rag-vectordb) 4 | 5 | ## Introduction 6 | 7 | This repository contains a collection of solutions revolving around Retrieval-Augmented Generations (RAG), a type of solution that works with data + Large Language Models. 8 | 9 | Select the step-by-step guide closest to what you want to learn / solve: 10 | 11 | - [OCI Retrieval-Augmented Generations (RAG) with Generative AI Agents Service](./README_rag.md) 12 | - [Build with GenAI and RAG with Autonomous Database](./README_autonomous.md) 13 | - [OCI RAG: Automation & ORDS](./README_ords.md) 14 | 15 | All guides are working with RAG in one way or the other. It's recommended to first take a look at **Build with GenAI and RAG with Autonomous Database** as it also talks about deploying the required infrastructure in OCI, and it's the most complete and customizable solution (as it's using the Oracle Autonomous Database 23AI service rather than OCI Object Storage or OpenSearch as storage mechanisms). 16 | 17 | The third solution (**OCI RAG: Automation & ORDS**) assumes you've deployed the infrastructure from the first solution. 18 | 19 | ## Contributing 20 | 21 | This project is open source. Please submit your contributions by forking this repository and submitting a pull request! Oracle appreciates any contributions that are made by the open source community. 22 | 23 | ## License 24 | 25 | Copyright (c) 2024 Oracle and/or its affiliates. 26 | 27 | Licensed under the Universal Permissive License (UPL), Version 1.0. 28 | 29 | See [LICENSE](LICENSE) for more details. 30 | 31 | ORACLE AND ITS AFFILIATES DO NOT PROVIDE ANY WARRANTY WHATSOEVER, EXPRESS OR IMPLIED, FOR ANY SOFTWARE, MATERIAL OR CONTENT OF ANY KIND CONTAINED OR PRODUCED WITHIN THIS REPOSITORY, AND IN PARTICULAR SPECIFICALLY DISCLAIM ANY AND ALL IMPLIED WARRANTIES OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. FURTHERMORE, ORACLE AND ITS AFFILIATES DO NOT REPRESENT THAT ANY CUSTOMARY SECURITY REVIEW HAS BEEN PERFORMED WITH RESPECT TO ANY SOFTWARE, MATERIAL OR CONTENT CONTAINED OR PRODUCED WITHIN THIS REPOSITORY. IN ADDITION, AND WITHOUT LIMITING THE FOREGOING, THIRD PARTIES MAY HAVE POSTED SOFTWARE, MATERIAL OR CONTENT TO THIS REPOSITORY WITHOUT ANY REVIEW. USE AT YOUR OWN RISK. 32 | -------------------------------------------------------------------------------- /README_autonomous.md: -------------------------------------------------------------------------------- 1 | # Build with GenAI and RAG with Autonomous Database 2 | 3 | [![License: UPL](https://img.shields.io/badge/license-UPL-green)](https://img.shields.io/badge/license-UPL-green) [![Quality gate](https://sonarcloud.io/api/project_badges/quality_gate?project=oracle-devrel_oci-rag-vectordb)](https://sonarcloud.io/dashboard?id=oracle-devrel_oci-rag-vectordb) 4 | 5 | ## Introduction 6 | 7 | RAG (Retrieval-Augmented Generation) is revolutionizing the way we interact with AI by seamlessly enhancing the capabilities of large language models (LLMs). Imagine an AI that not only generates text but also pulls in real-time information from vast databases, providing you with accurate and up-to-date responses instantly. 8 | 9 | With RAG, your LLM can access the latest knowledge —like the results of this year's Super Bowl (yesterday, at the time of writing) — regardless of its training cut-off date. This means you can empower your AI to deliver intelligent, context-aware answers with minimal effort. 10 | 11 | Thanks to the OCI GenAI Agents Service, harnessing the power of Oracle Autonomous Database 23AI's advanced vector search capabilities is easier than ever. This service enables you to efficiently process and store documents, allowing users to **interact** with this wealth of information through an intuitive chatbot experience! 12 | 13 | chat with model - autonomous 1 14 | 15 | Here's a list of the most prominent features of the service: 16 | 17 | - Supports several data on-boarding methods and interaction channels (chat interface or API) 18 | - Creates contextually relevant answers by searching your knowledge base 19 | - Provides source attribution for every answer 20 | - Leverages Oracle Autonomous Database 23AI's vector search capabilities for accurate semantic search 21 | - Includes content moderation options for input and output to ensure a safe and respectful chat experience 22 | - Supports multi-turn conversations, where users can ask follow-up questions and receive answers that consider the context of previous questions and answers 23 | - Can interpret data from two-axis charts and reference tables in a PDF, without needing explicit descriptions of the visual elements 24 | 25 | For the infrastructure, we have the following OCI Services present: 26 | 27 | - **Oracle Autonomous Database 23AI** for vector search, tokenization, and embeddings storage - providing a fully managed solution for RAG applications 28 | - **OCI Generative AI Agents** for communicating and interacting with the data in our Autonomous Database 29 | - **OCI Object Storage** to temporarily store PDF documents to later extract their text and embeddings with Autonomous Database 30 | In this specific solution, we will use **Oracle Autonomous Database 23AI** as our storage and vector search mechanism. The 23AI version of Autonomous Database comes with **built-in vector search** capabilities, making it ideal for RAG applications. It handles all the data processing, tokenization, and embedding storage, providing a simpler and more integrated solution compared to other approaches. 31 | **OCI Vault** to securely store database connection details 32 | 33 | OCI Generative AI Agents is a fully managed service that combines the power of large language models (LLMs) with an intelligent retrieval system to create contextually relevant answers by searching your knowledge base, making your AI applications smart and efficient. 34 | 35 | To use this service, we'll follow these five steps: 36 | 37 | 1. Create the necessary infrastructure and OCI resources 38 | 2. Upload and embed your data 39 | 3. Create a knowledge base 40 | 4. Create an agent 41 | 5. Start chatting 42 | 43 | ### Use Cases 44 | 45 | Use the OCI Generative AI Agents service for the following types of use cases: 46 | 47 | - Customer Support: In the customer service industry, RAG agents can retrieve information from a company's knowledge base to provide correct and contextually relevant answers to customer inquiries, reducing response times and improving customer satisfaction. 48 | - Legal Research: Legal professionals can use RAG agents to quickly find precedents and relevant case law from vast legal databases, streamlining the research process and ensuring thorough consideration of relevant legal texts. 49 | - Healthcare and Medical Guidance: In healthcare, RAG agents can help doctors and medical staff by providing diagnostic support, retrieving medical literature, treatment protocols, and patient history to suggest potential diagnoses and treatments. 50 | - Financial Analysis: In finance, RAG agents can analyze large volumes of financial data, reports, and news to provide analysis and recommendations for traders and analysts, helping them make informed investment decisions. 51 | - Educational Tutoring: RAG agents can function as personal tutors, providing students with explanations, resources, and answers to questions by accessing educational content and tailoring explanations to the student's current level of understanding. 52 | - Content Creation: In media and content creation, RAG agents can help writers and journalists by pulling information on specific topics, suggesting content ideas, and even drafting sections of articles based on the latest data and trends. 53 | - Technical Support and Troubleshooting: RAG agents can guide users through technical troubleshooting processes by accessing and synthesizing technical manuals and support forums to offer step-by-step help. 54 | - Supply Chain Management: In supply chain and logistics, RAG agents can provide insights by retrieving and synthesizing information on inventory levels, supplier data, and logistic metrics to optimize operations and predict potential disruptions. 55 | - Real Estate Market Analysis: RAG agents can help real estate professionals by aggregating and analyzing data from several sources, including market trends, property listings, and regulatory changes, to provide comprehensive market analyses. 56 | - Travel Planning and Help: In the travel industry, RAG agents can serve as interactive travel guides, pulling information on destinations, weather, local attractions, and regulations to provide personalized travel advice and itineraries. 57 | 58 | ## 0. Prerequisites and setup 59 | 60 | ### Prerequisites 61 | 62 | - Oracle Cloud Infrastructure (OCI) Account with available credits to spend 63 | - [Appropriate policies for the GenAI Agents Service](https://docs.oracle.com/en-us/iaas/Content/generative-ai-agents/iam-policies.htm#policies) set up properly within your tenancy 64 | - [Oracle Cloud Infrastructure Documentation - Generative AI Agents](https://docs.public.oneportal.content.oci.oraclecloud.com/en-us/iaas/Content/generative-ai-agents/home.htm) 65 | - You must be subscribed to the `Chicago` region in your tenancy. 66 | - You must have an Identity Domain before you create an agent. [Follow the steps here](https://docs.oracle.com/en-us/iaas/Content/generative-ai-agents/getting-started.htm#prereq-domain) to create an Identity Domain within your OCI Account. 67 | 68 | ### Docs 69 | 70 | - [OCI Object Storage Guidelines in Generative AI Agents](https://docs.public.oneportal.content.oci.oraclecloud.com/en-us/iaas/Content/generative-ai-agents/data-requirements.htm#data-requirements) 71 | - [OCI Search with OpenSearch Guidelines for Generative AI Agents](https://docs.public.oneportal.content.oci.oraclecloud.com/en-us/iaas/Content/generative-ai-agents/opensearch-guidelines.htm#opensearch-guide) 72 | - [Oracle Database Guidelines for Generative AI Agents](https://docs.public.oneportal.content.oci.oraclecloud.com/en-us/iaas/Content/generative-ai-agents/oracle-db-guidelines.htm) 73 | - [Oracle Cloud Infrastructure (OCI) Generative AI - Getting Started](https://docs.oracle.com/en-us/iaas/Content/generative-ai-agents/getting-started.htm#get-started) 74 | - [Oracle Cloud Infrastructure (OCI) Generative AI - API](https://docs.oracle.com/en-us/iaas/api/#/en/generative-ai-agents/20240531/) 75 | - [OCI GenAI Agents - Concepts](https://docs.public.oneportal.content.oci.oraclecloud.com/en-us/iaas/Content/generative-ai-agents/concepts.htm#concepts) 76 | - [LiveLabs - Deploy an ODA Chatbot powered by Generative AI Agents using 23ai Vector DB](https://livelabs.oracle.com/pls/apex/r/dbpm/livelabs/run-workshop?p210_wid=4070&p210_wec=&session=7267829819635) 77 | 78 | ### Setup 79 | 80 | In the navigation bar of the Console, choose a region that hosts Generative AI Agents - for example, US Midwest (Chicago). If you don't know which region to choose, see [Regions with Generative AI Agents](https://docs.oracle.com/en-us/iaas/Content/generative-ai-agents/overview.htm#regions). 81 | 82 | #### Task 1: Create Dynamic Group and Policies 83 | 84 | First, we will need to ensure that we have access to the service. For this, let's create a *dynamic group* and some *policies* to allow access to the service. 85 | 86 | 1. Go to your dynamic groups and create a new dynamic group: 87 | 88 | create dynamic group 89 | 90 | Create a dynamic group with the following name and the following matching rule: 91 | 92 | dynamic group name 93 | 94 | This will ensure all Generative AI Agent resources are allowed to be accessed by this dynamic group. 95 | 96 | 2. Add the following policies to the dynamic group: 97 | 98 | policy details 99 | 100 | Replace `genaiagentdg` with the name of your dynamic group, and `` with the name of the group which you are part of: 101 | 102 | ```bash 103 | allow dynamic-group genaiagentdg to manage database-tools-family in tenancy 104 | allow dynamic-group genaiagentdg to manage secret-bundle in tenancy 105 | allow group to manage object-family in tenancy 106 | allow group to manage genai-agent-family in tenancy 107 | # if you aren't in the Default domain, you'll need to prepend the domain name to the group name like this: 108 | # allow dynamic-group OracleIdentityCloudService/genaiagentdg to manage secret-bundle in tenancy 109 | # also for the group policies: 110 | # allow group OracleIdentityCloudService/ to manage genai-agent-family in tenancy 111 | ``` 112 | 113 | The four permissions are: `object-family`, `genai-agent-family`, `secret-bundle`, and `database-tools-family`. Ensure the user's that will make the requests is a member of the mentioned group and has the mentioned permissions (preferrably in the whole tenancy, although if you want to configure it per compartment or be more careful with your permissions, you can do so by following [this guide](https://docs.oracle.com/en-us/iaas/Content/generative-ai-agents/iam-policies.htm)). 114 | 115 | > **Note**: if you are working on an identity provider other than Oracle Identity Cloud Service to authenticate to your OCI tenancy, you'll need to *prepend* the name of your identity provider in the policies and dynamic group definitions. For example, if you're using 'OracleIdentityCloudService', your policy shall be set like 'OracleIdentityCloudService/' instead of ''. 116 | 117 | #### Task 2: Create VCN and Private Subnet 118 | 119 | We need to create a VCN and private subnet to host our Autonomous database securely in a private network. Then, we will use a Database Connection to act as a bastion. This will help our database be more secure and isolated from the public internet. 120 | 121 | 1. Create Virtual Cloud Network (VCN): 122 | - Navigate to Networking -> Virtual cloud networks 123 | - Click "Create VCN" 124 | - Provide IPv4 CIDR Block: `10.0.0.0/16` 125 | 126 | create vcn 127 | 128 | 2. Create Private Subnet: 129 | - In the newly created VCN, click "Create Subnet" 130 | - Configure: 131 | - IPv4 CIDR Block: `10.0.1.0/24` 132 | - Select "Private Subnet" 133 | - Leave other settings as default 134 | 135 | create subnet 136 | 137 | 3. Configure Security List: 138 | - Go to the new subnet 139 | - Navigate to Security List 140 | - Add ingress rules including: 141 | - Database access to ports `1521-1522` 142 | - Access to ports 80 and 53 143 | 144 | ingress rules 145 | 146 | #### Task 3: Create Vault for Database Secrets 147 | 148 | 1. Create Vault: 149 | - Navigate to Key Management & Secret Management -> Vault 150 | - Provide Name 151 | - Click Create Vault 152 | 153 | vault creation 154 | 155 | 2. Create Encryption Key: 156 | - In the new vault, click "Create Key" 157 | - Configure: 158 | - Provide Name 159 | - Protection Mode: HSM 160 | - Leave other settings as default 161 | - Click Create Key 162 | 163 | key creation 164 | 165 | > **Note**: set your protection mode to `HSM`. 166 | 167 | #### Task 4: Create Autonomous Database 168 | 169 | Now, we need to create the Autonomous Database that will be used by the Generative AI Agents service to store and retrieve data in the form of *embeddings*. 170 | 171 | databases menu 172 | 173 | 1. Create Database: 174 | - Navigate to Oracle Databases -> Autonomous Databases 175 | - Click "Create Autonomous Database" 176 | - Configure: 177 | - Select Compartment 178 | - Provide Display name and Database name 179 | - Workload type: Data Warehouse 180 | - Deployment type: Serverless 181 | - Database version: `23ai` 182 | - Set a password 183 | - Network Access: `Private Endpoint access` only 184 | - Select the VCN and subnets that we created in task 2 185 | - **Uncheck** "Require mutual TLS (mTLS) authentication" 186 | - Provide valid email ID 187 | - Click Create Autonomous Database 188 | 189 | database config 190 | 191 | #### Task 5: Create Database Tools Connection 192 | 193 | Now, we'll create a database connection to act as a bastion to our database. This will help us connect to the database securely and isolate it from the public internet. Additionally, this connection will be used by the Generative AI Agents service to retrieve data from the database. 194 | 195 | Go to the Database Tools Connections menu: 196 | 197 | connections menu 198 | 199 | Before, let's make sure we have the private IP address and connection strings of our Autonomous Database. Go to your Autonomous Database details page: 200 | 201 | database details 202 | 203 | Now, we can get the private IP address and connection strings from the details page: 204 | 205 | private db ip 206 | 207 | connection strings 208 | 209 | Your connection string should look something like this: 210 | 211 | ```bash 212 | (description= (retry_count=20)(retry_delay=3)(address=(protocol=tcps)(port=1522)(host=lpne8zzr.adb.us-chicago-1.oraclecloud.com))(connect_data=(service_name=gc3dd18cc561e12_agents_high.adb.oraclecloud.com))(security=(ssl_server_dn_match=no))) 213 | ``` 214 | 215 | Let's make the necessary changes to the connection string: 216 | 217 | - Change `retry_count` from `20` to `3` 218 | - Replace `host` with your database'sprivate IP address 219 | 220 | Your connection string should look like this: 221 | 222 | ```bash 223 | (description= (retry_count=3)(retry_delay=3)(address=(protocol=tcps)(port=1522)(host=10.0.1.76))(connect_data=(service_name=agents_low.adb.oraclecloud.com))(security=(ssl_server_dn_match=no))) 224 | ``` 225 | 226 | Let's save this info for later use. Now, we can create the database connection with this information: 227 | 228 | - Navigate to Developer Services -> Database Tools Connections 229 | - Click "Create connection" 230 | - Configure: 231 | - Provide Name and Compartment 232 | - Database cloud service: Oracle Autonomous Database 233 | - Username: `ADMIN` 234 | - Create a password secret: 235 | - Provide Name 236 | - Select the vault and keys from Task 3 237 | - Use the same password you used when creating the Autonomous Database 238 | - Copy the connection string from Task 5 239 | - Create private endpoint: 240 | - Provide Name 241 | - Select the private subnet from Task 2 242 | - In SSL details, select the wallet format: `None` 243 | 244 | Finally, let's validate the connection we just created: 245 | - Go to new Database Tools connection 246 | - Click `Validate` to verify setup 247 | 248 | validate connection 249 | 250 | If everything is correct, you should see the following message: 251 | 252 | validate connection - success 253 | 254 | As a recap, we have created the following resources: 255 | 256 | - **Policies and dynamic group**, to allow access to the service 257 | - **VCN** with private subnet and security list, to protect the Autonomous Database 258 | - **Autonomous Database**, in a private subnet of a VCN 259 | - **Database Tools Connection**, to connect to the Autonomous Database 260 | - **Vault**, to store the database password 261 | - **Encryption Key**, to encrypt the database password 262 | 263 | If you have followed every step, the infrastructure setup is complete. Now, we can start using this infrastructure to create the knowledge base for our RAG agent. 264 | 265 | #### Task 6: Set up the Autonomous Database 266 | 267 | To work with the Oracle Generative AI Agents service, we need to set up the Autonomous Database to conform to some requirements. 268 | 269 | To launch this SQL worksheet, go to the Autonomous Database details page and click on the `SQL worksheet` button: 270 | 271 | sql worksheet 272 | 273 | Now, we can proceed to run some SQL code: 274 | 275 | 1. First, we'll run an Access Control List rule to allow the database user to access the embedding model, amongst other things: 276 | 277 | ```sql 278 | -- ACL to let user go out everywhere (host =>'*'), it's not required for Oracle Base Database. 279 | begin 280 | -- Allow all hosts for HTTP/HTTP_PROXY 281 | dbms_network_acl_admin.append_host_ace( 282 | host =>'*', 283 | lower_port => 443, 284 | upper_port => 443, 285 | ace => xs$ace_type( 286 | privilege_list => xs$name_list('http', 'http_proxy'), 287 | principal_name => upper('admin'), 288 | principal_type => xs_acl.ptype_db) 289 | ); 290 | end; 291 | / 292 | ``` 293 | 294 | 2. We'll now create some credentials to access the OCI GenAI Agents service. For this, we'll need to add a new API key to our OCI user, and then use this API key with the `DBMS_CLOUD` plugin to authenticate. For this, go to your user's OCI page and click on the `API Keys` tab. Once generated (or uploaded), save it in your local computer as you will need to use the fingerprint and private keys in the following steps: 295 | 296 | generate api key 297 | 298 | 3. Let's use this API key and the `DBMS_CLOUD` plugin to authenticate. You will need your user, compartment and tenancy OCIDs, as well as your private key and fingerprint. In the following SQL code, replace the strings with your own values, and run the code: 299 | 300 | ```sql 301 | -- DBMS_CLOUD credentials 302 | -- Some examples are based on DBMS_CLOUD, that is included in Autonomous DB. 303 | -- If you need to install it (for example on Base Database) you can refer to: https://support.oracle.com/knowledge/Oracle%20Cloud/2748362_1.html 304 | begin 305 | DBMS_CLOUD.CREATE_CREDENTIAL ( 306 | credential_name => 'OCI_CRED_BUCKET', 307 | user_ocid => 'ocid1.user.oc1..aaaaaaaaa2...', 308 | tenancy_ocid => 'ocid1.tenancy.oc1..aaaaaaaa...', 309 | private_key => 'MIIEvgI...RpV', 310 | fingerprint => '0f:df...1d:88:d6' 311 | ); 312 | end; 313 | / 314 | ``` 315 | 316 | > **Note**: the private key shall not begin with `-----BEGIN PRIVATE KEY-----` or `-----END PRIVATE KEY-----`, it shall only have the key's content. You can also retrieve the key's fingerprint from the API key details page. 317 | 318 | 4. Let's create credentials for the Generative AI Agents service: 319 | 320 | ```sql 321 | declare 322 | jo json_object_t; 323 | begin 324 | jo := json_object_t(); 325 | jo.put('user_ocid','ocid1.user.oc1..aaaaaaaaa2...'); 326 | jo.put('tenancy_ocid','ocid1.tenancy.oc1..aaaaaaaa...'); 327 | jo.put('compartment_ocid','ocid1.tenancy.oc1..aaaaaaaa...'); 328 | jo.put('private_key','MIIEvgI...RpV'); 329 | jo.put('fingerprint','0f:df...1d:88:d6'); 330 | dbms_vector.create_credential( 331 | credential_name => 'OCI_CRED', 332 | params => json(jo.to_string) 333 | ); 334 | end; 335 | / 336 | ``` 337 | 338 | If the setup has been properly executed, you can run this SQL query as a test, to embed the word "hello" with the `cohere.embed-multilingual-v3.0` model: 339 | 340 | ```sql 341 | SELECT 342 | dbms_vector.utl_to_embedding( 343 | 'hello', 344 | json('{ 345 | "provider": "OCIGenAI", 346 | "credential_name": "OCI_CRED", 347 | "url": "https://inference.generativeai.us-chicago-1.oci.oraclecloud.com/20231130/actions/embedText", 348 | "model": "cohere.embed-multilingual-v3.0" 349 | }') 350 | ) 351 | FROM dual; 352 | ``` 353 | 354 | #### Task 7: Upload & embed your data 355 | 356 | Now that our setup is done and we can already generate embeddings, we can upload a test PDF file to an OCI Object Storage bucket. From there, we'll use the `DBMS_CLOUD.GET_OBJECT` function to embed the file and save the embeddings in the Autonomous Database, in chunks of 75 tokens. 357 | 358 | 1. Create an OCI Object Storage bucket: 359 | 360 | create bucket 361 | 362 | 2. Upload your PDF file to your bucket 363 | 364 | uploaded pdf 365 | 366 | 3. From this PDF, create a Pre-Authenticated Request (PAR) to access the file: 367 | 368 | create par 369 | 370 | 4. Copy the PAR URL: 371 | 372 | create par output 373 | 374 | 5. Use the `DBMS_CLOUD.GET_OBJECT` function to embed the file and save the embeddings in the Autonomous Database, in chunks of 75 tokens. For your data, make sure to replace that `https` PAR with your own PAR URL, and execute it: 375 | 376 | ```sql 377 | CREATE TABLE ai_extracted_data AS 378 | SELECT 379 | j.chunk_id, 380 | j.chunk_offset, 381 | j.chunk_length, 382 | j.chunk_data 383 | FROM 384 | -- divide a blob into chunks (utl_to_chunks): 385 | (select * from dbms_vector_chain.utl_to_chunks( 386 | dbms_vector_chain.utl_to_text( 387 | to_blob( 388 | DBMS_CLOUD.GET_OBJECT('OCI_CRED_BUCKET', 'https://objectstorage.us-chicago-1.oraclecloud.com/p/Aaklz9CEuOdwhdWbV-bLcDTvML4DNlRtTw7z6dMuSMh1gn2toBnmE1airTA-ZhkW/n/axk4z7krhqfx/b/AI_Vector_Search/o/oracle-ai-vector-search-users-guide.pdf') 389 | ) 390 | ), json('{"max":"75", "normalize":"all", "overlap":"15"}') 391 | )), 392 | JSON_TABLE(column_value, '$' 393 | COLUMNS ( 394 | chunk_id NUMBER PATH '$.chunk_id', 395 | chunk_offset NUMBER PATH '$.chunk_offset', 396 | chunk_length NUMBER PATH '$.chunk_length', 397 | chunk_data CLOB PATH '$.chunk_data' 398 | ) 399 | ) j; 400 | ``` 401 | 402 | 6. If everything went well, you can check the table's contents: 403 | 404 | table contents 405 | 406 | You can run the command yourself: 407 | 408 | ```sql 409 | SELECT * FROM ai_extracted_data; 410 | select COUNT(*) from ai_extracted_data 411 | ``` 412 | 413 | 7. Now, remember that, even though we already have some data in this table, it's in cleartext (not in its numerical embeddings form). To generate the embeddings from these cleartext chunks, let's first create the vector table: 414 | 415 | ```sql 416 | -- Create vector table from an existing table 417 | -- In the following table ai_extracted_data, chunk_id is the record id while chunk_data is the content column. 418 | create table ai_extracted_data_vector as ( 419 | select chunk_id as docid, to_char(chunk_data) as body, dbms_vector.utl_to_embedding( 420 | chunk_data, 421 | json('{ 422 | "provider": "OCIGenAI", 423 | "credential_name": "OCI_CRED", 424 | "url": "https://inference.generativeai.us-chicago-1.oci.oraclecloud.com/20231130/actions/embedText", 425 | "model": "cohere.embed-multilingual-v3.0" 426 | }') 427 | ) as text_vec 428 | from ai_extracted_data 429 | where chunk_id <= 400 430 | ) 431 | ``` 432 | 433 | > **Note**: there's a quota limit for running the embedding model. For datasets with more than 400 records, we can repeatedly load the data or write a script to load data in batches. 434 | 435 | > **Note**: if your existing data hasn't been processed into chunks yet, your chunk size might exceed 512, which would prevent embedding generation. If you run into this issue, refer to [Custom Chunking Specifications](https://docs.oracle.com/en-us/iaas/Content/generative-ai-agents/custom-chunking-specifications.htm) to convert content to chunks. 436 | 437 | 8. If you have more than 400 chunks/records in the table, you can repeat the process for the next batch of data with this script: 438 | 439 | ```sql 440 | insert into ai_extracted_data_vector 441 | select chunk_id as docid, to_char(chunk_data) as body, dbms_vector.utl_to_embedding( 442 | chunk_data, 443 | json('{ 444 | "provider": "OCIGenAI", 445 | "credential_name": "OCI_CRED", 446 | "url": "https://inference.generativeai.us-chicago-1.oci.oraclecloud.com/20231130/actions/embedText", 447 | "model": "cohere.embed-multilingual-v3.0" 448 | }') 449 | ) as text_vec 450 | from ai_extracted_data 451 | where chunk_id > 400 452 | ``` 453 | 454 | > **Note**: If you just have **too many** chunks/records in the table, you can repeat the process for the next batch of data sequentially by editing the SQL above, or through some additional programming logic (automating it). Just know that for now the limit is 400 chunks per data load. 455 | 456 | 457 | 9. Finally, create the function that will return `top_k` results when calling the function (by default, 5): 458 | 459 | ```sql 460 | -- Create function from vector table 461 | -- When returning the results, rename (alias) the record ID as 'DOCID', the content column as 'BODY', and the VECTOR_DISTANCE between text_vec and query_vec as 'SCORE'. These 3 columns are required. If the vector table includes 'URL' and 'Title' columns, rename them (alias) as 'URL' and 'TITLE' respectively. 462 | create or replace FUNCTION retrieval_func_ai ( 463 | p_query IN VARCHAR2, 464 | top_k IN NUMBER 465 | ) RETURN SYS_REFCURSOR IS 466 | v_results SYS_REFCURSOR; 467 | query_vec VECTOR; 468 | BEGIN 469 | query_vec := dbms_vector.utl_to_embedding( 470 | p_query, 471 | json('{ 472 | "provider": "OCIGenAI", 473 | "credential_name": "OCI_CRED", 474 | "url": "https://inference.generativeai.us-chicago-1.oci.oraclecloud.com/20231130/actions/embedText", 475 | "model": "cohere.embed-multilingual-v3.0" 476 | }') 477 | ); 478 | 479 | OPEN v_results FOR 480 | SELECT DOCID, BODY, VECTOR_DISTANCE(text_vec, query_vec) as SCORE 481 | FROM ai_extracted_data_vector 482 | ORDER BY SCORE 483 | FETCH FIRST top_k ROWS ONLY; 484 | 485 | RETURN v_results; 486 | END; 487 | ``` 488 | 489 | 10. You can now run this function to retrieve the top `n` results: 490 | 491 | ```sql 492 | -- Run & check the function 493 | -- Display the DOCID and SCORE 494 | DECLARE 495 | v_results SYS_REFCURSOR; 496 | v_docid VARCHAR2(100); 497 | v_body VARCHAR2(4000); 498 | v_score NUMBER; 499 | p_query VARCHAR2(100) := 'What is self-instruct?'; 500 | top_k NUMBER := 10; 501 | BEGIN 502 | v_results := retrieval_func_ai(p_query, top_k); 503 | 504 | DBMS_OUTPUT.PUT_LINE('DOCID | SCORE'); 505 | DBMS_OUTPUT.PUT_LINE('--------|------'); 506 | 507 | LOOP 508 | FETCH v_results INTO v_docid, v_body, v_score; 509 | EXIT WHEN v_results%NOTFOUND; 510 | 511 | DBMS_OUTPUT.PUT_LINE(v_docid || ' | ' || v_score); 512 | END LOOP; 513 | 514 | CLOSE v_results; 515 | END; 516 | ``` 517 | 518 | You should see something like this, with a ranking of the most relevant chunks (and their IDs), together with the similarity score: 519 | 520 | embeddings result 521 | 522 | Even though we were able to communicate with our embeddings directly (and you're perfectly fine if you wanted to create a system like this), we'll use the Generative AI Agents service to create an agent that can answer questions about our data through the OCI Console interface. 523 | 524 | 525 | ## 1. Create a knowledge base 526 | 527 | To associate every step we've done in the setup so far with the Generative AI Agents service, we'll need to create a knowledge base. This will let the agent know about our data and be able to answer questions about it. 528 | 529 | 1. Go to the Generative AI Agents service and click on the *Knowledge Bases* tab: 530 | 531 | knowledge bases 532 | 533 | 2. Click on *Create knowledge base* and enter the following information: 534 | 535 | knowledge base - autonomous 536 | 537 | Make sure to select `Oracle AI Vector Search` as the data store type, and the connection that you created in Task 5. Also, make sure to select the name of the `Retrieval Function` that you created in Task 9. 538 | 539 | > **Note**: after creating a knowledge base, and since the purpose of having used Autonomous Database is to have an updateable, searchable, in-real time vector database, we can now see one of the advantages of using Autonomous over Object Storage: after we upload some more data and vectorize it (can be automated), the knowledge base will be updated in real time, and will not require any additional human intervention, as the knowledge base only needs to know which retrieval function to use, and doesn't care how much data actually exists in the database. 540 | 541 | ## 2. Create an agent 542 | 543 | 1. Now, let's create an Agent in a similar fashion: 544 | 545 | new agent 546 | 547 | 2. Click on *Create agent* and enter the following information: 548 | 549 | new agent autonomous 550 | 551 | Make sure to select the knowledge base that you just created. Make sure to select the *Automatically create an endpoint for this agent* option to avoid later having to manually setup the endpoint. 552 | 553 | > **Note**: you can customize the welcome message when interacting with the user through chat, as well as providing some additional instructions to the RAG agent for it to follow during generations. 554 | 555 | In a few minutes, your agent will be ready to use! Go to the next section to chat with your new agent. 556 | 557 | ## 3. Chat with your new agent 558 | 559 | We can now access our agent's chat and start talking to it - and query about our data: 560 | 561 | chat autonomous 1 562 | 563 | The `traces` system will also retrieve the embeddings used for the responses (and their document IDs in the database), so you can verify the sources that contributed to the generated response by the agent: 564 | 565 | chat autonomous 2 566 | 567 | This can be applied to any domain: if you follow the instructions in this AI solution to process & upload your own data, you'll receive accurate responses from the agent (as well as some references so you can check the veracity of the model's responses). 568 | 569 | ## Demo 570 | 571 | [Watch the demo here](https://www.youtube.com/watch?v=JqF6Bc9am4s&list=PLPIzp-E1msraY9To-BB-vVzPsK08s4tQD&index=15) 572 | 573 | ## Physical Architecture 574 | 575 | architecture diagram 576 | 577 | ## Contributing 578 | 579 | This project is open source. Please submit your contributions by forking this repository and submitting a pull request! Oracle appreciates any contributions that are made by the open source community. 580 | 581 | ## License 582 | 583 | Copyright (c) 2022 Oracle and/or its affiliates. 584 | 585 | Licensed under the Universal Permissive License (UPL), Version 1.0. 586 | 587 | See [LICENSE](LICENSE) for more details. 588 | 589 | ORACLE AND ITS AFFILIATES DO NOT PROVIDE ANY WARRANTY WHATSOEVER, EXPRESS OR IMPLIED, FOR ANY SOFTWARE, MATERIAL OR CONTENT OF ANY KIND CONTAINED OR PRODUCED WITHIN THIS REPOSITORY, AND IN PARTICULAR SPECIFICALLY DISCLAIM ANY AND ALL IMPLIED WARRANTIES OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. FURTHERMORE, ORACLE AND ITS AFFILIATES DO NOT REPRESENT THAT ANY CUSTOMARY SECURITY REVIEW HAS BEEN PERFORMED WITH RESPECT TO ANY SOFTWARE, MATERIAL OR CONTENT CONTAINED OR PRODUCED WITHIN THIS REPOSITORY. IN ADDITION, AND WITHOUT LIMITING THE FOREGOING, THIRD PARTIES MAY HAVE POSTED SOFTWARE, MATERIAL OR CONTENT TO THIS REPOSITORY WITHOUT ANY REVIEW. USE AT YOUR OWN RISK. 590 | -------------------------------------------------------------------------------- /README_ords.md: -------------------------------------------------------------------------------- 1 | # OCI RAG: Automation & ORDS 2 | 3 | [![License: UPL](https://img.shields.io/badge/license-UPL-green)](https://img.shields.io/badge/license-UPL-green) [![Quality gate](https://sonarcloud.io/api/project_badges/quality_gate?project=oracle-devrel_oci-rag-vectordb)](https://sonarcloud.io/dashboard?id=oracle-devrel_oci-rag-vectordb) 4 | 5 | ## Introduction 6 | 7 | RAG is one of the most coveted use cases nowadays for AI. The great thing about RAG is that it allows you to augment the knowledge of an LLM without having to retrain it. How, you may ask? Well, it's a way for the LLM to extract information (like a database) and present this information to the user very quickly. 8 | 9 | This allows LLMs to acquire up-to-date knowledge, for example, the results of this year's SuperBowl, regardless of when the LLM you're running inference against has been trained. Therefore, you can make your LLM more intelligent and provide it with updated data with little to no effort. 10 | 11 | Luckily, OCI GenAI Agents Service allows us to do just that: we will be able to upload our documents, process this data, put it into an Index Store (OCI OpenSearch), create a Redis cluster for caching purposes, and provide users with a way to **consume** this data through a chatbot! 12 | 13 | For the infrastructure, we will have the following OCI Services present: 14 | 15 | - **OCI Redis** for caching user-agent interactions (so we can give some context to the model as well) 16 | - **OCI OpenSearch Cluster** for Index Similarity Search (Index Database) and storing indices with data (Vector Stores will be available in upcoming releases) 17 | - **OCI Compute** for connecting to the OpenSearch cluster securely (through OCI private subnet routing) 18 | - **OCI Generative AI Agents** for communicating and interacting with the data in our cluster 19 | 20 | Oracle Cloud Infrastructure Generative AI Agents (Beta) is a fully managed service that combines the power of large language models with an intelligent retrieval system to create contextually relevant answers by searching your knowledge base, making your AI applications smart and efficient. 21 | 22 | To use this service, index your data in OCI Search with OpenSearch and set up a cluster in OCI Cache with Redis for the cached user prompts and responses. Then you create an agent and attach your data source. Finally, you test your agent and allow it to generate insights and answer questions. We will see how to do all these steps in this application pattern. 23 | 24 | ### Use Cases 25 | 26 | Use the OCI Generative AI Agents service for the following types of use cases: 27 | 28 | - Chatbot for FAQs: Index FAQ and documentation so that users can easily access relevant topics and find answers to their questions through a chatbot or through the current documentation. 29 | - Chatbot for policies: Index policy documents, such as human resources, insurance, or finance documents. When users ask specific questions about these policies, they can get answers relevant answers from those documents through a chatbot interface. 30 | 31 | ### Available Regions in OCI with the Generative AI Agents Service 32 | 33 | Oracle hosts its OCI services in regions and availability domains. A region is a localized geographic area, and an availability domain is one or more data centers in that region. OCI Generative AI Agents is hosted in the following region: 34 | 35 | - Region name: US Midwest (Chicago) 36 | - Region identifier: `us-chicago-1` 37 | 38 | ## 0. Prerequisites and setup 39 | 40 | - Oracle Cloud Infrastructure (OCI) Account with available credits to spend 41 | - [Appropriate policies for the GenAI Agents Service](https://docs.oracle.com/en-us/iaas/Content/generative-ai-agents/iam-policies.htm#policies) set up properly within your tenancy 42 | - [Oracle Cloud Infrastructure Documentation - Generative AI Agents](https://docs.public.oneportal.content.oci.oraclecloud.com/en-us/iaas/Content/generative-ai-agents/home.htm) 43 | - [Oracle Cloud Infrastructure (OCI) Generative AI - Getting Started](https://docs.oracle.com/en-us/iaas/Content/generative-ai-agents/getting-started.htm#get-started) 44 | - [Oracle Cloud Infrastructure (OCI) Generative AI - API](https://docs.oracle.com/en-us/iaas/api/#/en/generative-ai-agents/20240331/) 45 | - [OCI GenAI Agents - Concepts](https://docs.public.oneportal.content.oci.oraclecloud.com/en-us/iaas/Content/generative-ai-agents/concepts.htm#concepts) 46 | - [Python 3.10](https://www.python.org/downloads/release/python-3100/) 47 | - [Conda](https://conda.io/projects/conda/en/latest/user-guide/install/index.html) 48 | - [OCI SDK](https://docs.oracle.com/en-us/iaas/Content/API/Concepts/sdkconfig.htm) 49 | - You must be subscribed to the Chicago region in your tenancy. Generative AI Agents is only available in Chicago at this moment. 50 | - You must have an Identity Domain before you create an agent. [Follow the steps here](https://docs.oracle.com/en-us/iaas/Content/generative-ai-agents/getting-started.htm#prereq-domain) to create an Identity Domain within your OCI Account. 51 | 52 | If you've just ran into this README, this is an extension of the functionality present in [this README file](README.md). If you haven't previously set up a GenAI Agent or performed the OCI Cloud setup, please refer to [the README](README.md) to find out how to set everything up to get the resources you need to complete this use case. 53 | 54 | Finally, let's install Python dependencies into a local environment (or you can use your OCI Cloud Shell instance for this), to run the Python code found in the `scripts/` folder: 55 | 56 | ```bash 57 | pip install -r requirements.txt 58 | ``` 59 | 60 | Now, we're ready to start working. 61 | 62 | ## 1. ORDS Overview and setup 63 | 64 | Oracle REST Data Services (ORDS) is a bridge between HTTP and Oracle Databases. In our case, we will be consuming an ORDS endpoint (hosted in the database that contains all F1 laps) and, therefore, we will be able to use this data as soon as it gets to the bastion. 65 | 66 | In this case, we will use some data from [F1 eSports game](https://www.ea.com/en-gb/games/f1/f1-23). See `data/f1game_data.json` for an example of what kind of data we will be storing in our database. 67 | 68 | Therefore, all F1 game laps are stored into the database, and we are able to consume all these laps from an ORDS endpoint. 69 | 70 | For a full ORDS setup guide please visit [this page](https://docs.oracle.com/en/database/oracle/apex/23.2/htmig/configuring-ords.html#GUID-D688F4D6-FCAB-4C4D-BA6D-9A3506B3E05F). 71 | 72 | To recreate the F1 eSports Ingestion and Analytics you can follow [this guide](https://apexapps.oracle.com/pls/apex/f?p=133:180:13122153387920::::wid:3708) 73 | 74 | Here is how you can use ORDS to create API end point. 75 | 76 | - Login to APEX Workspace and navigate to SQL Workshop 77 | 78 | ![SQL Workshop](./img/ords/1sqlworkshop.png) 79 | 80 | - Activate ORDS inside RESful Services 81 | 82 | ![RESTful Services](./img/ords/2restfulservices.png) 83 | 84 | - Click Create Module in Modules section 85 | 86 | ![Create Module](./img/ords/3modules.png) 87 | 88 | - Fill in necessary fields in Module Definition section and click Apply Changes, then click on Create Template from Resource Templates section at the bottom of the page 89 | 90 | ![Module Definition](./img/ords/4moduledefinition.png) 91 | 92 | - Add URI Template, and click on Apply Changes, after that click on Create Handler from Resource Handlers section at the bottom of the page 93 | 94 | ![Module Definition](./img/ords/5resourcetemplate.png) 95 | 96 | - Choose GET method and change Source Type to Media Resource 97 | 98 | ![Module Definition](./img/ords/6resourcehandler.png) 99 | 100 | Create JSON object definition in Source section, here is an example of how you can structure your query: 101 | 102 | ```sql 103 | SELECT 'application/json', 104 | JSON_OBJECT('OBJECT NAME' VALUE ( 105 | SELECT JSON_ARRAYAGG(JSON_OBJECT(*) RETURNING CLOB) 106 | FROM ( 107 | SELECT * FROM 'TABLE.NAME' 108 | ) 109 | ) RETURNING CLOB) AS CD 110 | FROM DUAL 111 | ``` 112 | 113 | - To *manually* consume the endpoint, we can run the following command: 114 | 115 | ```bash 116 | # obfuscated since it's an unauthenticated rest endpoint 117 | curl -O https://xxxxxxxx.adb.region-name-1.oraclecloudapps.com/ords/f1sim/all_laps/all_json 118 | ``` 119 | 120 | Once we have all laps, we will need perform the following steps on the data: 121 | 122 | - Process the JSON object into individual laps 123 | - Stringify-format each lap 124 | - Put each lap into OpenSearch format, ultimately creating a JSON file to mass-insert this data into our OpenSearch cluster 125 | - In the end, we will automatically push new laps into OpenSearch 126 | 127 | Remember that the bastion, according to the architecture we've prepared, is the only way to communicate and interact with our OpenSearch cluster. Therefore, we want to consume all laps from our bastion, and insert (the new ones) into the OpenSearch cluster - creating a real-time interaction between laps being inserted into the database, and the LLM's knowledge of these laps. 128 | 129 | ## 2. Preparing OpenSearch data 130 | 131 | This is one data point (one lap) from our dataset: 132 | 133 | ```json 134 | { 135 | "ID":99977, 136 | "R_NAME":"Checo Perez", 137 | "TRACKNAME":"UNKNOWN", 138 | "M_SESSION":"1372327188246629453", 139 | "M_GAMEHOST":"Checo Las Vegas", 140 | "M_TRACKID":"31", 141 | "LAP_NUM":1, 142 | "INVALID_LAP":1, 143 | "LAP_TIME_DSP":"1:58.727", 144 | "LAP_TIME_IN_MS":118727, 145 | "S1":" 57.897", 146 | "S2":" 36.621", 147 | "S3":" 24.208", 148 | "LAP_DATE":"2024-02-15T22:40:44", 149 | "AVG_LAP_TIME_DSP":"1:45.818", 150 | "AVG_LAP_TIME":105818, 151 | } 152 | ``` 153 | 154 | Corresponding to a lap that Checo recorded for us, so we have his and Max's laps to compare to event attendees throughout the world during events that we attend to. 155 | 156 | Now, this data, in JSON format, has to be put into a specific format (OpenSearch format), more specifically into a JSON file, with one JSON element per line, and one JSON object to represent the metadata (index information) of each lap as well. 157 | 158 | In the end, the data should look like this: 159 | 160 | ```json 161 | { "index": { "_index": "", "_id": "" } } 162 | { "A JSON": "document" } 163 | ``` 164 | 165 | In our case: 166 | 167 | ```json 168 | {"index": {"_index": "redbull", "_id": 99977}} 169 | {"data": "racer id: 99977, racer name: Checo Perez, track name: Texas, invalid lap: 1, total lap time: 1:58.727, sector 1 time: 57.897, sector 2 time: 36.621, sector 3 time: 24.208, lap date: 02/15/2024)"} 170 | ``` 171 | 172 | > **Note**: each JSON lap becomes 2 JSON lines, one for the index name and index ID, and another one for the data. I like putting this data into a single key called `data` but you can also store it into multiple key-value pairs. 173 | 174 | This conversion has been implemented in `scripts/consume_ords.py`, in the function called `create_opensearch_format()`. 175 | 176 | ## 3. Running the pipeline 177 | 178 | First, create a file called `auth.yaml` in the root directory of the repository, and put your ORDS endpoint in. My file looks like this: 179 | 180 | ```yaml 181 | ords_endpoint: https://xxxxxxxx.adb.region-name-1.oraclecloudapps.com/ords/f1sim/all_laps/all_json 182 | ip_address: ip_address (of your OpenSearch bastion) 183 | user: (SSH user for your OpenSearch bastion access) 184 | key_location: (SSH key location for your OpenSearch bastion) 185 | cluster_private_user: opensearch_cluster_username 186 | cluster_private_password: opensearch_cluster_password 187 | ``` 188 | 189 | This file is used in `consume_ords.py` to get the HTTPs endpoint to get all RedBull laps. 190 | 191 | Then, we just have to run the following Python script in the environment where we installed all dependencies: 192 | 193 | ```bash 194 | cd scripts/ 195 | python consume_ords.py 196 | ``` 197 | 198 | Note that a mechanism has been created for consistency purposes: a `tinydb` local database file is being used to actively check for new laps, and ignore duplicate laps. Therefore, if you run this step multiple times, it will check for duplicate laps before inserting them again, avoiding duplicate insertions and data redundancy. 199 | 200 | This will generate `data/opensearch_redbull_data.json`, in the proper format for OCI OpenSearch. Now that we have our well-formed data, we can create these data sources. 201 | 202 | ## 4. OpenSearch automatic data ingestion 203 | 204 | There are several methods to automate data ingestion, including: 205 | 206 | 1. We could access the bastion (only way to access the OpenSearch cluster) through SSH, and remotely execute a bash command through the SSH connection, to `scp` copy `opensearch_redbull_data.json`, and then make a HTTP call to insert this file's data in bulk. 207 | 2. We could have a FastAPI or similar API server running inside the bastion, and every time we decide to re-run our script, invoke the API to also push this data to OpenSearch automatically. 208 | 3. We could expand the existing pipeline we have to create two new functions: `send_file()` and `update_cluster()` and let Python do its job. These two functions will perform the jobs listed in option #1. 209 | 210 | Options #1 and #2 are feasible and can be devised in little time, but I have decided to develop this with strategy #3, as it's easier to automate and implement: every time we run the code to check for new laps, these new laps will be automatically inserted into the cluster with the help of Python. 211 | 212 | This is how the `send_file()` is implemented. It uses the SFTP protocol to transfer the file from one local directory (the source) to a remote directory (the destination) in our bastion: 213 | 214 | ```python 215 | def send_file(auth_data: dict, source: str, destination: str): 216 | # we string build the scp command to copy the file from local to the bastion 217 | scp_command = """scp -i {} {} {}@{}:{}""".format( 218 | auth_data['key_location'], 219 | source, 220 | auth_data['user'], 221 | auth_data['ip_address'], 222 | destination 223 | ) 224 | # we print it to debug 225 | print(scp_command) 226 | 227 | # we create an SSH client and, inside it, use its SFTP functionality 228 | # to send the file. 229 | ssh_client = paramiko.SSHClient() 230 | ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 231 | ssh_client.connect(auth_data['ip_address'], username=auth_data['user'], key_filename=auth_data['key_location'], password='') 232 | 233 | # send the file through SFTP 234 | ftp_client=ssh_client.open_sftp() 235 | ftp_client.put(source, destination) 236 | ftp_client.close() 237 | 238 | return ssh_client 239 | 240 | ``` 241 | 242 | And finally, to run the update command into our Index DB in OpenSearch, we have to create `update_cluster()`: 243 | 244 | ```python 245 | def update_cluster(auth_data: dict, ssh_client: paramiko.SSHClient): 246 | # this points to the private IP address of the OS cluster (not the bastion's ip address) 247 | # as this command will be remotely executed within the bastion 248 | # /redbull/ is the name of the index 249 | command = """curl -H 'Content-Type: application/x-ndjson' -XPOST https://10.0.3.12:9200/redbull/_bulk?pretty --data-binary @/home/opc/ords/opensearch_redbull_data.json -u {}:{} --insecure""".format( 250 | auth_data['cluster_private_user'], 251 | auth_data['cluster_private_password'] 252 | ) 253 | 254 | ssh_stdin, ssh_stdout, ssh_stderr = ssh_client.exec_command(command) 255 | print(ssh_stdout.read().decode()) 256 | print(ssh_stderr.read().decode()) 257 | ``` 258 | 259 | This function will force the bastion to execute a XPOST command to bulk insert all new laps into the db. 260 | 261 | > **Note**: sensitive data shall be stored in your `auth.yaml` file. 262 | 263 | ## 5. Full automation with crontab 264 | 265 | If you want to automate the whole process, without even having to check, I recommend to put this Python script running locally in your machine in a periodic fashion. For that, one of my favorite tools is `crontab` (for Linux, although you can find several alternatives for other operating systems). 266 | 267 | With [this tool](https://crontab.guru/) you can generate the crontab that you need to run the Python script in natural language: 268 | 269 | ![Crontab example](./img/crontabguru_output.PNG) 270 | 271 | 1. First, we execute the following command: 272 | 273 | ```bash 274 | crontab -e # edits the current crontab rules 275 | ``` 276 | 277 | 2. Then, we can paste the rule, depending on the frequency of executions. We can run it every 30 minutes, every day at 00:00, every week... This depends on how much data is coming into your database, but you're free to choose the cadence: 278 | 279 | ```bash 280 | 0 0 * * * /usr/bin/python /home/$USER/github/oci-rag-vectordb/scripts/consume_ords.py 281 | ``` 282 | 283 | The above code will run this script everyday at 00:00, checking for new laps and inserting them. 284 | 285 | > **Note**: I recommend that, due to specific things going on under the hood with crontab during the execution of cronjobs, your Python base environment shall have dependencies installed (present in `requirements.txt`). Also, I recommend you also specify the python binary with its full path (you can find it by running `which python` in your terminal.) 286 | 287 | Finally, remember to specify the Python script location in absolute terms (not relative ones) as the crontab daemon can lose the current working directory (amongst other things). 288 | 289 | We're done with our automation! Congratulations for getting to this point, you've successfully finished a data engineering problem: from ingestion with **ORDS**, to integration with OpenSearch with some Python magic. 290 | 291 | ## 6. Talk to your new agent 292 | 293 | Our agent is now ready! If you haven't previously set up a GenAI Agent, refer to [this README](README.md) to find out how to get started step by step. 294 | 295 | We can access our agent and start talking to it - and query about our data: 296 | 297 | ![Launch agent](./img/launch_agent.PNG) 298 | 299 | We observe that, when we make requests about our racers, we receive accurate responses from the Agent, meaning that we've successfully integrated our data source with the Generative AI Agent! 300 | 301 | Question: "Can you pull all information you have on racer id 6220?" 302 | 303 | > **Note**: you can also refer or query your data with whichever parameters you want. In this case, we've chosen the racer id as it's a unique identifier (sometimes, there are two racers with the same names, which cause confusions if you query them by just their name). 304 | 305 | ![End Result](./img/answer_1.PNG) 306 | 307 | Question: "Can you pull all information you have on racer id 10574 and racer id 10304?" 308 | 309 | ![End Result](./img/answer_2.PNG) 310 | 311 | Question: "How about the worst lap recorded for racer id 10304?" 312 | 313 | ![End Result](./img/answer_3_1.PNG) 314 | 315 | ![End Result](./img/answer_3_2.PNG) 316 | 317 | As you can see on the below image, the LLM also knows how to communicate with other laps from *Mark*, and is able to discern the good laps vs. the bad ones 318 | 319 | Question: "What can he do to improve his sector 3 time? It was on the Texas F1 Grand Prix. I need recommendations to improve his sector time." 320 | 321 | ![End Result](./img/answer_4.PNG) 322 | 323 | > **Note**: here you can see semantic search in action: not only does the LLM find the right vectors to pull from OpenSearch, but also knows how to properly tackle issues in a specific sector for the track. It understands this sector has a lot of curves and gives personalized suggestions on how to improve it. (You may ask: how does the model know this?? The base model's knowledge is actually contributing to this analysis a lot, as we haven't given it any data about the characteristics of specific track sectors in F1.) 324 | 325 | ## Demo 326 | 327 | [Watch the demo here](https://www.youtube.com/watch?v=JqF6Bc9am4s&list=PLPIzp-E1msraY9To-BB-vVzPsK08s4tQD&index=15) 328 | 329 | ## Tutorial 330 | 331 | [This is a tutorial](https://docs.oracle.com/en/learn/oci-opensearch/index.html#introduction) about OCI OpenSearch if you're interested in learning more about vectorization, indexation, connecting to the cluster, ingesting data, searching for data and visualizing it. 332 | 333 | ## Physical Architecture 334 | 335 | ![arch](./img/arch.PNG) 336 | 337 | ## Contributing 338 | 339 | This project is open source. Please submit your contributions by forking this repository and submitting a pull request! Oracle appreciates any contributions that are made by the open source community. 340 | 341 | ## License 342 | 343 | Copyright (c) 2022 Oracle and/or its affiliates. 344 | 345 | Licensed under the Universal Permissive License (UPL), Version 1.0. 346 | 347 | See [LICENSE](LICENSE) for more details. 348 | 349 | ORACLE AND ITS AFFILIATES DO NOT PROVIDE ANY WARRANTY WHATSOEVER, EXPRESS OR IMPLIED, FOR ANY SOFTWARE, MATERIAL OR CONTENT OF ANY KIND CONTAINED OR PRODUCED WITHIN THIS REPOSITORY, AND IN PARTICULAR SPECIFICALLY DISCLAIM ANY AND ALL IMPLIED WARRANTIES OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. FURTHERMORE, ORACLE AND ITS AFFILIATES DO NOT REPRESENT THAT ANY CUSTOMARY SECURITY REVIEW HAS BEEN PERFORMED WITH RESPECT TO ANY SOFTWARE, MATERIAL OR CONTENT CONTAINED OR PRODUCED WITHIN THIS REPOSITORY. IN ADDITION, AND WITHOUT LIMITING THE FOREGOING, THIRD PARTIES MAY HAVE POSTED SOFTWARE, MATERIAL OR CONTENT TO THIS REPOSITORY WITHOUT ANY REVIEW. USE AT YOUR OWN RISK. 350 | -------------------------------------------------------------------------------- /README_rag.md: -------------------------------------------------------------------------------- 1 | # OCI Retrieval-Augmented Generations (RAG) with Generative AI Agents Service 2 | 3 | [![License: UPL](https://img.shields.io/badge/license-UPL-green)](https://img.shields.io/badge/license-UPL-green) [![Quality gate](https://sonarcloud.io/api/project_badges/quality_gate?project=oracle-devrel_oci-rag-vectordb)](https://sonarcloud.io/dashboard?id=oracle-devrel_oci-rag-vectordb) 4 | 5 | ## Introduction 6 | 7 | RAG is one of the most coveted use cases nowadays for AI. The great thing about RAG is that it allows you to augment the knowledge of an LLM without having to retrain it. How, you may ask? Well, it's a way for the LLM to extract information (like a database) and present this information to the user very quickly. 8 | 9 | This allows LLMs to acquire up-to-date knowledge, for example, the results of this year's SuperBowl, regardless of when the LLM you're running inference against has been trained. Therefore, you can make your LLM more intelligent and provide it with updated data with little to no effort. 10 | 11 | Luckily, OCI GenAI Agents Service allows us to do just that: we will be able to upload our documents, process this data, and provide users with a way to **consume** this data through a chatbot! 12 | 13 | ![chat with model - patient related 2](./img/chat_patient_2.png) 14 | 15 | Here's a list of the most prominent features of the service: 16 | 17 | - Supports several data on-boarding methods and interaction channels (chat interface or API) 18 | - Creates contextually relevant answers by searching your knowledge base 19 | - Provides source attribution for every answer 20 | - Offers hybrid search capabilities (lexical and semantic) for more correct answers 21 | - Includes content moderation options for input and output to ensure a safe and respectful chat experience 22 | - Supports multi-turn conversations, where users can ask follow-up questions and receive answers that consider the context of previous questions and answers 23 | - Can interpret data from two-axis charts and reference tables in a PDF, without needing explicit descriptions of the visual elements 24 | - All the hyperlinks present in the PDF documents are extracted and displayed as hyperlinks in the chat response. 25 | 26 | For the infrastructure, we have the following OCI Services present: 27 | 28 | - **OCI Object Storage** files where you can have up to 1,000 text and PDF files of 100 MB each. And you can request an increase through a limit request. (Fully managed) 29 | - **Oracle Autonomous Database 23AI** for vector search, as an alternative to using OCI Object Storage (Partially managed, see [here](https://docs.public.oneportal.content.oci.oraclecloud.com/en-us/iaas/Content/generative-ai-agents/oracle-db-guidelines.htm) for more information) 30 | - **OCI Search with OpenSearch** for Index Similarity Search (Index Database) and storing indices with data (Requires you to chunk, index and vector-embed the data, a bit more complex) 31 | - **OCI Compute** for connecting to the OpenSearch cluster securely (through OCI private subnet routing) 32 | - **OCI Generative AI Agents** for communicating and interacting with the data in our cluster 33 | 34 | In this specific solution, we will use Object Storage as our storage mechanism, as it's the simplest mechanism of the three available (you don't need to do any additional data processing to *consume* the data, unlike with OpenSearch and Autonomous.) although you can always swap into Autonomous 23AI or OCI Search with OpenSearch, provided you setup these data sources correctly. (More info on the docs section) 35 | 36 | OCI Generative AI Agents is a fully managed service that combines the power of large language models (LLMs) with an intelligent retrieval system to create contextually relevant answers by searching your knowledge base, making your AI applications smart and efficient. 37 | 38 | To use this service, we'll follow these four steps: 39 | 40 | 1. Create a knowledge base 41 | 2. Add your data 42 | 3. Create an agent 43 | 4. Set up endpoints for user interaction 44 | 5. Start chatting 45 | 46 | OCI Generative AI Agents takes care of the rest, providing relevant answers to you and your customers' questions, and tracks the conversation context to enable more informed and helpful responses. 47 | 48 | ### Use Cases 49 | 50 | Use the OCI Generative AI Agents service for the following types of use cases: 51 | 52 | - Customer Support: In the customer service industry, RAG agents can retrieve information from a company’s knowledge base to provide correct and contextually relevant answers to customer inquiries, reducing response times and improving customer satisfaction. 53 | - Legal Research: Legal professionals can use RAG agents to quickly find precedents and relevant case law from vast legal databases, streamlining the research process and ensuring thorough consideration of relevant legal texts. 54 | - Healthcare and Medical Guidance: In healthcare, RAG agents can help doctors and medical staff by providing diagnostic support, retrieving medical literature, treatment protocols, and patient history to suggest potential diagnoses and treatments. 55 | - Financial Analysis: In finance, RAG agents can analyze large volumes of financial data, reports, and news to provide analysis and recommendations for traders and analysts, helping them make informed investment decisions. 56 | - Educational Tutoring: RAG agents can function as personal tutors, providing students with explanations, resources, and answers to questions by accessing educational content and tailoring explanations to the student’s current level of understanding. 57 | - Content Creation: In media and content creation, RAG agents can help writers and journalists by pulling information on specific topics, suggesting content ideas, and even drafting sections of articles based on the latest data and trends. 58 | - Technical Support and Troubleshooting: RAG agents can guide users through technical troubleshooting processes by accessing and synthesizing technical manuals and support forums to offer step-by-step help. 59 | - Supply Chain Management: In supply chain and logistics, RAG agents can provide insights by retrieving and synthesizing information on inventory levels, supplier data, and logistic metrics to optimize operations and predict potential disruptions. 60 | - Real Estate Market Analysis: RAG agents can help real estate professionals by aggregating and analyzing data from several sources, including market trends, property listings, and regulatory changes, to provide comprehensive market analyses. 61 | - Travel Planning and Help: In the travel industry, RAG agents can serve as interactive travel guides, pulling information on destinations, weather, local attractions, and regulations to provide personalized travel advice and itineraries. 62 | 63 | ### Available Regions in OCI with the Generative AI Agents Service 64 | 65 | Oracle hosts its OCI services in regions and availability domains. A region is a localized geographic area, and an availability domain is one or more data centers in that region. OCI Generative AI Agents is hosted in the following region: 66 | 67 | - Region name: US Midwest (Chicago) 68 | - Region identifier: `us-chicago-1` 69 | 70 | ## 0. Prerequisites and setup 71 | 72 | ### Prerequisites 73 | 74 | - Oracle Cloud Infrastructure (OCI) Account with available credits to spend 75 | - [Appropriate policies for the GenAI Agents Service](https://docs.oracle.com/en-us/iaas/Content/generative-ai-agents/iam-policies.htm#policies) set up properly within your tenancy 76 | - [Oracle Cloud Infrastructure Documentation - Generative AI Agents](https://docs.public.oneportal.content.oci.oraclecloud.com/en-us/iaas/Content/generative-ai-agents/home.htm) 77 | - [Python 3.10](https://www.python.org/downloads/release/python-3100/) 78 | - [Conda](https://conda.io/projects/conda/en/latest/user-guide/install/index.html) 79 | - [OCI SDK](https://docs.oracle.com/en-us/iaas/Content/API/Concepts/sdkconfig.htm) 80 | - You must be subscribed to the Chicago region in your tenancy. Generative AI Agents is only available in Chicago at this moment. 81 | - You must have an Identity Domain before you create an agent. [Follow the steps here](https://docs.oracle.com/en-us/iaas/Content/generative-ai-agents/getting-started.htm#prereq-domain) to create an Identity Domain within your OCI Account. 82 | 83 | ### Docs 84 | 85 | - [OCI Object Storage Guidelines in Generative AI Agents](https://docs.public.oneportal.content.oci.oraclecloud.com/en-us/iaas/Content/generative-ai-agents/data-requirements.htm#data-requirements) 86 | - [OCI Search with OpenSearch Guidelines for Generative AI Agents](https://docs.public.oneportal.content.oci.oraclecloud.com/en-us/iaas/Content/generative-ai-agents/opensearch-guidelines.htm#opensearch-guide) 87 | - [Oracle Database Guidelines for Generative AI Agents](https://docs.public.oneportal.content.oci.oraclecloud.com/en-us/iaas/Content/generative-ai-agents/oracle-db-guidelines.htm) 88 | - [Oracle Cloud Infrastructure (OCI) Generative AI - Getting Started](https://docs.oracle.com/en-us/iaas/Content/generative-ai-agents/getting-started.htm#get-started) 89 | - [Oracle Cloud Infrastructure (OCI) Generative AI - API](https://docs.oracle.com/en-us/iaas/api/#/en/generative-ai-agents/20240331/) 90 | - [OCI GenAI Agents - Concepts](https://docs.public.oneportal.content.oci.oraclecloud.com/en-us/iaas/Content/generative-ai-agents/concepts.htm#concepts) 91 | - [Search and Visualize Data using Oracle Cloud Infrastructure Search with OpenSearch](https://docs.oracle.com/en/learn/oci-opensearch/index.html) 92 | 93 | ### Setup 94 | 95 | 1. If you don't have access in your tenancy to the service, sign up for the [Beta program](https://apexadb.oracle.com/ords/f?p=108:501:508002131060566::::P501_SELF_NOMINATION:Self-Nomination) and download the Source Development Kit after you've been approved. 96 | 2. In the navigation bar of the Console, choose a region that hosts Generative AI Agents - for example, US Midwest (Chicago). If you don't know which region to choose, see [Regions with Generative AI Agents](https://docs.oracle.com/en-us/iaas/Content/generative-ai-agents/overview.htm#regions). 97 | 98 | Finally, if you want to use the GenAI Agents service with **Object Storage** buckets, create a bucket where you'll store your files: 99 | 100 | ![create bucket](./img/create_bucket.png) 101 | 102 | Some considerations for which files are allowed to be used as data in the bucket: 103 | 104 | - Supported File Types: Only **PDF** and **txt** files are supported. 105 | - File Size Limit: Each file must be no larger than **100 MB**. 106 | - PDF Contents: PDF files can include images, charts, and reference tables but these must not exceed **8 MB**. 107 | - Chart Preparation: No special preparation is needed for charts, as long as they're **two-dimensional** with **labeled axes**. The model can answer questions about the charts without explicit explanations. 108 | - Table Preparation: Use reference tables with several rows and columns. For example, the agent can read the table [on this website](https://docs.public.oneportal.content.oci.oraclecloud.com/en-us/iaas/Content/generative-ai-agents/limits.htm#limits). 109 | - URLs: All the hyperlinks present in the PDF documents are extracted and displayed as hyperlinks in the chat response. 110 | 111 | ## 1. Create knowledge base & data source 112 | 113 | ![step 1](./img/step_1.png) 114 | 115 | On the Knowledge Bases list page, click *Create knowledge base*. 116 | Enter the following values: 117 | - **Name**: A name that starts with a letter or underscore, followed by letters, numbers, hyphens, or underscores. The length can be from 1 to 255 characters. 118 | - **Compartment**: The compartment that you want to store the knowledge base in 119 | - **Description**: An optional description 120 | 121 | Select one of the following options for the data store type. 122 | 123 | - Object Storage (recommended) 124 | - OCI OpenSearch: you must have documents chunked to files with less than 512 tokens each, ingested and indexed those documents in OpenSearch before you continue. See [OCI Search with OpenSearch Guidelines for Generative AI Agents](https://docs.public.oneportal.content.oci.oraclecloud.com/en-us/iaas/Content/generative-ai-agents/opensearch-guidelines.htm#opensearch-guide) for more information. 125 | - Oracle AI Vector Search: this option is to ask about data already present in Oracle Database 23ai. See [Oracle Database Guidelines for Generative AI Agents](https://docs.public.oneportal.content.oci.oraclecloud.com/en-us/iaas/Content/generative-ai-agents/oracle-db-guidelines.htm) for the required setup. 126 | 127 | ### (Recommended) (Option 1) Object Storage Knowledge Base 128 | 129 | If you selected Object Storage, perform the following actions: 130 | 131 | - Select **Enable hybrid search** to combine lexical and semantic search. Without hybrid search, you get lexical search only. 132 | - Select Specify data source and enter a name and optional description for the data source, if you haven't created one before. 133 | - Select the bucket that contains the data for the knowledge store. Change the compartment if the bucket is in another compartment. 134 | - After the contents of the bucket are listed, perform one of the following actions: 135 | - Select all in bucket 136 | - Select the files and folders to include. 137 | - Click Create. 138 | - (Optional) Select *Automatically start ingestion job* for above data sources. If you don't select this option, you must ingest the data later for your agent to use it. 139 | 140 | ![knowledge base on object storage](./img/knowledge_base.png) 141 | 142 | ![data source - new](./img/data_source_new.png) 143 | 144 | > **Note**: you can only have one data source per knowledge base. If you're going to reuse your knowledge base (uploading more documents to your bucket), you'll need to create an ingestion job manually within the knowledge base, to update the model's knowledge: 145 | 146 | ![ingestion job](./img/ingestion_job.png) 147 | 148 | Then, after creating an ingestion job: 149 | 150 | - Review the status logs to confirm that all updated files were successfully ingested. 151 | - If the ingestion job fails (for example, because of a file being too large), address the issue and restart the job. 152 | 153 | > **Note**: When you restart a previously run ingestion job, the pipeline detects files that were successfully ingested earlier and skip them; while only ingesting files that failed previously and have since been updated. 154 | 155 | ### (Option 2) OCI Search with OpenSearch Knowledge Base 156 | 157 | Enter the following information: 158 | 159 | - OpenSearch cluster name 160 | - OpenSearch index information: 161 | - **Index** Name: the name of the index to look for. 162 | - **Body** key: the field that contains the vector. 163 | - Embed body key (Optional) 164 | - URL key (Optional) 165 | - Title key (Optional) 166 | - For **Secret details** select one of the following options: 167 | - *Basic* auth secret: For this option, select the Vault secret for OCI Search with OpenSearch. 168 | - *IDCS* secret: For this option enter the following information for the IDCS confidential application that you want to use for the agent: 169 | - **Identity domain** application name - Change the compartment if the identity domain is in another compartment. 170 | - **Client ID** for the OpenSearch cluster's IDCS client application. 171 | - **Client secret** vault that contains the client secret - Change the compartment if the secret is in another compartment. 172 | - **Scope URL** that's the API endpoint for the identity domain's resource server application and includes the agent scope. For example, for genaiagent scope, the URL is `https://*.agent.aiservice.us-chicago-1.oci.oraclecloud.com/genaiagent`. 173 | 174 | Take a look at [this docs page](https://docs.public.oneportal.content.oci.oraclecloud.com/en-us/iaas/Content/search-opensearch/Tasks/get-opensearch-cluster.htm) to learn about OpenSearch clusters and be able to get the cluster's details. 175 | 176 | ![knowledge base with opensearch](./img/knowledge_base_opensearch.png) 177 | 178 | ### (Option 3) Autonomous Database 23AI Knowledge Base 179 | 180 | If you selected **Oracle AI Vector Search**, you'll need to have a 23AI Autonomous Database instance created. If you haven't create one now: 181 | 182 | ![db creation - part 1](./img/database_creation_1.png) 183 | 184 | ![db creation - part 2](./img/database_creation_2.png) 185 | 186 | ![db creation - end](./img/database_creation_3.png) 187 | 188 | Then, create a **connection** to this database. You can see your connections under the [`Database Tools`](https://cloud.oracle.com/dbtools/connections) menu: 189 | 190 | ![connection creation](./img/create_connection.png) 191 | 192 | ![connection creation - end](./img/create_connection_end.png) 193 | 194 | Now that we have a connection created, select the Database tool connection and then click **Test connection** to confirm a successful connection to the database. If successful, the database name and version is displayed. Then, enter the Vector search function for the database tool connection. 195 | 196 | > **Note**: see the [Oracle Database Guidelines for Generative AI Agents](https://docs.public.oneportal.content.oci.oraclecloud.com/en-us/iaas/Content/generative-ai-agents/oracle-db-guidelines.htm) to help you enter the values for this step. 197 | 198 | ## 2. Create agent 199 | 200 | Now, we need to create the agent, which will associate with one of our knowlegde bases: 201 | 202 | ![new agent](./img/new_agent.png) 203 | 204 | Select the *Automatically create an endpoint for this agent* option to avoid later having to manually setup the endpoint. 205 | 206 | > **Note**. You can customize the welcome message when interacting with the user through chat. 207 | 208 | ## 3. Start chatting 209 | 210 | Now that our agent is created, we can start talking to it! 211 | 212 | ## 4. Talk to your new agent 213 | 214 | We can access our agent and start talking to it - and query about our data: 215 | 216 | ![chat with model - patient related 1](./img/chat_patient_1.png) 217 | 218 | From our patient data: 219 | 220 | ![reference 1](./img/reference_1.png) 221 | 222 | Apart from patient data in the hospital, I can also ask questions about best practices, policies, and intricacies of legal documents. Anyone with doubts can come chat with the agent and leave with accurate and verifiable responses: 223 | 224 | ![chat with model - patient related 2](./img/chat_patient_2.png) 225 | 226 | From the original documents, we see the response is accurate: 227 | 228 | ![reference 2](./img/reference_2.png) 229 | 230 | We observe that, when we ask the model anything present in our documents or data in Object Storage, it's able to gather the necessary bits and pieces from one (or multiple) files and return a well-formed response, taking into consideration all our data. In the example above, I had uploaded a 75-page scientific paper called *"Language Models are Few-Shot Learners"*, and ask complex questions: 231 | 232 | ![chat with model](./img/chat_with_model.png) 233 | 234 | But this can be applied to any domain: if you have your own data, you'll receive accurate responses from the agent (as well as some references so you can check the veracity of the model's responses) meaning that we've successfully integrated our data source with the Generative AI Agent! 235 | 236 | ## Demo 237 | 238 | [Watch the demo here](https://www.youtube.com/watch?v=JqF6Bc9am4s&list=PLPIzp-E1msraY9To-BB-vVzPsK08s4tQD&index=15) 239 | 240 | ## Physical Architecture 241 | 242 | ![arch](./img/arch.PNG) 243 | 244 | ## Contributing 245 | 246 | This project is open source. Please submit your contributions by forking this repository and submitting a pull request! Oracle appreciates any contributions that are made by the open source community. 247 | 248 | ## License 249 | 250 | Copyright (c) 2022 Oracle and/or its affiliates. 251 | 252 | Licensed under the Universal Permissive License (UPL), Version 1.0. 253 | 254 | See [LICENSE](LICENSE) for more details. 255 | 256 | ORACLE AND ITS AFFILIATES DO NOT PROVIDE ANY WARRANTY WHATSOEVER, EXPRESS OR IMPLIED, FOR ANY SOFTWARE, MATERIAL OR CONTENT OF ANY KIND CONTAINED OR PRODUCED WITHIN THIS REPOSITORY, AND IN PARTICULAR SPECIFICALLY DISCLAIM ANY AND ALL IMPLIED WARRANTIES OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. FURTHERMORE, ORACLE AND ITS AFFILIATES DO NOT REPRESENT THAT ANY CUSTOMARY SECURITY REVIEW HAS BEEN PERFORMED WITH RESPECT TO ANY SOFTWARE, MATERIAL OR CONTENT CONTAINED OR PRODUCED WITHIN THIS REPOSITORY. IN ADDITION, AND WITHOUT LIMITING THE FOREGOING, THIRD PARTIES MAY HAVE POSTED SOFTWARE, MATERIAL OR CONTENT TO THIS REPOSITORY WITHOUT ANY REVIEW. USE AT YOUR OWN RISK. 257 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Reporting security vulnerabilities 2 | 3 | Oracle values the independent security research community and believes that 4 | responsible disclosure of security vulnerabilities helps us ensure the security 5 | and privacy of all our users. 6 | 7 | Please do NOT raise a GitHub Issue to report a security vulnerability. If you 8 | believe you have found a security vulnerability, please submit a report to 9 | [secalert_us@oracle.com][1] preferably with a proof of concept. Please review 10 | some additional information on [how to report security vulnerabilities to Oracle][2]. 11 | We encourage people who contact Oracle Security to use email encryption using 12 | [our encryption key][3]. 13 | 14 | We ask that you do not use other channels or contact the project maintainers 15 | directly. 16 | 17 | Non-vulnerability related security issues including ideas for new or improved 18 | security features are welcome on GitHub Issues. 19 | 20 | ## Security updates, alerts and bulletins 21 | 22 | Security updates will be released on a regular cadence. Many of our projects 23 | will typically release security fixes in conjunction with the 24 | Oracle Critical Patch Update program. Additional 25 | information, including past advisories, is available on our [security alerts][4] 26 | page. 27 | 28 | ## Security-related information 29 | 30 | We will provide security related information such as a threat model, considerations 31 | for secure use, or any known security issues in our documentation. Please note 32 | that labs and sample code are intended to demonstrate a concept and may not be 33 | sufficiently hardened for production use. 34 | 35 | [1]: mailto:secalert_us@oracle.com 36 | [2]: https://www.oracle.com/corporate/security-practices/assurance/vulnerability/reporting.html 37 | [3]: https://www.oracle.com/security-alerts/encryptionkey.html 38 | [4]: https://www.oracle.com/security-alerts/ 39 | -------------------------------------------------------------------------------- /data/commands_opensearch.txt: -------------------------------------------------------------------------------- 1 | curl -XPUT https://10.0.3.12:9200/health3 -u osmaster:Osmaster@123 --insecure 2 | curl -H 'Content-Type: application/x-ndjson' -XPOST https://10.0.3.12:9200/health3/_bulk?pretty --data-binary @opensearch_data.json -u osmaster:Osmaster@123 --insecure 3 | curl -XGET https://10.0.3.12:9200/health3/_count/?pretty -u osmaster:Osmaster@123 --insecure 4 | 5 | 6 | curl -XPUT "https://10.0.3.12:9200/_plugins/_security/api/securityconfig/config" -u osmaster:Osmaster@123 --insecure -H 'Content-Type: application/json' -d' 7 | { 8 | "dynamic": { 9 | "security_mode": "ENFORCING", 10 | "http": { 11 | "anonymous_auth_enabled": false, 12 | "xff": { 13 | "enabled": false 14 | } 15 | }, 16 | "authc": { 17 | "openid_auth_domain": { 18 | "http_enabled": true, 19 | "transport_enabled": true, 20 | "order": 0, 21 | "http_authenticator": { 22 | "challenge": false, 23 | "type": "openid", 24 | "config": { 25 | "subject_key": "sub", 26 | "roles_key": "scope", 27 | "openid_connect_url": "https://idcs-079085887d6d4920b0203114bf7bb9be.identity.oraclecloud.com/.well-known/openid-configuration" 28 | } 29 | }, 30 | "authentication_backend": { 31 | "type": "noop", 32 | "config": {} 33 | }, 34 | "description": "Authenticate using OpenId connect" 35 | }, 36 | "basic_internal_auth_domain": { 37 | "http_enabled": true, 38 | "transport_enabled": true, 39 | "order": 1, 40 | "http_authenticator": { 41 | "challenge": true, 42 | "type": "basic", 43 | "config": {} 44 | }, 45 | "authentication_backend": { 46 | "type": "intern", 47 | "config": {} 48 | }, 49 | "description": "Authenticate via HTTP Basic against internal users database" 50 | } 51 | }, 52 | "authz": null 53 | } 54 | }' 55 | 56 | 57 | 58 | # Step 5: Create Readonly Role 59 | curl -XPUT "https://10.0.3.12:9200/_plugins/_security/api/roles/genaiagent_readall" -u osmaster:Osmaster@123 --insecure -H 'Content-Type: application/json' -d'{ 60 | "description": "Role to be used by Generative AI Agent having read only permission to all Indexes", 61 | "cluster_permissions": [ 62 | "cluster_composite_ops_ro" 63 | ], 64 | "index_permissions": [{ 65 | "index_patterns": [ 66 | "*" 67 | ], 68 | "fls": [], 69 | "masked_fields": [], 70 | "allowed_actions": [ 71 | "read" 72 | ] 73 | }], 74 | "tenant_permissions": [] 75 | }' 76 | 77 | # Step 6: Add role mapping for genaiagent_readall 78 | curl -XPUT "https://10.0.3.12:9200/_plugins/_security/api/rolesmapping/genaiagent_readall" -u osmaster:Osmaster@123 --insecure -H 'Content-Type: application/json' -d'{ 79 | "backend_roles" : [ "genaiagent" ], 80 | "hosts" : [], 81 | "users" : [] 82 | }' -------------------------------------------------------------------------------- /data/fake_patient_data.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/data/fake_patient_data.pdf -------------------------------------------------------------------------------- /data/generated_data.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "Nicole Young", 4 | "age": 29, 5 | "gender": "female", 6 | "blood_type": "O-", 7 | "address": "316 Patricia Islands Suite 134\nSouth Bruce, DE 77656", 8 | "phone": "5422605298219", 9 | "last_visit": "2023-05-12", 10 | "passport": "M62429750", 11 | "appointments": [ 12 | { 13 | "doctor": "Dr. John Smith", 14 | "date": "2023-03-01", 15 | "time": "14:00", 16 | "reason": "Annual Checkup" 17 | }, 18 | { 19 | "doctor": "Dr. John Smith", 20 | "date": "2023-05-12", 21 | "time": "10:30", 22 | "reason": "Follow-up for knee surgery" 23 | } 24 | ], 25 | "medical_records": [ 26 | { 27 | "date": "2022-12-15", 28 | "doctor": "Dr. Jane Doe", 29 | "diagnosis": "Common cold", 30 | "prescription": "Rest, fluids, and over-the-counter medication" 31 | }, 32 | { 33 | "date": "2022-02-11", 34 | "doctor": "Dr. John Smith", 35 | "diagnosis": "Knee injury", 36 | "prescription": "Physical therapy and pain medication" 37 | } 38 | ] 39 | }, 40 | { 41 | "name": "Kimberly Chavez", 42 | "age": 30, 43 | "gender": "female", 44 | "blood_type": "O+", 45 | "address": "25145 Brittney Trace\nAndersonton, PR 78517", 46 | "phone": "6386870872186", 47 | "last_visit": "2023-05-12", 48 | "passport": "S70647457", 49 | "appointments": [ 50 | { 51 | "doctor": "Dr. John Smith", 52 | "date": "2023-03-01", 53 | "time": "14:00", 54 | "reason": "Annual Checkup" 55 | }, 56 | { 57 | "doctor": "Dr. John Smith", 58 | "date": "2023-05-12", 59 | "time": "10:30", 60 | "reason": "Follow-up for knee surgery" 61 | } 62 | ], 63 | "medical_records": [ 64 | { 65 | "date": "2022-12-15", 66 | "doctor": "Dr. Jane Doe", 67 | "diagnosis": "Common cold", 68 | "prescription": "Rest, fluids, and over-the-counter medication" 69 | }, 70 | { 71 | "date": "2022-02-11", 72 | "doctor": "Dr. John Smith", 73 | "diagnosis": "Knee injury", 74 | "prescription": "Physical therapy and pain medication" 75 | } 76 | ] 77 | }, 78 | { 79 | "name": "Sherry Miller", 80 | "age": 44, 81 | "gender": "female", 82 | "blood_type": "B+", 83 | "address": "47297 Craig Flats\nTimothybury, AZ 91578", 84 | "phone": "4953813371579", 85 | "last_visit": "2023-05-12", 86 | "passport": "866865308", 87 | "appointments": [ 88 | { 89 | "doctor": "Dr. John Smith", 90 | "date": "2023-03-01", 91 | "time": "14:00", 92 | "reason": "Annual Checkup" 93 | }, 94 | { 95 | "doctor": "Dr. John Smith", 96 | "date": "2023-05-12", 97 | "time": "10:30", 98 | "reason": "Follow-up for knee surgery" 99 | } 100 | ], 101 | "medical_records": [ 102 | { 103 | "date": "2022-12-15", 104 | "doctor": "Dr. Jane Doe", 105 | "diagnosis": "Common cold", 106 | "prescription": "Rest, fluids, and over-the-counter medication" 107 | }, 108 | { 109 | "date": "2022-02-11", 110 | "doctor": "Dr. John Smith", 111 | "diagnosis": "Knee injury", 112 | "prescription": "Physical therapy and pain medication" 113 | } 114 | ] 115 | }, 116 | { 117 | "name": "Cynthia Young", 118 | "age": 28, 119 | "gender": "female", 120 | "blood_type": "A+", 121 | "address": "034 Caroline Ford\nJohnsonbury, RI 33954", 122 | "phone": "3636233685591", 123 | "last_visit": "2023-05-12", 124 | "passport": "B61319919", 125 | "appointments": [ 126 | { 127 | "doctor": "Dr. John Smith", 128 | "date": "2023-03-01", 129 | "time": "14:00", 130 | "reason": "Annual Checkup" 131 | }, 132 | { 133 | "doctor": "Dr. John Smith", 134 | "date": "2023-05-12", 135 | "time": "10:30", 136 | "reason": "Follow-up for knee surgery" 137 | } 138 | ], 139 | "medical_records": [ 140 | { 141 | "date": "2022-12-15", 142 | "doctor": "Dr. Jane Doe", 143 | "diagnosis": "Common cold", 144 | "prescription": "Rest, fluids, and over-the-counter medication" 145 | }, 146 | { 147 | "date": "2022-02-11", 148 | "doctor": "Dr. John Smith", 149 | "diagnosis": "Knee injury", 150 | "prescription": "Physical therapy and pain medication" 151 | } 152 | ] 153 | }, 154 | { 155 | "name": "Benjamin Johnson", 156 | "age": 40, 157 | "gender": "male", 158 | "blood_type": "O-", 159 | "address": "79007 Ashley Street\nNew Nicoleview, MS 11285", 160 | "phone": "4997980123334", 161 | "last_visit": "2023-05-12", 162 | "passport": "G05019872", 163 | "appointments": [ 164 | { 165 | "doctor": "Dr. John Smith", 166 | "date": "2023-03-01", 167 | "time": "14:00", 168 | "reason": "Annual Checkup" 169 | }, 170 | { 171 | "doctor": "Dr. John Smith", 172 | "date": "2023-05-12", 173 | "time": "10:30", 174 | "reason": "Follow-up for knee surgery" 175 | } 176 | ], 177 | "medical_records": [ 178 | { 179 | "date": "2022-12-15", 180 | "doctor": "Dr. Jane Doe", 181 | "diagnosis": "Common cold", 182 | "prescription": "Rest, fluids, and over-the-counter medication" 183 | }, 184 | { 185 | "date": "2022-02-11", 186 | "doctor": "Dr. John Smith", 187 | "diagnosis": "Knee injury", 188 | "prescription": "Physical therapy and pain medication" 189 | } 190 | ] 191 | }, 192 | { 193 | "name": "Laura Walker", 194 | "age": 31, 195 | "gender": "female", 196 | "blood_type": "AB-", 197 | "address": "18012 Oconnell Alley Apt. 766\nLake Gabrielle, GA 02779", 198 | "phone": "9981235357799", 199 | "last_visit": "2023-05-12", 200 | "passport": "016719107", 201 | "appointments": [ 202 | { 203 | "doctor": "Dr. John Smith", 204 | "date": "2023-03-01", 205 | "time": "14:00", 206 | "reason": "Annual Checkup" 207 | }, 208 | { 209 | "doctor": "Dr. John Smith", 210 | "date": "2023-05-12", 211 | "time": "10:30", 212 | "reason": "Follow-up for knee surgery" 213 | } 214 | ], 215 | "medical_records": [ 216 | { 217 | "date": "2022-12-15", 218 | "doctor": "Dr. Jane Doe", 219 | "diagnosis": "Common cold", 220 | "prescription": "Rest, fluids, and over-the-counter medication" 221 | }, 222 | { 223 | "date": "2022-02-11", 224 | "doctor": "Dr. John Smith", 225 | "diagnosis": "Knee injury", 226 | "prescription": "Physical therapy and pain medication" 227 | } 228 | ] 229 | }, 230 | { 231 | "name": "James Acosta", 232 | "age": 20, 233 | "gender": "male", 234 | "blood_type": "O-", 235 | "address": "915 Bennett Springs Suite 198\nRiversmouth, IN 43746", 236 | "phone": "1678204507711", 237 | "last_visit": "2023-05-12", 238 | "passport": "J45171279", 239 | "appointments": [ 240 | { 241 | "doctor": "Dr. John Smith", 242 | "date": "2023-03-01", 243 | "time": "14:00", 244 | "reason": "Annual Checkup" 245 | }, 246 | { 247 | "doctor": "Dr. John Smith", 248 | "date": "2023-05-12", 249 | "time": "10:30", 250 | "reason": "Follow-up for knee surgery" 251 | } 252 | ], 253 | "medical_records": [ 254 | { 255 | "date": "2022-12-15", 256 | "doctor": "Dr. Jane Doe", 257 | "diagnosis": "Common cold", 258 | "prescription": "Rest, fluids, and over-the-counter medication" 259 | }, 260 | { 261 | "date": "2022-02-11", 262 | "doctor": "Dr. John Smith", 263 | "diagnosis": "Knee injury", 264 | "prescription": "Physical therapy and pain medication" 265 | } 266 | ] 267 | }, 268 | { 269 | "name": "Mr. Christian Miller", 270 | "age": 27, 271 | "gender": "male", 272 | "blood_type": "A+", 273 | "address": "5745 Johnson Landing Suite 539\nLake Mary, LA 15679", 274 | "phone": "3165861322739", 275 | "last_visit": "2023-05-12", 276 | "passport": "228186476", 277 | "appointments": [ 278 | { 279 | "doctor": "Dr. John Smith", 280 | "date": "2023-03-01", 281 | "time": "14:00", 282 | "reason": "Annual Checkup" 283 | }, 284 | { 285 | "doctor": "Dr. John Smith", 286 | "date": "2023-05-12", 287 | "time": "10:30", 288 | "reason": "Follow-up for knee surgery" 289 | } 290 | ], 291 | "medical_records": [ 292 | { 293 | "date": "2022-12-15", 294 | "doctor": "Dr. Jane Doe", 295 | "diagnosis": "Common cold", 296 | "prescription": "Rest, fluids, and over-the-counter medication" 297 | }, 298 | { 299 | "date": "2022-02-11", 300 | "doctor": "Dr. John Smith", 301 | "diagnosis": "Knee injury", 302 | "prescription": "Physical therapy and pain medication" 303 | } 304 | ] 305 | }, 306 | { 307 | "name": "Sierra Walton", 308 | "age": 39, 309 | "gender": "female", 310 | "blood_type": "B+", 311 | "address": "0952 Ramirez Mountains\nPort Teresa, FM 08101", 312 | "phone": "2465823175767", 313 | "last_visit": "2023-05-12", 314 | "passport": "I35945065", 315 | "appointments": [ 316 | { 317 | "doctor": "Dr. John Smith", 318 | "date": "2023-03-01", 319 | "time": "14:00", 320 | "reason": "Annual Checkup" 321 | }, 322 | { 323 | "doctor": "Dr. John Smith", 324 | "date": "2023-05-12", 325 | "time": "10:30", 326 | "reason": "Follow-up for knee surgery" 327 | } 328 | ], 329 | "medical_records": [ 330 | { 331 | "date": "2022-12-15", 332 | "doctor": "Dr. Jane Doe", 333 | "diagnosis": "Common cold", 334 | "prescription": "Rest, fluids, and over-the-counter medication" 335 | }, 336 | { 337 | "date": "2022-02-11", 338 | "doctor": "Dr. John Smith", 339 | "diagnosis": "Knee injury", 340 | "prescription": "Physical therapy and pain medication" 341 | } 342 | ] 343 | }, 344 | { 345 | "name": "Renee Ferguson", 346 | "age": 33, 347 | "gender": "female", 348 | "blood_type": "B+", 349 | "address": "9077 Fisher Well\nHopkinstown, WI 30843", 350 | "phone": "7801471064663", 351 | "last_visit": "2023-05-12", 352 | "passport": "697693588", 353 | "appointments": [ 354 | { 355 | "doctor": "Dr. John Smith", 356 | "date": "2023-03-01", 357 | "time": "14:00", 358 | "reason": "Annual Checkup" 359 | }, 360 | { 361 | "doctor": "Dr. John Smith", 362 | "date": "2023-05-12", 363 | "time": "10:30", 364 | "reason": "Follow-up for knee surgery" 365 | } 366 | ], 367 | "medical_records": [ 368 | { 369 | "date": "2022-12-15", 370 | "doctor": "Dr. Jane Doe", 371 | "diagnosis": "Common cold", 372 | "prescription": "Rest, fluids, and over-the-counter medication" 373 | }, 374 | { 375 | "date": "2022-02-11", 376 | "doctor": "Dr. John Smith", 377 | "diagnosis": "Knee injury", 378 | "prescription": "Physical therapy and pain medication" 379 | } 380 | ] 381 | }, 382 | { 383 | "name": "Andrea Lopez", 384 | "age": 18, 385 | "gender": "female", 386 | "blood_type": "A+", 387 | "address": "223 Wall Mountains Apt. 086\nJohntown, LA 55852", 388 | "phone": "0064582513129", 389 | "last_visit": "2023-05-12", 390 | "passport": "511826258", 391 | "appointments": [ 392 | { 393 | "doctor": "Dr. John Smith", 394 | "date": "2023-03-01", 395 | "time": "14:00", 396 | "reason": "Annual Checkup" 397 | }, 398 | { 399 | "doctor": "Dr. John Smith", 400 | "date": "2023-05-12", 401 | "time": "10:30", 402 | "reason": "Follow-up for knee surgery" 403 | } 404 | ], 405 | "medical_records": [ 406 | { 407 | "date": "2022-12-15", 408 | "doctor": "Dr. Jane Doe", 409 | "diagnosis": "Common cold", 410 | "prescription": "Rest, fluids, and over-the-counter medication" 411 | }, 412 | { 413 | "date": "2022-02-11", 414 | "doctor": "Dr. John Smith", 415 | "diagnosis": "Knee injury", 416 | "prescription": "Physical therapy and pain medication" 417 | } 418 | ] 419 | }, 420 | { 421 | "name": "Keith Lee", 422 | "age": 44, 423 | "gender": "male", 424 | "blood_type": "O-", 425 | "address": "741 Mercado Tunnel\nLake Robert, GA 25542", 426 | "phone": "9509789782691", 427 | "last_visit": "2023-05-12", 428 | "passport": "255144676", 429 | "appointments": [ 430 | { 431 | "doctor": "Dr. John Smith", 432 | "date": "2023-03-01", 433 | "time": "14:00", 434 | "reason": "Annual Checkup" 435 | }, 436 | { 437 | "doctor": "Dr. John Smith", 438 | "date": "2023-05-12", 439 | "time": "10:30", 440 | "reason": "Follow-up for knee surgery" 441 | } 442 | ], 443 | "medical_records": [ 444 | { 445 | "date": "2022-12-15", 446 | "doctor": "Dr. Jane Doe", 447 | "diagnosis": "Common cold", 448 | "prescription": "Rest, fluids, and over-the-counter medication" 449 | }, 450 | { 451 | "date": "2022-02-11", 452 | "doctor": "Dr. John Smith", 453 | "diagnosis": "Knee injury", 454 | "prescription": "Physical therapy and pain medication" 455 | } 456 | ] 457 | }, 458 | { 459 | "name": "James Hernandez", 460 | "age": 49, 461 | "gender": "male", 462 | "blood_type": "A-", 463 | "address": "97006 Shelby Expressway\nBoydport, MT 83083", 464 | "phone": "1912486306561", 465 | "last_visit": "2023-05-12", 466 | "passport": "E99756939", 467 | "appointments": [ 468 | { 469 | "doctor": "Dr. John Smith", 470 | "date": "2023-03-01", 471 | "time": "14:00", 472 | "reason": "Annual Checkup" 473 | }, 474 | { 475 | "doctor": "Dr. John Smith", 476 | "date": "2023-05-12", 477 | "time": "10:30", 478 | "reason": "Follow-up for knee surgery" 479 | } 480 | ], 481 | "medical_records": [ 482 | { 483 | "date": "2022-12-15", 484 | "doctor": "Dr. Jane Doe", 485 | "diagnosis": "Common cold", 486 | "prescription": "Rest, fluids, and over-the-counter medication" 487 | }, 488 | { 489 | "date": "2022-02-11", 490 | "doctor": "Dr. John Smith", 491 | "diagnosis": "Knee injury", 492 | "prescription": "Physical therapy and pain medication" 493 | } 494 | ] 495 | }, 496 | { 497 | "name": "Zachary Patton", 498 | "age": 33, 499 | "gender": "male", 500 | "blood_type": "O-", 501 | "address": "Unit 2067 Box 5252\nDPO AE 35658", 502 | "phone": "8801557702284", 503 | "last_visit": "2023-05-12", 504 | "passport": "G85564016", 505 | "appointments": [ 506 | { 507 | "doctor": "Dr. John Smith", 508 | "date": "2023-03-01", 509 | "time": "14:00", 510 | "reason": "Annual Checkup" 511 | }, 512 | { 513 | "doctor": "Dr. John Smith", 514 | "date": "2023-05-12", 515 | "time": "10:30", 516 | "reason": "Follow-up for knee surgery" 517 | } 518 | ], 519 | "medical_records": [ 520 | { 521 | "date": "2022-12-15", 522 | "doctor": "Dr. Jane Doe", 523 | "diagnosis": "Common cold", 524 | "prescription": "Rest, fluids, and over-the-counter medication" 525 | }, 526 | { 527 | "date": "2022-02-11", 528 | "doctor": "Dr. John Smith", 529 | "diagnosis": "Knee injury", 530 | "prescription": "Physical therapy and pain medication" 531 | } 532 | ] 533 | }, 534 | { 535 | "name": "Whitney Lee", 536 | "age": 40, 537 | "gender": "female", 538 | "blood_type": "B+", 539 | "address": "9897 Fleming Point Suite 704\nLake Matthew, ME 89477", 540 | "phone": "2556398591419", 541 | "last_visit": "2023-05-12", 542 | "passport": "W74936454", 543 | "appointments": [ 544 | { 545 | "doctor": "Dr. John Smith", 546 | "date": "2023-03-01", 547 | "time": "14:00", 548 | "reason": "Annual Checkup" 549 | }, 550 | { 551 | "doctor": "Dr. John Smith", 552 | "date": "2023-05-12", 553 | "time": "10:30", 554 | "reason": "Follow-up for knee surgery" 555 | } 556 | ], 557 | "medical_records": [ 558 | { 559 | "date": "2022-12-15", 560 | "doctor": "Dr. Jane Doe", 561 | "diagnosis": "Common cold", 562 | "prescription": "Rest, fluids, and over-the-counter medication" 563 | }, 564 | { 565 | "date": "2022-02-11", 566 | "doctor": "Dr. John Smith", 567 | "diagnosis": "Knee injury", 568 | "prescription": "Physical therapy and pain medication" 569 | } 570 | ] 571 | }, 572 | { 573 | "name": "Helen Larson", 574 | "age": 49, 575 | "gender": "female", 576 | "blood_type": "O-", 577 | "address": "574 Day Pine Suite 144\nWheelertown, WI 15452", 578 | "phone": "7736963599381", 579 | "last_visit": "2023-05-12", 580 | "passport": "605651124", 581 | "appointments": [ 582 | { 583 | "doctor": "Dr. John Smith", 584 | "date": "2023-03-01", 585 | "time": "14:00", 586 | "reason": "Annual Checkup" 587 | }, 588 | { 589 | "doctor": "Dr. John Smith", 590 | "date": "2023-05-12", 591 | "time": "10:30", 592 | "reason": "Follow-up for knee surgery" 593 | } 594 | ], 595 | "medical_records": [ 596 | { 597 | "date": "2022-12-15", 598 | "doctor": "Dr. Jane Doe", 599 | "diagnosis": "Common cold", 600 | "prescription": "Rest, fluids, and over-the-counter medication" 601 | }, 602 | { 603 | "date": "2022-02-11", 604 | "doctor": "Dr. John Smith", 605 | "diagnosis": "Knee injury", 606 | "prescription": "Physical therapy and pain medication" 607 | } 608 | ] 609 | }, 610 | { 611 | "name": "Scott Oneill", 612 | "age": 22, 613 | "gender": "male", 614 | "blood_type": "B+", 615 | "address": "08256 Wendy Ridge Suite 198\nEast Joseph, NM 14062", 616 | "phone": "0581529754747", 617 | "last_visit": "2023-05-12", 618 | "passport": "X16805745", 619 | "appointments": [ 620 | { 621 | "doctor": "Dr. John Smith", 622 | "date": "2023-03-01", 623 | "time": "14:00", 624 | "reason": "Annual Checkup" 625 | }, 626 | { 627 | "doctor": "Dr. John Smith", 628 | "date": "2023-05-12", 629 | "time": "10:30", 630 | "reason": "Follow-up for knee surgery" 631 | } 632 | ], 633 | "medical_records": [ 634 | { 635 | "date": "2022-12-15", 636 | "doctor": "Dr. Jane Doe", 637 | "diagnosis": "Common cold", 638 | "prescription": "Rest, fluids, and over-the-counter medication" 639 | }, 640 | { 641 | "date": "2022-02-11", 642 | "doctor": "Dr. John Smith", 643 | "diagnosis": "Knee injury", 644 | "prescription": "Physical therapy and pain medication" 645 | } 646 | ] 647 | }, 648 | { 649 | "name": "Karen Taylor", 650 | "age": 34, 651 | "gender": "female", 652 | "blood_type": "A+", 653 | "address": "657 Allen Bridge Apt. 094\nPort Selena, LA 10679", 654 | "phone": "4832387375549", 655 | "last_visit": "2023-05-12", 656 | "passport": "G86952286", 657 | "appointments": [ 658 | { 659 | "doctor": "Dr. John Smith", 660 | "date": "2023-03-01", 661 | "time": "14:00", 662 | "reason": "Annual Checkup" 663 | }, 664 | { 665 | "doctor": "Dr. John Smith", 666 | "date": "2023-05-12", 667 | "time": "10:30", 668 | "reason": "Follow-up for knee surgery" 669 | } 670 | ], 671 | "medical_records": [ 672 | { 673 | "date": "2022-12-15", 674 | "doctor": "Dr. Jane Doe", 675 | "diagnosis": "Common cold", 676 | "prescription": "Rest, fluids, and over-the-counter medication" 677 | }, 678 | { 679 | "date": "2022-02-11", 680 | "doctor": "Dr. John Smith", 681 | "diagnosis": "Knee injury", 682 | "prescription": "Physical therapy and pain medication" 683 | } 684 | ] 685 | }, 686 | { 687 | "name": "Benjamin Moore", 688 | "age": 15, 689 | "gender": "male", 690 | "blood_type": "O+", 691 | "address": "79192 Payne Pine Suite 943\nNorth Hannah, CO 09030", 692 | "phone": "5955707256178", 693 | "last_visit": "2023-05-12", 694 | "passport": "D66174476", 695 | "appointments": [ 696 | { 697 | "doctor": "Dr. John Smith", 698 | "date": "2023-03-01", 699 | "time": "14:00", 700 | "reason": "Annual Checkup" 701 | }, 702 | { 703 | "doctor": "Dr. John Smith", 704 | "date": "2023-05-12", 705 | "time": "10:30", 706 | "reason": "Follow-up for knee surgery" 707 | } 708 | ], 709 | "medical_records": [ 710 | { 711 | "date": "2022-12-15", 712 | "doctor": "Dr. Jane Doe", 713 | "diagnosis": "Common cold", 714 | "prescription": "Rest, fluids, and over-the-counter medication" 715 | }, 716 | { 717 | "date": "2022-02-11", 718 | "doctor": "Dr. John Smith", 719 | "diagnosis": "Knee injury", 720 | "prescription": "Physical therapy and pain medication" 721 | } 722 | ] 723 | }, 724 | { 725 | "name": "Mr. John Price", 726 | "age": 33, 727 | "gender": "male", 728 | "blood_type": "A+", 729 | "address": "62620 Robert Plains\nLake Jose, AL 56212", 730 | "phone": "4932118969961", 731 | "last_visit": "2023-05-12", 732 | "passport": "458560808", 733 | "appointments": [ 734 | { 735 | "doctor": "Dr. John Smith", 736 | "date": "2023-03-01", 737 | "time": "14:00", 738 | "reason": "Annual Checkup" 739 | }, 740 | { 741 | "doctor": "Dr. John Smith", 742 | "date": "2023-05-12", 743 | "time": "10:30", 744 | "reason": "Follow-up for knee surgery" 745 | } 746 | ], 747 | "medical_records": [ 748 | { 749 | "date": "2022-12-15", 750 | "doctor": "Dr. Jane Doe", 751 | "diagnosis": "Common cold", 752 | "prescription": "Rest, fluids, and over-the-counter medication" 753 | }, 754 | { 755 | "date": "2022-02-11", 756 | "doctor": "Dr. John Smith", 757 | "diagnosis": "Knee injury", 758 | "prescription": "Physical therapy and pain medication" 759 | } 760 | ] 761 | }, 762 | { 763 | "name": "Mackenzie Graves", 764 | "age": 45, 765 | "gender": "female", 766 | "blood_type": "O+", 767 | "address": "369 Brown Corner\nLake Kyle, ND 46586", 768 | "phone": "2464255429075", 769 | "last_visit": "2023-05-12", 770 | "passport": "S00440596", 771 | "appointments": [ 772 | { 773 | "doctor": "Dr. John Smith", 774 | "date": "2023-03-01", 775 | "time": "14:00", 776 | "reason": "Annual Checkup" 777 | }, 778 | { 779 | "doctor": "Dr. John Smith", 780 | "date": "2023-05-12", 781 | "time": "10:30", 782 | "reason": "Follow-up for knee surgery" 783 | } 784 | ], 785 | "medical_records": [ 786 | { 787 | "date": "2022-12-15", 788 | "doctor": "Dr. Jane Doe", 789 | "diagnosis": "Common cold", 790 | "prescription": "Rest, fluids, and over-the-counter medication" 791 | }, 792 | { 793 | "date": "2022-02-11", 794 | "doctor": "Dr. John Smith", 795 | "diagnosis": "Knee injury", 796 | "prescription": "Physical therapy and pain medication" 797 | } 798 | ] 799 | }, 800 | { 801 | "name": "Michael Klein", 802 | "age": 27, 803 | "gender": "male", 804 | "blood_type": "O-", 805 | "address": "Unit 6786 Box 8015\nDPO AA 20107", 806 | "phone": "7518181998180", 807 | "last_visit": "2023-05-12", 808 | "passport": "832640153", 809 | "appointments": [ 810 | { 811 | "doctor": "Dr. John Smith", 812 | "date": "2023-03-01", 813 | "time": "14:00", 814 | "reason": "Annual Checkup" 815 | }, 816 | { 817 | "doctor": "Dr. John Smith", 818 | "date": "2023-05-12", 819 | "time": "10:30", 820 | "reason": "Follow-up for knee surgery" 821 | } 822 | ], 823 | "medical_records": [ 824 | { 825 | "date": "2022-12-15", 826 | "doctor": "Dr. Jane Doe", 827 | "diagnosis": "Common cold", 828 | "prescription": "Rest, fluids, and over-the-counter medication" 829 | }, 830 | { 831 | "date": "2022-02-11", 832 | "doctor": "Dr. John Smith", 833 | "diagnosis": "Knee injury", 834 | "prescription": "Physical therapy and pain medication" 835 | } 836 | ] 837 | }, 838 | { 839 | "name": "Ashley Turner", 840 | "age": 53, 841 | "gender": "female", 842 | "blood_type": "B-", 843 | "address": "72866 Ramirez Flats Suite 952\nCherylberg, SD 82468", 844 | "phone": "0219474498867", 845 | "last_visit": "2023-05-12", 846 | "passport": "380618882", 847 | "appointments": [ 848 | { 849 | "doctor": "Dr. John Smith", 850 | "date": "2023-03-01", 851 | "time": "14:00", 852 | "reason": "Annual Checkup" 853 | }, 854 | { 855 | "doctor": "Dr. John Smith", 856 | "date": "2023-05-12", 857 | "time": "10:30", 858 | "reason": "Follow-up for knee surgery" 859 | } 860 | ], 861 | "medical_records": [ 862 | { 863 | "date": "2022-12-15", 864 | "doctor": "Dr. Jane Doe", 865 | "diagnosis": "Common cold", 866 | "prescription": "Rest, fluids, and over-the-counter medication" 867 | }, 868 | { 869 | "date": "2022-02-11", 870 | "doctor": "Dr. John Smith", 871 | "diagnosis": "Knee injury", 872 | "prescription": "Physical therapy and pain medication" 873 | } 874 | ] 875 | }, 876 | { 877 | "name": "Gary Henderson", 878 | "age": 53, 879 | "gender": "male", 880 | "blood_type": "AB-", 881 | "address": "831 Hayes Way Suite 709\nKarenside, WY 22692", 882 | "phone": "7715122392680", 883 | "last_visit": "2023-05-12", 884 | "passport": "166248732", 885 | "appointments": [ 886 | { 887 | "doctor": "Dr. John Smith", 888 | "date": "2023-03-01", 889 | "time": "14:00", 890 | "reason": "Annual Checkup" 891 | }, 892 | { 893 | "doctor": "Dr. John Smith", 894 | "date": "2023-05-12", 895 | "time": "10:30", 896 | "reason": "Follow-up for knee surgery" 897 | } 898 | ], 899 | "medical_records": [ 900 | { 901 | "date": "2022-12-15", 902 | "doctor": "Dr. Jane Doe", 903 | "diagnosis": "Common cold", 904 | "prescription": "Rest, fluids, and over-the-counter medication" 905 | }, 906 | { 907 | "date": "2022-02-11", 908 | "doctor": "Dr. John Smith", 909 | "diagnosis": "Knee injury", 910 | "prescription": "Physical therapy and pain medication" 911 | } 912 | ] 913 | }, 914 | { 915 | "name": "Robert Norris", 916 | "age": 42, 917 | "gender": "male", 918 | "blood_type": "O+", 919 | "address": "401 Smith Harbor Suite 669\nDavidberg, WV 04197", 920 | "phone": "6980508384616", 921 | "last_visit": "2023-05-12", 922 | "passport": "O90297700", 923 | "appointments": [ 924 | { 925 | "doctor": "Dr. John Smith", 926 | "date": "2023-03-01", 927 | "time": "14:00", 928 | "reason": "Annual Checkup" 929 | }, 930 | { 931 | "doctor": "Dr. John Smith", 932 | "date": "2023-05-12", 933 | "time": "10:30", 934 | "reason": "Follow-up for knee surgery" 935 | } 936 | ], 937 | "medical_records": [ 938 | { 939 | "date": "2022-12-15", 940 | "doctor": "Dr. Jane Doe", 941 | "diagnosis": "Common cold", 942 | "prescription": "Rest, fluids, and over-the-counter medication" 943 | }, 944 | { 945 | "date": "2022-02-11", 946 | "doctor": "Dr. John Smith", 947 | "diagnosis": "Knee injury", 948 | "prescription": "Physical therapy and pain medication" 949 | } 950 | ] 951 | }, 952 | { 953 | "name": "Richard Dudley", 954 | "age": 30, 955 | "gender": "male", 956 | "blood_type": "O-", 957 | "address": "845 Wagner Dale Suite 423\nEast Tyler, MD 60678", 958 | "phone": "0506492552548", 959 | "last_visit": "2023-05-12", 960 | "passport": "406806850", 961 | "appointments": [ 962 | { 963 | "doctor": "Dr. John Smith", 964 | "date": "2023-03-01", 965 | "time": "14:00", 966 | "reason": "Annual Checkup" 967 | }, 968 | { 969 | "doctor": "Dr. John Smith", 970 | "date": "2023-05-12", 971 | "time": "10:30", 972 | "reason": "Follow-up for knee surgery" 973 | } 974 | ], 975 | "medical_records": [ 976 | { 977 | "date": "2022-12-15", 978 | "doctor": "Dr. Jane Doe", 979 | "diagnosis": "Common cold", 980 | "prescription": "Rest, fluids, and over-the-counter medication" 981 | }, 982 | { 983 | "date": "2022-02-11", 984 | "doctor": "Dr. John Smith", 985 | "diagnosis": "Knee injury", 986 | "prescription": "Physical therapy and pain medication" 987 | } 988 | ] 989 | }, 990 | { 991 | "name": "Jack Stevens", 992 | "age": 20, 993 | "gender": "male", 994 | "blood_type": "O-", 995 | "address": "31979 Russell Drive\nLloydborough, IL 85773", 996 | "phone": "7292690839345", 997 | "last_visit": "2023-05-12", 998 | "passport": "E27727813", 999 | "appointments": [ 1000 | { 1001 | "doctor": "Dr. John Smith", 1002 | "date": "2023-03-01", 1003 | "time": "14:00", 1004 | "reason": "Annual Checkup" 1005 | }, 1006 | { 1007 | "doctor": "Dr. John Smith", 1008 | "date": "2023-05-12", 1009 | "time": "10:30", 1010 | "reason": "Follow-up for knee surgery" 1011 | } 1012 | ], 1013 | "medical_records": [ 1014 | { 1015 | "date": "2022-12-15", 1016 | "doctor": "Dr. Jane Doe", 1017 | "diagnosis": "Common cold", 1018 | "prescription": "Rest, fluids, and over-the-counter medication" 1019 | }, 1020 | { 1021 | "date": "2022-02-11", 1022 | "doctor": "Dr. John Smith", 1023 | "diagnosis": "Knee injury", 1024 | "prescription": "Physical therapy and pain medication" 1025 | } 1026 | ] 1027 | }, 1028 | { 1029 | "name": "Dr. Marcus Bell", 1030 | "age": 50, 1031 | "gender": "male", 1032 | "blood_type": "B-", 1033 | "address": "51838 Martinez Landing\nSouth Stephen, MS 06574", 1034 | "phone": "3754165462885", 1035 | "last_visit": "2023-05-12", 1036 | "passport": "681077835", 1037 | "appointments": [ 1038 | { 1039 | "doctor": "Dr. John Smith", 1040 | "date": "2023-03-01", 1041 | "time": "14:00", 1042 | "reason": "Annual Checkup" 1043 | }, 1044 | { 1045 | "doctor": "Dr. John Smith", 1046 | "date": "2023-05-12", 1047 | "time": "10:30", 1048 | "reason": "Follow-up for knee surgery" 1049 | } 1050 | ], 1051 | "medical_records": [ 1052 | { 1053 | "date": "2022-12-15", 1054 | "doctor": "Dr. Jane Doe", 1055 | "diagnosis": "Common cold", 1056 | "prescription": "Rest, fluids, and over-the-counter medication" 1057 | }, 1058 | { 1059 | "date": "2022-02-11", 1060 | "doctor": "Dr. John Smith", 1061 | "diagnosis": "Knee injury", 1062 | "prescription": "Physical therapy and pain medication" 1063 | } 1064 | ] 1065 | }, 1066 | { 1067 | "name": "Matthew Stephenson", 1068 | "age": 19, 1069 | "gender": "male", 1070 | "blood_type": "A-", 1071 | "address": "9555 Wade Fork\nPort Annatown, VT 05498", 1072 | "phone": "0674524166218", 1073 | "last_visit": "2023-05-12", 1074 | "passport": "422576232", 1075 | "appointments": [ 1076 | { 1077 | "doctor": "Dr. John Smith", 1078 | "date": "2023-03-01", 1079 | "time": "14:00", 1080 | "reason": "Annual Checkup" 1081 | }, 1082 | { 1083 | "doctor": "Dr. John Smith", 1084 | "date": "2023-05-12", 1085 | "time": "10:30", 1086 | "reason": "Follow-up for knee surgery" 1087 | } 1088 | ], 1089 | "medical_records": [ 1090 | { 1091 | "date": "2022-12-15", 1092 | "doctor": "Dr. Jane Doe", 1093 | "diagnosis": "Common cold", 1094 | "prescription": "Rest, fluids, and over-the-counter medication" 1095 | }, 1096 | { 1097 | "date": "2022-02-11", 1098 | "doctor": "Dr. John Smith", 1099 | "diagnosis": "Knee injury", 1100 | "prescription": "Physical therapy and pain medication" 1101 | } 1102 | ] 1103 | }, 1104 | { 1105 | "name": "Nancy Lawrence", 1106 | "age": 55, 1107 | "gender": "female", 1108 | "blood_type": "AB+", 1109 | "address": "2521 King Stravenue Suite 507\nBrownberg, LA 59049", 1110 | "phone": "0908716795205", 1111 | "last_visit": "2023-05-12", 1112 | "passport": "W02954742", 1113 | "appointments": [ 1114 | { 1115 | "doctor": "Dr. John Smith", 1116 | "date": "2023-03-01", 1117 | "time": "14:00", 1118 | "reason": "Annual Checkup" 1119 | }, 1120 | { 1121 | "doctor": "Dr. John Smith", 1122 | "date": "2023-05-12", 1123 | "time": "10:30", 1124 | "reason": "Follow-up for knee surgery" 1125 | } 1126 | ], 1127 | "medical_records": [ 1128 | { 1129 | "date": "2022-12-15", 1130 | "doctor": "Dr. Jane Doe", 1131 | "diagnosis": "Common cold", 1132 | "prescription": "Rest, fluids, and over-the-counter medication" 1133 | }, 1134 | { 1135 | "date": "2022-02-11", 1136 | "doctor": "Dr. John Smith", 1137 | "diagnosis": "Knee injury", 1138 | "prescription": "Physical therapy and pain medication" 1139 | } 1140 | ] 1141 | }, 1142 | { 1143 | "name": "Kristie Brown", 1144 | "age": 33, 1145 | "gender": "female", 1146 | "blood_type": "B+", 1147 | "address": "60354 Hanson Parkways\nSouth Ryanbury, UT 16368", 1148 | "phone": "9122493474476", 1149 | "last_visit": "2023-05-12", 1150 | "passport": "P71079333", 1151 | "appointments": [ 1152 | { 1153 | "doctor": "Dr. John Smith", 1154 | "date": "2023-03-01", 1155 | "time": "14:00", 1156 | "reason": "Annual Checkup" 1157 | }, 1158 | { 1159 | "doctor": "Dr. John Smith", 1160 | "date": "2023-05-12", 1161 | "time": "10:30", 1162 | "reason": "Follow-up for knee surgery" 1163 | } 1164 | ], 1165 | "medical_records": [ 1166 | { 1167 | "date": "2022-12-15", 1168 | "doctor": "Dr. Jane Doe", 1169 | "diagnosis": "Common cold", 1170 | "prescription": "Rest, fluids, and over-the-counter medication" 1171 | }, 1172 | { 1173 | "date": "2022-02-11", 1174 | "doctor": "Dr. John Smith", 1175 | "diagnosis": "Knee injury", 1176 | "prescription": "Physical therapy and pain medication" 1177 | } 1178 | ] 1179 | }, 1180 | { 1181 | "name": "Robert Byrd", 1182 | "age": 26, 1183 | "gender": "male", 1184 | "blood_type": "AB-", 1185 | "address": "41738 Maurice Valleys Suite 165\nRodriguezchester, CT 45712", 1186 | "phone": "5712605831757", 1187 | "last_visit": "2023-05-12", 1188 | "passport": "458003134", 1189 | "appointments": [ 1190 | { 1191 | "doctor": "Dr. John Smith", 1192 | "date": "2023-03-01", 1193 | "time": "14:00", 1194 | "reason": "Annual Checkup" 1195 | }, 1196 | { 1197 | "doctor": "Dr. John Smith", 1198 | "date": "2023-05-12", 1199 | "time": "10:30", 1200 | "reason": "Follow-up for knee surgery" 1201 | } 1202 | ], 1203 | "medical_records": [ 1204 | { 1205 | "date": "2022-12-15", 1206 | "doctor": "Dr. Jane Doe", 1207 | "diagnosis": "Common cold", 1208 | "prescription": "Rest, fluids, and over-the-counter medication" 1209 | }, 1210 | { 1211 | "date": "2022-02-11", 1212 | "doctor": "Dr. John Smith", 1213 | "diagnosis": "Knee injury", 1214 | "prescription": "Physical therapy and pain medication" 1215 | } 1216 | ] 1217 | }, 1218 | { 1219 | "name": "Harry Choi", 1220 | "age": 52, 1221 | "gender": "male", 1222 | "blood_type": "A-", 1223 | "address": "671 Kayla Greens Apt. 521\nSloanstad, AZ 18388", 1224 | "phone": "6243684251695", 1225 | "last_visit": "2023-05-12", 1226 | "passport": "J76542225", 1227 | "appointments": [ 1228 | { 1229 | "doctor": "Dr. John Smith", 1230 | "date": "2023-03-01", 1231 | "time": "14:00", 1232 | "reason": "Annual Checkup" 1233 | }, 1234 | { 1235 | "doctor": "Dr. John Smith", 1236 | "date": "2023-05-12", 1237 | "time": "10:30", 1238 | "reason": "Follow-up for knee surgery" 1239 | } 1240 | ], 1241 | "medical_records": [ 1242 | { 1243 | "date": "2022-12-15", 1244 | "doctor": "Dr. Jane Doe", 1245 | "diagnosis": "Common cold", 1246 | "prescription": "Rest, fluids, and over-the-counter medication" 1247 | }, 1248 | { 1249 | "date": "2022-02-11", 1250 | "doctor": "Dr. John Smith", 1251 | "diagnosis": "Knee injury", 1252 | "prescription": "Physical therapy and pain medication" 1253 | } 1254 | ] 1255 | }, 1256 | { 1257 | "name": "April Terrell", 1258 | "age": 23, 1259 | "gender": "female", 1260 | "blood_type": "B+", 1261 | "address": "3532 Jeffrey Ridges Apt. 561\nChristianfort, CT 83520", 1262 | "phone": "7424242705538", 1263 | "last_visit": "2023-05-12", 1264 | "passport": "M18538937", 1265 | "appointments": [ 1266 | { 1267 | "doctor": "Dr. John Smith", 1268 | "date": "2023-03-01", 1269 | "time": "14:00", 1270 | "reason": "Annual Checkup" 1271 | }, 1272 | { 1273 | "doctor": "Dr. John Smith", 1274 | "date": "2023-05-12", 1275 | "time": "10:30", 1276 | "reason": "Follow-up for knee surgery" 1277 | } 1278 | ], 1279 | "medical_records": [ 1280 | { 1281 | "date": "2022-12-15", 1282 | "doctor": "Dr. Jane Doe", 1283 | "diagnosis": "Common cold", 1284 | "prescription": "Rest, fluids, and over-the-counter medication" 1285 | }, 1286 | { 1287 | "date": "2022-02-11", 1288 | "doctor": "Dr. John Smith", 1289 | "diagnosis": "Knee injury", 1290 | "prescription": "Physical therapy and pain medication" 1291 | } 1292 | ] 1293 | }, 1294 | { 1295 | "name": "Robert Williams", 1296 | "age": 51, 1297 | "gender": "male", 1298 | "blood_type": "O+", 1299 | "address": "0254 Brittany Loop Suite 772\nFostershire, PR 50875", 1300 | "phone": "4154125453845", 1301 | "last_visit": "2023-05-12", 1302 | "passport": "627152023", 1303 | "appointments": [ 1304 | { 1305 | "doctor": "Dr. John Smith", 1306 | "date": "2023-03-01", 1307 | "time": "14:00", 1308 | "reason": "Annual Checkup" 1309 | }, 1310 | { 1311 | "doctor": "Dr. John Smith", 1312 | "date": "2023-05-12", 1313 | "time": "10:30", 1314 | "reason": "Follow-up for knee surgery" 1315 | } 1316 | ], 1317 | "medical_records": [ 1318 | { 1319 | "date": "2022-12-15", 1320 | "doctor": "Dr. Jane Doe", 1321 | "diagnosis": "Common cold", 1322 | "prescription": "Rest, fluids, and over-the-counter medication" 1323 | }, 1324 | { 1325 | "date": "2022-02-11", 1326 | "doctor": "Dr. John Smith", 1327 | "diagnosis": "Knee injury", 1328 | "prescription": "Physical therapy and pain medication" 1329 | } 1330 | ] 1331 | }, 1332 | { 1333 | "name": "Tiffany Singleton", 1334 | "age": 46, 1335 | "gender": "female", 1336 | "blood_type": "A+", 1337 | "address": "0883 John Ferry Suite 053\nStevenstad, PA 09476", 1338 | "phone": "0603942189818", 1339 | "last_visit": "2023-05-12", 1340 | "passport": "D08949996", 1341 | "appointments": [ 1342 | { 1343 | "doctor": "Dr. John Smith", 1344 | "date": "2023-03-01", 1345 | "time": "14:00", 1346 | "reason": "Annual Checkup" 1347 | }, 1348 | { 1349 | "doctor": "Dr. John Smith", 1350 | "date": "2023-05-12", 1351 | "time": "10:30", 1352 | "reason": "Follow-up for knee surgery" 1353 | } 1354 | ], 1355 | "medical_records": [ 1356 | { 1357 | "date": "2022-12-15", 1358 | "doctor": "Dr. Jane Doe", 1359 | "diagnosis": "Common cold", 1360 | "prescription": "Rest, fluids, and over-the-counter medication" 1361 | }, 1362 | { 1363 | "date": "2022-02-11", 1364 | "doctor": "Dr. John Smith", 1365 | "diagnosis": "Knee injury", 1366 | "prescription": "Physical therapy and pain medication" 1367 | } 1368 | ] 1369 | }, 1370 | { 1371 | "name": "Billy Taylor", 1372 | "age": 23, 1373 | "gender": "male", 1374 | "blood_type": "AB-", 1375 | "address": "088 Ruiz Cape Suite 887\nSantosport, KS 76206", 1376 | "phone": "6157897160195", 1377 | "last_visit": "2023-05-12", 1378 | "passport": "414777443", 1379 | "appointments": [ 1380 | { 1381 | "doctor": "Dr. John Smith", 1382 | "date": "2023-03-01", 1383 | "time": "14:00", 1384 | "reason": "Annual Checkup" 1385 | }, 1386 | { 1387 | "doctor": "Dr. John Smith", 1388 | "date": "2023-05-12", 1389 | "time": "10:30", 1390 | "reason": "Follow-up for knee surgery" 1391 | } 1392 | ], 1393 | "medical_records": [ 1394 | { 1395 | "date": "2022-12-15", 1396 | "doctor": "Dr. Jane Doe", 1397 | "diagnosis": "Common cold", 1398 | "prescription": "Rest, fluids, and over-the-counter medication" 1399 | }, 1400 | { 1401 | "date": "2022-02-11", 1402 | "doctor": "Dr. John Smith", 1403 | "diagnosis": "Knee injury", 1404 | "prescription": "Physical therapy and pain medication" 1405 | } 1406 | ] 1407 | }, 1408 | { 1409 | "name": "Nicole Reynolds", 1410 | "age": 19, 1411 | "gender": "female", 1412 | "blood_type": "O-", 1413 | "address": "745 Green Rapid Suite 288\nMariatown, KY 22239", 1414 | "phone": "5422469959300", 1415 | "last_visit": "2023-05-12", 1416 | "passport": "146195335", 1417 | "appointments": [ 1418 | { 1419 | "doctor": "Dr. John Smith", 1420 | "date": "2023-03-01", 1421 | "time": "14:00", 1422 | "reason": "Annual Checkup" 1423 | }, 1424 | { 1425 | "doctor": "Dr. John Smith", 1426 | "date": "2023-05-12", 1427 | "time": "10:30", 1428 | "reason": "Follow-up for knee surgery" 1429 | } 1430 | ], 1431 | "medical_records": [ 1432 | { 1433 | "date": "2022-12-15", 1434 | "doctor": "Dr. Jane Doe", 1435 | "diagnosis": "Common cold", 1436 | "prescription": "Rest, fluids, and over-the-counter medication" 1437 | }, 1438 | { 1439 | "date": "2022-02-11", 1440 | "doctor": "Dr. John Smith", 1441 | "diagnosis": "Knee injury", 1442 | "prescription": "Physical therapy and pain medication" 1443 | } 1444 | ] 1445 | }, 1446 | { 1447 | "name": "Daniel Hayes", 1448 | "age": 43, 1449 | "gender": "male", 1450 | "blood_type": "O-", 1451 | "address": "69887 Lindsey Lights Suite 353\nChristophertown, VT 86915", 1452 | "phone": "2881464985252", 1453 | "last_visit": "2023-05-12", 1454 | "passport": "794700462", 1455 | "appointments": [ 1456 | { 1457 | "doctor": "Dr. John Smith", 1458 | "date": "2023-03-01", 1459 | "time": "14:00", 1460 | "reason": "Annual Checkup" 1461 | }, 1462 | { 1463 | "doctor": "Dr. John Smith", 1464 | "date": "2023-05-12", 1465 | "time": "10:30", 1466 | "reason": "Follow-up for knee surgery" 1467 | } 1468 | ], 1469 | "medical_records": [ 1470 | { 1471 | "date": "2022-12-15", 1472 | "doctor": "Dr. Jane Doe", 1473 | "diagnosis": "Common cold", 1474 | "prescription": "Rest, fluids, and over-the-counter medication" 1475 | }, 1476 | { 1477 | "date": "2022-02-11", 1478 | "doctor": "Dr. John Smith", 1479 | "diagnosis": "Knee injury", 1480 | "prescription": "Physical therapy and pain medication" 1481 | } 1482 | ] 1483 | }, 1484 | { 1485 | "name": "Ms. Connie Patton", 1486 | "age": 40, 1487 | "gender": "female", 1488 | "blood_type": "A-", 1489 | "address": "27441 Ruiz Route\nMichaelland, NM 25493", 1490 | "phone": "6974553754011", 1491 | "last_visit": "2023-05-12", 1492 | "passport": "R81658740", 1493 | "appointments": [ 1494 | { 1495 | "doctor": "Dr. John Smith", 1496 | "date": "2023-03-01", 1497 | "time": "14:00", 1498 | "reason": "Annual Checkup" 1499 | }, 1500 | { 1501 | "doctor": "Dr. John Smith", 1502 | "date": "2023-05-12", 1503 | "time": "10:30", 1504 | "reason": "Follow-up for knee surgery" 1505 | } 1506 | ], 1507 | "medical_records": [ 1508 | { 1509 | "date": "2022-12-15", 1510 | "doctor": "Dr. Jane Doe", 1511 | "diagnosis": "Common cold", 1512 | "prescription": "Rest, fluids, and over-the-counter medication" 1513 | }, 1514 | { 1515 | "date": "2022-02-11", 1516 | "doctor": "Dr. John Smith", 1517 | "diagnosis": "Knee injury", 1518 | "prescription": "Physical therapy and pain medication" 1519 | } 1520 | ] 1521 | }, 1522 | { 1523 | "name": "Kimberly Mitchell", 1524 | "age": 51, 1525 | "gender": "female", 1526 | "blood_type": "A-", 1527 | "address": "729 Alec Circle\nLake Meghan, IA 75286", 1528 | "phone": "3711589860665", 1529 | "last_visit": "2023-05-12", 1530 | "passport": "O77437670", 1531 | "appointments": [ 1532 | { 1533 | "doctor": "Dr. John Smith", 1534 | "date": "2023-03-01", 1535 | "time": "14:00", 1536 | "reason": "Annual Checkup" 1537 | }, 1538 | { 1539 | "doctor": "Dr. John Smith", 1540 | "date": "2023-05-12", 1541 | "time": "10:30", 1542 | "reason": "Follow-up for knee surgery" 1543 | } 1544 | ], 1545 | "medical_records": [ 1546 | { 1547 | "date": "2022-12-15", 1548 | "doctor": "Dr. Jane Doe", 1549 | "diagnosis": "Common cold", 1550 | "prescription": "Rest, fluids, and over-the-counter medication" 1551 | }, 1552 | { 1553 | "date": "2022-02-11", 1554 | "doctor": "Dr. John Smith", 1555 | "diagnosis": "Knee injury", 1556 | "prescription": "Physical therapy and pain medication" 1557 | } 1558 | ] 1559 | }, 1560 | { 1561 | "name": "Luis Ramirez", 1562 | "age": 47, 1563 | "gender": "male", 1564 | "blood_type": "B-", 1565 | "address": "2005 Linda Roads\nNorth Robertberg, SD 69454", 1566 | "phone": "3692352480947", 1567 | "last_visit": "2023-05-12", 1568 | "passport": "F48331619", 1569 | "appointments": [ 1570 | { 1571 | "doctor": "Dr. John Smith", 1572 | "date": "2023-03-01", 1573 | "time": "14:00", 1574 | "reason": "Annual Checkup" 1575 | }, 1576 | { 1577 | "doctor": "Dr. John Smith", 1578 | "date": "2023-05-12", 1579 | "time": "10:30", 1580 | "reason": "Follow-up for knee surgery" 1581 | } 1582 | ], 1583 | "medical_records": [ 1584 | { 1585 | "date": "2022-12-15", 1586 | "doctor": "Dr. Jane Doe", 1587 | "diagnosis": "Common cold", 1588 | "prescription": "Rest, fluids, and over-the-counter medication" 1589 | }, 1590 | { 1591 | "date": "2022-02-11", 1592 | "doctor": "Dr. John Smith", 1593 | "diagnosis": "Knee injury", 1594 | "prescription": "Physical therapy and pain medication" 1595 | } 1596 | ] 1597 | }, 1598 | { 1599 | "name": "Michelle Fuller", 1600 | "age": 44, 1601 | "gender": "female", 1602 | "blood_type": "O+", 1603 | "address": "510 Vickie Street\nSouth Antonio, CT 61535", 1604 | "phone": "9434336775796", 1605 | "last_visit": "2023-05-12", 1606 | "passport": "339550164", 1607 | "appointments": [ 1608 | { 1609 | "doctor": "Dr. John Smith", 1610 | "date": "2023-03-01", 1611 | "time": "14:00", 1612 | "reason": "Annual Checkup" 1613 | }, 1614 | { 1615 | "doctor": "Dr. John Smith", 1616 | "date": "2023-05-12", 1617 | "time": "10:30", 1618 | "reason": "Follow-up for knee surgery" 1619 | } 1620 | ], 1621 | "medical_records": [ 1622 | { 1623 | "date": "2022-12-15", 1624 | "doctor": "Dr. Jane Doe", 1625 | "diagnosis": "Common cold", 1626 | "prescription": "Rest, fluids, and over-the-counter medication" 1627 | }, 1628 | { 1629 | "date": "2022-02-11", 1630 | "doctor": "Dr. John Smith", 1631 | "diagnosis": "Knee injury", 1632 | "prescription": "Physical therapy and pain medication" 1633 | } 1634 | ] 1635 | }, 1636 | { 1637 | "name": "Mary Little", 1638 | "age": 48, 1639 | "gender": "female", 1640 | "blood_type": "AB-", 1641 | "address": "750 Conley Rest Apt. 268\nNew Kayla, FM 94324", 1642 | "phone": "1687230459557", 1643 | "last_visit": "2023-05-12", 1644 | "passport": "692303974", 1645 | "appointments": [ 1646 | { 1647 | "doctor": "Dr. John Smith", 1648 | "date": "2023-03-01", 1649 | "time": "14:00", 1650 | "reason": "Annual Checkup" 1651 | }, 1652 | { 1653 | "doctor": "Dr. John Smith", 1654 | "date": "2023-05-12", 1655 | "time": "10:30", 1656 | "reason": "Follow-up for knee surgery" 1657 | } 1658 | ], 1659 | "medical_records": [ 1660 | { 1661 | "date": "2022-12-15", 1662 | "doctor": "Dr. Jane Doe", 1663 | "diagnosis": "Common cold", 1664 | "prescription": "Rest, fluids, and over-the-counter medication" 1665 | }, 1666 | { 1667 | "date": "2022-02-11", 1668 | "doctor": "Dr. John Smith", 1669 | "diagnosis": "Knee injury", 1670 | "prescription": "Physical therapy and pain medication" 1671 | } 1672 | ] 1673 | }, 1674 | { 1675 | "name": "Emily Jones DDS", 1676 | "age": 44, 1677 | "gender": "female", 1678 | "blood_type": "A+", 1679 | "address": "5671 Rollins Trail Suite 070\nStevenhaven, OH 13360", 1680 | "phone": "4706719585054", 1681 | "last_visit": "2023-05-12", 1682 | "passport": "G36300363", 1683 | "appointments": [ 1684 | { 1685 | "doctor": "Dr. John Smith", 1686 | "date": "2023-03-01", 1687 | "time": "14:00", 1688 | "reason": "Annual Checkup" 1689 | }, 1690 | { 1691 | "doctor": "Dr. John Smith", 1692 | "date": "2023-05-12", 1693 | "time": "10:30", 1694 | "reason": "Follow-up for knee surgery" 1695 | } 1696 | ], 1697 | "medical_records": [ 1698 | { 1699 | "date": "2022-12-15", 1700 | "doctor": "Dr. Jane Doe", 1701 | "diagnosis": "Common cold", 1702 | "prescription": "Rest, fluids, and over-the-counter medication" 1703 | }, 1704 | { 1705 | "date": "2022-02-11", 1706 | "doctor": "Dr. John Smith", 1707 | "diagnosis": "Knee injury", 1708 | "prescription": "Physical therapy and pain medication" 1709 | } 1710 | ] 1711 | }, 1712 | { 1713 | "name": "Micheal Chambers", 1714 | "age": 24, 1715 | "gender": "male", 1716 | "blood_type": "B-", 1717 | "address": "USNS Hill\nFPO AA 65061", 1718 | "phone": "7287550804025", 1719 | "last_visit": "2023-05-12", 1720 | "passport": "V65650155", 1721 | "appointments": [ 1722 | { 1723 | "doctor": "Dr. John Smith", 1724 | "date": "2023-03-01", 1725 | "time": "14:00", 1726 | "reason": "Annual Checkup" 1727 | }, 1728 | { 1729 | "doctor": "Dr. John Smith", 1730 | "date": "2023-05-12", 1731 | "time": "10:30", 1732 | "reason": "Follow-up for knee surgery" 1733 | } 1734 | ], 1735 | "medical_records": [ 1736 | { 1737 | "date": "2022-12-15", 1738 | "doctor": "Dr. Jane Doe", 1739 | "diagnosis": "Common cold", 1740 | "prescription": "Rest, fluids, and over-the-counter medication" 1741 | }, 1742 | { 1743 | "date": "2022-02-11", 1744 | "doctor": "Dr. John Smith", 1745 | "diagnosis": "Knee injury", 1746 | "prescription": "Physical therapy and pain medication" 1747 | } 1748 | ] 1749 | }, 1750 | { 1751 | "name": "Francisco Gomez", 1752 | "age": 16, 1753 | "gender": "male", 1754 | "blood_type": "B+", 1755 | "address": "473 Davis Prairie\nJoseton, NE 79464", 1756 | "phone": "6280261421843", 1757 | "last_visit": "2023-05-12", 1758 | "passport": "B66178906", 1759 | "appointments": [ 1760 | { 1761 | "doctor": "Dr. John Smith", 1762 | "date": "2023-03-01", 1763 | "time": "14:00", 1764 | "reason": "Annual Checkup" 1765 | }, 1766 | { 1767 | "doctor": "Dr. John Smith", 1768 | "date": "2023-05-12", 1769 | "time": "10:30", 1770 | "reason": "Follow-up for knee surgery" 1771 | } 1772 | ], 1773 | "medical_records": [ 1774 | { 1775 | "date": "2022-12-15", 1776 | "doctor": "Dr. Jane Doe", 1777 | "diagnosis": "Common cold", 1778 | "prescription": "Rest, fluids, and over-the-counter medication" 1779 | }, 1780 | { 1781 | "date": "2022-02-11", 1782 | "doctor": "Dr. John Smith", 1783 | "diagnosis": "Knee injury", 1784 | "prescription": "Physical therapy and pain medication" 1785 | } 1786 | ] 1787 | }, 1788 | { 1789 | "name": "Michael Reilly", 1790 | "age": 27, 1791 | "gender": "male", 1792 | "blood_type": "AB-", 1793 | "address": "0839 Michael Turnpike\nPort Patrick, IL 39668", 1794 | "phone": "4556091587137", 1795 | "last_visit": "2023-05-12", 1796 | "passport": "S43051200", 1797 | "appointments": [ 1798 | { 1799 | "doctor": "Dr. John Smith", 1800 | "date": "2023-03-01", 1801 | "time": "14:00", 1802 | "reason": "Annual Checkup" 1803 | }, 1804 | { 1805 | "doctor": "Dr. John Smith", 1806 | "date": "2023-05-12", 1807 | "time": "10:30", 1808 | "reason": "Follow-up for knee surgery" 1809 | } 1810 | ], 1811 | "medical_records": [ 1812 | { 1813 | "date": "2022-12-15", 1814 | "doctor": "Dr. Jane Doe", 1815 | "diagnosis": "Common cold", 1816 | "prescription": "Rest, fluids, and over-the-counter medication" 1817 | }, 1818 | { 1819 | "date": "2022-02-11", 1820 | "doctor": "Dr. John Smith", 1821 | "diagnosis": "Knee injury", 1822 | "prescription": "Physical therapy and pain medication" 1823 | } 1824 | ] 1825 | }, 1826 | { 1827 | "name": "Thomas Mccarthy", 1828 | "age": 45, 1829 | "gender": "male", 1830 | "blood_type": "O-", 1831 | "address": "1783 Jeffrey Mount\nGibsonbury, NC 11956", 1832 | "phone": "8335499674159", 1833 | "last_visit": "2023-05-12", 1834 | "passport": "704973506", 1835 | "appointments": [ 1836 | { 1837 | "doctor": "Dr. John Smith", 1838 | "date": "2023-03-01", 1839 | "time": "14:00", 1840 | "reason": "Annual Checkup" 1841 | }, 1842 | { 1843 | "doctor": "Dr. John Smith", 1844 | "date": "2023-05-12", 1845 | "time": "10:30", 1846 | "reason": "Follow-up for knee surgery" 1847 | } 1848 | ], 1849 | "medical_records": [ 1850 | { 1851 | "date": "2022-12-15", 1852 | "doctor": "Dr. Jane Doe", 1853 | "diagnosis": "Common cold", 1854 | "prescription": "Rest, fluids, and over-the-counter medication" 1855 | }, 1856 | { 1857 | "date": "2022-02-11", 1858 | "doctor": "Dr. John Smith", 1859 | "diagnosis": "Knee injury", 1860 | "prescription": "Physical therapy and pain medication" 1861 | } 1862 | ] 1863 | }, 1864 | { 1865 | "name": "Alexander Molina", 1866 | "age": 45, 1867 | "gender": "male", 1868 | "blood_type": "B+", 1869 | "address": "898 Sara Key Apt. 274\nNorth Donald, VA 57563", 1870 | "phone": "5956006006551", 1871 | "last_visit": "2023-05-12", 1872 | "passport": "326190226", 1873 | "appointments": [ 1874 | { 1875 | "doctor": "Dr. John Smith", 1876 | "date": "2023-03-01", 1877 | "time": "14:00", 1878 | "reason": "Annual Checkup" 1879 | }, 1880 | { 1881 | "doctor": "Dr. John Smith", 1882 | "date": "2023-05-12", 1883 | "time": "10:30", 1884 | "reason": "Follow-up for knee surgery" 1885 | } 1886 | ], 1887 | "medical_records": [ 1888 | { 1889 | "date": "2022-12-15", 1890 | "doctor": "Dr. Jane Doe", 1891 | "diagnosis": "Common cold", 1892 | "prescription": "Rest, fluids, and over-the-counter medication" 1893 | }, 1894 | { 1895 | "date": "2022-02-11", 1896 | "doctor": "Dr. John Smith", 1897 | "diagnosis": "Knee injury", 1898 | "prescription": "Physical therapy and pain medication" 1899 | } 1900 | ] 1901 | } 1902 | ] -------------------------------------------------------------------------------- /data/janedoe.json: -------------------------------------------------------------------------------- 1 | { 2 | "patient":{ 3 | "name":"Jane Doe", 4 | "age":35, 5 | "gender":"female", 6 | "blood_type":"AB+", 7 | "address":"123 Main Street, Anytown, USA", 8 | "phone":"555-1234", 9 | "last_visit": "2023-05-12", 10 | "passport": "938778408", 11 | "appointments":[ 12 | { 13 | "doctor":"Dr. John Smith", 14 | "date":"2023-03-01", 15 | "time":"14:00", 16 | "reason":"Annual Checkup" 17 | }, 18 | { 19 | "doctor":"Dr. John Smith", 20 | "date":"2023-05-12", 21 | "time":"10:30", 22 | "reason":"Follow-up for knee surgery" 23 | } 24 | ], 25 | "medical_records":[ 26 | { 27 | "date":"2022-12-15", 28 | "doctor":"Dr. Jane Doe", 29 | "diagnosis":"Common cold", 30 | "prescription":"Rest, fluids, and over-the-counter medication" 31 | }, 32 | { 33 | "date":"2022-02-11", 34 | "doctor":"Dr. John Smith", 35 | "diagnosis":"Knee injury", 36 | "prescription":"Physical therapy and pain medication" 37 | } 38 | ] 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /data/nursing_best_practices.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/data/nursing_best_practices.pdf -------------------------------------------------------------------------------- /data/opensearch_data.json: -------------------------------------------------------------------------------- 1 | {"index": {"_index": "11", "_id": 0}} 2 | {"data": "name: Edward Turner, age: 37, gender: male, blood_type: AB+, address: 3178 Laura Ports Hudsonstad, NC 29761, phone: 4710872054891, last_visit: 2023-05-12, passport: I44961231)"} 3 | {"index": {"_index": "11", "_id": 1}} 4 | {"data": "name: Matthew Black, age: 21, gender: male, blood_type: B+, address: 1716 Graham Spring Micheleland, ID 41056, phone: 1178626551342, last_visit: 2023-05-12, passport: R56522881)"} 5 | {"index": {"_index": "11", "_id": 2}} 6 | {"data": "name: Justin Cuevas, age: 30, gender: male, blood_type: AB+, address: 3790 Michael Roads Apt. 571 South Christina, IA 53619, phone: 1146081548113, last_visit: 2023-05-12, passport: 155567270)"} 7 | {"index": {"_index": "11", "_id": 3}} 8 | {"data": "name: Linda Thornton, age: 38, gender: female, blood_type: O-, address: 897 Julia Flats Apt. 375 Port Donaldfort, NY 02220, phone: 2171610936685, last_visit: 2023-05-12, passport: 060616577)"} 9 | {"index": {"_index": "11", "_id": 4}} 10 | {"data": "name: Christopher Rowe, age: 26, gender: male, blood_type: O-, address: 3171 Julie Point Suite 916 East Toddborough, ND 95189, phone: 9099132974498, last_visit: 2023-05-12, passport: 935995469)"} 11 | {"index": {"_index": "11", "_id": 5}} 12 | {"data": "name: Tony Campbell, age: 44, gender: male, blood_type: AB+, address: Unit 3382 Box 9185 DPO AE 79131, phone: 7347648585777, last_visit: 2023-05-12, passport: T93578520)"} 13 | {"index": {"_index": "11", "_id": 6}} 14 | {"data": "name: Jacqueline Johnston, age: 55, gender: female, blood_type: O+, address: 726 Monroe Plain New Aimeehaven, PA 39213, phone: 1973762291168, last_visit: 2023-05-12, passport: L71840599)"} 15 | {"index": {"_index": "11", "_id": 7}} 16 | {"data": "name: Andrew Adams, age: 20, gender: male, blood_type: AB-, address: 12117 Cain Forges Suite 124 Briannatown, ND 25235, phone: 4336995341525, last_visit: 2023-05-12, passport: 119054588)"} 17 | {"index": {"_index": "11", "_id": 8}} 18 | {"data": "name: Robert Smith, age: 54, gender: male, blood_type: B-, address: 28070 Ryan Dale Apt. 789 Williamsshire, OK 72359, phone: 4926642386860, last_visit: 2023-05-12, passport: C12565303)"} 19 | {"index": {"_index": "11", "_id": 9}} 20 | {"data": "name: Christina Jones, age: 35, gender: female, blood_type: B-, address: 441 Greer Port New Tamarachester, WA 52717, phone: 0604417529204, last_visit: 2023-05-12, passport: T50636185)"} 21 | {"index": {"_index": "11", "_id": 10}} 22 | {"data": "name: Stephanie Day, age: 41, gender: female, blood_type: O-, address: 321 Chang Extensions Suite 698 Pamelastad, KS 74405, phone: 7241078748484, last_visit: 2023-05-12, passport: 113023349)"} 23 | {"index": {"_index": "11", "_id": 11}} 24 | {"data": "name: Pamela Collins MD, age: 53, gender: female, blood_type: O+, address: 022 Alexander Villages Pamelashire, OR 74641, phone: 7677916911909, last_visit: 2023-05-12, passport: W58432650)"} 25 | {"index": {"_index": "11", "_id": 12}} 26 | {"data": "name: Brian Johnson, age: 26, gender: male, blood_type: B+, address: 5293 Darius Causeway Jenniferbury, MP 87477, phone: 5635283823283, last_visit: 2023-05-12, passport: D90963177)"} 27 | {"index": {"_index": "11", "_id": 13}} 28 | {"data": "name: Ana Stout, age: 37, gender: female, blood_type: O+, address: 18764 Ian Avenue North Robert, VI 22961, phone: 1661808138266, last_visit: 2023-05-12, passport: 944223377)"} 29 | {"index": {"_index": "11", "_id": 14}} 30 | {"data": "name: Sabrina Martinez, age: 55, gender: female, blood_type: AB+, address: 1994 Bentley Mills Apt. 284 Andreshire, NH 73165, phone: 4881483415773, last_visit: 2023-05-12, passport: 057307318)"} 31 | {"index": {"_index": "11", "_id": 15}} 32 | {"data": "name: Kyle Freeman, age: 45, gender: male, blood_type: B+, address: 4640 Brown Pine Suite 979 Stephenland, VA 09418, phone: 5272387435814, last_visit: 2023-05-12, passport: I51287745)"} 33 | {"index": {"_index": "11", "_id": 16}} 34 | {"data": "name: James Booker, age: 35, gender: male, blood_type: AB-, address: 33236 Adam Shoals Stokesborough, AK 81183, phone: 4316845959528, last_visit: 2023-05-12, passport: 331075656)"} 35 | {"index": {"_index": "11", "_id": 17}} 36 | {"data": "name: Christina Oliver, age: 21, gender: female, blood_type: A-, address: 30207 Damon Mission Port Lisamouth, NM 40550, phone: 3630414890443, last_visit: 2023-05-12, passport: 451449937)"} 37 | {"index": {"_index": "11", "_id": 18}} 38 | {"data": "name: Jordan Howard, age: 19, gender: male, blood_type: AB-, address: 8568 Glenda Extension Lake Connie, NV 00712, phone: 6981007629429, last_visit: 2023-05-12, passport: 431999572)"} 39 | {"index": {"_index": "11", "_id": 19}} 40 | {"data": "name: Rachel Hayes, age: 49, gender: female, blood_type: O-, address: 180 Martinez Union Suite 820 Rodriguezmouth, WA 89398, phone: 7130740834051, last_visit: 2023-05-12, passport: W39139439)"} 41 | {"index": {"_index": "11", "_id": 20}} 42 | {"data": "name: Morgan Perez, age: 53, gender: female, blood_type: A-, address: 64752 Bartlett Lock Jaimeport, TN 11504, phone: 8183619889141, last_visit: 2023-05-12, passport: O22359227)"} 43 | {"index": {"_index": "11", "_id": 21}} 44 | {"data": "name: Nicole Ruiz, age: 15, gender: female, blood_type: B-, address: 2474 Rebecca Lakes West Matthew, MH 45981, phone: 8379855105131, last_visit: 2023-05-12, passport: C33035297)"} 45 | {"index": {"_index": "11", "_id": 22}} 46 | {"data": "name: Steven Miller, age: 40, gender: male, blood_type: AB+, address: 0434 Anna Plains Apt. 869 South Laura, GU 42564, phone: 3039831023136, last_visit: 2023-05-12, passport: I44159462)"} 47 | {"index": {"_index": "11", "_id": 23}} 48 | {"data": "name: Natalie Gibbs, age: 25, gender: female, blood_type: A-, address: 9980 Paul Cove Woodsside, MO 24607, phone: 3903768330119, last_visit: 2023-05-12, passport: L76260236)"} 49 | {"index": {"_index": "11", "_id": 24}} 50 | {"data": "name: Derek Castro, age: 19, gender: male, blood_type: AB-, address: 978 Murray Villages New David, CA 61476, phone: 0974359310206, last_visit: 2023-05-12, passport: N97475797)"} 51 | {"index": {"_index": "11", "_id": 25}} 52 | {"data": "name: Jimmy Richardson II, age: 54, gender: male, blood_type: A+, address: 106 Drew Roads Apt. 024 West John, WV 89643, phone: 1274130452137, last_visit: 2023-05-12, passport: 511965600)"} 53 | {"index": {"_index": "11", "_id": 26}} 54 | {"data": "name: Teresa Estrada, age: 48, gender: female, blood_type: AB-, address: PSC 4855, Box 1479 APO AA 95560, phone: 1298449506881, last_visit: 2023-05-12, passport: Q18920003)"} 55 | {"index": {"_index": "11", "_id": 27}} 56 | {"data": "name: Matthew Casey, age: 47, gender: male, blood_type: A+, address: USS Ingram FPO AE 09500, phone: 2373457012072, last_visit: 2023-05-12, passport: 907950633)"} 57 | {"index": {"_index": "11", "_id": 28}} 58 | {"data": "name: Dustin Morales, age: 27, gender: male, blood_type: B+, address: 1426 Heather Groves Suite 916 North Jesse, WI 81057, phone: 5514511068097, last_visit: 2023-05-12, passport: 888993441)"} 59 | {"index": {"_index": "11", "_id": 29}} 60 | {"data": "name: Margaret Melton, age: 40, gender: female, blood_type: O-, address: 2799 Henderson Glens Suite 611 Anthonymouth, GU 88186, phone: 6591735937832, last_visit: 2023-05-12, passport: Q28060807)"} 61 | {"index": {"_index": "11", "_id": 30}} 62 | {"data": "name: Matthew Mckinney, age: 15, gender: male, blood_type: AB-, address: 654 Jimenez Locks Valeriebury, ME 70102, phone: 9801909168385, last_visit: 2023-05-12, passport: 134390951)"} 63 | {"index": {"_index": "11", "_id": 31}} 64 | {"data": "name: Patrick Grant, age: 28, gender: male, blood_type: B-, address: 244 Rebecca Corners Apt. 987 Lake Philiptown, KY 70485, phone: 2287880966124, last_visit: 2023-05-12, passport: S74372753)"} 65 | {"index": {"_index": "11", "_id": 32}} 66 | {"data": "name: Andrew Parker, age: 53, gender: male, blood_type: A+, address: 6283 Rebecca Place Floresburgh, NV 71277, phone: 1085564671439, last_visit: 2023-05-12, passport: 941498775)"} 67 | {"index": {"_index": "11", "_id": 33}} 68 | {"data": "name: Ashley Morrow, age: 23, gender: female, blood_type: O+, address: 197 Johnson Village Apt. 466 Zacharychester, TN 77180, phone: 6368027786053, last_visit: 2023-05-12, passport: G65305446)"} 69 | {"index": {"_index": "11", "_id": 34}} 70 | {"data": "name: Madison Hester, age: 26, gender: female, blood_type: AB+, address: 80388 Brittany Plains Apt. 911 Port Michelleborough, ND 84648, phone: 1679998606562, last_visit: 2023-05-12, passport: D22468980)"} 71 | {"index": {"_index": "11", "_id": 35}} 72 | {"data": "name: Joshua Avery, age: 44, gender: male, blood_type: AB+, address: 92930 Sanders Mews South Sarahport, PR 38363, phone: 8206472106542, last_visit: 2023-05-12, passport: 624573924)"} 73 | {"index": {"_index": "11", "_id": 36}} 74 | {"data": "name: Matthew Walter, age: 55, gender: male, blood_type: AB-, address: 038 Maria Forges Dunnborough, FM 19370, phone: 2582676948202, last_visit: 2023-05-12, passport: 620915238)"} 75 | {"index": {"_index": "11", "_id": 37}} 76 | {"data": "name: Ronald Gonzales, age: 21, gender: male, blood_type: A-, address: USNV Peterson FPO AE 07490, phone: 3715541811860, last_visit: 2023-05-12, passport: D05017607)"} 77 | {"index": {"_index": "11", "_id": 38}} 78 | {"data": "name: Katherine Wall, age: 52, gender: female, blood_type: AB-, address: 36499 Timothy Crossing East Jasonburgh, GA 13867, phone: 7850339447628, last_visit: 2023-05-12, passport: 679750041)"} 79 | {"index": {"_index": "11", "_id": 39}} 80 | {"data": "name: Matthew Manning, age: 22, gender: male, blood_type: B-, address: 057 Long Extensions Suite 859 Foxhaven, CA 65151, phone: 3655667680859, last_visit: 2023-05-12, passport: A45859510)"} 81 | {"index": {"_index": "11", "_id": 40}} 82 | {"data": "name: David Lewis, age: 27, gender: male, blood_type: O+, address: 94985 John Expressway Davidton, FL 70722, phone: 3110405750243, last_visit: 2023-05-12, passport: 427133493)"} 83 | {"index": {"_index": "11", "_id": 41}} 84 | {"data": "name: Alan Carter, age: 39, gender: male, blood_type: O+, address: 7006 Michael Meadows North Debra, AS 33923, phone: 3468761360316, last_visit: 2023-05-12, passport: 542710504)"} 85 | {"index": {"_index": "11", "_id": 42}} 86 | {"data": "name: Barbara Franco, age: 39, gender: female, blood_type: O+, address: 13124 Donna Viaduct Simmonston, WY 76662, phone: 9662355390954, last_visit: 2023-05-12, passport: I02872571)"} 87 | {"index": {"_index": "11", "_id": 43}} 88 | {"data": "name: Elijah Hicks, age: 19, gender: male, blood_type: AB-, address: 9249 Amber Pines Apt. 037 Smithhaven, ID 80649, phone: 4708459795359, last_visit: 2023-05-12, passport: R81655902)"} 89 | {"index": {"_index": "11", "_id": 44}} 90 | {"data": "name: Jessica Johnson, age: 24, gender: female, blood_type: B-, address: 290 Harding Stravenue New Sheritown, MS 93099, phone: 8033803521167, last_visit: 2023-05-12, passport: 073715786)"} 91 | {"index": {"_index": "11", "_id": 45}} 92 | {"data": "name: Sherri Turner, age: 23, gender: female, blood_type: A+, address: 13122 Alexander Well Stewartfort, IA 51740, phone: 6725455987327, last_visit: 2023-05-12, passport: 058162497)"} 93 | {"index": {"_index": "11", "_id": 46}} 94 | {"data": "name: Holly Crawford, age: 36, gender: female, blood_type: A-, address: 16979 Kathryn Orchard North Scott, MA 93103, phone: 1281788960368, last_visit: 2023-05-12, passport: O43770140)"} 95 | {"index": {"_index": "11", "_id": 47}} 96 | {"data": "name: Courtney Wolf, age: 33, gender: female, blood_type: O-, address: 72753 Randy Court Richardsonchester, KY 82571, phone: 8483629371883, last_visit: 2023-05-12, passport: 114399952)"} 97 | {"index": {"_index": "11", "_id": 48}} 98 | {"data": "name: Jenna Davis, age: 37, gender: female, blood_type: A-, address: Unit 4171 Box 8796 DPO AA 31351, phone: 4334438199580, last_visit: 2023-05-12, passport: Y47606543)"} 99 | {"index": {"_index": "11", "_id": 49}} 100 | {"data": "name: Collin Powell, age: 47, gender: male, blood_type: O+, address: 85526 Wright Forks North Michael, OK 67126, phone: 7250253913197, last_visit: 2023-05-12, passport: H74048136)"} 101 | -------------------------------------------------------------------------------- /data/questions_llm_rag.txt: -------------------------------------------------------------------------------- 1 | Can you give me info on Mary Poole? 2 | 3 | And, can you also give me info on patient John Briggs? 4 | 5 | Could John Briggs donate blood to Mary Poole, based on their blood types? 6 | 7 | 8 | ------ 9 | ------ 10 | 11 | Can you pull all information you have on racer id 6220? 12 | 13 | Can you pull all information you have on racer id 10574 and racer id 10304? 14 | 15 | How about the worst lap recorded for racer id 10304? 16 | 17 | What can he do to improve his sector 3 time? It was on the Texas F1 Grand Prix. I need recommendations to improve his sector time. 18 | 19 | 20 | ------ 21 | ------ 22 | 23 | What steps do I take if I have a new patient under the patient admission recommendations? 24 | 25 | Can you give me all the information on the patient with this phone number? +1-331-704-6971 -------------------------------------------------------------------------------- /img/agent.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/agent.PNG -------------------------------------------------------------------------------- /img/agents_autonomous.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/agents_autonomous.png -------------------------------------------------------------------------------- /img/answer_1.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/answer_1.PNG -------------------------------------------------------------------------------- /img/answer_2.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/answer_2.PNG -------------------------------------------------------------------------------- /img/answer_3_1.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/answer_3_1.PNG -------------------------------------------------------------------------------- /img/answer_3_2.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/answer_3_2.PNG -------------------------------------------------------------------------------- /img/answer_4.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/answer_4.PNG -------------------------------------------------------------------------------- /img/arch.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/arch.PNG -------------------------------------------------------------------------------- /img/chat_autonomous_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/chat_autonomous_1.png -------------------------------------------------------------------------------- /img/chat_autonomous_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/chat_autonomous_2.png -------------------------------------------------------------------------------- /img/chat_patient_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/chat_patient_1.png -------------------------------------------------------------------------------- /img/chat_patient_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/chat_patient_2.png -------------------------------------------------------------------------------- /img/chat_with_model.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/chat_with_model.png -------------------------------------------------------------------------------- /img/christopher_jordan.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/christopher_jordan.PNG -------------------------------------------------------------------------------- /img/connection_strings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/connection_strings.png -------------------------------------------------------------------------------- /img/connections_menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/connections_menu.png -------------------------------------------------------------------------------- /img/create_bucket.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/create_bucket.png -------------------------------------------------------------------------------- /img/create_connection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/create_connection.png -------------------------------------------------------------------------------- /img/create_connection_end.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/create_connection_end.png -------------------------------------------------------------------------------- /img/create_par.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/create_par.png -------------------------------------------------------------------------------- /img/create_par_output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/create_par_output.png -------------------------------------------------------------------------------- /img/create_subnet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/create_subnet.png -------------------------------------------------------------------------------- /img/create_vcn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/create_vcn.png -------------------------------------------------------------------------------- /img/crontabguru_output.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/crontabguru_output.PNG -------------------------------------------------------------------------------- /img/data_source_1.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/data_source_1.PNG -------------------------------------------------------------------------------- /img/data_source_2.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/data_source_2.PNG -------------------------------------------------------------------------------- /img/data_source_new.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/data_source_new.png -------------------------------------------------------------------------------- /img/data_source_old.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/data_source_old.PNG -------------------------------------------------------------------------------- /img/database_config.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/database_config.png -------------------------------------------------------------------------------- /img/database_creation_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/database_creation_1.png -------------------------------------------------------------------------------- /img/database_creation_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/database_creation_2.png -------------------------------------------------------------------------------- /img/database_creation_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/database_creation_3.png -------------------------------------------------------------------------------- /img/database_details.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/database_details.png -------------------------------------------------------------------------------- /img/databases_menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/databases_menu.png -------------------------------------------------------------------------------- /img/dg_details.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/dg_details.png -------------------------------------------------------------------------------- /img/dynamic_group_create.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/dynamic_group_create.png -------------------------------------------------------------------------------- /img/embeddings_result.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/embeddings_result.png -------------------------------------------------------------------------------- /img/endpoint.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/endpoint.PNG -------------------------------------------------------------------------------- /img/extra_info.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/extra_info.PNG -------------------------------------------------------------------------------- /img/generate_api_key.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/generate_api_key.png -------------------------------------------------------------------------------- /img/ingestion_job.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/ingestion_job.png -------------------------------------------------------------------------------- /img/key_creation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/key_creation.png -------------------------------------------------------------------------------- /img/knowledge_base.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/knowledge_base.png -------------------------------------------------------------------------------- /img/knowledge_base_autonomous.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/knowledge_base_autonomous.png -------------------------------------------------------------------------------- /img/knowledge_base_opensearch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/knowledge_base_opensearch.png -------------------------------------------------------------------------------- /img/knowledge_bases.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/knowledge_bases.png -------------------------------------------------------------------------------- /img/launch_agent.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/launch_agent.PNG -------------------------------------------------------------------------------- /img/new_agent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/new_agent.png -------------------------------------------------------------------------------- /img/new_agent_autonomous.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/new_agent_autonomous.png -------------------------------------------------------------------------------- /img/new_landing_page.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/new_landing_page.png -------------------------------------------------------------------------------- /img/ords/1sqlworkshop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/ords/1sqlworkshop.png -------------------------------------------------------------------------------- /img/ords/2restfulservices.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/ords/2restfulservices.png -------------------------------------------------------------------------------- /img/ords/3modules.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/ords/3modules.png -------------------------------------------------------------------------------- /img/ords/4moduledefinition.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/ords/4moduledefinition.png -------------------------------------------------------------------------------- /img/ords/5resourcetemplate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/ords/5resourcetemplate.png -------------------------------------------------------------------------------- /img/ords/6resourcehandler.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/ords/6resourcehandler.png -------------------------------------------------------------------------------- /img/output_model.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/output_model.PNG -------------------------------------------------------------------------------- /img/policy_details.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/policy_details.png -------------------------------------------------------------------------------- /img/private_db_ip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/private_db_ip.png -------------------------------------------------------------------------------- /img/private_ip.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/private_ip.PNG -------------------------------------------------------------------------------- /img/reference_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/reference_1.png -------------------------------------------------------------------------------- /img/reference_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/reference_2.png -------------------------------------------------------------------------------- /img/result_end.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/result_end.PNG -------------------------------------------------------------------------------- /img/sql_worksheet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/sql_worksheet.png -------------------------------------------------------------------------------- /img/step_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/step_1.png -------------------------------------------------------------------------------- /img/step_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/step_2.png -------------------------------------------------------------------------------- /img/step_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/step_3.png -------------------------------------------------------------------------------- /img/table_contents.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/table_contents.png -------------------------------------------------------------------------------- /img/uploaded_pdf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/uploaded_pdf.png -------------------------------------------------------------------------------- /img/validate_connection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/validate_connection.png -------------------------------------------------------------------------------- /img/validate_result.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/validate_result.png -------------------------------------------------------------------------------- /img/vault_creation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/vault_creation.png -------------------------------------------------------------------------------- /img/vcn_creation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oracle-devrel/oci-rag-vectordb/b056d63bf1bac45098fdc2d3f8f25a8895ad4168/img/vcn_creation.png -------------------------------------------------------------------------------- /license_policy.yml: -------------------------------------------------------------------------------- 1 | license_policies: 2 | - license_key: upl-1.0 3 | label: Approved License 4 | color_code: '#00800' 5 | icon: icon-ok-circle 6 | - license_key: bsd-simplified 7 | label: Approved License 8 | color_code: '#00800' 9 | icon: icon-ok-circle 10 | - license_key: bsd-new 11 | label: Approved License 12 | color_code: '#00800' 13 | icon: icon-ok-circle 14 | - license_key: mit 15 | label: Approved License 16 | color_code: '#00800' 17 | icon: icon-ok-circle 18 | - license_key: apache-1.1 19 | label: Approved License 20 | color_code: '#00800' 21 | icon: icon-ok-circle 22 | - license_key: apache-2.0 23 | label: Approved License 24 | color_code: '#00800' 25 | icon: icon-ok-circle 26 | -------------------------------------------------------------------------------- /ords_redo.md: -------------------------------------------------------------------------------- 1 | 2 | ## 1. Create/Use data 3 | 4 | We will generate some data points for our use case: we want to have **healthcare patient records** with some information from their previous visits. This is information we will give our LLM access to, through our Generative AI Agent, and ask the Agent questions about our patient records - this shows that even if the LLM hasn't trained for solving a specific type of prompt or query, RAG can facilitate this data *instantaneously* to the agent. 5 | 6 | To generate data, we will go into our Conda environment and install Python dependencies to produce this data: 7 | 8 | ```bash 9 | pip install -r requirements.txt 10 | ``` 11 | 12 | After, we can run `data_generator.py`: 13 | 14 | ```bash 15 | cd scripts/ 16 | python data_generator.py 17 | ``` 18 | 19 | The console will ask for how many synthetic users' data you want. For testing purposes, this can be any small value that will let us test; for your own use case in practice, your only job is to select which data will go into the vector store database, and in which form (JSON, structured data, raw text... and their properties (if any)). 20 | 21 | Finally, we need to run `data_converter.py` to convert the data source into expected OCI OpenSearch format. From the docs, [this is the expected format](https://opensearch.org/docs/latest/im-plugin/) for a JSON Object being inserted in OpenSearch: 22 | 23 | ```json 24 | { "index": { "_index": "", "_id": "" } } 25 | { "A JSON": "document" } 26 | ``` 27 | 28 | For that, we just have to execute the following script, making sure that there's a file called `data/generated_data.json` in your `data/` directory: 29 | 30 | ```bash 31 | python data_converter.py 32 | ``` 33 | 34 | This will generate `data/opensearch_data.json`, in the proper format for OCI OpenSearch. Now that we have our data properly-formatted, we can use the data to create our knowlegde base. 35 | 36 | TODO We need to connect to the VM in the same private subnet as our deployed OpenSearch and Redis cluster; through this VM, we will push the generated data into the OpenSearch cluster: -------------------------------------------------------------------------------- /release_files.json: -------------------------------------------------------------------------------- 1 | // see https://github.com/oracle-devrel/action-release-zip-maker for docs 2 | [ 3 | ] 4 | -------------------------------------------------------------------------------- /repolinter.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/todogroup/repolinter/master/rulesets/schema.json", 3 | "version": 2, 4 | "axioms": {}, 5 | "rules": { 6 | "readme-file-exists" : { 7 | "level": "error", 8 | "rule": { 9 | "type": "file-existence", 10 | "options": { 11 | "globsAny": ["README*"] 12 | } 13 | } 14 | }, 15 | "disclaimer-present" : { 16 | "level": "error", 17 | "rule": { 18 | "type": "file-contents", 19 | "options": { 20 | "globsAll": ["README*"], 21 | "noCase": true, 22 | "fail-on-non-existent": true, 23 | "content": "ORACLE AND ITS AFFILIATES DO NOT PROVIDE ANY WARRANTY WHATSOEVER, EXPRESS OR IMPLIED, FOR ANY SOFTWARE, MATERIAL OR CONTENT OF ANY KIND" 24 | } 25 | } 26 | }, 27 | "license-file-exists" : { 28 | "level": "error", 29 | "rule": { 30 | "type": "file-existence", 31 | "options": { 32 | "globsAny": ["LICENSE*"] 33 | } 34 | } 35 | }, 36 | "copyright-notice-present" : { 37 | "level": "warning", 38 | "rule": { 39 | "type": "file-starts-with", 40 | "options": { 41 | "globsAll": ["**/*"], 42 | "skip-binary-files": true, 43 | "skip-paths-matching": { 44 | "extensions": ["yaml","yml","md","json","xml","tpl","ipynb","pickle","joblib","properties"], 45 | "patterns": ["\\.github"], 46 | "flags": "" 47 | }, 48 | "lineCount": 2, 49 | "patterns": [ 50 | "Copyright \\([cC]\\) [12][90]\\d\\d(\\-[12][90]\\d\\d)? Oracle and/or its affiliates\\." 51 | ], 52 | "succeed-on-non-exist": true 53 | } 54 | } 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | Faker 2 | ujson 3 | tinydb 4 | fastapi 5 | python-multipart 6 | paramiko -------------------------------------------------------------------------------- /scripts/consume_ords.py: -------------------------------------------------------------------------------- 1 | # @author jasperan 2 | ''' 3 | This script consumes an ORDS endpoint with requests, gets the JSON data, formats it, and prepares it for 4 | insertion into the OpenSearch cluster. 5 | ''' 6 | 7 | import requests 8 | import yaml 9 | from tinydb import TinyDB, Query 10 | import paramiko 11 | from base64 import decodebytes 12 | import random 13 | 14 | def generate_random_16_digit_number(): 15 | return int(''.join([str(random.randint(0, 9)) for _ in range(16)])) 16 | 17 | 18 | db = TinyDB('../data/laps_db.json') 19 | records_table = db.table('redbull') 20 | 21 | def read_ords_endpoint(auth_data: dict): 22 | 23 | 24 | ords_endpoint = auth_data['ords_endpoint'] 25 | 26 | # Consume ORDS endpoint - protected into a YAML file for security purposes 27 | response = requests.get(ords_endpoint) 28 | data = response.json()['f1sim'] 29 | try: 30 | assert type(data) == type(list()) 31 | except AssertionError: 32 | print('[ORDS ERROR] Endpoint not returning properly formatted data') 33 | return data 34 | 35 | # after this function completes, you will get C = A - B, where 36 | # A = all records 37 | # B = records already inserted in previous executions of the program 38 | # so, you will only get C = a JSON file with NEW laps. 39 | 40 | def create_opensearch_format(data: list): 41 | line_writer = list() 42 | i = 0 43 | 44 | for x in data: 45 | 46 | # check tinydb existence of this record. if not, add it to the db. 47 | result = check_tinydb(x['ID'], x['LAP_TIME_DSP']) 48 | if result == 1: 49 | # this means it's new data, so we insert it too to our OpenSearch cluster. 50 | line_writer.append({"index": {"_index": "redbull_ords", "_id": generate_random_16_digit_number()}}) 51 | lap_str = "racer id: {ID}, racer name: {R_NAME}, track name: {TRACKNAME}, invalid lap: {INVALID_LAP}, total lap time: {LAP_TIME_DSP}, sector 1 time: {S1}, sector 2 time: {S2}, sector 3 time: {S3}, lap date: {LAP_DATE}".format(**x).replace("\"", "") 52 | new_obj = {"data": lap_str} 53 | line_writer.append(new_obj) 54 | print('[NEW LAP] {}/{}'.format(i, len(data))) 55 | 56 | else: 57 | # don't do anything if this data was already present. 58 | print('[DUPLICATE LAP] {}/{}'.format(i, len(data))) 59 | i+= 1 60 | return line_writer 61 | 62 | def check_tinydb(id: str, lap_time: str): 63 | lap_exists = records_table.search((Query().racer_id == id) & (Query().lap_time == lap_time)) 64 | if not lap_exists: 65 | records_table.insert({'racer_id': id, 'lap_time': lap_time}) 66 | return 1 67 | else: return 0 68 | 69 | def output_opensearch_file(file_path: str, line_writer: list): 70 | num_errors = 0 71 | with open(file_path, 'w', encoding="utf-8") as output_file: 72 | for item in line_writer: 73 | try: 74 | write_str = str(item).replace("\'", "\"") 75 | output_file.write("{}\n".format(write_str)) 76 | except UnicodeEncodeError as e: 77 | print('[ERR] {}: {}'.format(write_str, e)) 78 | num_errors += 1 79 | 80 | print('[FINISHED] TOTAL ERRORS: {}'.format(num_errors)) 81 | 82 | 83 | def send_file(auth_data: dict, source: str, destination: str): 84 | scp_command = """scp -i {} {} {}@{}:{}""".format( 85 | auth_data['key_location'], 86 | source, 87 | auth_data['user'], 88 | auth_data['ip_address'], 89 | destination 90 | ) 91 | print(scp_command) 92 | 93 | ssh_client = paramiko.SSHClient() 94 | ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 95 | ssh_client.connect(auth_data['ip_address'], username=auth_data['user'], key_filename=auth_data['key_location'], password='') 96 | 97 | # send the file through SFTP 98 | ftp_client=ssh_client.open_sftp() 99 | ftp_client.put(source, destination) 100 | ftp_client.close() 101 | 102 | return ssh_client 103 | 104 | 105 | def update_cluster(auth_data: dict, ssh_client: paramiko.SSHClient): 106 | # this points to the private IP address of the OS cluster (not the bastion's ip address) 107 | # as this command will be remotely executed within the bastion 108 | # /redbull/ is the name of the index 109 | command = """curl -H 'Content-Type: application/x-ndjson' -XPOST https://10.0.3.12:9200/redbull/_bulk?pretty --data-binary @/home/opc/ords/opensearch_redbull_data.json -u {}:{} --insecure""".format( 110 | auth_data['cluster_private_user'], 111 | auth_data['cluster_private_password'] 112 | ) 113 | 114 | ssh_stdin, ssh_stdout, ssh_stderr = ssh_client.exec_command(command) 115 | print(ssh_stdout.read().decode()) 116 | print(ssh_stderr.read().decode()) 117 | 118 | 119 | 120 | def main(): 121 | opensearch_file_location = '../data/opensearch_redbull_data.json' 122 | bastion_destination_path = '/home/opc/ords/opensearch_redbull_data.json' 123 | with open('../auth.yaml', 'r') as file: 124 | auth_data = yaml.safe_load(file) 125 | 126 | 127 | # 1. Read ORDS data 128 | data = read_ords_endpoint(auth_data) 129 | # 2. Process data and convert to OpenSearch JSON format 130 | new_opensearch_laps = create_opensearch_format(data) 131 | # 3. Create resulting opensearch.json file 132 | output_opensearch_file(opensearch_file_location, new_opensearch_laps) 133 | # 4. Send this file through SFTP to the bastion 134 | ssh_client = send_file(auth_data, opensearch_file_location, bastion_destination_path) 135 | # 5. Run OpenCluster PUT command 136 | update_cluster(auth_data, ssh_client) 137 | 138 | if __name__ == '__main__': 139 | main() 140 | 141 | -------------------------------------------------------------------------------- /scripts/data_converter.py: -------------------------------------------------------------------------------- 1 | import ujson as json 2 | 3 | with open('../data/generated_data.json', 'r') as file: 4 | data = json.load(file) 5 | all_data = list() 6 | 7 | i = 0 8 | line_writer = list() 9 | for item in data: 10 | line_writer.append({"index": {"_index": "11", "_id": i}}) 11 | extended_item = dict() 12 | 13 | 14 | #extended_item['url'] = '' 15 | #extended_item['title'] = '' 16 | # we build our formatted string 17 | patient_str = '''name: {name}, age: {age}, gender: {gender}, blood_type: {blood_type}, address: 18 | {address}, phone: {phone}, last_visit: {last_visit}, passport: {passport}'''.format(**item).replace("\"", "") 19 | 20 | extended_item['data'] = ', '.join("{!s}={!r}".format(key,val) for (key,val) in item.items()) 21 | #"yesterday:{yesterday}, today:{today}, tomorrow:{tomorrow}".format(**mydict) 22 | 23 | #str_data = '''{"data": {}}'''.format(extended_item['data']) 24 | print(patient_str) 25 | line_writer.append({"data": "{})".format(patient_str).replace("\n", " ")}) 26 | i += 1 27 | 28 | 29 | #{"title": "", "body": "Oracle...", "url": "https://docs.oracle.com/en-us/iaas/Content/Compute/known-issues.htm"} 30 | 31 | with open('../data/opensearch_data.json', 'w') as output_file: 32 | for item in line_writer: 33 | write_str = str(item).replace("\'", "\"") 34 | output_file.write("{}\n".format(write_str)) 35 | -------------------------------------------------------------------------------- /scripts/data_generator.py: -------------------------------------------------------------------------------- 1 | import json 2 | from faker import Faker 3 | import random 4 | fake = Faker() 5 | 6 | 7 | ''' 8 | @author jasperan 9 | This script will generate as many fake users as we want for our RAG healthcare dataset. 10 | This is intended to generate some synthetic data that can be embedded into a vector 11 | store and retrieved using OCI GenAI Agents Service. 12 | ''' 13 | 14 | number_generations = input('Please, input how many patient records you want to generate:') 15 | number_generations = int(number_generations) 16 | 17 | if number_generations < 0: 18 | number_generations = input('Please, input a positive valid integer number:') 19 | 20 | 21 | with open('../data/janedoe.json', 'r') as file: 22 | data = json.load(file) 23 | # Generate similar objects based on data 24 | all_data = list() 25 | for _ in range(number_generations): 26 | patient_gender = random.choice(["male", "female"]) 27 | fake_data = { 28 | "name":fake.name_male() if patient_gender == "male" else fake.name_female(), 29 | "age":random.randint(15, 55), 30 | "gender":patient_gender, 31 | "blood_type":random.choice(['A+', 'A-', 'B+', 'B-', 'O+', 'O-', 'AB+', 'AB-']), 32 | "address":fake.address(), 33 | "phone":fake.msisdn(), 34 | "last_visit": "2023-05-12", 35 | "passport": fake.passport_number(), 36 | "appointments":[ 37 | { 38 | "doctor":"Dr. John Smith", 39 | "date":"2023-03-01", 40 | "time":"14:00", 41 | "reason":"Annual Checkup" 42 | }, 43 | { 44 | "doctor":"Dr. John Smith", 45 | "date":"2023-05-12", 46 | "time":"10:30", 47 | "reason":"Follow-up for knee surgery" 48 | } 49 | ], 50 | "medical_records":[ 51 | { 52 | "date":"2022-12-15", 53 | "doctor":"Dr. Jane Doe", 54 | "diagnosis":"Common cold", 55 | "prescription":"Rest, fluids, and over-the-counter medication" 56 | }, 57 | { 58 | "date":"2022-02-11", 59 | "doctor":"Dr. John Smith", 60 | "diagnosis":"Knee injury", 61 | "prescription":"Physical therapy and pain medication" 62 | } 63 | ] 64 | } 65 | print('[NEW] {} | {} || {} | Phone Number: {}'.format( 66 | fake_data['name'], 67 | fake_data['gender'], 68 | fake_data['passport'], 69 | fake_data['phone'] 70 | )) 71 | all_data.append(fake_data) 72 | 73 | with open('../data/generated_data.json', 'w') as file: 74 | json.dump(all_data, file, indent=4) 75 | -------------------------------------------------------------------------------- /sonar-project.properties: -------------------------------------------------------------------------------- 1 | sonar.projectKey=oracle-devrel_oci-rag-vectordb 2 | sonar.organization=oracle-devrel 3 | 4 | # This is the name and version displayed in the SonarCloud UI. 5 | #sonar.projectName=test 6 | #sonar.projectVersion=1.0 7 | 8 | # Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows. 9 | #sonar.sources=. 10 | 11 | # Encoding of the source code. Default is default system encoding 12 | #sonar.sourceEncoding=UTF-8 --------------------------------------------------------------------------------