├── .gitignore ├── LICENSE-CODE.txt ├── LICENSE.txt ├── NOTICE.txt ├── README.md ├── _config.yml ├── labs ├── lab-01-environment-creation.md ├── lab-02-azure-search.md ├── lab-03-text-skills.md ├── lab-04-image-skills.md ├── lab-05-custom-skills.md ├── lab-06-bot-business-documents.md └── lab-final-case.md └── resources ├── code-azure-function ├── CognitiveSkill.sln ├── CognitiveSkill │ ├── .gitignore │ ├── CognitiveSkill.csproj │ ├── Moderation.cs │ ├── WebApiSkill │ │ ├── WebAPISkillContract.cs │ │ └── WebApiSkillHelpers.cs │ └── host.json └── README.md ├── code-bot ├── .deployment ├── .gitignore ├── BotAccessors.cs ├── BotConfiguration.bot ├── BotState.cs ├── CognitiveSearchBot.cs ├── CognitiveSearchBot.csproj ├── CognitiveSearchBot.deps.json ├── CognitiveSearchBot.runtimeconfig.json ├── CognitiveSearchBot.sln ├── Constants.cs ├── Dialogs │ ├── MainDialog.cs │ ├── ModeratedContentSearchDialog.cs │ ├── SearchDialog.cs │ └── SearchDialogBase.cs ├── Middleware │ ├── EntityRecognizers.cs │ ├── IntentRecognizerMiddleware.cs │ └── RegExpRecognizerMiddleware.cs ├── Models │ ├── ImageMapper.cs │ ├── SearchHit.cs │ └── SearchHitStyler.cs ├── PostDeployScripts │ ├── IncludeSources.targets │ ├── githubProject.json.template │ ├── prepareSrc.cmd │ ├── publish.cmd.template │ ├── publishProfile.xml.template │ ├── publishSettings.xml.template │ ├── runGulp.cmd │ ├── setupGithubRemoteRepo.cmd │ ├── setupVsoRemoteRepo.cmd │ └── vsoProject.json.template ├── Program.cs ├── Properties │ └── launchSettings.json ├── Responses │ ├── MainResponses.cs │ └── SearchResponses.cs ├── Startup.cs ├── Utilities │ └── HeroCardUtility.cs ├── appsettings.json ├── build.cmd ├── deploy.cmd ├── readme.md ├── web.config └── wwwroot │ └── default.htm ├── dataset-hackathon ├── 1003_MS_Coppola_079B.jpg ├── HollysHillVineyards.jpg ├── Italy-Wine-Map-wine-folly.jpg ├── README.md ├── barbaresco-nebbiolo-wine.jpg ├── bouza-monte-vide-eu.pdf ├── bouza-tannat.pdf ├── catena-zapata-2015.pdf ├── catena-zapata-2016.pdf ├── coppola wine thief628x471.jpg ├── el-enemigo-stamp.jpg ├── garzon-tannat.pdf ├── green-wine-certificates.pdf ├── green-wine-grapes.pdf ├── green-wine-region.pdf ├── jon-arvid-rosengren.pdf ├── l_6231_jon-arvid-rosengren-winner.jpg ├── rosengren_arvid_l.jpg ├── rosengrenmsm.jpg ├── terrazas-cabernet-sauvignon.pdf ├── terrazas-chadornay.jpg ├── terrazas-chadornay.pdf ├── trapiche.jpg ├── trapiche.pdf ├── wine-producers.pdf ├── wine-reviews.csv ├── zuccardi.jpg └── zuccardi.pdf ├── dataset ├── 10-K-FY16.html ├── 20190506_Microsoft_Build_435-630x450 Open Satya.jpg ├── 5074.clip_image002_6FE27E85.png ├── Cognitive Search Skills.PNG ├── Cognitive Services and Bots (spanish).pdf ├── Form.png ├── KMB V1.pdf ├── LearnAI-portal.PNG ├── MSFT_FY17_10K.docx ├── MSFT_cloud_architecture_contoso.pdf ├── NYSE_LNKD_2015.PDF ├── PII.txt ├── README.md ├── SQL Server on Linux.JPG ├── Satya AI democratization.jpg ├── Satya Brazil KM.jpg ├── board.PNG ├── finished-solution-lab-azure-search.md ├── guthrie.jpg ├── redshirt.jpg ├── satyanadellalinux.jpg ├── satyasletter.txt └── words cloud.PNG ├── finished-solutions ├── 02-Azure Search.postman_collection.json ├── 03-Text Skills.postman_collection.json ├── 04-Image Skills.postman_collection.json ├── 05-Custom Skills.postman_collection.json ├── finished-solution-lab-02-azure-search.md ├── finished-solution-lab-04-image-skills.md └── finished-solution-lab-05-custom-skills.md ├── images ├── enrichment-pipeline-details │ ├── Slide1.PNG │ ├── Slide10.PNG │ ├── Slide11.PNG │ ├── Slide12.PNG │ ├── Slide13.PNG │ ├── Slide2.PNG │ ├── Slide3.PNG │ ├── Slide4.PNG │ ├── Slide5.PNG │ ├── Slide6.PNG │ ├── Slide7.PNG │ ├── Slide8.PNG │ └── Slide9.PNG ├── lab-azure-search │ ├── cog-search.png │ ├── compete.png │ ├── data-source-2.png │ ├── data-source.png │ ├── example.png │ ├── import-data.png │ ├── index-settings.png │ ├── indexer-advanced.png │ ├── inverted.png │ ├── query.png │ ├── redirect.png │ ├── search-explorer.png │ └── search-options.png ├── lab-bot │ ├── bot-builder-dotnet-project.png │ ├── bots-concepts-middleware.png │ ├── diagram.png │ ├── emulator-running.png │ ├── expected.png │ ├── locals.png │ ├── locals2.png │ ├── retrieving-cognitive-attrributes.gif │ └── setbreak.png ├── lab-custom-skills │ ├── cmd.png │ ├── code.png │ ├── moderatedtex-query-portal.png │ ├── panel.png │ ├── structure.png │ ├── versions.png │ └── yellow-flag.png ├── lab-environment-creation │ ├── create-search-collect-info.png │ ├── create-search-service.png │ ├── create-service-full-portal.png │ └── git.png ├── lab-final-case │ ├── complex1.png │ ├── complex2.png │ ├── complex4.png │ └── simple.png ├── lab-image-skills │ └── postman-no-data.png ├── lab-text-skills │ ├── plan.png │ ├── postman-help.png │ └── skillset.png ├── readme │ ├── architecture.png │ ├── header.png │ └── tech-map.png └── sol-arch │ ├── architecture.png │ ├── cost.png │ ├── no-meta.png │ └── postman.png ├── instructor-notes ├── KMB-Opening.pptx └── README.md ├── md-files ├── alternative-agendas.md ├── enrichment-pipeline-details.md ├── introduction.md ├── qa-feedback-survey.md └── solution-architecture.md ├── resources └── template.json └── slides ├── 01.png ├── 02.png ├── 03.png ├── 04.png ├── 05.png ├── 06.png ├── 07.png ├── 08.png ├── 09.png ├── 10.png ├── 11.png ├── 12.png ├── 13.png ├── 14.png ├── 15.png ├── 16.png ├── 17.png ├── 18.png ├── 19.png ├── 20.png ├── 21.png ├── 22.png ├── 23_new.png ├── 24.png ├── 25.png ├── 26.png ├── 27.png ├── 28.png ├── 29.png ├── 30.png ├── 31.png ├── 32.png ├── 33.png ├── 34.png ├── 35.png ├── introduction-pdf ├── kmb-introduction-v1.pdf └── readme.md └── introduction-ppt ├── README.md └── kmb-introduction-v1.pptx /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore github pages things 2 | _site 3 | Gemfile.lock 4 | 5 | ## Ignore Visual Studio temporary files, build results, and 6 | ## files generated by popular Visual Studio add-ons. 7 | 8 | # User-specific files 9 | *.suo 10 | *.user 11 | *.userosscache 12 | *.sln.docstates 13 | 14 | # User-specific files (MonoDevelop/Xamarin Studio) 15 | *.userprefs 16 | .vscode/ 17 | 18 | # Build results 19 | [Dd]ebug/ 20 | [Dd]ebugPublic/ 21 | [Rr]elease/ 22 | [Rr]eleases/ 23 | x64/ 24 | x86/ 25 | bld/ 26 | [Bb]in/ 27 | [Oo]bj/ 28 | [Ll]og/ 29 | 30 | # Visual Studio 2015 cache/options directory 31 | .vs/ 32 | # Uncomment if you have tasks that create the project's static files in wwwroot 33 | #wwwroot/ 34 | 35 | # MSTest test Results 36 | [Tt]est[Rr]esult*/ 37 | [Bb]uild[Ll]og.* 38 | 39 | # NUNIT 40 | *.VisualState.xml 41 | TestResult.xml 42 | 43 | # Build Results of an ATL Project 44 | [Dd]ebugPS/ 45 | [Rr]eleasePS/ 46 | dlldata.c 47 | 48 | # DNX 49 | project.lock.json 50 | project.fragment.lock.json 51 | artifacts/ 52 | 53 | *_i.c 54 | *_p.c 55 | *_i.h 56 | *.ilk 57 | *.meta 58 | *.obj 59 | *.pch 60 | *.pdb 61 | *.pgc 62 | *.pgd 63 | *.rsp 64 | *.sbr 65 | *.tlb 66 | *.tli 67 | *.tlh 68 | *.tmp 69 | *.tmp_proj 70 | *.log 71 | *.vspscc 72 | *.vssscc 73 | .builds 74 | *.pidb 75 | *.svclog 76 | *.scc 77 | 78 | # Chutzpah Test files 79 | _Chutzpah* 80 | 81 | # Visual C++ cache files 82 | ipch/ 83 | *.aps 84 | *.ncb 85 | *.opendb 86 | *.opensdf 87 | *.sdf 88 | *.cachefile 89 | *.VC.db 90 | *.VC.VC.opendb 91 | 92 | # Visual Studio profiler 93 | *.psess 94 | *.vsp 95 | *.vspx 96 | *.sap 97 | 98 | # TFS 2012 Local Workspace 99 | $tf/ 100 | 101 | # Guidance Automation Toolkit 102 | *.gpState 103 | 104 | # ReSharper is a .NET coding add-in 105 | _ReSharper*/ 106 | *.[Rr]e[Ss]harper 107 | *.DotSettings.user 108 | 109 | # JustCode is a .NET coding add-in 110 | .JustCode 111 | 112 | # TeamCity is a build add-in 113 | _TeamCity* 114 | 115 | # DotCover is a Code Coverage Tool 116 | *.dotCover 117 | 118 | # NCrunch 119 | _NCrunch_* 120 | .*crunch*.local.xml 121 | nCrunchTemp_* 122 | 123 | # MightyMoose 124 | *.mm.* 125 | AutoTest.Net/ 126 | 127 | # Web workbench (sass) 128 | .sass-cache/ 129 | 130 | # Installshield output folder 131 | [Ee]xpress/ 132 | 133 | # DocProject is a documentation generator add-in 134 | DocProject/buildhelp/ 135 | DocProject/Help/*.HxT 136 | DocProject/Help/*.HxC 137 | DocProject/Help/*.hhc 138 | DocProject/Help/*.hhk 139 | DocProject/Help/*.hhp 140 | DocProject/Help/Html2 141 | DocProject/Help/html 142 | 143 | # Click-Once directory 144 | publish/ 145 | 146 | # Publish Web Output 147 | *.[Pp]ublish.xml 148 | *.azurePubxml 149 | # TODO: Comment the next line if you want to checkin your web deploy settings 150 | # but database connection strings (with potential passwords) will be unencrypted 151 | *.pubxml 152 | *.publishproj 153 | 154 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 155 | # checkin your Azure Web App publish settings, but sensitive information contained 156 | # in these scripts will be unencrypted 157 | PublishScripts/ 158 | 159 | # NuGet Packages 160 | *.nupkg 161 | # The packages folder can be ignored because of Package Restore 162 | **/packages/* 163 | # except build/, which is used as an MSBuild target. 164 | !**/packages/build/ 165 | # Uncomment if necessary however generally it will be regenerated when needed 166 | #!**/packages/repositories.config 167 | # NuGet v3's project.json files produces more ignoreable files 168 | *.nuget.props 169 | *.nuget.targets 170 | 171 | # Microsoft Azure Build Output 172 | csx/ 173 | *.build.csdef 174 | 175 | # Microsoft Azure Emulator 176 | ecf/ 177 | rcf/ 178 | 179 | # Windows Store app package directories and files 180 | AppPackages/ 181 | BundleArtifacts/ 182 | Package.StoreAssociation.xml 183 | _pkginfo.txt 184 | 185 | # Visual Studio cache files 186 | # files ending in .cache can be ignored 187 | *.[Cc]ache 188 | # but keep track of directories ending in .cache 189 | !*.[Cc]ache/ 190 | 191 | # Others 192 | ClientBin/ 193 | ~$* 194 | *~ 195 | *.dbmdl 196 | *.dbproj.schemaview 197 | *.pfx 198 | *.publishsettings 199 | node_modules/ 200 | orleans.codegen.cs 201 | 202 | # Since there are multiple workflows, uncomment next line to ignore bower_components 203 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 204 | #bower_components/ 205 | 206 | # RIA/Silverlight projects 207 | Generated_Code/ 208 | 209 | # Backup & report files from converting an old project file 210 | # to a newer Visual Studio version. Backup files are not needed, 211 | # because we have git ;-) 212 | _UpgradeReport_Files/ 213 | Backup*/ 214 | UpgradeLog*.XML 215 | UpgradeLog*.htm 216 | 217 | # SQL Server files 218 | *.mdf 219 | *.ldf 220 | 221 | # Business Intelligence projects 222 | *.rdl.data 223 | *.bim.layout 224 | *.bim_*.settings 225 | 226 | # Microsoft Fakes 227 | FakesAssemblies/ 228 | 229 | # GhostDoc plugin setting file 230 | *.GhostDoc.xml 231 | 232 | # Node.js Tools for Visual Studio 233 | .ntvs_analysis.dat 234 | 235 | # Visual Studio 6 build log 236 | *.plg 237 | 238 | # Visual Studio 6 workspace options file 239 | *.opt 240 | 241 | # Visual Studio LightSwitch build output 242 | **/*.HTMLClient/GeneratedArtifacts 243 | **/*.DesktopClient/GeneratedArtifacts 244 | **/*.DesktopClient/ModelManifest.xml 245 | **/*.Server/GeneratedArtifacts 246 | **/*.Server/ModelManifest.xml 247 | _Pvt_Extensions 248 | 249 | # Paket dependency manager 250 | .paket/paket.exe 251 | paket-files/ 252 | 253 | # FAKE - F# Make 254 | .fake/ 255 | 256 | # JetBrains Rider 257 | .idea/ 258 | *.sln.iml -------------------------------------------------------------------------------- /LICENSE-CODE.txt: -------------------------------------------------------------------------------- 1 |  MIT License 2 | 3 | Copyright (c) Microsoft Corporation. All rights reserved. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE -------------------------------------------------------------------------------- /NOTICE.txt: -------------------------------------------------------------------------------- 1 | ##Legal Notices 2 | Microsoft and any contributors grant you a license to the Microsoft documentation and other content 3 | in this repository under the [Creative Commons Attribution 4.0 International Public License](https://creativecommons.org/licenses/by/4.0/legalcode), 4 | see the LICENSE file, and grant you a license to any code in the repository under the [MIT License](https://opensource.org/licenses/MIT), see the 5 | LICENSE-CODE file. 6 | 7 | Microsoft, Windows, Microsoft Azure and/or other Microsoft products and services referenced in the documentation 8 | may be either trademarks or registered trademarks of Microsoft in the United States and/or other countries. 9 | The licenses for this project do not grant you rights to use any Microsoft names, logos, or trademarks. 10 | Microsoft's general trademark guidelines can be found at http://go.microsoft.com/fwlink/?LinkID=254653. 11 | 12 | Privacy information can be found at https://privacy.microsoft.com/ 13 | 14 | Microsoft and any contributors reserve all others rights, whether under their respective copyrights, patents, 15 | or trademarks, whether by implication, estoppel or otherwise. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Knowledge Mining 2 | 3 | ![Logo](./resources/images/readme/header.png) 4 | 5 | ## Knowledge Mining Bootcamp - Build a Cognitive Search Solution for business documents using Microsoft AI Platform 6 | 7 | ## About this course 8 | 9 | In this course, you will create an enterprise search solution by applying knowledge mining to business documents like contracts, memos, presentations and images. 10 | You will use Microsoft Azure AI technology to extract insights from unstructured data and expose the results in a Bot interface. 11 | 12 | This training is two days long, but you can compress the duration with [alternative agendas](./resources/md-files/alternative-agendas.md). 13 | 14 | ## Goals 15 | 16 | At the end of this training you will have learned: 17 | 18 | + **What** Azure Cognitive Search is 19 | + **How** to implement a Cognitive Search Solution 20 | + **Why** this technology can be useful for any company 21 | + **When** to use this solution for demos, POCs and other business scenarios 22 | 23 | The hands-on labs will teach you how to use Microsoft Azure Search combined with Microsoft Cognitive Services for entity recognition, image analysis, text translation and indexed search on enterprise business documents. This approach uses Artificial Intelligence to create an advanced search experience. 24 | 25 | While this course focuses on Azure Cognitive Search capabilities, an in-depth course on building Bots and integrating various Azure Cognitive Services is available here - [Azure Cognitive Services Bootcamp](https://github.com/Azure/LearnAI-Bootcamp). 26 | 27 | In this course we will cover these key concepts: 28 | 29 | 1. Fundamentals of Azure Search and its capabilities 30 | 31 | 1. Microsoft Cognitive Search and its key business scenarios 32 | 33 | 1. Building an enrichment data pipeline for search using predefined and custom skillsets: 34 | 35 | + Text skills like entity recognition, language detection, text manipulation and key phrase extraction 36 | + Image skills like OCR 37 | + Content moderation skills to detect documents with incompliant content 38 | 39 | 1. Use the enriched data for an advanced search experience for business documents within an enterprise. 40 | 41 | 1. Expose the knowledge mining solution using a bot interface for document search and consumption. 42 | 43 | ### Architecture 44 | 45 | ![Architecture](./resources/images/readme/architecture.png) 46 | 47 | ### Technologies Covered 48 | 49 | ![Technology](./resources/images/readme/tech-map.png) 50 | 51 | ### Industry application 52 | 53 | Intelligent search is relevant to many major industries. Some are listed below. 54 | 55 | 1. Retail and health care industries employ chatbots with advanced multi-language support capabilities to service their customers. 56 | 57 | 1. Retail, Housing and Automotive industries for sales/listing. 58 | 59 | 1. Law firms and legal departments can use this technology to enforce compliance or improve search capabilities. 60 | 61 | ### Pre-requisites 62 | 63 | 1. Fundamental working knowledge of Azure Portal, Azure Functions and Azure Search 64 | 1. Familiarity with Visual Studio and minimum C# knowledge 65 | 1. Familiarity with Azure Bots and Microsoft Bot Framework v4 66 | 1. Familiarity with [Postman](https://www.getpostman.com/) 67 | 68 | If you do not have any of the above pre-requisites, please find below links 69 | 70 | 1. *To Read (10 minutes):* [Visual Studio Tutorial](https://docs.microsoft.com/en-us/visualstudio/ide/visual-studio-ide) 71 | 1. *To Read (8 minutes):* [Azure Bot Service Overview](https://docs.microsoft.com/en-us/azure/bot-service/bot-service-overview-introduction?view=azure-bot-service-4.0) 72 | 1. *To Read (4 minutes):* [Azure Functions Overview](https://docs.microsoft.com/en-us/azure/azure-functions/functions-overview) 73 | 1. *To Read (10 minutes):* [Azure Search Overview](https://docs.microsoft.com/en-us/azure/search/search-what-is-azure-search) 74 | 1. *To Read (7 minutes):* [Postman Tutorial](https://docs.microsoft.com/en-us/azure/search/search-fiddler) 75 | 1. *To Do (30 minutes):* [C# Quickstart](https://docs.microsoft.com/en-us/dotnet/csharp/quick-starts/) 76 | 77 | ### Pre-Setup before you attend the class Mandatory 78 | 79 | 1. *To Create:* You need a Microsoft Azure account to create the services we use in our solution. You can create a [free account](https://azure.microsoft.com/en-us/free/), use your MSDN account or any other subscription where you have permission to create services 80 | 1. *To Install:* [Visual Studio 2019](https://www.visualstudio.com/vs/) or later, *including the Azure development workload* 81 | 1. *To Install:* [Postman](https://www.getpostman.com/). To call the labs APIs 82 | 1. *To Install:* [Bot Emulator](https://github.com/Microsoft/BotFramework-Emulator/releases), use the '.exe' file from release 4.1.0 or newer 83 | 1. *To Install:* [Git for Windows](https://gitforwindows.org/) or any other git app you prefer 84 | 85 | ### Course Details 86 | 87 | Primary Audience: Azure AI Developers, Solution Architects. 88 | Secondary Audience: Any professional interested in learning AI. 89 | 90 | ### Level 91 | 92 | This content is designed as an intermediate to advanced level course for AI developers and/or architects. 93 | 94 | ### Type 95 | 96 | This course, in its full form, is designed to be taught in-person but you can also use the materials in a self-paced fashion. There are assignments and multiple reference links throughout the materials that support the concepts and skills you will learn. 97 | 98 | ### Length 99 | 100 | Full Course classroom training: 16 hours 101 | 102 | ### Related LearnAI Courses 103 | 104 | [Azure Cognitive Services Bootcamp](https://github.com/Azure/LearnAI-Bootcamp) 105 | [Cognitive Search Workshop](https://azure.github.io/LearnAI-Cognitive-Search/) 106 | [Designing and Architecting Intelligent Agents](https://azure.github.io/LearnAI-DesigningandArchitectingIntelligentAgents/) 107 | 108 | ### Course Modules 109 | 110 | 1. [Introduction](./resources/md-files/introduction.md) – **Presentation** overview of Azure Search, Cognitive Search, business scenarios and industry specific applications. 111 | 112 | 2. [Architecture](./resources/md-files/solution-architecture.md) – **Solution Architecture** for building enterprise search solution. 113 | 114 | 3. [Lab 1](./labs/lab-01-environment-creation.md) - Azure - **Environment Creation** 115 | 116 | 4. [Lab 2](./labs/lab-02-azure-search.md) - Azure Search - **Indexing Blob Storage** 117 | 118 | 5. [Lab 3](./labs/lab-03-text-skills.md) - Cognitive Search – **Text Skills** 119 | 120 | 6. [Lab 4](./labs/lab-04-image-skills.md) - Cognitive Search – **Image Skills** 121 | 122 | 7. [Lab 5](./labs/lab-05-custom-skills.md) - Cognitive Search – **Custom Skills** 123 | 124 | 8. [Lab 6](./labs/lab-06-bot-business-documents.md) - Build and Integrate a **Bot** with Cognitive Search API 125 | 126 | 9. [Lab 7](./labs/lab-final-case.md) - **Architecture Design Session + Hackathon** 127 | 128 | > **Note**: Once you've completed the labs, we recommend deleting the resource group (and all the resources in it) to avoid incurring extra charges. 129 | 130 | ## Contact 131 | 132 | Contact us: and 133 | 134 | ## Certifications 135 | 136 | The LearnAI team had intense participation in the creation of the following new Microsoft certifications and its required tests: 137 | 138 | + [Azure Data Engineer​](https://www.microsoft.com/en-us/learning/azure-data-engineer.aspx) 139 | + DP-200: Implementing an Azure Data Solution 140 | + DP-201: Designing an Azure Data Solutions​ 141 | 142 | + [Azure AI Engineer​](https://www.microsoft.com/en-us/learning/azure-ai-engineer.aspx) 143 | + AI-100: Designing and Implementing an Azure AI Solution 144 | 145 | + [Azure Data Scientist](https://www.microsoft.com/en-us/learning/azure-data-scientist.aspx) 146 | + DP-100: Designing and Implementing a Data Science Solution on Azure​ 147 | 148 | ## Cognitive Services Compliance 149 | 150 | Click [here](https://azure.microsoft.com/en-us/support/legal/cognitive-services-compliance-and-privacy/) to learn how Microsoft Cognitive Services handle your data. 151 | 152 | ### Q&A and Survey 153 | 154 | Please help the LearnAI Team with [questions and feedback](./resources/md-files/qa-feedback-survey.md) about this training. -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-slate -------------------------------------------------------------------------------- /labs/lab-01-environment-creation.md: -------------------------------------------------------------------------------- 1 | # Environment Creation 2 | 3 | In this lab, you will create an Azure Search service and a storage account. We recommend keeping both in a new and unique resource group, to make it easier to delete at the end of the workshop (if you want to). We will also upload the data to a blob storage within the storage account. 4 | 5 | ## Step 1 - Clone the Repo 6 | 7 | Cloning the repo will download all the training materials to your computer, including the dataset, the slides and the code for the Bot project. **The cloning of the repository will use close to 110 MB in total**. 8 | 9 | ### Task 1: Download GitHub resources 10 | 11 | 1. Open a browser window to the GitHub repository (). 12 | 13 | 1. Select **Clone or download**, then select **Download Zip**. 14 | 15 | 1. Extract the zip file to your local machine, be sure to keep note of where you have extracted the files. You should now see a set of folders: 16 | 17 | ## Step 2 - Create the Azure Search service 18 | 19 | 1. Go to the [Azure portal](https://portal.azure.com) and sign in with your Azure account. 20 | 21 | 1. Create a new resource group, click **Resources groups**, then click **Add**. Select a subscription, type a name for the group, such as **INIT-kmb** and then select a region. Click **Review + Create**, then click **Create** 22 | 23 | 1. In the resource group, click **Add**. Search for **Azure Search**, then select **Azure Search**, then click **Create**. In addition to facilitating organization and visualization in the portal, using a single resource group helps you, if necessary at the end of the training, remove all services created. If you want to keep this solution up and running, for demos and POCs in minutes with your own data, this resources cleaning isn't necessary. 24 | 25 | 1. Click **Create a resource**, search for Azure Search, and click **Create**. See [Create an Azure Search service in the portal](https://docs.microsoft.com/en-us/azure/search/search-create-service-portal) if you are setting up a search service for the first time, and use the bullet point list below for the details you will use to fill out the details for the Azure Search service. 26 | 27 | ![Dashboard portal](../resources/images/lab-environment-creation/create-service-full-portal.png) 28 | 29 | 1. Ensure your newly created resource group is selected. 30 | 31 | 1. For the **URL**, type your service name, choose a name that you can easily remember. We will use it many times in the labs. 32 | 33 | > **Note** The name of the service in the screenshots of this lab won't be available, you must create your own service name. 34 | 35 | 1. For **Location**, choose one of the regions below, Cognitive Search is not available in all Azure regions. 36 | 37 | - West Central US 38 | - South Central US 39 | - East US 40 | - East US 2 41 | - West US 2 42 | - Canada Central 43 | - West Europe 44 | - UK South 45 | - North Europe 46 | - Brazil South 47 | - Southeast Asia 48 | - Central India 49 | - Australia East 50 | 51 | 1. For **Pricing tier**, select **Standard**. For deeper information on Azure Search pricing and limits, click [here](https://azure.microsoft.com/pricing/details/search/) and [here](https://docs.microsoft.com/en-us/azure/search/search-limits-quotas-capacity). 52 | 53 | 1. Click **Review + Create**, then click **Create** 54 | 55 | 1. Once the service is created, under **Settings**, click **Keys** 56 | 57 | 1. Copy the **Primary admin key** to notepad or similar text editor for use later in the labs. 58 | 59 | ![Endpoint and key information in the portal](../resources/images/lab-environment-creation/create-search-collect-info.png "Endpoint and key information in the portal") 60 | 61 | > **Note** Azure Search must have 2 replicas for read-only SLA and 3 replicas for read/write SLA. This is not addressed in this training. For more information, click [here](https://azure.microsoft.com/en-us/support/legal/sla/search/v1_0/) 62 | 63 | ## Step 3 - Create the Azure Blob service and upload the dataset 64 | 65 | The enrichment pipeline pulls from Azure data sources. Source data must originate from a supported data source type of an [Azure Search indexer](https://docs.microsoft.com/en-us/azure/search/search-indexer-overview). For this exercise, we use blob storage to showcase multiple content types. 66 | 67 | 1. From the resource group, click **+Add**. Search for **storage account**, select it, then click **Create** 68 | 69 | 1. Ensure your newly created resource group is selected. Type a unique name for your storage account, such as **INITkmbstorage**, 70 | 71 | 1. Select the same location as your Azure Search resource. This will help to avoid latency. 72 | 73 | 1. For performance, select **Standard** 74 | 75 | 1. For **account kind**, select **StorageV2** 76 | 77 | 1. For replication, select **Locally-redundant storage LRS** 78 | 79 | 1. Click **Review + create**, then click **Create** 80 | 81 | 1. From the storage account **Overview** tab, click the link to **Blobs**. 82 | 83 | 1. Click the **+Container** link. For the name type `projections`: 84 | 85 | 1. Select **Container** for Access Type. 86 | 87 | 1. Click the **+Container** link. For the name type `basicdemo`: 88 | 89 | 1. Select **Container** for Access Type. 90 | 91 | 1. Select the new container, then click **Upload**. Browse to the **\resources\dataset** cloned github folder and select all the files, then click **Open** 92 | 93 | 1. Click **Upload**, wait for all the files to upload. 94 | 95 | > **Note** You can also use the [Azure Storage Explorer](https://docs.microsoft.com/en-us/azure/storage/blobs/storage-quickstart-blobs-storage-explorer) to upload files. If you use the Storage Explorer, be careful not to create another folder level. This training is created with the assumption that all of the data is located in the root folder of the container. 96 | 97 | 1. Ensure that 21 files were uploaded to the **basicdemo** container. 98 | 99 | 1. Navigate back to the storage account blade, under **Settings**, click **Access keys**. 100 | 101 | 1. Copy the **key1** **Connection string** by clicking the copy button. Save the key to notepad or similar text editor. 102 | 103 | ## Step 4 - Create the Cognitive Services Account 104 | 105 | A Cognitive Services resource is needed in order to enrich more than 20 documents per day in diromg Azure Search indexing. 106 | 107 | 1. From the resource group, click **+Add**. Search for **cognitive services**, select it, then click **Create** 108 | 109 | 1. For the name, type **INIT-cogs** 110 | 111 | 1. For the location, select the same resource group as your search and storage account 112 | 113 | 1. For the pricing tier, select **S0** 114 | 115 | 1. Check the **I confirm I have read and understood the notice below** checkbox 116 | 117 | 1. Click **Create** 118 | 119 | ## Next Step 120 | 121 | [Azure Search Lab](../labs/lab-02-azure-search.md) or 122 | [Back to Read Me](../README.md) -------------------------------------------------------------------------------- /labs/lab-final-case.md: -------------------------------------------------------------------------------- 1 | # Final Case 2 | 3 | ## Objective 4 | 5 | > **Note** This activity was designed as a group exercise for in-classroom ILTs (Instructor Lead Trainings), the idea is a final discussion after the exercise. But you also can do it if by yourself. 6 | 7 | ## Complex Scenarios 8 | 9 | Now you are very familiar to 1x1x1x1 scenarios: one dataset, one index, one skillset and one indexer. The diagrams below describe this situation but also complex scenarios of Cognitive Search. 10 | 11 | ### Performance Optimization with Partitioning for Parallel Processing 12 | 13 | Parallel processing helps to increase performance of your indexing process, with 2 or more indexers running at the same time. They will be using partitioned data sources and sharing the same target index. 14 | 15 | To divide the data into multiple containers, or partitions, helps to increase performance. It is required to create one data source and one indexer for partition, pointing to the same index. It is possible to use the same skillset or not, depends on the business requirements and also how the partitions were made. As an example, let's say that all images are separated from text documents. In this case, it may make sense to have different skillsets for the images and text documents. 16 | 17 | To run them in parallel, Standard Service Tier is required, with the correct number of replicas and partitions. The number or maximum parallel indexers executions at the same time is calculated with this simple formula: number of partitions x number of replicas. If you have 3 replicas and 3 partitions, you can have up to 9 indexers at the same time. 18 | 19 | For more information on sizing, click [here](https://docs.microsoft.com/en-us/azure/search/search-capacity-planning). 20 | 21 | ### Cognitive Search Typical Scenarios 22 | 23 | The diagrams below explain some of the scenarios for Cognitive Search 24 | 25 | 1. **Simple Scenario**: Visual representation of the scenario addressed in this training. 26 | 27 | 1. **Multiple Data Sources Scenario**: It is the situation explained in the section above, about parallel processing: Big data volume requires parallel processing, what demands data partitioning and one indexer per partition. 28 | 29 | + If the data was partitioned per timestamp, you should the same indexer definition for all indexers. 30 | + If the data was partitioned by business rules or file types, you can see different indexers definitions. Image skills are heavier than text ones. If your images are separated in a partition, you can increase performance not applying image skills on text documents. 31 | 32 | 1. **Multiple Indexes Scenario**: This scenario is used when you need to: 33 | 34 | + Physically isolate the created metadata 35 | + Different index properties of the index: facetable, searchable, filterable, etc 36 | 37 | 1. **Multiple Skisets Scenario**: This scenario is used when you have one of the following situations: 38 | 39 | + A Custom Skill that has different update times. So, you don't need to call that API for all of your executions. 40 | + Your data has multiple updates periods. Example: images are updated in the morning, text documents in the afternoon. 41 | 42 | ![Simple Scenario](../resources/images/lab-final-case/simple.png) 43 | ![Complex Scenario 1](../resources/images/lab-final-case/complex1.png) 44 | ![Complex Scenario 2](../resources/images/lab-final-case/complex2.png) 45 | ![Complex Scenario 4](../resources/images/lab-final-case/complex4.png) 46 | 47 | ## Case Study 48 | 49 | **Contoso Total Wines** is a relatively new wine dealership that is gaining popularity quickly due to several factors. One reason is the monthly subscription model, with progressive discounts. 50 | The company has an award-winning customer service, what helped the business growth in South America countries. While Gold subscribers can chat with sommeliers to customize the next wine delivery, Silver clients can chat with intelligent bots to customize their options. 51 | 52 | Now the company needs to increase their search capabilities, for channels like chat, web portal and mobile Application. They decided to enrich and index their product catalog to increase accuracy of clients and sommeliers searches. The product catalog is a series of HTML, Microsoft Word and PDFs documents. Some of them have images and they are all written in English, which is a problem for their Latin America clients. 53 | 54 | They also want to provide links for places, grapes and other entities their data has. The company owner and the Master Sommelier are famous figures and the marketing department wants to highlight this as well. 55 | 56 | ## Exercise 57 | 58 | Using what you've learned throughout the course, develop a potential Cognitive Search enrichment pipeline to help the company achieve their search business goals. The expected outputs of this exercise are: 59 | 60 | 1. Build your solution using one of the complex scenarios listed above. Justify your choice. Presenting another diagram is valid, you can draw freehand or use any software 61 | 1. List of the predefined and custom skills 62 | 1. The skills sequence and how they are integrated 63 | 1. The necessary Azure Search tier for this solution 64 | 1. List other Data & AI Azure services that could improve the search experience, including all labs, experiments, demos, and breaking news you saw in this training. Also including everything you know about Azure, AI, Data Science, and Analytics. 65 | 66 | ## Hackathon - Challenge - Optional 67 | 68 | Create an Azure Cognitive Search Solution for the Case Study above, using everything you learned in this training. The instructions are: 69 | 70 | 1. Use one of the complex scenarios above. 71 | 2. Use the Hackathon data set: **/resources/dataset-hackathon** folder of this repo. 72 | 3. Apply the following Cognitive skills 73 | 74 | + OCR 75 | + Image Analysis, saving the caption and the celebrities detected into different index fields 76 | + Sentiment analysis for all text (content + extracted from the images skills) 77 | + Entity Extraction: Organizations, names and locations 78 | + Save all the text information into the index with the original language but also in Portuguese 79 | 80 | 4. Using Postman or Azure Portal, find: 81 | 82 | + Who are the celebrities of the dataset? 83 | + What are the wine regions detected? 84 | + What are the best wines according to the reviews? 85 | + Search for Terrazas and report which data was found. 86 | + What are the wines from Uruguay and Argentina? 87 | 88 | ## Cleaning your environment - Again 89 | 90 | You have completed all of the hands-on portions of the course. We recommend deleting the resource group (and all of the resources in it) to avoid incurring extra charges. 91 | 92 | ## Next Step 93 | 94 | [Back to Read Me](../README.md) -------------------------------------------------------------------------------- /resources/code-azure-function/CognitiveSkill.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.28010.2036 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CognitiveSkill", "CognitiveSkill\CognitiveSkill.csproj", "{9E6A53C5-3CEC-4295-ADD2-31A368C019ED}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {9E6A53C5-3CEC-4295-ADD2-31A368C019ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {9E6A53C5-3CEC-4295-ADD2-31A368C019ED}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {9E6A53C5-3CEC-4295-ADD2-31A368C019ED}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {9E6A53C5-3CEC-4295-ADD2-31A368C019ED}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {CF8F2C35-53C4-4708-8EE4-8F023C19033D} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /resources/code-azure-function/CognitiveSkill/.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # Azure Functions localsettings file 5 | local.settings.json 6 | 7 | # User-specific files 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Build results 17 | [Dd]ebug/ 18 | [Dd]ebugPublic/ 19 | [Rr]elease/ 20 | [Rr]eleases/ 21 | x64/ 22 | x86/ 23 | bld/ 24 | [Bb]in/ 25 | [Oo]bj/ 26 | [Ll]og/ 27 | 28 | # Visual Studio 2015 cache/options directory 29 | .vs/ 30 | # Uncomment if you have tasks that create the project's static files in wwwroot 31 | #wwwroot/ 32 | 33 | # MSTest test Results 34 | [Tt]est[Rr]esult*/ 35 | [Bb]uild[Ll]og.* 36 | 37 | # NUNIT 38 | *.VisualState.xml 39 | TestResult.xml 40 | 41 | # Build Results of an ATL Project 42 | [Dd]ebugPS/ 43 | [Rr]eleasePS/ 44 | dlldata.c 45 | 46 | # DNX 47 | project.lock.json 48 | project.fragment.lock.json 49 | artifacts/ 50 | 51 | *_i.c 52 | *_p.c 53 | *_i.h 54 | *.ilk 55 | *.meta 56 | *.obj 57 | *.pch 58 | *.pdb 59 | *.pgc 60 | *.pgd 61 | *.rsp 62 | *.sbr 63 | *.tlb 64 | *.tli 65 | *.tlh 66 | *.tmp 67 | *.tmp_proj 68 | *.log 69 | *.vspscc 70 | *.vssscc 71 | .builds 72 | *.pidb 73 | *.svclog 74 | *.scc 75 | 76 | # Chutzpah Test files 77 | _Chutzpah* 78 | 79 | # Visual C++ cache files 80 | ipch/ 81 | *.aps 82 | *.ncb 83 | *.opendb 84 | *.opensdf 85 | *.sdf 86 | *.cachefile 87 | *.VC.db 88 | *.VC.VC.opendb 89 | 90 | # Visual Studio profiler 91 | *.psess 92 | *.vsp 93 | *.vspx 94 | *.sap 95 | 96 | # TFS 2012 Local Workspace 97 | $tf/ 98 | 99 | # Guidance Automation Toolkit 100 | *.gpState 101 | 102 | # ReSharper is a .NET coding add-in 103 | _ReSharper*/ 104 | *.[Rr]e[Ss]harper 105 | *.DotSettings.user 106 | 107 | # JustCode is a .NET coding add-in 108 | .JustCode 109 | 110 | # TeamCity is a build add-in 111 | _TeamCity* 112 | 113 | # DotCover is a Code Coverage Tool 114 | *.dotCover 115 | 116 | # NCrunch 117 | _NCrunch_* 118 | .*crunch*.local.xml 119 | nCrunchTemp_* 120 | 121 | # MightyMoose 122 | *.mm.* 123 | AutoTest.Net/ 124 | 125 | # Web workbench (sass) 126 | .sass-cache/ 127 | 128 | # Installshield output folder 129 | [Ee]xpress/ 130 | 131 | # DocProject is a documentation generator add-in 132 | DocProject/buildhelp/ 133 | DocProject/Help/*.HxT 134 | DocProject/Help/*.HxC 135 | DocProject/Help/*.hhc 136 | DocProject/Help/*.hhk 137 | DocProject/Help/*.hhp 138 | DocProject/Help/Html2 139 | DocProject/Help/html 140 | 141 | # Click-Once directory 142 | publish/ 143 | 144 | # Publish Web Output 145 | *.[Pp]ublish.xml 146 | *.azurePubxml 147 | # TODO: Comment the next line if you want to checkin your web deploy settings 148 | # but database connection strings (with potential passwords) will be unencrypted 149 | #*.pubxml 150 | *.publishproj 151 | 152 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 153 | # checkin your Azure Web App publish settings, but sensitive information contained 154 | # in these scripts will be unencrypted 155 | PublishScripts/ 156 | 157 | # NuGet Packages 158 | *.nupkg 159 | # The packages folder can be ignored because of Package Restore 160 | **/packages/* 161 | # except build/, which is used as an MSBuild target. 162 | !**/packages/build/ 163 | # Uncomment if necessary however generally it will be regenerated when needed 164 | #!**/packages/repositories.config 165 | # NuGet v3's project.json files produces more ignoreable files 166 | *.nuget.props 167 | *.nuget.targets 168 | 169 | # Microsoft Azure Build Output 170 | csx/ 171 | *.build.csdef 172 | 173 | # Microsoft Azure Emulator 174 | ecf/ 175 | rcf/ 176 | 177 | # Windows Store app package directories and files 178 | AppPackages/ 179 | BundleArtifacts/ 180 | Package.StoreAssociation.xml 181 | _pkginfo.txt 182 | 183 | # Visual Studio cache files 184 | # files ending in .cache can be ignored 185 | *.[Cc]ache 186 | # but keep track of directories ending in .cache 187 | !*.[Cc]ache/ 188 | 189 | # Others 190 | ClientBin/ 191 | ~$* 192 | *~ 193 | *.dbmdl 194 | *.dbproj.schemaview 195 | *.jfm 196 | *.pfx 197 | *.publishsettings 198 | node_modules/ 199 | orleans.codegen.cs 200 | 201 | # Since there are multiple workflows, uncomment next line to ignore bower_components 202 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 203 | #bower_components/ 204 | 205 | # RIA/Silverlight projects 206 | Generated_Code/ 207 | 208 | # Backup & report files from converting an old project file 209 | # to a newer Visual Studio version. Backup files are not needed, 210 | # because we have git ;-) 211 | _UpgradeReport_Files/ 212 | Backup*/ 213 | UpgradeLog*.XML 214 | UpgradeLog*.htm 215 | 216 | # SQL Server files 217 | *.mdf 218 | *.ldf 219 | 220 | # Business Intelligence projects 221 | *.rdl.data 222 | *.bim.layout 223 | *.bim_*.settings 224 | 225 | # Microsoft Fakes 226 | FakesAssemblies/ 227 | 228 | # GhostDoc plugin setting file 229 | *.GhostDoc.xml 230 | 231 | # Node.js Tools for Visual Studio 232 | .ntvs_analysis.dat 233 | 234 | # Visual Studio 6 build log 235 | *.plg 236 | 237 | # Visual Studio 6 workspace options file 238 | *.opt 239 | 240 | # Visual Studio LightSwitch build output 241 | **/*.HTMLClient/GeneratedArtifacts 242 | **/*.DesktopClient/GeneratedArtifacts 243 | **/*.DesktopClient/ModelManifest.xml 244 | **/*.Server/GeneratedArtifacts 245 | **/*.Server/ModelManifest.xml 246 | _Pvt_Extensions 247 | 248 | # Paket dependency manager 249 | .paket/paket.exe 250 | paket-files/ 251 | 252 | # FAKE - F# Make 253 | .fake/ 254 | 255 | # JetBrains Rider 256 | .idea/ 257 | *.sln.iml 258 | 259 | # CodeRush 260 | .cr/ 261 | 262 | # Python Tools for Visual Studio (PTVS) 263 | __pycache__/ 264 | *.pyc -------------------------------------------------------------------------------- /resources/code-azure-function/CognitiveSkill/CognitiveSkill.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net461 4 | v1 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | PreserveNewest 15 | 16 | 17 | PreserveNewest 18 | Never 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /resources/code-azure-function/CognitiveSkill/Moderation.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using System.Net; 4 | using System.Net.Http; 5 | using System.Net.Http.Headers; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | using Microsoft.Azure.WebJobs; 9 | using Microsoft.Azure.WebJobs.Extensions.Http; 10 | using Microsoft.Azure.WebJobs.Host; 11 | using Microsoft.CognitiveSearch.WebApiSkills; 12 | using Newtonsoft.Json; 13 | using Newtonsoft.Json.Linq; 14 | 15 | namespace CognitiveSkill 16 | { 17 | public static class Function1 18 | { 19 | [FunctionName("ContentModerator")] 20 | public static async Task Run([HttpTrigger(AuthorizationLevel.Function, "post", Route = null)]HttpRequestMessage req, TraceWriter log, ExecutionContext executionContext) 21 | { 22 | log.Info("C# HTTP trigger function processed a request."); 23 | string skillName = executionContext.FunctionName; 24 | 25 | IEnumerable requestRecords = WebApiSkillHelpers.GetRequestRecords(req); 26 | if (requestRecords == null) 27 | { 28 | 29 | return req.CreateErrorResponse(HttpStatusCode.BadRequest, $"{skillName} - Invalid request record array."); 30 | } 31 | dynamic obj = requestRecords.First().Data.First().Value; 32 | 33 | if (obj.Length > 1024) 34 | obj = obj.Substring(0, 1024); 35 | 36 | string val = await MakeRequest(obj); 37 | ContentModerator mod = JsonConvert.DeserializeObject(val); 38 | 39 | bool requiresModeration = false; 40 | //Jon Dobrzeniecki helped with the code below, since may 2019 the CM API isn't returning the PII section if there is no data for it 41 | if (mod.PII != null) 42 | { 43 | if (mod.PII.Email.Length > 0) 44 | requiresModeration = true; 45 | if (mod.PII.Address.Length > 0) 46 | requiresModeration = true; 47 | if (mod.PII.IPA.Length > 0) 48 | requiresModeration = true; 49 | if (mod.PII.Phone.Length > 0) 50 | requiresModeration = true; 51 | } 52 | WebApiResponseRecord output = new WebApiResponseRecord(); 53 | output.RecordId = requestRecords.First().RecordId; 54 | output.Data["text"] = requiresModeration; 55 | 56 | WebApiSkillResponse resp = new WebApiSkillResponse(); 57 | resp.Values = new List(); 58 | resp.Values.Add(output); 59 | return req.CreateResponse(HttpStatusCode.OK, resp); 60 | } 61 | static async Task MakeRequest(string input) 62 | { 63 | var client = new HttpClient(); 64 | 65 | //TO-DO: URL of the Moderator API. Fix the Prefix with your URL, what can be found in the Azure Portal. 66 | //If you are using southcentralus, don't need to change anything 67 | var uriPrefix = "https://southcentralus.api.cognitive.microsoft.com/contentmoderator"; 68 | var uriSuffix = "/moderate/v1.0/ProcessText/Screen?autocorrect=false&PII=true&classify=false&language=eng"; 69 | 70 | //TO-DO: Add your content moderator key here 71 | client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", "your content moderator key here"); 72 | 73 | //TO-DO: WITHOUT he https://, check the url of the region of your content moderator API. If nos southcentralus, change it. 74 | client.DefaultRequestHeaders.Add("Host", "southcentralus.api.cognitive.microsoft.com"); 75 | 76 | 77 | var uri = uriPrefix + uriSuffix; 78 | 79 | HttpResponseMessage response; 80 | byte[] byteData = Encoding.UTF8.GetBytes(input); 81 | using (var content = new ByteArrayContent(byteData)) 82 | { 83 | content.Headers.ContentType = new MediaTypeHeaderValue("text/plain"); 84 | response = await client.PostAsync(uri, content); 85 | } 86 | var result = response.Content.ReadAsStringAsync(); 87 | 88 | return await result; 89 | 90 | } 91 | } 92 | 93 | 94 | public class ContentModerator 95 | { 96 | public string OriginalText { get; set; } 97 | public string NormalizedText { get; set; } 98 | public string AutoCorrectedText { get; set; } 99 | public object Misrepresentation { get; set; } 100 | public Classification Classification { get; set; } 101 | public Status Status { get; set; } 102 | public PII PII { get; set; } 103 | public string Language { get; set; } 104 | public Terms[] Terms { get; set; } 105 | public string TrackingId { get; set; } 106 | } 107 | 108 | public class Classification 109 | { 110 | public Category1 Category1 { get; set; } 111 | public Category2 Category2 { get; set; } 112 | public Category3 Category3 { get; set; } 113 | public bool ReviewRecommended { get; set; } 114 | } 115 | 116 | public class Category1 117 | { 118 | public float Score { get; set; } 119 | } 120 | 121 | public class Category2 122 | { 123 | public float Score { get; set; } 124 | } 125 | 126 | public class Category3 127 | { 128 | public float Score { get; set; } 129 | } 130 | 131 | public class Status 132 | { 133 | public int Code { get; set; } 134 | public string Description { get; set; } 135 | public object Exception { get; set; } 136 | } 137 | 138 | public class PII 139 | { 140 | public Email[] Email { get; set; } 141 | public IPA[] IPA { get; set; } 142 | public Phone[] Phone { get; set; } 143 | public Address[] Address { get; set; } 144 | } 145 | 146 | public class Email 147 | { 148 | public string Detected { get; set; } 149 | public string SubType { get; set; } 150 | public string Text { get; set; } 151 | public int Index { get; set; } 152 | } 153 | 154 | public class IPA 155 | { 156 | public string SubType { get; set; } 157 | public string Text { get; set; } 158 | public int Index { get; set; } 159 | } 160 | 161 | public class Phone 162 | { 163 | public string CountryCode { get; set; } 164 | public string Text { get; set; } 165 | public int Index { get; set; } 166 | } 167 | 168 | public class Address 169 | { 170 | public string Text { get; set; } 171 | public int Index { get; set; } 172 | } 173 | 174 | public class Terms 175 | { 176 | public int Index { get; set; } 177 | public int OriginalIndex { get; set; } 178 | public int ListId { get; set; } 179 | public string Term { get; set; } 180 | } 181 | 182 | } 183 | -------------------------------------------------------------------------------- /resources/code-azure-function/CognitiveSkill/WebApiSkill/WebAPISkillContract.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Microsoft.CognitiveSearch.WebApiSkills 4 | { 5 | public class WebApiSkillRequest 6 | { 7 | public List Values { get; set; } = new List(); 8 | } 9 | 10 | public class WebApiSkillResponse 11 | { 12 | public List Values { get; set; } = new List(); 13 | } 14 | 15 | public class WebApiRequestRecord 16 | { 17 | public string RecordId { get; set; } 18 | public Dictionary Data { get; set; } = new Dictionary(); 19 | } 20 | 21 | public class WebApiResponseRecord 22 | { 23 | public string RecordId { get; set; } 24 | public Dictionary Data { get; set; } = new Dictionary(); 25 | public List Errors { get; set; } = new List(); 26 | public List Warnings { get; set; } = new List(); 27 | } 28 | 29 | public class WebApiErrorWarningContract 30 | { 31 | public string Message { get; set; } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /resources/code-azure-function/CognitiveSkill/WebApiSkill/WebApiSkillHelpers.cs: -------------------------------------------------------------------------------- 1 |  2 | using Newtonsoft.Json; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.IO; 6 | using System.Net.Http; 7 | using System.Threading.Tasks; 8 | 9 | namespace Microsoft.CognitiveSearch.WebApiSkills 10 | { 11 | static class WebApiSkillHelpers 12 | { 13 | public static IEnumerable GetRequestRecords(HttpRequestMessage req) 14 | { 15 | string jsonRequest = req.Content.ReadAsStringAsync().Result; 16 | WebApiSkillRequest docs = JsonConvert.DeserializeObject(jsonRequest); 17 | return docs.Values; 18 | } 19 | 20 | public static WebApiSkillResponse ProcessRequestRecords(string functionName, IEnumerable requestRecords, Func processRecord) 21 | { 22 | WebApiSkillResponse response = new WebApiSkillResponse(); 23 | 24 | foreach (WebApiRequestRecord inRecord in requestRecords) 25 | { 26 | WebApiResponseRecord outRecord = new WebApiResponseRecord() { RecordId = inRecord.RecordId }; 27 | 28 | try 29 | { 30 | outRecord = processRecord(inRecord, outRecord); 31 | } 32 | catch (Exception e) 33 | { 34 | outRecord.Errors.Add(new WebApiErrorWarningContract() { Message = $"{functionName} - Error processing the request record : {e.ToString() }" }); 35 | } 36 | response.Values.Add(outRecord); 37 | } 38 | 39 | return response; 40 | } 41 | 42 | public static async Task ProcessRequestRecordsAsync(string functionName, IEnumerable requestRecords, Func> processRecord) 43 | { 44 | WebApiSkillResponse response = new WebApiSkillResponse(); 45 | 46 | foreach (WebApiRequestRecord inRecord in requestRecords) 47 | { 48 | WebApiResponseRecord outRecord = new WebApiResponseRecord() { RecordId = inRecord.RecordId }; 49 | 50 | try 51 | { 52 | outRecord = await processRecord(inRecord, outRecord); 53 | } 54 | catch (Exception e) 55 | { 56 | outRecord.Errors.Add(new WebApiErrorWarningContract() { Message = $"{functionName} - Error processing the request record : {e.ToString() }" }); 57 | } 58 | response.Values.Add(outRecord); 59 | } 60 | 61 | return response; 62 | } 63 | 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /resources/code-azure-function/CognitiveSkill/host.json: -------------------------------------------------------------------------------- 1 | { 2 | } -------------------------------------------------------------------------------- /resources/code-azure-function/README.md: -------------------------------------------------------------------------------- 1 | # AzureCognitiveSkill 2 | 3 | A sample Azure Function implementation of a Cognitive Skill in C#. Calls the content moderator cognitive service and returns a boolean informing if the text has **Personal Indetifiable Information**. 4 | 5 | Search for the **TO-DO** sections, where you will edit the code to add your Content moderator API credentials. 6 | -------------------------------------------------------------------------------- /resources/code-bot/.deployment: -------------------------------------------------------------------------------- 1 | [config] 2 | command = deploy.cmd -------------------------------------------------------------------------------- /resources/code-bot/.gitignore: -------------------------------------------------------------------------------- 1 | *.dll 2 | *.pdb -------------------------------------------------------------------------------- /resources/code-bot/BotAccessors.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using Microsoft.Bot.Builder; 6 | using Microsoft.Bot.Builder.Dialogs; 7 | 8 | namespace Microsoft.CognitiveSearchBot 9 | { 10 | /// 11 | /// This class is created as a Singleton and passed into the IBot-derived constructor. 12 | /// - See constructor for how that is injected. 13 | /// - See the Startup.cs file for more details on creating the Singleton that gets 14 | /// injected into the constructor. 15 | /// 16 | public class BotAccessors 17 | { 18 | /// 19 | /// Initializes a new instance of the class. 20 | /// Contains the and associated . 21 | /// 22 | /// The state object that stores the counter. 23 | public BotAccessors(ConversationState conversationState) 24 | { 25 | ConversationState = conversationState ?? throw new ArgumentNullException(nameof(conversationState)); 26 | } 27 | 28 | /// 29 | /// Gets the name used for the accessor. 30 | /// 31 | /// Accessors require a unique name. 32 | /// The accessor name for the counter accessor. 33 | public static string BotStateName { get; } = $"{nameof(BotAccessors)}.BotState"; 34 | 35 | /// 36 | /// Gets or sets the for CounterState. 37 | /// 38 | /// 39 | /// The accessor stores the turn count for the conversation. 40 | /// 41 | public IStatePropertyAccessor BotState { get; set; } 42 | 43 | /// 44 | /// Gets the object for the conversation. 45 | /// 46 | /// The object. 47 | public ConversationState ConversationState { get; } 48 | 49 | /// Gets the IStatePropertyAccessor{T} name used for the DialogState accessor. 50 | public static string DialogStateName { get; } = $"{nameof(BotAccessors)}.DialogState"; 51 | 52 | /// Gets or sets the IStatePropertyAccessor{T} for DialogState. 53 | public IStatePropertyAccessor DialogStateAccessor { get; set; } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /resources/code-bot/BotConfiguration.bot: -------------------------------------------------------------------------------- 1 | { 2 | "name": "CognitiveSearchBot", 3 | "services": [ 4 | { 5 | "type": "endpoint", 6 | "name": "development", 7 | "endpoint": "http://localhost:3978/api/messages", 8 | "appId": "", 9 | "appPassword": "", 10 | "id": "1" 11 | } 12 | ], 13 | "padlock": "", 14 | "version": "2.0" 15 | } -------------------------------------------------------------------------------- /resources/code-bot/BotState.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | namespace Microsoft.CognitiveSearchBot 5 | { 6 | /// 7 | /// Stores counter state for the conversation. 8 | /// Stored in and 9 | /// backed by . 10 | /// 11 | public class BotState 12 | { 13 | /// 14 | /// Gets or sets the number of turns in the conversation. 15 | /// 16 | /// The number of turns in the conversation. 17 | public string Greeted { get; set; } = "not greeted"; 18 | public string Search { get; set; } = ""; 19 | public string Searching { get; set; } = "no"; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /resources/code-bot/CognitiveSearchBot.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using CognitiveSearchBot.Dialogs; 5 | using Microsoft.Bot.Builder; 6 | using Microsoft.Bot.Builder.Dialogs; 7 | using Microsoft.Extensions.Logging; 8 | using System.Threading; 9 | using System.Threading.Tasks; 10 | 11 | namespace Microsoft.CognitiveSearchBot 12 | { 13 | /******************************************************************************** 14 | * replace "YourSearchServiceName", "YourSearchServiceKey", and "YourIndexName" * 15 | * with your search service values in Constants.cs * 16 | ********************************************************************************/ 17 | 18 | /// 19 | /// Represents a bot that processes incoming activities. 20 | /// For each user interaction, an instance of this class is created and the OnTurnAsync method is called. 21 | /// This is a Transient lifetime service. Transient lifetime services are created 22 | /// each time they're requested. For each Activity received, a new instance of this 23 | /// class is created. Objects that are expensive to construct, or have a lifetime 24 | /// beyond the single turn, should be carefully managed. 25 | /// For example, the object and associated 26 | /// object are created with a singleton lifetime. 27 | /// 28 | /// 29 | /// Contains the set of dialogs and prompts for the cognitive search bot. 30 | public class CognitiveSearchBot : IBot 31 | { 32 | private readonly BotAccessors _accessors; 33 | private readonly ILogger _logger; 34 | private DialogSet _dialogs; 35 | 36 | /// 37 | /// Every conversation turn for our CognitiveSearchBot will call this method. 38 | /// There are no dialogs used, since it's "single turn" processing, meaning a single 39 | /// request and response. Later, when we add Dialogs, we'll have to navigate through this method. 40 | /// 41 | /// A containing all the data needed 42 | /// for processing this conversation turn. 43 | /// (Optional) A that can be used by other objects 44 | /// or threads to receive notice of cancellation. 45 | /// A that represents the work queued to execute. 46 | /// 47 | /// 48 | /// 49 | public async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken)) 50 | { 51 | if (turnContext.Activity.Type is "message") 52 | { 53 | // Establish dialog context from the conversation state. 54 | var dc = await _dialogs.CreateContextAsync(turnContext); 55 | // Continue any current dialog. 56 | var results = await dc.ContinueDialogAsync(cancellationToken); 57 | 58 | // Every turn sends a response, so if no response was sent, 59 | // then there no dialog is currently active. 60 | if (!turnContext.Responded) 61 | { 62 | // Start the main dialog 63 | await dc.BeginDialogAsync("mainDialog", null, cancellationToken); 64 | } 65 | } 66 | } 67 | /// 68 | /// Initializes a new instance of the class. 69 | /// 70 | /// A class containing used to manage state. 71 | /// A that is hooked to the Azure App Service provider. 72 | /// 73 | public CognitiveSearchBot(BotAccessors accessors, ILoggerFactory loggerFactory) 74 | { 75 | if (loggerFactory == null) 76 | { 77 | throw new System.ArgumentNullException(nameof(loggerFactory)); 78 | } 79 | // These lines are something you don't ned to worry about. 80 | // We're basically setting up loggin potential and the accessors needed to access dialogs 81 | _logger = loggerFactory.CreateLogger(); 82 | _logger.LogTrace("CognitiveSearchBot turn start."); 83 | _accessors = accessors ?? throw new System.ArgumentNullException(nameof(accessors)); 84 | _dialogs = new DialogSet(_accessors.DialogStateAccessor); 85 | 86 | // Add named dialogs to the DialogSet. These names are saved in the dialog state. 87 | _dialogs.Add(new MainDialog(_accessors).Build()); 88 | _dialogs.Add(new SearchDialog(_accessors).Build()); 89 | _dialogs.Add(new ModeratedContentSearchDialog(_accessors).Build()); 90 | // The following line allows us to use a prompt within the dialogs 91 | _dialogs.Add(new TextPrompt("searchPrompt")); 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /resources/code-bot/CognitiveSearchBot.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.0 5 | EchoBotWithCounter.ruleset 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /resources/code-bot/CognitiveSearchBot.runtimeconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "runtimeOptions": { 3 | "tfm": "netcoreapp2.0", 4 | "framework": { 5 | "name": "Microsoft.NETCore.App", 6 | "version": "2.0.0" 7 | }, 8 | "configProperties": { 9 | "System.GC.Server": true 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /resources/code-bot/CognitiveSearchBot.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 12.00 2 | # Visual Studio 15 3 | VisualStudioVersion = 15.0.27428.2043 4 | MinimumVisualStudioVersion = 10.0.40219.1 5 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CognitiveSearchBot", "CognitiveSearchBot.csproj", "{FDE8B63A-F28A-4A08-ACD9-6F45015F1848}" 6 | EndProject 7 | Global 8 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 9 | Debug|Any CPU = Debug|Any CPU 10 | Release|Any CPU = Release|Any CPU 11 | EndGlobalSection 12 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 13 | {FDE8B63A-F28A-4A08-ACD9-6F45015F1848}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 14 | {FDE8B63A-F28A-4A08-ACD9-6F45015F1848}.Debug|Any CPU.Build.0 = Debug|Any CPU 15 | {FDE8B63A-F28A-4A08-ACD9-6F45015F1848}.Release|Any CPU.ActiveCfg = Release|Any CPU 16 | {FDE8B63A-F28A-4A08-ACD9-6F45015F1848}.Release|Any CPU.Build.0 = Release|Any CPU 17 | EndGlobalSection 18 | GlobalSection(SolutionProperties) = preSolution 19 | HideSolutionNode = FALSE 20 | EndGlobalSection 21 | GlobalSection(ExtensibilityGlobals) = postSolution 22 | SolutionGuid = {4F447F19-6AA1-449F-A8CA-632F2AB9D062} 23 | EndGlobalSection 24 | EndGlobal 25 | -------------------------------------------------------------------------------- /resources/code-bot/Constants.cs: -------------------------------------------------------------------------------- 1 | // Recognition and appreciation 2 | // This bot was develop in partnership with Pragmatismo Consulting: General Bots open-core - https://github.com/pragmatismo-io/BotServer 3 | // This bot also was also created with support from David Ruhlemann from Tallan inc. 4 | 5 | 6 | 7 | namespace CognitiveSearchBot 8 | { 9 | public static class Constants 10 | { 11 | // replace "Your-Azure-Search-Service-Name", "Your-Azure-Search-Service-key", and "Your-Azure-Search-Index-name" with your Azure search service values 12 | public static string SearchServiceName = "Your-Azure-Search-Service-Name"; 13 | public static string SearchServiceApiKey = "Your-Azue-Search-Service-Key"; 14 | public static string TargetIndexName = "Your-Azure-Search-Index-name"; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /resources/code-bot/Dialogs/MainDialog.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Bot.Builder.Dialogs; 2 | using Microsoft.CognitiveSearchBot; 3 | using Responses; 4 | using System.Threading; 5 | using System.Threading.Tasks; 6 | 7 | namespace CognitiveSearchBot.Dialogs 8 | { 9 | public class MainDialog 10 | { 11 | private readonly BotAccessors _accessors; 12 | public static string DialogName = "mainDialog"; 13 | public MainDialog(BotAccessors botAccessors) 14 | { 15 | _accessors = botAccessors; 16 | } 17 | 18 | public WaterfallDialog Build() 19 | { 20 | return new WaterfallDialog(DialogName, new WaterfallStep[] { GreetingAsync, MainMenuAsync }); 21 | } 22 | private async Task GreetingAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken) 23 | { 24 | // Get the state for the current step in the conversation 25 | var state = await _accessors.BotState.GetAsync(stepContext.Context, () => new BotState()); 26 | 27 | // If we haven't greeted the user 28 | if (state.Greeted == "not greeted") 29 | { 30 | // Greet the user 31 | await MainResponses.ReplyWithGreeting(stepContext.Context); 32 | // Update the GreetedState to greeted 33 | state.Greeted = "greeted"; 34 | // Save the new greeted state into the conversation state 35 | // This is to ensure in future turns we do not greet the user again 36 | await _accessors.ConversationState.SaveChangesAsync(stepContext.Context); 37 | // Ask the user what they want to do next 38 | await MainResponses.ReplyWithHelp(stepContext.Context); 39 | // Since we aren't explicitly prompting the user in this step, we'll end the dialog 40 | // When the user replies, since state is maintained, the else clause will move them 41 | // to the next waterfall step 42 | return await stepContext.EndDialogAsync(); 43 | } 44 | else // We've already greeted the user 45 | { 46 | // Move to the next waterfall step, which is MainMenuAsync 47 | return await stepContext.NextAsync(); 48 | } 49 | } 50 | 51 | // This step routes the user to different dialogs 52 | // In this case, there's only one other dialog, so it is more simple, 53 | // but in more complex scenarios you can go off to other dialogs in a similar 54 | public async Task MainMenuAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken) 55 | { 56 | // Check if we are currently processing a user's search 57 | var state = await _accessors.BotState.GetAsync(stepContext.Context); 58 | 59 | // If Regex picks up on anything, store it 60 | var recognizedIntents = stepContext.Context.TurnState.Get(); 61 | // Based on the recognized intent, direct the conversation 62 | switch (recognizedIntents.TopIntent?.Name) 63 | { 64 | case "search": 65 | // switch to the search dialog 66 | return await stepContext.BeginDialogAsync(SearchDialog.DialogName, null, cancellationToken); 67 | case "help": 68 | // show help 69 | await MainResponses.ReplyWithHelp(stepContext.Context); 70 | return await stepContext.EndDialogAsync(); 71 | case "moderated-content": 72 | return await stepContext.BeginDialogAsync(ModeratedContentSearchDialog.DialogName, null, cancellationToken); 73 | default: 74 | { 75 | await MainResponses.ReplyWithConfused(stepContext.Context); 76 | return await stepContext.EndDialogAsync(); 77 | } 78 | } 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /resources/code-bot/Dialogs/ModeratedContentSearchDialog.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Bot.Builder.Dialogs; 2 | using Microsoft.CognitiveSearchBot; 3 | using Responses; 4 | using System.Threading; 5 | using System.Threading.Tasks; 6 | 7 | namespace CognitiveSearchBot.Dialogs 8 | { 9 | public class ModeratedContentSearchDialog : SearchDialogBase 10 | { 11 | private readonly BotAccessors _accessors; 12 | public static string DialogName = "moderatedContentSearchDialog"; 13 | public ModeratedContentSearchDialog(BotAccessors botAccessors) 14 | { 15 | _accessors = botAccessors; 16 | } 17 | 18 | public WaterfallDialog Build() 19 | { 20 | return new WaterfallDialog(DialogName, new WaterfallStep[] { SearchForModeratedContentRequestAsync }); 21 | } 22 | private async Task SearchForModeratedContentRequestAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken) 23 | { 24 | await SearchResponses.ReplyWithSearchForModeratedContentConfirmation(stepContext.Context); 25 | 26 | await ExecuteSearchAsync(stepContext.Context, "*", "needsModeration eq true"); 27 | return await stepContext.EndDialogAsync(); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /resources/code-bot/Dialogs/SearchDialog.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Bot.Builder; 2 | using Microsoft.Bot.Builder.Dialogs; 3 | using Microsoft.CognitiveSearchBot; 4 | using Responses; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | 8 | namespace CognitiveSearchBot.Dialogs 9 | { 10 | public class SearchDialog : SearchDialogBase 11 | { 12 | private readonly BotAccessors _accessors; 13 | public static string DialogName = "searchDialog"; 14 | public SearchDialog(BotAccessors botAccessors) 15 | { 16 | _accessors = botAccessors; 17 | } 18 | 19 | public WaterfallDialog Build() 20 | { 21 | return new WaterfallDialog(DialogName, new WaterfallStep[] { SearchRequestAsync, SearchAsync }); 22 | } 23 | private async Task SearchRequestAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken) 24 | { 25 | // Check if a user has already started searching, and if you know what to search for 26 | var state = await _accessors.BotState.GetAsync(stepContext.Context); 27 | 28 | // If they're just starting to search for photos 29 | if (state.Searching == "no") 30 | { 31 | // Update the searching state 32 | state.Searching = "yes"; 33 | // Save the new state into the conversation state. 34 | await _accessors.ConversationState.SaveChangesAsync(stepContext.Context); 35 | // Prompt the user for what they want to search for. 36 | // Instead of using SearchResponses.ReplyWithSearchRequest, 37 | // we're experimenting with using text prompts 38 | return await stepContext.PromptAsync("searchPrompt", new PromptOptions { Prompt = MessageFactory.Text("What would you like to search for?") }, cancellationToken); 39 | } 40 | else // This means they just told us what they want to search for 41 | // Go to the next step in the dialog, which is "SearchAsync" 42 | return await stepContext.NextAsync(); 43 | } 44 | private async Task SearchAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken) 45 | { 46 | // Add state so we can update it throughout the turn 47 | var state = await _accessors.BotState.GetAsync(stepContext.Context); 48 | // If we haven't stored what they want to search for 49 | if (state.Search == "") 50 | { 51 | // Store it and update the ConversationState 52 | state.Search = (string)stepContext.Result; 53 | await _accessors.ConversationState.SaveChangesAsync(stepContext.Context); 54 | } 55 | var searchText = state.Search; 56 | // Confirm with the user what you're searching for 57 | await SearchResponses.ReplyWithSearchConfirmation(stepContext.Context, searchText); 58 | // Process the search request and send the results to the user 59 | await ExecuteSearchAsync(stepContext.Context, searchText); 60 | 61 | // Clear out Search or future searches, set the searching state to no, 62 | // update the conversation state 63 | state.Search = ""; 64 | state.Searching = "no"; 65 | await _accessors.ConversationState.SaveChangesAsync(stepContext.Context); 66 | 67 | return await stepContext.EndDialogAsync(); 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /resources/code-bot/Dialogs/SearchDialogBase.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Azure.Search; 2 | using Microsoft.Azure.Search.Models; 3 | using Microsoft.Bot.Builder; 4 | using Microsoft.Bot.Schema; 5 | using Models; 6 | using Responses; 7 | using System.Linq; 8 | using System.Threading.Tasks; 9 | 10 | namespace CognitiveSearchBot.Dialogs 11 | { 12 | public class SearchDialogBase 13 | { 14 | // Add search related tasks 15 | // These tasks will actually configure the client and connection to your 16 | // specific index. We'll call the service with the searchText, and process 17 | // the results in a way that looks nice in a bot 18 | public async Task ExecuteSearchAsync(ITurnContext context, string searchText, string filter = "") 19 | { 20 | ISearchIndexClient indexClientForQueries = CreateSearchIndexClient(); 21 | // For more examples of calling search with SearchParameters, see 22 | // https://github.com/Azure-Samples/search-dotnet-getting-started/blob/master/DotNetHowTo/DotNetHowTo/Program.cs. 23 | // Call the search service and store the results 24 | DocumentSearchResult results = await indexClientForQueries.Documents.SearchAsync(searchText, new SearchParameters { Filter = filter }); 25 | await SendResultsAsync(context, searchText, results); 26 | } 27 | 28 | public async Task SendResultsAsync(ITurnContext context, string searchText, DocumentSearchResult results) 29 | { 30 | IMessageActivity activity = context.Activity.CreateReply(); 31 | // if the search returns no results 32 | if (results.Results.Count == 0) 33 | { 34 | await SearchResponses.ReplyWithNoResults(context, searchText); 35 | } 36 | else // this means there was at least one hit for the search 37 | { 38 | // create the response with the result(s) and send to the user 39 | // the response is formatted with the files within the Models folder 40 | SearchHitStyler searchHitStyler = new SearchHitStyler(); 41 | searchHitStyler.Apply( 42 | ref activity, 43 | "Here are the results that I found:", 44 | results.Results.Select(r => ImageMapper.ToSearchHit(r)).ToList().AsReadOnly()); 45 | // send the response to the user 46 | await context.SendActivityAsync(activity); 47 | } 48 | } 49 | public ISearchIndexClient CreateSearchIndexClient() 50 | { 51 | // Configure the search service and establish a connection, call it in StartAsync() 52 | return new SearchIndexClient(Constants.SearchServiceName, Constants.TargetIndexName, new SearchCredentials(Constants.SearchServiceApiKey)); ; 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /resources/code-bot/Middleware/EntityRecognizers.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using Newtonsoft.Json; 5 | 6 | namespace Microsoft.CognitiveSearchBot 7 | { 8 | public class Entity 9 | { 10 | public string GroupName { get; set; } 11 | public double Score { get; set; } 12 | 13 | public object Value { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /resources/code-bot/Middleware/IntentRecognizerMiddleware.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Threading; 7 | using System.Threading.Tasks; 8 | using Microsoft.Bot.Builder; 9 | 10 | namespace Microsoft.CognitiveSearchBot 11 | { 12 | public interface IRecognizedIntents 13 | { 14 | Intent TopIntent { get; set; } 15 | IList Intents { get; set; } 16 | } 17 | public class IntentRecognition : IRecognizedIntents 18 | { 19 | public IntentRecognition() 20 | { 21 | } 22 | 23 | public Intent TopIntent { get; set; } 24 | public IList Intents { get; set; } = new Intent[0]; 25 | } 26 | 27 | public class Intent 28 | { 29 | public string Name { get; set; } 30 | public double Score { get; set; } 31 | 32 | public IList Entities { get; } = new List(); 33 | } 34 | 35 | 36 | public class IntentRecognizerMiddleware : IMiddleware 37 | { 38 | public delegate Task IntentDisabler(ITurnContext context); 39 | public delegate Task> IntentRecognizer(ITurnContext context); 40 | public delegate Task IntentResultMutator(ITurnContext context, IList intents); 41 | 42 | private readonly LinkedList _intentDisablers = new LinkedList(); 43 | private readonly LinkedList _intentRecognizers = new LinkedList(); 44 | private readonly LinkedList _intentResultMutators = new LinkedList(); 45 | 46 | /// 47 | /// method for accessing recognized intents added by middleware to context 48 | /// 49 | /// 50 | /// 51 | public static IRecognizedIntents Get(ITurnContext context) { return context.TurnState.Get(); } 52 | 53 | public async Task OnTurnAsync(ITurnContext context, NextDelegate nextTurn, CancellationToken cancellationToken) 54 | { 55 | BotAssert.ContextNotNull(context); 56 | 57 | var intents = await this.Recognize(context); 58 | var result = new IntentRecognition(); 59 | if (intents.Count != 0) 60 | { 61 | result.Intents = intents; 62 | var topIntent = FindTopIntent(intents); 63 | if (topIntent.Score > 0.0) 64 | { 65 | result.TopIntent = topIntent; 66 | } 67 | } 68 | context.TurnState.Add((IRecognizedIntents)result); 69 | await nextTurn(cancellationToken).ConfigureAwait(false); 70 | } 71 | 72 | public async Task> Recognize(ITurnContext context) 73 | { 74 | BotAssert.ContextNotNull(context); 75 | 76 | bool isEnabled = await IsRecognizerEnabled(context).ConfigureAwait(false); 77 | if (isEnabled) 78 | { 79 | var allRecognizedIntents = await RunRecognizer(context).ConfigureAwait(false); 80 | await RunFilters(context, allRecognizedIntents); 81 | return allRecognizedIntents; 82 | } 83 | else 84 | { 85 | return new List(); 86 | } 87 | } 88 | 89 | private async Task> RunRecognizer(ITurnContext context) 90 | { 91 | List allRecognizedIntents = new List(); 92 | 93 | foreach (var recognizer in _intentRecognizers) 94 | { 95 | IList intents = await recognizer(context).ConfigureAwait(false); 96 | if (intents != null && intents.Count > 0) 97 | { 98 | allRecognizedIntents.AddRange(intents); 99 | } 100 | } 101 | 102 | return allRecognizedIntents; 103 | } 104 | 105 | private async Task IsRecognizerEnabled(ITurnContext context) 106 | { 107 | foreach (var userCode in _intentDisablers) 108 | { 109 | bool isEnabled = await userCode(context).ConfigureAwait(false); 110 | if (isEnabled == false) 111 | { 112 | return false; 113 | } 114 | } 115 | 116 | return true; 117 | } 118 | 119 | private async Task RunFilters(ITurnContext context, IList intents) 120 | { 121 | foreach (var filter in _intentResultMutators) 122 | { 123 | await filter(context, intents); 124 | } 125 | } 126 | 127 | /// 128 | /// An IntentDisabler that's registered here will fire BEFORE the intent recognizer code 129 | /// is run, and will have the oppertunity to prevent the recognizer from running. 130 | /// 131 | /// As soon as one function returns 'Do Not Run' no further methods will be called. 132 | /// 133 | /// Enabled/Disabled methods that are registered are run in the order registered. 134 | /// 135 | public IntentRecognizerMiddleware OnEnabled(IntentDisabler preCondition) 136 | { 137 | if (preCondition == null) 138 | throw new ArgumentNullException(nameof(preCondition)); 139 | 140 | _intentDisablers.AddLast(preCondition); 141 | 142 | return this; 143 | } 144 | 145 | /// 146 | /// Recognizer methods are run in the ordered registered. 147 | /// 148 | public IntentRecognizerMiddleware OnRecognize(IntentRecognizer recognizer) 149 | { 150 | if (recognizer == null) 151 | throw new ArgumentNullException(nameof(recognizer)); 152 | 153 | _intentRecognizers.AddLast(recognizer); 154 | 155 | return this; 156 | } 157 | 158 | /// 159 | /// Filter method are run in REVERSE order registered. That is, they are run from "last -> first". 160 | /// 161 | public IntentRecognizerMiddleware OnFilter(IntentResultMutator postCondition) 162 | { 163 | if (postCondition == null) 164 | throw new ArgumentNullException(nameof(postCondition)); 165 | 166 | _intentResultMutators.AddFirst(postCondition); 167 | 168 | return this; 169 | } 170 | 171 | public static Intent FindTopIntent(IList intents) 172 | { 173 | if (intents == null) 174 | throw new ArgumentNullException(nameof(intents)); 175 | 176 | var enumerator = intents.GetEnumerator(); 177 | if (!enumerator.MoveNext()) 178 | throw new ArgumentException($"No Intents on '{nameof(intents)}'"); 179 | 180 | var topIntent = enumerator.Current; 181 | var topScore = topIntent.Score; 182 | 183 | while (enumerator.MoveNext()) 184 | { 185 | var currVal = enumerator.Current.Score; 186 | 187 | if (currVal.CompareTo(topScore) > 0) 188 | { 189 | topScore = currVal; 190 | topIntent = enumerator.Current; 191 | } 192 | } 193 | return topIntent; 194 | } 195 | public static string CleanString(string s) 196 | { 197 | return string.IsNullOrWhiteSpace(s) ? string.Empty : s.Trim(); 198 | } 199 | 200 | } 201 | } -------------------------------------------------------------------------------- /resources/code-bot/Middleware/RegExpRecognizerMiddleware.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Text.RegularExpressions; 7 | using Microsoft.Bot.Builder; 8 | 9 | namespace Microsoft.CognitiveSearchBot 10 | { 11 | public class RegExpRecognizerSettings 12 | { 13 | /// 14 | /// Minimum score, on a scale from 0.0 to 1.0, that should be returned for a matched 15 | /// expression.This defaults to a value of 0.0. 16 | /// 17 | public double MinScore { get; set; } = 0.0; 18 | } 19 | 20 | public class RegExLocaleMap 21 | { 22 | private Dictionary> _map = new Dictionary>(); 23 | private const string Default_Key = "*"; 24 | 25 | public RegExLocaleMap() 26 | { 27 | } 28 | 29 | public RegExLocaleMap(List items) 30 | { 31 | _map[Default_Key] = items; 32 | } 33 | 34 | public List GetLocale(string locale) 35 | { 36 | if (_map.ContainsKey(locale)) 37 | return _map[locale]; 38 | else if (_map.ContainsKey(Default_Key)) 39 | return _map[Default_Key]; 40 | else 41 | return new List(); 42 | } 43 | 44 | public Dictionary> Map 45 | { 46 | get { return _map; } 47 | } 48 | 49 | } 50 | 51 | public class RegExpRecognizerMiddleware : IntentRecognizerMiddleware 52 | { 53 | private RegExpRecognizerSettings _settings; 54 | private Dictionary _intents = new Dictionary(); 55 | public const string DefaultEntityType = "string"; 56 | 57 | public RegExpRecognizerMiddleware() : this(new RegExpRecognizerSettings() { MinScore = 0.0 }) 58 | { 59 | } 60 | 61 | public RegExpRecognizerMiddleware(RegExpRecognizerSettings settings) 62 | { 63 | _settings = settings ?? throw new ArgumentNullException("settings"); 64 | if (_settings.MinScore < 0 || _settings.MinScore > 1.0) 65 | { 66 | throw new ArgumentException($"RegExpRecognizerMiddleware: a minScore of {_settings.MinScore} is out of range."); 67 | } 68 | 69 | this.OnRecognize(async (context) => 70 | { 71 | IList intents = new List(); 72 | string utterance = CleanString(context.Activity.Text); 73 | double minScore = _settings.MinScore; 74 | 75 | foreach (var name in _intents.Keys) 76 | { 77 | var map = _intents[name]; 78 | List expressions = GetExpressions(context, map); 79 | Intent top = null; 80 | foreach (Regex exp in expressions) 81 | { 82 | List entityTypes = new List(); 83 | Intent intent = Recognize(utterance, exp, entityTypes, minScore); 84 | if (intent != null) 85 | { 86 | if (top == null) 87 | { 88 | top = intent; 89 | } 90 | else if (intent.Score > top.Score) 91 | { 92 | top = intent; 93 | } 94 | } 95 | 96 | if (top != null) 97 | { 98 | top.Name = name; 99 | intents.Add(top); 100 | } 101 | } 102 | } 103 | return intents; 104 | }); 105 | } 106 | 107 | public RegExpRecognizerMiddleware AddIntent(string intentName, Regex regex) 108 | { 109 | if (regex == null) 110 | throw new ArgumentNullException("regex"); 111 | 112 | return AddIntent(intentName, new List { regex }); 113 | } 114 | public RegExpRecognizerMiddleware AddIntent(string intentName, List regexList) 115 | { 116 | if (regexList == null) 117 | throw new ArgumentNullException("regexList"); 118 | 119 | return AddIntent(intentName, new RegExLocaleMap(regexList)); 120 | } 121 | 122 | public RegExpRecognizerMiddleware AddIntent(string intentName, RegExLocaleMap map) 123 | { 124 | if (string.IsNullOrWhiteSpace(intentName)) 125 | throw new ArgumentNullException("intentName"); 126 | 127 | if (_intents.ContainsKey(intentName)) 128 | throw new ArgumentException($"RegExpRecognizer: an intent name '{intentName}' already exists."); 129 | 130 | _intents[intentName] = map; 131 | 132 | return this; 133 | } 134 | private List GetExpressions(ITurnContext context, RegExLocaleMap map) 135 | { 136 | 137 | var locale = string.IsNullOrWhiteSpace(context.Activity.Locale) ? "*" : context.Activity.Locale; 138 | var entry = map.GetLocale(locale); 139 | return entry; 140 | } 141 | 142 | public static Intent Recognize(string text, Regex expression, double minScore) 143 | { 144 | return Recognize(text, expression, new List(), minScore); 145 | } 146 | public static Intent Recognize(string text, Regex expression, List entityTypes, double minScore) 147 | { 148 | // Note: Not throwing here, as users enter whitespace all the time. 149 | if (string.IsNullOrWhiteSpace(text)) 150 | return null; 151 | 152 | if (expression == null) 153 | throw new ArgumentNullException("expression"); 154 | 155 | if (entityTypes == null) 156 | throw new ArgumentNullException("entity Types"); 157 | 158 | if (minScore < 0 || minScore > 1.0) 159 | throw new ArgumentOutOfRangeException($"RegExpRecognizer: a minScore of '{minScore}' is out of range for expression '{expression.ToString()}'"); 160 | 161 | var match = expression.Match(text); 162 | //var matches = expression.Matches(text); 163 | if (match.Success) 164 | { 165 | double coverage = (double)match.Length / (double)text.Length; 166 | double score = minScore + ((1.0 - minScore) * coverage); 167 | 168 | Intent intent = new Intent() 169 | { 170 | Name = expression.ToString(), 171 | Score = score 172 | }; 173 | 174 | for (int i = 0; i < match.Groups.Count; i++) 175 | { 176 | if (i == 0) 177 | continue; // First one is always the entire capture, so just skip 178 | 179 | string groupName = DefaultEntityType; 180 | if (entityTypes.Count > 0) 181 | { 182 | // If the dev passed in group names, use them. 183 | groupName = (i - 1) < entityTypes.Count ? entityTypes[i - 1] : DefaultEntityType; 184 | } 185 | else 186 | { 187 | groupName = expression.GroupNameFromNumber(i); 188 | if (string.IsNullOrEmpty(groupName)) 189 | { 190 | groupName = DefaultEntityType; 191 | } 192 | } 193 | 194 | Group g = match.Groups[i]; 195 | if (g.Success) 196 | { 197 | Entity newEntity = new Entity() 198 | { 199 | GroupName = groupName, 200 | Score = 1.0, 201 | Value = match.Groups[i].Value 202 | }; 203 | intent.Entities.Add(newEntity); 204 | } 205 | } 206 | 207 | return intent; 208 | } 209 | 210 | return null; 211 | } 212 | } 213 | } 214 | -------------------------------------------------------------------------------- /resources/code-bot/Models/ImageMapper.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Azure.Search.Models; 2 | using System.Linq; 3 | 4 | namespace Models 5 | { 6 | public class ImageMapper 7 | { 8 | public static SearchHit ToSearchHit(SearchResult hit) 9 | { 10 | var searchHit = new SearchHit(); 11 | // Retrieves fields from Cognitive Search. 12 | hit.Document.ToList().ForEach(x => searchHit.PropertyBag.Add(x.Key, x.Value)); 13 | 14 | //var description = "𝐂𝐨𝐠𝐧𝐢𝐭𝐢𝐯𝐞 𝐊𝐞𝐲 𝐏𝐡𝐫𝐚𝐬𝐞𝐬: " + 15 | // System.Environment.NewLine + 16 | // keyPhrases + 17 | // System.Environment.NewLine + 18 | // "𝐎𝐫𝐠𝐚𝐧𝐢𝐳𝐚𝐭𝐢𝐨𝐧𝐬 𝐈𝐝𝐞𝐧𝐭𝐢𝐟𝐢𝐞𝐝: " + 19 | // System.Environment.NewLine + 20 | // organizations + 21 | // System.Environment.NewLine 22 | // ; 23 | 24 | return searchHit; 25 | } 26 | 27 | } 28 | } -------------------------------------------------------------------------------- /resources/code-bot/Models/SearchHit.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using System.Text; 4 | 5 | namespace Models 6 | { 7 | public class SearchHit 8 | { 9 | public SearchHit() 10 | { 11 | this.PropertyBag = new Dictionary(); 12 | } 13 | public string Title { get; set; } 14 | public string DocumentUrl 15 | { 16 | get 17 | { 18 | object blobUri = string.Empty; 19 | return PropertyBag.TryGetValue("blob_uri", out blobUri) ? blobUri.ToString() : string.Empty; 20 | } 21 | } 22 | public string FileName 23 | { 24 | get 25 | { 26 | return !string.IsNullOrWhiteSpace(DocumentUrl) ? DocumentUrl.Split('/').Last() : string.Empty; 27 | } 28 | } 29 | public bool ShouldBeModerated 30 | { 31 | get 32 | { 33 | object result = string.Empty; 34 | var results = PropertyBag.TryGetValue("needsModeration", out result); 35 | return bool.Parse(result.ToString()); 36 | } 37 | } 38 | 39 | public string Description 40 | { 41 | get 42 | { 43 | StringBuilder sb = new StringBuilder(); 44 | if (!IsImage) 45 | { 46 | ComposeDetail(sb, "content", (ShouldBeModerated ? "Content Preview - Contains PII Data" : "Content Preview")); 47 | } 48 | ComposeArrayDetail(sb, "keyPhrases", "Key Phrases"); 49 | ComposeArrayDetail(sb, "organizations", "Organizations"); 50 | ComposeArrayDetail(sb, "myOcrText", "OCR Text"); 51 | return sb.ToString(); 52 | } 53 | } 54 | 55 | private void ComposeArrayDetail(StringBuilder sb, string dictionaryEntryName, string displayHeading) 56 | { 57 | object items = string.Empty; 58 | var results = PropertyBag.TryGetValue(dictionaryEntryName, out items) && (items as string[]).Count() > 0 ? $"\r\n## **{displayHeading}**\r\n---\r\n{CreateTruncatedList(items as string[])}" : string.Empty; 59 | if (!string.IsNullOrWhiteSpace(results)) 60 | { 61 | sb.AppendLine(results); 62 | } 63 | } 64 | private void ComposeDetail(StringBuilder sb, string dictionaryEntryName, string displayHeading) 65 | { 66 | object item = string.Empty; 67 | var results = PropertyBag.TryGetValue(dictionaryEntryName, out item) && (item as string).Count() > 0 ? $"\r\n## **{displayHeading}**\r\n---\r\n{CreateTruncatedList(new string[] { item as string }, maxTermLength:500)}" : string.Empty; 68 | if (!string.IsNullOrWhiteSpace(results)) 69 | { 70 | sb.AppendLine(results); 71 | } 72 | } 73 | public bool IsImage 74 | { 75 | get 76 | { 77 | return !string.IsNullOrWhiteSpace(FileName) && FilenameIsImage(); 78 | } 79 | } 80 | public IDictionary PropertyBag { get; set; } 81 | private bool FilenameIsImage() 82 | { 83 | var fileExtension = FileName.Split('.').Last(); 84 | if (!string.IsNullOrWhiteSpace(fileExtension)) 85 | { 86 | switch (fileExtension.ToLower()) 87 | { 88 | case ("png"): 89 | case ("jpg"): 90 | case ("jpeg"): 91 | return true; 92 | default: 93 | return false; 94 | } 95 | } 96 | else 97 | { 98 | return false; 99 | } 100 | } 101 | 102 | private string CreateTruncatedList(string[] items, int maxCount = 20, int maxTermLength = 100) 103 | { 104 | StringBuilder sb = new StringBuilder(); 105 | int count = 0; 106 | foreach (var item in items) 107 | { 108 | var current = item; 109 | if (item.Length > maxTermLength) 110 | { 111 | current = item.Substring(0, maxTermLength); 112 | } 113 | sb.Append($"{current}, "); 114 | count++; 115 | if (count >= maxCount) 116 | { 117 | break; 118 | } 119 | } 120 | return sb.ToString().Trim().TrimEnd(','); 121 | } 122 | } 123 | } -------------------------------------------------------------------------------- /resources/code-bot/Models/SearchHitStyler.cs: -------------------------------------------------------------------------------- 1 | using CognitiveSearchBot.Utilities; 2 | using Microsoft.Bot.Schema; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Net; 6 | 7 | namespace Models 8 | { 9 | public class SearchHitStyler 10 | { 11 | public void Apply(ref IMessageActivity activity, string prompt, IReadOnlyList options, IReadOnlyList descriptions = null) 12 | { 13 | if (options is IList hits) 14 | { 15 | List cardButtons = new List(); 16 | var cards = hits.Select(h => 17 | { 18 | var card = new HeroCard 19 | { 20 | Title = WebUtility.UrlDecode(h.FileName).Replace(' ', '_'), 21 | Text = h.Description, 22 | Buttons = new List { new CardAction() 23 | { 24 | Value = h.DocumentUrl, 25 | Type = "openUrl", 26 | Title = "Open Document" 27 | } } 28 | }; 29 | if (h.IsImage) 30 | { 31 | card.Images = new List 32 | { 33 | new CardImage(h.DocumentUrl) 34 | }; 35 | } 36 | return card; 37 | }); 38 | 39 | activity.AttachmentLayout = AttachmentLayoutTypes.Carousel; 40 | activity.Attachments = cards.Select(c => c.ToAttachment()).ToList(); 41 | activity.SuggestedActions = HeroCardUtility.FollowupSuggestions(); 42 | activity.Text = prompt; 43 | } 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /resources/code-bot/PostDeployScripts/IncludeSources.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | $(CoreCompileDependsOn);IncludeSource 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /resources/code-bot/PostDeployScripts/githubProject.json.template: -------------------------------------------------------------------------------- 1 | { 2 | "name": "{WEB_SITE_NAME}", 3 | "description": "{WEB_SITE_NAME} Azure Bot Service Code", 4 | "homepage": "https://github.com", 5 | "private": false, 6 | "has_issues": true, 7 | "has_projects": true, 8 | "has_wiki": true 9 | } -------------------------------------------------------------------------------- /resources/code-bot/PostDeployScripts/prepareSrc.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | SET password=%1 4 | SET repoName=srcRepo 5 | SET repoUrl=file:///%HOMEDRIVE:~0,1%/%HOMEPATH:~1%/site/%repoName% 6 | SET download=bot-src 7 | 8 | echo %repoUrl% 9 | 10 | rem cd to project root 11 | pushd ..\wwwroot 12 | 13 | rem init git 14 | call git init 15 | call git config user.name "botframework" 16 | call git config user.email "util@botframework.com" 17 | call git add . 18 | call git commit -m "prepare to download source" 19 | call git remote add srcRepo %repoUrl% 20 | popd 21 | 22 | rem init upstream 23 | pushd %HOME%\site 24 | mkdir srcRepo 25 | cd srcRepo 26 | call git init --bare 27 | popd 28 | 29 | rem push to upstream 30 | pushd ..\wwwroot 31 | call git push --set-upstream srcRepo master 32 | popd 33 | 34 | rem clone srcRepo 35 | pushd %HOME%\site 36 | call git clone %repoUrl% %download% 37 | rem delete .git 38 | cd %download% 39 | call rm -r -f .git 40 | popd 41 | 42 | rem prepare for publish 43 | pushd %HOME%\site\%download% 44 | mkdir Properties\PublishProfiles 45 | pushd Properties\PublishProfiles 46 | type ..\..\PostDeployScripts\publishProfile.xml.template | sed -e s/\{WEB_SITE_NAME\}/%WEBSITE_SITE_NAME%/g > %WEBSITE_SITE_NAME%-Web-Deploy.pubxml 47 | popd 48 | 49 | set SOLUTION_NAME= 50 | for /f "delims=" %%a in ('dir /b *.sln') do @set SOLUTION_NAME=%%a 51 | 52 | type PostDeployScripts\publish.cmd.template | sed -e s/\{SOLUTION_NAME\}/%SOLUTION_NAME%/g | sed -e s/\{PUBLISH_PROFILE\}/%WEBSITE_SITE_NAME%-Web-Deploy.pubxml/g | sed -e s/\{PASSWORD\}/%password%/g > publish.cmd 53 | type PostDeployScripts\publishSettings.xml.template | sed -e s/\{WEB_SITE_NAME\}/%WEBSITE_SITE_NAME%/g | sed -e s/\{PASSWORD\}/%password%/g > PostDeployScripts\%WEBSITE_SITE_NAME%.PublishSettings 54 | 55 | popd 56 | 57 | rem preare the zip file 58 | %HOMEDRIVE%\7zip\7za a %HOME%\site\%download%.zip %HOME%\site\%download%\* 59 | 60 | rem cleanup git stuff 61 | pushd ..\wwwroot 62 | call rm -r -f .git 63 | popd 64 | 65 | pushd %HOME%\site 66 | call rm -r -f %download% 67 | call rm -r -f %repoName% 68 | popd 69 | 70 | endlocal 71 | -------------------------------------------------------------------------------- /resources/code-bot/PostDeployScripts/publish.cmd.template: -------------------------------------------------------------------------------- 1 | nuget restore 2 | msbuild {SOLUTION_NAME} -p:DeployOnBuild=true -p:PublishProfile={PUBLISH_PROFILE} -p:Password={PASSWORD} 3 | 4 | -------------------------------------------------------------------------------- /resources/code-bot/PostDeployScripts/publishProfile.xml.template: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | MSDeploy 9 | AzureWebSite 10 | Release 11 | Any CPU 12 | http://{WEB_SITE_NAME}.azurewebsites.net 13 | True 14 | False 15 | {WEB_SITE_NAME}.scm.azurewebsites.net:443 16 | {WEB_SITE_NAME} 17 | 18 | True 19 | WMSVC 20 | True 21 | ${WEB_SITE_NAME} 22 | <_SavePWD>True 23 | <_DestinationType>AzureWebSite 24 | 25 | -------------------------------------------------------------------------------- /resources/code-bot/PostDeployScripts/publishSettings.xml.template: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /resources/code-bot/PostDeployScripts/runGulp.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | 4 | set DEPLOYMENT_SOURCE= 5 | set IN_PLACE_DEPLOYMENT=1 6 | 7 | if exist ..\wwwroot\deploy.cmd ( 8 | pushd ..\wwwroot 9 | call deploy.cmd 10 | popd 11 | ) 12 | 13 | rem kick of build of csproj 14 | 15 | echo record deployment timestamp 16 | date /t >> ..\deployment.log 17 | time /t >> ..\deployment.log 18 | echo ---------------------- >> ..\deployment.log 19 | echo Deployment done 20 | 21 | endlocal 22 | 23 | 24 | -------------------------------------------------------------------------------- /resources/code-bot/PostDeployScripts/setupGithubRemoteRepo.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | rem ------------------------------------------------------------------------------------------ 4 | rem setupVsoRemoteRepo [remoteUser] [personalAccessToken] [projName{optional}] 5 | rem create and populate VSO git repo for the ABS code instance 6 | rem 7 | rem remoteUser: user account name of the personal access token 8 | rem personalAccessToken: the personal access token used to access github REST API (requires repos scope) 9 | rem projName the name of the project to create (default to WEBSITE_SITE_NAME) 10 | rem ------------------------------------------------------------------------------------------ 11 | set remoteUrl=https://api.github.com 12 | set remoteUser=%1 13 | set remotePwd=%2 14 | set projName=%3 15 | if '%projName%'=='' set projName=%WEBSITE_SITE_NAME% 16 | set repoUrl=https://%remoteUser%:%remotePwd%@github.com/%remoteUser%/%projName%.git 17 | rem use curl to create project 18 | pushd ..\wwwroot 19 | type PostDeployScripts\githubProject.json.template | sed -e s/\{WEB_SITE_NAME\}/%projName%/g > %TEMP%\githubProject.json 20 | call curl -H "Content-Type: application/json" -u %remoteUser%:%remotePwd% -d "@%TEMP%\githubProject.json" -X POST %remoteUrl%/user/repos 21 | rem rm %TEMP%\githubProject.json 22 | popd 23 | 24 | popd 25 | rem cd to project root 26 | pushd ..\wwwroot 27 | 28 | rem init git 29 | call git init 30 | call git config user.name "%remoteUser%" 31 | call git config user.password "%remotePwd%" 32 | call git config user.email "util@botframework.com" 33 | call git add . 34 | call git commit -m "prepare to setup source control" 35 | call git push %repoUrl% master 36 | popd 37 | 38 | 39 | rem cleanup git stuff 40 | pushd ..\wwwroot 41 | call rm -r -f .git 42 | popd 43 | 44 | endlocal -------------------------------------------------------------------------------- /resources/code-bot/PostDeployScripts/setupVsoRemoteRepo.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | rem ------------------------------------------------------------------------------------------ 4 | rem setupVsoRemoteRepo [vsoRemote] [vsoUserName] [vsoPersonalAccessToken] [projName{optional}] 5 | rem create and populate VSO git repo for the ABS code instance 6 | rem 7 | rem vsoRmote: url of the VSO site (e.g. https://awesomebot.visualstudio.com ) 8 | rem vosUserName: user account name of the personal access token 9 | rem vsoPersonalAccessToken: the personal access token used to access VSO REST api 10 | rem projName the name of the project to create (default to WEBSITE_SITE_NAME) 11 | rem ------------------------------------------------------------------------------------------ 12 | set remoteUrl=%1 13 | set remoteUser=%2 14 | set remotePwd=%3 15 | set projName=%4 16 | if '%projName%'=='' set projName=%WEBSITE_SITE_NAME% 17 | set vstsRoot=%remoteUrl% 18 | set repoUrl=https://%remoteUser%:%remotePwd%@%remoteUrl:~8%/_git/%projName% 19 | set vstsCreateProject=https://%remoteUser%:%remotePwd%@%remoteUrl:~8%/defaultcollection/_apis/projects?api-version=3.0 20 | 21 | rem use curl to create project 22 | pushd ..\wwwroot 23 | type PostDeployScripts\vsoProject.json.template | sed -e s/\{WEB_SITE_NAME\}/%projName%/g > %TEMP%\vsoProject.json 24 | call curl -H "Content-Type: application/json" -d "@%TEMP%\vsoProject.json" -X POST %vstsCreateProject% 25 | rm %TEMP%\vsoProject.json 26 | rem sleep for 15 seconds for the creation to complete, this is a wild guess 27 | call sleep 15 28 | popd 29 | 30 | popd 31 | rem cd to project root 32 | pushd ..\wwwroot 33 | 34 | rem init git 35 | call git init 36 | call git config user.name "%remoteUser%" 37 | call git config user.password "%remotePwd%" 38 | call git config user.email "util@botframework.com" 39 | call git add . 40 | call git commit -m "prepare to setup source control" 41 | call git push %repoUrl% master 42 | popd 43 | 44 | 45 | rem cleanup git stuff 46 | pushd ..\wwwroot 47 | call rm -r -f .git 48 | popd 49 | 50 | endlocal -------------------------------------------------------------------------------- /resources/code-bot/PostDeployScripts/vsoProject.json.template: -------------------------------------------------------------------------------- 1 | { 2 | "name": "{WEB_SITE_NAME}", 3 | "description": "{WEB_SITE_NAME} Azure Bot Service Code", 4 | "capabilities": { 5 | "versioncontrol": { 6 | "sourceControlType": "Git" 7 | }, 8 | "processTemplate": { 9 | "templateTypeId": "6b724908-ef14-45cf-84f8-768b5384da45" 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /resources/code-bot/Program.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using Microsoft.AspNetCore; 5 | using Microsoft.AspNetCore.Hosting; 6 | using Microsoft.Extensions.Logging; 7 | 8 | namespace Microsoft.CognitiveSearchBot 9 | { 10 | public class Program 11 | { 12 | public static void Main(string[] args) 13 | { 14 | BuildWebHost(args).Run(); 15 | } 16 | 17 | public static IWebHost BuildWebHost(string[] args) => 18 | WebHost.CreateDefaultBuilder(args) 19 | .ConfigureLogging((hostingContext, logging) => 20 | { 21 | // Add Azure Logging 22 | logging.AddAzureWebAppDiagnostics(); 23 | 24 | // Logging Options. 25 | // There are other logging options available: 26 | // https://docs.microsoft.com/en-us/aspnet/core/fundamentals/logging/?view=aspnetcore-2.1 27 | // logging.AddDebug(); 28 | // logging.AddConsole(); 29 | }) 30 | 31 | // Logging Options. 32 | // Consider using Application Insights for your logging and metrics needs. 33 | // https://azure.microsoft.com/en-us/services/application-insights/ 34 | // .UseApplicationInsights() 35 | .UseStartup() 36 | .Build(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /resources/code-bot/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:3978/", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "CognitiveSearchBot": { 12 | "commandName": "Project", 13 | "launchBrowser": true, 14 | "environmentVariables": { 15 | "ASPNETCORE_ENVIRONMENT": "Development" 16 | }, 17 | "applicationUrl": "http://localhost:3978/" 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /resources/code-bot/Responses/MainResponses.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Threading.Tasks; 3 | using CognitiveSearchBot.Utilities; 4 | using Microsoft.Bot.Builder; 5 | using Microsoft.Bot.Schema; 6 | 7 | namespace Responses 8 | { 9 | public class MainResponses 10 | { 11 | public static async Task ReplyWithGreeting(ITurnContext context) 12 | { 13 | // Add a greeting 14 | await context.SendActivityAsync($"Hi, I'm CognitiveSearchBot!"); 15 | } 16 | public static async Task ReplyWithHelp(ITurnContext context) 17 | { 18 | IMessageActivity activity = context.Activity.CreateReply(); 19 | activity.Text = $"I can retrieve cognitive fields from Azure Search. To start a new search, respond \"search\""; 20 | activity.SuggestedActions = HeroCardUtility.InitialSuggestions(); 21 | await context.SendActivityAsync(activity); 22 | } 23 | public static async Task ReplyWithResumeTopic(ITurnContext context) 24 | { 25 | await context.SendActivityAsync($"What can I do for you?"); 26 | } 27 | public static async Task ReplyWithConfused(ITurnContext context) 28 | { 29 | // Add a response for the user if Regex doesn't know 30 | // What the user is trying to communicate 31 | IMessageActivity activity = context.Activity.CreateReply(); 32 | activity.Text = $"I'm sorry, I don't understand."; 33 | activity.SuggestedActions = HeroCardUtility.InitialSuggestions(); 34 | await context.SendActivityAsync(activity); 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /resources/code-bot/Responses/SearchResponses.cs: -------------------------------------------------------------------------------- 1 | using CognitiveSearchBot.Utilities; 2 | using Microsoft.Bot.Builder; 3 | using Microsoft.Bot.Schema; 4 | using System.Threading.Tasks; 5 | 6 | namespace Responses 7 | { 8 | public class SearchResponses 9 | { 10 | // add a task called "ReplyWithSearchRequest" 11 | // it should take in the context and ask the 12 | // user what they want to search for 13 | internal static async Task ReplyWithSearchRequest(ITurnContext context) 14 | { 15 | await context.SendActivityAsync($"What would you like to search for?"); 16 | } 17 | internal static async Task ReplyWithSearchConfirmation(ITurnContext context, string utterance) 18 | { 19 | await context.SendActivityAsync($"Ok, searching for \"" + utterance + "\"..."); 20 | } 21 | internal static async Task ReplyWithNoResults(ITurnContext context, string utterance) 22 | { 23 | IMessageActivity activity = context.Activity.CreateReply(); 24 | activity.Text = "There were no results found for \"" + utterance + "\"."; 25 | activity.SuggestedActions = HeroCardUtility.FollowupSuggestions(); 26 | await context.SendActivityAsync(activity); 27 | } 28 | 29 | internal static async Task ReplyWithSearchForModeratedContentConfirmation(ITurnContext context) 30 | { 31 | await context.SendActivityAsync($"Ok, searching for content that should be moderated..."); 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /resources/code-bot/Startup.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. 2 | // Licensed under the MIT License. 3 | 4 | using System; 5 | using System.Linq; 6 | using Microsoft.AspNetCore.Builder; 7 | using Microsoft.AspNetCore.Hosting; 8 | using Microsoft.Bot.Builder; 9 | using Microsoft.Bot.Builder.Integration; 10 | using Microsoft.Bot.Builder.Integration.AspNet.Core; 11 | using Microsoft.Bot.Configuration; 12 | using Microsoft.Bot.Connector.Authentication; 13 | using Microsoft.Extensions.Configuration; 14 | using Microsoft.Extensions.DependencyInjection; 15 | using Microsoft.Extensions.Logging; 16 | using Microsoft.Extensions.Options; 17 | using System.Text.RegularExpressions; 18 | using Microsoft.Bot.Builder.Dialogs; 19 | 20 | namespace Microsoft.CognitiveSearchBot 21 | { 22 | /// 23 | /// The Startup class configures services and the request pipeline. 24 | /// 25 | public class Startup 26 | { 27 | private ILoggerFactory _loggerFactory; 28 | private bool _isProduction = false; 29 | 30 | public Startup(IHostingEnvironment env) 31 | { 32 | _isProduction = env.IsProduction(); 33 | var builder = new ConfigurationBuilder() 34 | .SetBasePath(env.ContentRootPath) 35 | .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) 36 | .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) 37 | .AddEnvironmentVariables(); 38 | 39 | Configuration = builder.Build(); 40 | } 41 | 42 | /// 43 | /// Gets the configuration that represents a set of key/value application configuration properties. 44 | /// 45 | /// 46 | /// The that represents a set of key/value application configuration properties. 47 | /// 48 | public IConfiguration Configuration { get; } 49 | 50 | /// 51 | /// This method gets called by the runtime. Use this method to add services to the container. 52 | /// 53 | /// The specifies the contract for a collection of service descriptors. 54 | /// 55 | /// 56 | /// 57 | public void ConfigureServices(IServiceCollection services) 58 | { 59 | services.AddBot(options => 60 | { 61 | var secretKey = Configuration.GetSection("botFileSecret")?.Value; 62 | var botFilePath = Configuration.GetSection("botFilePath")?.Value; 63 | 64 | // Loads .bot configuration file and adds a singleton that your Bot can access through dependency injection. 65 | var botConfig = BotConfiguration.Load(botFilePath ?? @".\BotConfiguration.bot", secretKey); 66 | services.AddSingleton(sp => botConfig ?? throw new InvalidOperationException($"The .bot config file could not be loaded. ({botConfig})")); 67 | 68 | // Retrieve current endpoint. 69 | var environment = _isProduction ? "production" : "development"; 70 | var service = botConfig.Services.Where(s => s.Type == "endpoint" && s.Name == environment).FirstOrDefault(); 71 | if (!(service is EndpointService endpointService)) 72 | { 73 | throw new InvalidOperationException($"The .bot file does not contain an endpoint with name '{environment}'."); 74 | } 75 | 76 | options.CredentialProvider = new SimpleCredentialProvider(endpointService.AppId, endpointService.AppPassword); 77 | 78 | // Creates a logger for the application to use. 79 | ILogger logger = _loggerFactory.CreateLogger(); 80 | 81 | // Catches any errors that occur during a conversation turn and logs them. 82 | options.OnTurnError = async (context, exception) => 83 | { 84 | logger.LogError($"Exception caught : {exception}"); 85 | await context.SendActivityAsync("Sorry, it looks like something went wrong."); 86 | }; 87 | 88 | // The Memory Storage used here is for local bot debugging only. When the bot 89 | // is restarted, everything stored in memory will be gone. 90 | IStorage dataStore = new MemoryStorage(); 91 | 92 | // For production bots use the Azure Blob or 93 | // Azure CosmosDB storage providers. For the Azure 94 | // based storage providers, add the Microsoft.Bot.Builder.Azure 95 | // Nuget package to your solution. That package is found at: 96 | // https://www.nuget.org/packages/Microsoft.Bot.Builder.Azure/ 97 | // Uncomment the following lines to use Azure Blob Storage 98 | // //Storage configuration name or ID from the .bot file. 99 | // const string StorageConfigurationId = ""; 100 | // var blobConfig = botConfig.FindServiceByNameOrId(StorageConfigurationId); 101 | // if (!(blobConfig is BlobStorageService blobStorageConfig)) 102 | // { 103 | // throw new InvalidOperationException($"The .bot file does not contain an blob storage with name '{StorageConfigurationId}'."); 104 | // } 105 | // // Default container name. 106 | // const string DefaultBotContainer = "botstate"; 107 | // var storageContainer = string.IsNullOrWhiteSpace(blobStorageConfig.Container) ? DefaultBotContainer : blobStorageConfig.Container; 108 | // IStorage dataStore = new Microsoft.Bot.Builder.Azure.AzureBlobStorage(blobStorageConfig.ConnectionString, storageContainer); 109 | 110 | // Create Conversation State object. 111 | // The Conversation State object is where we persist anything at the conversation-scope. 112 | var conversationState = new ConversationState(dataStore); 113 | 114 | options.State.Add(conversationState); 115 | 116 | var middleware = options.Middleware; 117 | // Add middleware below with "middleware.Add(...." 118 | // Add Regex below 119 | middleware.Add(new RegExpRecognizerMiddleware() 120 | .AddIntent("search", new Regex("search(?:)*(.*)", RegexOptions.IgnoreCase)) 121 | .AddIntent("help", new Regex("help(.*)", RegexOptions.IgnoreCase)) 122 | .AddIntent("moderated-content", new Regex(".*moderat.*", RegexOptions.IgnoreCase)) 123 | ); 124 | }); 125 | 126 | // Create and register state accesssors. 127 | // Acessors created here are passed into the IBot-derived class on every turn. 128 | services.AddSingleton(sp => 129 | { 130 | var options = sp.GetRequiredService>().Value; 131 | if (options == null) 132 | { 133 | throw new InvalidOperationException("BotFrameworkOptions must be configured prior to setting up the state accessors"); 134 | } 135 | 136 | var conversationState = options.State.OfType().FirstOrDefault(); 137 | if (conversationState == null) 138 | { 139 | throw new InvalidOperationException("ConversationState must be defined and added before adding conversation-scoped state accessors."); 140 | } 141 | 142 | // Create the custom state accessor. 143 | // State accessors enable other components to read and write individual properties of state. 144 | var accessors = new BotAccessors(conversationState) 145 | { 146 | BotState = conversationState.CreateProperty(BotAccessors.BotStateName), 147 | DialogStateAccessor = conversationState.CreateProperty("DialogState"), 148 | }; 149 | 150 | return accessors; 151 | }); 152 | } 153 | 154 | public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 155 | { 156 | _loggerFactory = loggerFactory; 157 | 158 | app.UseDefaultFiles() 159 | .UseStaticFiles() 160 | .UseBotFramework(); 161 | } 162 | } 163 | } 164 | -------------------------------------------------------------------------------- /resources/code-bot/Utilities/HeroCardUtility.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Bot.Schema; 2 | using System.Collections.Generic; 3 | 4 | namespace CognitiveSearchBot.Utilities 5 | { 6 | public class HeroCardUtility 7 | { 8 | private static readonly CardAction InitialSearch = new CardAction() { Title = "Perform Search", Type = ActionTypes.ImBack, Value = "search" }; 9 | private static readonly CardAction FollowupSearch = new CardAction() { Title = "Search for another term", Type = ActionTypes.ImBack, Value = "search" }; 10 | private static readonly CardAction ModeratedContent = new CardAction() { Title = "Find moderated content", Type = ActionTypes.ImBack, Value = "moderated content" }; 11 | private static readonly CardAction Help = new CardAction() { Title = "Help", Type = ActionTypes.ImBack, Value = "Help" }; 12 | public static SuggestedActions InitialSuggestions() 13 | { 14 | return new SuggestedActions() 15 | { 16 | Actions = new List() 17 | { 18 | InitialSearch, 19 | ModeratedContent, 20 | Help 21 | } 22 | }; 23 | } 24 | 25 | public static SuggestedActions FollowupSuggestions() 26 | { 27 | return new SuggestedActions() 28 | { 29 | Actions = new List() 30 | { 31 | FollowupSearch, 32 | ModeratedContent, 33 | Help 34 | } 35 | }; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /resources/code-bot/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "botFilePath": "BotConfiguration.bot", 3 | "botFileSecret": "" 4 | } -------------------------------------------------------------------------------- /resources/code-bot/build.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | 4 | set DEPLOYMENT_SOURCE= 5 | set DEPLOYMENT_TARGET=%~dp0%. 6 | 7 | copy %~dp0wwwroot\default.htm %~dp0app_offline.htm 8 | 9 | if exist ..\wwwroot\deploy.cmd ( 10 | pushd ..\wwwroot 11 | call deploy.cmd 12 | popd 13 | ) 14 | 15 | del %~dp0%\app_offline.htm 16 | 17 | endlocal 18 | -------------------------------------------------------------------------------- /resources/code-bot/deploy.cmd: -------------------------------------------------------------------------------- 1 | @if "%SCM_TRACE_LEVEL%" NEQ "4" @echo off 2 | 3 | :: ---------------------- 4 | :: KUDU Deployment Script 5 | :: Version: 1.0.17 6 | :: ---------------------- 7 | 8 | :: Prerequisites 9 | :: ------------- 10 | 11 | :: Verify node.js installed 12 | where node 2>nul >nul 13 | IF %ERRORLEVEL% NEQ 0 ( 14 | echo Missing node.js executable, please install node.js, if already installed make sure it can be reached from current environment. 15 | goto error 16 | ) 17 | 18 | :: Setup 19 | :: ----- 20 | 21 | setlocal enabledelayedexpansion 22 | 23 | SET ARTIFACTS=%~dp0%..\artifacts 24 | 25 | IF NOT DEFINED DEPLOYMENT_SOURCE ( 26 | SET DEPLOYMENT_SOURCE=%~dp0%. 27 | ) 28 | 29 | IF NOT DEFINED DEPLOYMENT_TARGET ( 30 | SET DEPLOYMENT_TARGET=%ARTIFACTS%\wwwroot 31 | ) 32 | 33 | IF NOT DEFINED NEXT_MANIFEST_PATH ( 34 | SET NEXT_MANIFEST_PATH=%ARTIFACTS%\manifest 35 | 36 | IF NOT DEFINED PREVIOUS_MANIFEST_PATH ( 37 | SET PREVIOUS_MANIFEST_PATH=%ARTIFACTS%\manifest 38 | ) 39 | ) 40 | 41 | IF NOT DEFINED KUDU_SYNC_CMD ( 42 | :: Install kudu sync 43 | echo Installing Kudu Sync 44 | call npm install kudusync -g --silent 45 | IF !ERRORLEVEL! NEQ 0 goto error 46 | 47 | :: Locally just running "kuduSync" would also work 48 | SET KUDU_SYNC_CMD=%appdata%\npm\kuduSync.cmd 49 | ) 50 | IF NOT DEFINED DEPLOYMENT_TEMP ( 51 | SET DEPLOYMENT_TEMP=%temp%\___deployTemp%random% 52 | SET CLEAN_LOCAL_DEPLOYMENT_TEMP=true 53 | ) 54 | 55 | IF DEFINED CLEAN_LOCAL_DEPLOYMENT_TEMP ( 56 | IF EXIST "%DEPLOYMENT_TEMP%" rd /s /q "%DEPLOYMENT_TEMP%" 57 | mkdir "%DEPLOYMENT_TEMP%" 58 | ) 59 | 60 | IF DEFINED MSBUILD_PATH goto MsbuildPathDefined 61 | SET MSBUILD_PATH=%ProgramFiles(x86)%\MSBuild\14.0\Bin\MSBuild.exe 62 | :MsbuildPathDefined 63 | :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: 64 | :: Deployment 65 | :: ---------- 66 | 67 | echo Handling ASP.NET Core Web Application deployment. 68 | 69 | :: 1. Restore nuget packages 70 | call :ExecuteCmd dotnet restore "%DEPLOYMENT_SOURCE%\EchoBotWithCounter.sln" 71 | IF !ERRORLEVEL! NEQ 0 goto error 72 | 73 | :: 2. Build and publish 74 | call :ExecuteCmd dotnet publish "%DEPLOYMENT_SOURCE%\EchoBotWithCounter.csproj" --output "%DEPLOYMENT_TEMP%" --configuration Release 75 | IF !ERRORLEVEL! NEQ 0 goto error 76 | 77 | :: 3. KuduSync 78 | call :ExecuteCmd "%KUDU_SYNC_CMD%" -v 50 -f "%DEPLOYMENT_TEMP%" -t "%DEPLOYMENT_TARGET%" -n "%NEXT_MANIFEST_PATH%" -p "%PREVIOUS_MANIFEST_PATH%" -i ".git;.hg;.deployment;deploy.cmd" 79 | IF !ERRORLEVEL! NEQ 0 goto error 80 | 81 | :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: 82 | goto end 83 | 84 | :: Execute command routine that will echo out when error 85 | :ExecuteCmd 86 | setlocal 87 | set _CMD_=%* 88 | call %_CMD_% 89 | if "%ERRORLEVEL%" NEQ "0" echo Failed exitCode=%ERRORLEVEL%, command=%_CMD_% 90 | exit /b %ERRORLEVEL% 91 | 92 | :error 93 | endlocal 94 | echo An error has occurred during web site deployment. 95 | call :exitSetErrorLevel 96 | call :exitFromFunction 2>nul 97 | 98 | :exitSetErrorLevel 99 | exit /b 1 100 | 101 | :exitFromFunction 102 | () 103 | 104 | :end 105 | endlocal 106 | echo Finished successfully. 107 | -------------------------------------------------------------------------------- /resources/code-bot/readme.md: -------------------------------------------------------------------------------- 1 | At the bottom of CognitiveSearchBot.cs, you need to add your Azure Search service name, key, and index name. -------------------------------------------------------------------------------- /resources/code-bot/web.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /resources/dataset-hackathon/1003_MS_Coppola_079B.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/dataset-hackathon/1003_MS_Coppola_079B.jpg -------------------------------------------------------------------------------- /resources/dataset-hackathon/HollysHillVineyards.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/dataset-hackathon/HollysHillVineyards.jpg -------------------------------------------------------------------------------- /resources/dataset-hackathon/Italy-Wine-Map-wine-folly.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/dataset-hackathon/Italy-Wine-Map-wine-folly.jpg -------------------------------------------------------------------------------- /resources/dataset-hackathon/README.md: -------------------------------------------------------------------------------- 1 | # LearnAI Team - Knowledge Mining Bootcamp - Azure Cognitive Search - Hackathon Dataset 2 | 3 | This is the Hackathon dataset. Details: 4 | 5 | 1. Public Microsoft documents and images 6 | 1. Multiple languages 7 | 1. Multiple formats 8 | 1. Allow multiple challenges for the Hackathon -------------------------------------------------------------------------------- /resources/dataset-hackathon/barbaresco-nebbiolo-wine.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/dataset-hackathon/barbaresco-nebbiolo-wine.jpg -------------------------------------------------------------------------------- /resources/dataset-hackathon/bouza-monte-vide-eu.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/dataset-hackathon/bouza-monte-vide-eu.pdf -------------------------------------------------------------------------------- /resources/dataset-hackathon/bouza-tannat.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/dataset-hackathon/bouza-tannat.pdf -------------------------------------------------------------------------------- /resources/dataset-hackathon/catena-zapata-2015.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/dataset-hackathon/catena-zapata-2015.pdf -------------------------------------------------------------------------------- /resources/dataset-hackathon/catena-zapata-2016.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/dataset-hackathon/catena-zapata-2016.pdf -------------------------------------------------------------------------------- /resources/dataset-hackathon/coppola wine thief628x471.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/dataset-hackathon/coppola wine thief628x471.jpg -------------------------------------------------------------------------------- /resources/dataset-hackathon/el-enemigo-stamp.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/dataset-hackathon/el-enemigo-stamp.jpg -------------------------------------------------------------------------------- /resources/dataset-hackathon/garzon-tannat.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/dataset-hackathon/garzon-tannat.pdf -------------------------------------------------------------------------------- /resources/dataset-hackathon/green-wine-certificates.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/dataset-hackathon/green-wine-certificates.pdf -------------------------------------------------------------------------------- /resources/dataset-hackathon/green-wine-grapes.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/dataset-hackathon/green-wine-grapes.pdf -------------------------------------------------------------------------------- /resources/dataset-hackathon/green-wine-region.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/dataset-hackathon/green-wine-region.pdf -------------------------------------------------------------------------------- /resources/dataset-hackathon/jon-arvid-rosengren.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/dataset-hackathon/jon-arvid-rosengren.pdf -------------------------------------------------------------------------------- /resources/dataset-hackathon/l_6231_jon-arvid-rosengren-winner.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/dataset-hackathon/l_6231_jon-arvid-rosengren-winner.jpg -------------------------------------------------------------------------------- /resources/dataset-hackathon/rosengren_arvid_l.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/dataset-hackathon/rosengren_arvid_l.jpg -------------------------------------------------------------------------------- /resources/dataset-hackathon/rosengrenmsm.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/dataset-hackathon/rosengrenmsm.jpg -------------------------------------------------------------------------------- /resources/dataset-hackathon/terrazas-cabernet-sauvignon.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/dataset-hackathon/terrazas-cabernet-sauvignon.pdf -------------------------------------------------------------------------------- /resources/dataset-hackathon/terrazas-chadornay.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/dataset-hackathon/terrazas-chadornay.jpg -------------------------------------------------------------------------------- /resources/dataset-hackathon/terrazas-chadornay.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/dataset-hackathon/terrazas-chadornay.pdf -------------------------------------------------------------------------------- /resources/dataset-hackathon/trapiche.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/dataset-hackathon/trapiche.jpg -------------------------------------------------------------------------------- /resources/dataset-hackathon/trapiche.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/dataset-hackathon/trapiche.pdf -------------------------------------------------------------------------------- /resources/dataset-hackathon/wine-producers.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/dataset-hackathon/wine-producers.pdf -------------------------------------------------------------------------------- /resources/dataset-hackathon/zuccardi.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/dataset-hackathon/zuccardi.jpg -------------------------------------------------------------------------------- /resources/dataset-hackathon/zuccardi.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/dataset-hackathon/zuccardi.pdf -------------------------------------------------------------------------------- /resources/dataset/10-K-FY16.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/dataset/10-K-FY16.html -------------------------------------------------------------------------------- /resources/dataset/20190506_Microsoft_Build_435-630x450 Open Satya.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/dataset/20190506_Microsoft_Build_435-630x450 Open Satya.jpg -------------------------------------------------------------------------------- /resources/dataset/5074.clip_image002_6FE27E85.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/dataset/5074.clip_image002_6FE27E85.png -------------------------------------------------------------------------------- /resources/dataset/Cognitive Search Skills.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/dataset/Cognitive Search Skills.PNG -------------------------------------------------------------------------------- /resources/dataset/Cognitive Services and Bots (spanish).pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/dataset/Cognitive Services and Bots (spanish).pdf -------------------------------------------------------------------------------- /resources/dataset/Form.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/dataset/Form.png -------------------------------------------------------------------------------- /resources/dataset/KMB V1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/dataset/KMB V1.pdf -------------------------------------------------------------------------------- /resources/dataset/LearnAI-portal.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/dataset/LearnAI-portal.PNG -------------------------------------------------------------------------------- /resources/dataset/MSFT_FY17_10K.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/dataset/MSFT_FY17_10K.docx -------------------------------------------------------------------------------- /resources/dataset/MSFT_cloud_architecture_contoso.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/dataset/MSFT_cloud_architecture_contoso.pdf -------------------------------------------------------------------------------- /resources/dataset/NYSE_LNKD_2015.PDF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/dataset/NYSE_LNKD_2015.PDF -------------------------------------------------------------------------------- /resources/dataset/PII.txt: -------------------------------------------------------------------------------- 1 | Personally Identifiable Information (PII) 2 | 3 | The PII feature detects the potential presence of this information: Email address, US Mailing address, IP address, US Phone number, UK Phone number, Social Security Number (SSN) 4 | 5 | Is this a crap email abcdef@abcd.com, phone: 6657789887, IP: 255.255.255.255, 1 Microsoft Way, Redmond, WA 98052 -------------------------------------------------------------------------------- /resources/dataset/README.md: -------------------------------------------------------------------------------- 1 | # LearnAI Team - Knowledge Mining Bootcamp - Azure Cognitive Search - Dataset 2 | 3 | This is the dataset we will for the trainining. Details: 4 | 5 | 1. Public Microsoft documents and images 6 | 1. Multiple languages 7 | 1. Multiple formats 8 | 1. Multiple challenges for the Hackathon -------------------------------------------------------------------------------- /resources/dataset/SQL Server on Linux.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/dataset/SQL Server on Linux.JPG -------------------------------------------------------------------------------- /resources/dataset/Satya AI democratization.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/dataset/Satya AI democratization.jpg -------------------------------------------------------------------------------- /resources/dataset/Satya Brazil KM.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/dataset/Satya Brazil KM.jpg -------------------------------------------------------------------------------- /resources/dataset/board.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/dataset/board.PNG -------------------------------------------------------------------------------- /resources/dataset/finished-solution-lab-azure-search.md: -------------------------------------------------------------------------------- 1 | # Finished Solution - CusAzure Search Lab 2 | 3 | 1. Return only the first document: `$top=1` 4 | 5 | 1. Search documents where words "Microsoft" and "Cloud" are up to 20 words distant one from the other: `"Microsoft Azure" ~ 20` 6 | 7 | 1. Search for documents about Cloud, ordering the results by the score: `* orderby 2` 8 | 9 | 1. Search for documents about Cloud, but filtering those with mentions to Oracle: `"Cloud" -Oracle` 10 | 11 | 1. Search for documents about Cognitive Services and Bots: `"Cognitive Services", Bots` 12 | -------------------------------------------------------------------------------- /resources/dataset/guthrie.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/dataset/guthrie.jpg -------------------------------------------------------------------------------- /resources/dataset/redshirt.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/dataset/redshirt.jpg -------------------------------------------------------------------------------- /resources/dataset/satyanadellalinux.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/dataset/satyanadellalinux.jpg -------------------------------------------------------------------------------- /resources/dataset/satyasletter.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/dataset/satyasletter.txt -------------------------------------------------------------------------------- /resources/dataset/words cloud.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/dataset/words cloud.PNG -------------------------------------------------------------------------------- /resources/finished-solutions/finished-solution-lab-02-azure-search.md: -------------------------------------------------------------------------------- 1 | # Finished Solution - Custom Skills Lab 2 | 3 | Hello! 4 | 5 | Here are suggestions for the challenge at the end of the [Azure Search Lab](../../labs/lab-02-azure-search.md) 6 | 7 | The commands below should be types in the Search Explorer **Query string** bar. Use `Ctrl+F` to make sure your queries are working as expected. 8 | 9 | 1. Return only the first document: `$top=1` 10 | 11 | 1. Search documents where words "Microsoft" and "Cloud" are up to 20 words distant one from the other: `"Microsoft Cloud" ~20` 12 | 13 | 1. Search for documents about Cloud, ordering the results by the score: `cloud order by score desc` 14 | 15 | 1. Search for documents about Cloud, but filtering those with mentions to Oracle: `+cloud -oracle &searchMode=all` 16 | 17 | 1. Search for documents about Cognitive Services and Bots: `"Cognitive Services", Bots` 18 | 19 | 1. Search for all celebrities: `$select=celebrities` 20 | 21 | ## Next Step 22 | 23 | [Text Skills Lab](../../labs/lab-03-text-skills.md) or 24 | [Back to Read Me](../../README.md) -------------------------------------------------------------------------------- /resources/finished-solutions/finished-solution-lab-04-image-skills.md: -------------------------------------------------------------------------------- 1 | # Finished Solution - Image Skills Lab 2 | 3 | Hello! 4 | 5 | Here are the body requests for the Image Skills lab. Don't forget to adjust the URLs to use your Azure Search service name. 6 | 7 | ## Delete Skillset 8 | 9 | ```http 10 | DELETE https://[your-service-name].search.windows.net/skillsets/demoskillset?api-version=2019-05-06 11 | Content-Type: application/json 12 | api-key: [api-key] 13 | ``` 14 | 15 | ## Delete Index 16 | 17 | ```http 18 | DELETE https://[your-service-name].search.windows.net/indexes/demoindex?api-version=2019-05-06 19 | Content-Type: application/json 20 | api-key: [api-key] 21 | ``` 22 | 23 | ## Delete Indexer 24 | 25 | ```http 26 | DELETE https://[your-service-name].search.windows.net/indexers/demoindexer?api-version=2019-05-06 27 | Content-Type: application/json 28 | api-key: [api-key] 29 | ``` 30 | 31 | ## Skillset 32 | 33 | ```http 34 | PUT https://[your-service-name].search.windows.net/skillset/demoskillset?api-version=2019-05-06 35 | Content-Type: application/json 36 | api-key: [api-key] 37 | ``` 38 | 39 | ```json 40 | { 41 | "description": 42 | "Extract OCR, entities, detect language and extract key-phrases, with MERGE AND SPLITS", 43 | "skills": 44 | [ 45 | { 46 | "description": "Extract text (plain and structured) from image.", 47 | "@odata.type": "#Microsoft.Skills.Vision.OcrSkill", 48 | "context": "/document/normalized_images/*", 49 | "defaultLanguageCode": "en", 50 | "detectOrientation": true, 51 | "inputs": [ 52 | { 53 | "name": "image", 54 | "source": "/document/normalized_images/*" 55 | } 56 | ], 57 | "outputs": [ 58 | { 59 | "name": "text", "targetName": "myOcrText" 60 | } 61 | ] 62 | }, 63 | { 64 | "@odata.type": "#Microsoft.Skills.Text.MergeSkill", 65 | "description": "Create mergedText, which includes all the textual representation of each image inserted at the right location in the content field.", 66 | "context": "/document", 67 | "insertPreTag": " ", 68 | "insertPostTag": " ", 69 | "inputs": [ 70 | { 71 | "name":"text", "source": "/document/content" 72 | }, 73 | { 74 | "name": "itemsToInsert", "source": "/document/normalized_images/*/myOcrText" 75 | }, 76 | { 77 | "name":"offsets", "source": "/document/normalized_images/*/contentOffset" 78 | } 79 | ], 80 | "outputs": [ 81 | { 82 | "name": "mergedText", "targetName" : "mergedText" 83 | } 84 | ] 85 | }, 86 | { 87 | "@odata.type": "#Microsoft.Skills.Text.LanguageDetectionSkill", 88 | "inputs": [ 89 | { 90 | "name": "text", "source": "/document/mergedText" 91 | } 92 | ], 93 | "outputs": [ 94 | { 95 | "name": "languageCode", 96 | "targetName": "languageCode" 97 | } 98 | ] 99 | }, 100 | { 101 | "@odata.type": "#Microsoft.Skills.Text.SplitSkill", 102 | "textSplitMode" : "pages", 103 | "maximumPageLength": 4000, 104 | "inputs": [ 105 | { 106 | "name": "text", 107 | "source": "/document/mergedText" 108 | }, 109 | { 110 | "name": "languageCode", 111 | "source": "/document/languageCode" 112 | } 113 | ], 114 | "outputs": [ 115 | { 116 | "name": "textItems", 117 | "targetName": "pages" 118 | } 119 | ] 120 | }, 121 | { 122 | "@odata.type": "#Microsoft.Skills.Text.KeyPhraseExtractionSkill", 123 | "context": "/document/pages/*", 124 | "inputs": [ 125 | { 126 | "name": "text", "source": "/document/pages/*" 127 | }, 128 | { 129 | "name":"languageCode", "source": "/document/languageCode" 130 | } 131 | ], 132 | "outputs": [ 133 | { 134 | "name": "keyPhrases", 135 | "targetName": "keyPhrases" 136 | } 137 | ] 138 | }, 139 | { 140 | "@odata.type": "#Microsoft.Skills.Text.EntityRecognitionSkill", 141 | "categories": [ "Organization" ], 142 | "defaultLanguageCode": "en", 143 | "context": "/document/pages/*", 144 | "inputs": [ 145 | { 146 | "name": "text", "source": "/document/pages/*" 147 | } 148 | ], 149 | "outputs": [ 150 | { 151 | "name": "organizations", "targetName": "organizations" 152 | } 153 | ] 154 | } 155 | ], 156 | "cognitiveServices": { 157 | "@odata.type": "#Microsoft.Azure.Search.CognitiveServicesByKey", 158 | "description": "my-cog-serv", 159 | "key": "your-api-key-here" 160 | } 161 | } 162 | ``` 163 | 164 | ## Index 165 | 166 | ```http 167 | PUT https://[your-service-name].search.windows.net/indexes/demoindex?api-version=2019-05-06 168 | Content-Type: application/json 169 | api-key: [api-key] 170 | ``` 171 | 172 | ```json 173 | { 174 | "fields": [ 175 | { 176 | "name": "id", 177 | "type": "Edm.String", 178 | "key": true, 179 | "searchable": true, 180 | "filterable": false, 181 | "facetable": false, 182 | "sortable": true 183 | }, 184 | { 185 | "name": "blob_uri", 186 | "type": "Edm.String", 187 | "searchable": true, 188 | "filterable": false, 189 | "facetable": false, 190 | "sortable": true 191 | }, 192 | { 193 | "name": "content", 194 | "type": "Edm.String", 195 | "sortable": false, 196 | "searchable": true, 197 | "filterable": false, 198 | "facetable": false 199 | }, 200 | { 201 | "name": "languageCode", 202 | "type": "Edm.String", 203 | "searchable": true, 204 | "filterable": false, 205 | "facetable": false 206 | }, 207 | { 208 | "name": "keyPhrases", 209 | "type": "Collection(Edm.String)", 210 | "searchable": true, 211 | "filterable": false, 212 | "facetable": false 213 | }, 214 | { 215 | "name": "organizations", 216 | "type": "Collection(Edm.String)", 217 | "searchable": true, 218 | "sortable": false, 219 | "filterable": false, 220 | "facetable": false 221 | }, 222 | { 223 | "name": "myOcrText", 224 | "type": "Collection(Edm.String)", 225 | "searchable": true, 226 | "filterable": false, 227 | "facetable": false 228 | } 229 | ] 230 | } 231 | ``` 232 | 233 | ## Indexer 234 | 235 | ```http 236 | PUT https://[your-service-name].search.windows.net/indexers/demoindexer?api-version=2019-05-06 237 | Content-Type: application/json 238 | api-key: [api-key] 239 | ``` 240 | 241 | ```json 242 | { 243 | "dataSourceName" : "demodata", 244 | "targetIndexName" : "demoindex", 245 | "skillsetName" : "demoskillset", 246 | "fieldMappings" : [ 247 | { 248 | "sourceFieldName" : "metadata_storage_path", 249 | "targetFieldName" : "id", 250 | "mappingFunction" : 251 | { "name" : "base64Encode" } 252 | }, 253 | { 254 | "sourceFieldName" : "content", 255 | "targetFieldName" : "content" 256 | }, 257 | { 258 | "sourceFieldName" : "metadata_storage_path", 259 | "targetFieldName" : "blob_uri" 260 | } 261 | ], 262 | "outputFieldMappings" : 263 | [ 264 | { 265 | "sourceFieldName" : "/document/pages/*/organizations/*", 266 | "targetFieldName" : "organizations" 267 | }, 268 | { 269 | "sourceFieldName" : "/document/pages/*/keyPhrases/*", 270 | "targetFieldName" : "keyPhrases" 271 | }, 272 | { 273 | "sourceFieldName": "/document/languageCode", 274 | "targetFieldName": "languageCode" 275 | }, 276 | { 277 | "sourceFieldName": "/document/normalized_images/*/myOcrText", 278 | "targetFieldName": "myOcrText" 279 | } 280 | ], 281 | "parameters": 282 | { 283 | "maxFailedItems":-1, 284 | "maxFailedItemsPerBatch":-1, 285 | "configuration": 286 | { 287 | "dataToExtract": "contentAndMetadata", 288 | "imageAction": "generateNormalizedImages" 289 | } 290 | } 291 | } 292 | ``` 293 | 294 | ## Check Status 295 | 296 | ```http 297 | GET https://[your-service-name].search.windows.net/indexers/demoindexer/status?api-version=2019-05-06 298 | api-key: [api-key] 299 | Content-Type: application/json 300 | ``` 301 | 302 | ## Check organizations, languageCode and keyPhrases 303 | 304 | ```http 305 | https://[your-service-name].search.windows.net/indexes/demoindex/docs?search=*&$select=blob_uri,organizations,languageCode,keyPhrases&api-version=2019-05-06 306 | api-key: [api-key] 307 | Content-Type: application/json 308 | ``` 309 | 310 | ## Check the OCR Content extracted 311 | 312 | ```http 313 | GET https://[your-service-name].search.windows.net/indexes/demoindex/docs?search=*&$select=blob_uri,myOcrText&api-version=2019-05-06 314 | api-key: [api-key] 315 | Content-Type: application/json 316 | ``` 317 | 318 | ## Next Step 319 | 320 | [Custom Skills Lab](../../labs/lab-05-custom-skills.md) or 321 | [Back to Read Me](../../README.md) -------------------------------------------------------------------------------- /resources/finished-solutions/finished-solution-lab-05-custom-skills.md: -------------------------------------------------------------------------------- 1 | # Finished Solution - Custom Skills Lab 2 | 3 | Hello! 4 | 5 | Here are the body requests for the custom skills lab. Don't forget to adjust the URLs to use your Azure Search service name. 6 | 7 | ## Delete Skillset 8 | 9 | ```http 10 | DELETE https://[your-service-name].search.windows.net/skillsets/demoskillset?api-version=2019-05-06 11 | Content-Type: application/json 12 | api-key: [api-key] 13 | ``` 14 | ## Delete Index 15 | 16 | ```http 17 | DELETE https://[your-service-name].search.windows.net/indexes/demoindex?api-version=2019-05-06 18 | Content-Type: application/json 19 | api-key: [api-key] 20 | ``` 21 | 22 | ## Delete Indexer 23 | 24 | ```http 25 | DELETE https://[your-service-name].search.windows.net/indexers/demoindexer?api-version=2019-05-06 26 | Content-Type: application/json 27 | api-key: [api-key] 28 | ``` 29 | 30 | ```http 31 | PUT https://[your-service-name].search.windows.net/skillset/demoskillset?api-version=2019-05-06 32 | Content-Type: application/json 33 | api-key: [api-key] 34 | ``` 35 | 36 | ## Skillset 37 | 38 | ```http 39 | PUT https://[your-service-name].search.windows.net/skillset/demoskillset?api-version=2019-05-06 40 | Content-Type: application/json 41 | api-key: [api-key] 42 | ``` 43 | 44 | >**Note** Be sure to replace the function url with your deployed funtion url. 45 | 46 | ```json 47 | { 48 | "description": 49 | "Extract entities, detect language and extract key-phrases. Also does OCR and submit everything to Content Moderator", 50 | "skills": 51 | [ 52 | { 53 | "description": "Extract text (plain and structured) from image.", 54 | "@odata.type": "#Microsoft.Skills.Vision.OcrSkill", 55 | "context": "/document/normalized_images/*", 56 | "defaultLanguageCode": "en", 57 | "detectOrientation": true, 58 | "inputs": [ 59 | { 60 | "name": "image", 61 | "source": "/document/normalized_images/*" 62 | } 63 | ], 64 | "outputs": [ 65 | { 66 | "name": "text", "targetName": "myOcrText" 67 | } 68 | ] 69 | }, 70 | { 71 | "@odata.type": "#Microsoft.Skills.Text.MergeSkill", 72 | "description": "Create mergedText, which includes all the textual representation of each image inserted at the right location in the content field.", 73 | "context": "/document", 74 | "insertPreTag": " ", 75 | "insertPostTag": " ", 76 | "inputs": [ 77 | { 78 | "name":"text", "source": "/document/content" 79 | }, 80 | { 81 | "name": "itemsToInsert", "source": "/document/normalized_images/*/myOcrText" 82 | }, 83 | { 84 | "name":"offsets", "source": "/document/normalized_images/*/contentOffset" 85 | } 86 | ], 87 | "outputs": [ 88 | { 89 | "name": "mergedText", "targetName" : "mergedText" 90 | } 91 | ] 92 | }, 93 | { 94 | "@odata.type": "#Microsoft.Skills.Text.LanguageDetectionSkill", 95 | "inputs": [ 96 | { 97 | "name": "text", "source": "/document/mergedText" 98 | } 99 | ], 100 | "outputs": [ 101 | { 102 | "name": "languageCode", 103 | "targetName": "languageCode" 104 | } 105 | ] 106 | }, 107 | { 108 | "@odata.type": "#Microsoft.Skills.Text.SplitSkill", 109 | "textSplitMode" : "pages", 110 | "maximumPageLength": 4000, 111 | "inputs": [ 112 | { 113 | "name": "text", 114 | "source": "/document/mergedText" 115 | }, 116 | { 117 | "name": "languageCode", 118 | "source": "/document/languageCode" 119 | } 120 | ], 121 | "outputs": [ 122 | { 123 | "name": "textItems", 124 | "targetName": "pages" 125 | } 126 | ] 127 | }, 128 | { 129 | "@odata.type": "#Microsoft.Skills.Text.KeyPhraseExtractionSkill", 130 | "context": "/document/pages/*", 131 | "inputs": [ 132 | { 133 | "name": "text", "source": "/document/pages/*" 134 | }, 135 | { 136 | "name":"languageCode", "source": "/document/languageCode" 137 | } 138 | ], 139 | "outputs": [ 140 | { 141 | "name": "keyPhrases", 142 | "targetName": "keyPhrases" 143 | } 144 | ] 145 | }, 146 | { 147 | "@odata.type": "#Microsoft.Skills.Text.EntityRecognitionSkill", 148 | "categories": [ "Organization" ], 149 | "defaultLanguageCode": "en", 150 | "context": "/document/pages/*", 151 | "inputs": [ 152 | { 153 | "name": "text", "source": "/document/pages/*" 154 | } 155 | ], 156 | "outputs": [ 157 | { 158 | "name": "organizations", "targetName": "organizations" 159 | } 160 | ] 161 | }, 162 | { 163 | "@odata.type": "#Microsoft.Skills.Custom.WebApiSkill", 164 | "description": "Our new moderator custom skill", 165 | "uri": "https://[your-function-urll].azurewebsites.net/api/ContentModerator?code=[your-content-moderator-api-key]", 166 | "batchSize":1, 167 | "context": "/document", 168 | "inputs": [ 169 | { 170 | "name": "text", 171 | "source": "/document/mergedText" 172 | } 173 | ], 174 | "outputs": [ 175 | { 176 | "name": "text", 177 | "targetName": "needsModeration" 178 | } 179 | ] 180 | } 181 | ], 182 | "cognitiveServices": { 183 | "@odata.type": "#Microsoft.Azure.Search.CognitiveServicesByKey", 184 | "description": "my-cog-serv", 185 | "key": "your-api-key-here" 186 | } 187 | } 188 | ``` 189 | 190 | ## Index 191 | 192 | ```http 193 | PUT https://[your-service-name].search.windows.net/indexes/demoindex?api-version=2019-05-06 194 | Content-Type: application/json 195 | api-key: [api-key] 196 | ``` 197 | 198 | ```json 199 | { 200 | "fields": [ 201 | { 202 | "name": "id", 203 | "type": "Edm.String", 204 | "key": true, 205 | "searchable": true, 206 | "filterable": false, 207 | "facetable": false, 208 | "sortable": true 209 | }, 210 | { 211 | "name": "blob_uri", 212 | "type": "Edm.String", 213 | "searchable": true, 214 | "filterable": false, 215 | "facetable": false, 216 | "sortable": true 217 | }, 218 | { 219 | "name": "content", 220 | "type": "Edm.String", 221 | "sortable": false, 222 | "searchable": true, 223 | "filterable": false, 224 | "facetable": false 225 | }, 226 | { 227 | "name": "languageCode", 228 | "type": "Edm.String", 229 | "searchable": true, 230 | "filterable": false, 231 | "facetable": false 232 | }, 233 | { 234 | "name": "keyPhrases", 235 | "type": "Collection(Edm.String)", 236 | "searchable": true, 237 | "filterable": false, 238 | "facetable": false 239 | }, 240 | { 241 | "name": "organizations", 242 | "type": "Collection(Edm.String)", 243 | "searchable": true, 244 | "sortable": false, 245 | "filterable": false, 246 | "facetable": false 247 | }, 248 | { 249 | "name": "myOcrText", 250 | "type": "Collection(Edm.String)", 251 | "searchable": true, 252 | "filterable": false, 253 | "facetable": false 254 | } , 255 | { 256 | "name": "needsModeration", 257 | "type": "Edm.Boolean", 258 | "searchable": false, 259 | "sortable": false, 260 | "filterable": true, 261 | "facetable": false 262 | } 263 | ] 264 | } 265 | ``` 266 | 267 | ## Indexer 268 | 269 | ```http 270 | PUT https://[your-service-name].search.windows.net/indexers/demoindexer?api-version=2019-05-06 271 | Content-Type: application/json 272 | api-key: [api-key] 273 | ``` 274 | 275 | ```json 276 | { 277 | "dataSourceName" : "demodata", 278 | "targetIndexName" : "demoindex", 279 | "skillsetName" : "demoskillset", 280 | "fieldMappings" : [ 281 | { 282 | "sourceFieldName" : "metadata_storage_path", 283 | "targetFieldName" : "id", 284 | "mappingFunction" : 285 | { "name" : "base64Encode" } 286 | }, 287 | { 288 | "sourceFieldName" : "content", 289 | "targetFieldName" : "content" 290 | }, 291 | { 292 | "sourceFieldName" : "metadata_storage_path", 293 | "targetFieldName" : "blob_uri" 294 | } 295 | ], 296 | "outputFieldMappings" : 297 | [ 298 | { 299 | "sourceFieldName" : "/document/pages/*/organizations/*", 300 | "targetFieldName" : "organizations" 301 | }, 302 | { 303 | "sourceFieldName" : "/document/pages/*/keyPhrases/*", 304 | "targetFieldName" : "keyPhrases" 305 | }, 306 | { 307 | "sourceFieldName": "/document/languageCode", 308 | "targetFieldName": "languageCode" 309 | }, 310 | { 311 | "sourceFieldName": "/document/normalized_images/*/myOcrText", 312 | "targetFieldName": "myOcrText" 313 | }, 314 | { 315 | "sourceFieldName": "/document/needsModeration", 316 | "targetFieldName": "needsModeration" 317 | } 318 | ], 319 | "parameters": 320 | { 321 | "maxFailedItems":-1, 322 | "maxFailedItemsPerBatch":-1, 323 | "configuration": 324 | { 325 | "dataToExtract": "contentAndMetadata", 326 | "imageAction": "generateNormalizedImages" 327 | } 328 | } 329 | } 330 | 331 | ``` 332 | 333 | ## Check Status 334 | 335 | ```http 336 | GET https://[your-service-name].search.windows.net/indexers/demoindexer/status?api-version=2019-05-06 337 | Content-Type: application/json 338 | api-key: [api-key] 339 | ``` 340 | 341 | ## Check files and the moderated text indicator 342 | 343 | ```http 344 | GET https://[your-service-name].search.windows.net/indexes/demoindex/docs?search=*&$select=blob_uri,needsModeration,organizations&api-version=2019-05-06 345 | Content-Type: application/json 346 | api-key: [api-key] 347 | ``` 348 | 349 | ## Filter moderated content using Azure Search Explorer 350 | 351 | ```http 352 | $select=blob_uri,needsModeration,content&$filter=needsModeration eq true 353 | ``` 354 | 355 | ## Next Step 356 | 357 | [Bots Lab](../../labs/lab-06-bot-business-documents.md) or 358 | [Back to Read Me](../../README.md) -------------------------------------------------------------------------------- /resources/images/enrichment-pipeline-details/Slide1.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/enrichment-pipeline-details/Slide1.PNG -------------------------------------------------------------------------------- /resources/images/enrichment-pipeline-details/Slide10.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/enrichment-pipeline-details/Slide10.PNG -------------------------------------------------------------------------------- /resources/images/enrichment-pipeline-details/Slide11.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/enrichment-pipeline-details/Slide11.PNG -------------------------------------------------------------------------------- /resources/images/enrichment-pipeline-details/Slide12.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/enrichment-pipeline-details/Slide12.PNG -------------------------------------------------------------------------------- /resources/images/enrichment-pipeline-details/Slide13.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/enrichment-pipeline-details/Slide13.PNG -------------------------------------------------------------------------------- /resources/images/enrichment-pipeline-details/Slide2.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/enrichment-pipeline-details/Slide2.PNG -------------------------------------------------------------------------------- /resources/images/enrichment-pipeline-details/Slide3.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/enrichment-pipeline-details/Slide3.PNG -------------------------------------------------------------------------------- /resources/images/enrichment-pipeline-details/Slide4.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/enrichment-pipeline-details/Slide4.PNG -------------------------------------------------------------------------------- /resources/images/enrichment-pipeline-details/Slide5.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/enrichment-pipeline-details/Slide5.PNG -------------------------------------------------------------------------------- /resources/images/enrichment-pipeline-details/Slide6.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/enrichment-pipeline-details/Slide6.PNG -------------------------------------------------------------------------------- /resources/images/enrichment-pipeline-details/Slide7.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/enrichment-pipeline-details/Slide7.PNG -------------------------------------------------------------------------------- /resources/images/enrichment-pipeline-details/Slide8.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/enrichment-pipeline-details/Slide8.PNG -------------------------------------------------------------------------------- /resources/images/enrichment-pipeline-details/Slide9.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/enrichment-pipeline-details/Slide9.PNG -------------------------------------------------------------------------------- /resources/images/lab-azure-search/cog-search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/lab-azure-search/cog-search.png -------------------------------------------------------------------------------- /resources/images/lab-azure-search/compete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/lab-azure-search/compete.png -------------------------------------------------------------------------------- /resources/images/lab-azure-search/data-source-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/lab-azure-search/data-source-2.png -------------------------------------------------------------------------------- /resources/images/lab-azure-search/data-source.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/lab-azure-search/data-source.png -------------------------------------------------------------------------------- /resources/images/lab-azure-search/example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/lab-azure-search/example.png -------------------------------------------------------------------------------- /resources/images/lab-azure-search/import-data.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/lab-azure-search/import-data.png -------------------------------------------------------------------------------- /resources/images/lab-azure-search/index-settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/lab-azure-search/index-settings.png -------------------------------------------------------------------------------- /resources/images/lab-azure-search/indexer-advanced.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/lab-azure-search/indexer-advanced.png -------------------------------------------------------------------------------- /resources/images/lab-azure-search/inverted.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/lab-azure-search/inverted.png -------------------------------------------------------------------------------- /resources/images/lab-azure-search/query.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/lab-azure-search/query.png -------------------------------------------------------------------------------- /resources/images/lab-azure-search/redirect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/lab-azure-search/redirect.png -------------------------------------------------------------------------------- /resources/images/lab-azure-search/search-explorer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/lab-azure-search/search-explorer.png -------------------------------------------------------------------------------- /resources/images/lab-azure-search/search-options.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/lab-azure-search/search-options.png -------------------------------------------------------------------------------- /resources/images/lab-bot/bot-builder-dotnet-project.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/lab-bot/bot-builder-dotnet-project.png -------------------------------------------------------------------------------- /resources/images/lab-bot/bots-concepts-middleware.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/lab-bot/bots-concepts-middleware.png -------------------------------------------------------------------------------- /resources/images/lab-bot/diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/lab-bot/diagram.png -------------------------------------------------------------------------------- /resources/images/lab-bot/emulator-running.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/lab-bot/emulator-running.png -------------------------------------------------------------------------------- /resources/images/lab-bot/expected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/lab-bot/expected.png -------------------------------------------------------------------------------- /resources/images/lab-bot/locals.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/lab-bot/locals.png -------------------------------------------------------------------------------- /resources/images/lab-bot/locals2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/lab-bot/locals2.png -------------------------------------------------------------------------------- /resources/images/lab-bot/retrieving-cognitive-attrributes.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/lab-bot/retrieving-cognitive-attrributes.gif -------------------------------------------------------------------------------- /resources/images/lab-bot/setbreak.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/lab-bot/setbreak.png -------------------------------------------------------------------------------- /resources/images/lab-custom-skills/cmd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/lab-custom-skills/cmd.png -------------------------------------------------------------------------------- /resources/images/lab-custom-skills/code.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/lab-custom-skills/code.png -------------------------------------------------------------------------------- /resources/images/lab-custom-skills/moderatedtex-query-portal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/lab-custom-skills/moderatedtex-query-portal.png -------------------------------------------------------------------------------- /resources/images/lab-custom-skills/panel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/lab-custom-skills/panel.png -------------------------------------------------------------------------------- /resources/images/lab-custom-skills/structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/lab-custom-skills/structure.png -------------------------------------------------------------------------------- /resources/images/lab-custom-skills/versions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/lab-custom-skills/versions.png -------------------------------------------------------------------------------- /resources/images/lab-custom-skills/yellow-flag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/lab-custom-skills/yellow-flag.png -------------------------------------------------------------------------------- /resources/images/lab-environment-creation/create-search-collect-info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/lab-environment-creation/create-search-collect-info.png -------------------------------------------------------------------------------- /resources/images/lab-environment-creation/create-search-service.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/lab-environment-creation/create-search-service.png -------------------------------------------------------------------------------- /resources/images/lab-environment-creation/create-service-full-portal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/lab-environment-creation/create-service-full-portal.png -------------------------------------------------------------------------------- /resources/images/lab-environment-creation/git.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/lab-environment-creation/git.png -------------------------------------------------------------------------------- /resources/images/lab-final-case/complex1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/lab-final-case/complex1.png -------------------------------------------------------------------------------- /resources/images/lab-final-case/complex2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/lab-final-case/complex2.png -------------------------------------------------------------------------------- /resources/images/lab-final-case/complex4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/lab-final-case/complex4.png -------------------------------------------------------------------------------- /resources/images/lab-final-case/simple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/lab-final-case/simple.png -------------------------------------------------------------------------------- /resources/images/lab-image-skills/postman-no-data.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/lab-image-skills/postman-no-data.png -------------------------------------------------------------------------------- /resources/images/lab-text-skills/plan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/lab-text-skills/plan.png -------------------------------------------------------------------------------- /resources/images/lab-text-skills/postman-help.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/lab-text-skills/postman-help.png -------------------------------------------------------------------------------- /resources/images/lab-text-skills/skillset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/lab-text-skills/skillset.png -------------------------------------------------------------------------------- /resources/images/readme/architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/readme/architecture.png -------------------------------------------------------------------------------- /resources/images/readme/header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/readme/header.png -------------------------------------------------------------------------------- /resources/images/readme/tech-map.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/readme/tech-map.png -------------------------------------------------------------------------------- /resources/images/sol-arch/architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/sol-arch/architecture.png -------------------------------------------------------------------------------- /resources/images/sol-arch/cost.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/sol-arch/cost.png -------------------------------------------------------------------------------- /resources/images/sol-arch/no-meta.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/sol-arch/no-meta.png -------------------------------------------------------------------------------- /resources/images/sol-arch/postman.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/images/sol-arch/postman.png -------------------------------------------------------------------------------- /resources/instructor-notes/KMB-Opening.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/instructor-notes/KMB-Opening.pptx -------------------------------------------------------------------------------- /resources/instructor-notes/README.md: -------------------------------------------------------------------------------- 1 | # Instructor Notes 2 | 3 | This folder has resources for the instructor listed below. 4 | 5 | ## Opening Presentation 6 | 7 | Use the KMB-Opening.pptx presentation to: 8 | 9 | 1. Presenters name 10 | 1. Start your training 11 | 1. Polls 12 | 1. Customized Agenda 13 | 1. Announcements 14 | 1. Known bugs not fixed yet 15 | 1. CSW x KMB difference (slide 4) 16 | 1. Breaking News 17 | 1. Spektra Instructions 18 | 1. Github link - or 19 | 1. Survey URL 20 | 1. Talk about environment cleaning, to avoid costs. 21 | 22 | While the introduction has a pdf version, this one won't have one. The idea is to keep on editing this presentation for each delivery. 23 | 24 | ## Azure Search LAB 25 | 26 | Open the page to show how important is the Analyzer definition. This page shows the different results you can get from Standard Lucene, English Lucene and English Microsoft. Search for: 27 | 28 | + "Alice": Standard Lucene gets 10 hits less than the others 29 | + "Thinking": Now the hits totals are very different. English Lucene returns "think" too. English Microsoft returns even"thought" 30 | + "Knives": Only Microsoft English returns information, where "knife" was found 31 | 32 | ## Text Skills LAB 33 | 34 | + Important to read the skills been used with the students, explain why pages with 4000 characters is an example of valuable information that teaches how text split is important. It also helps to learn how the output of one skill is input of another one. 35 | + Some warnings about long words and/or text are expected, Cognitive Search works with the limitations of the Cognitive Services APIs that are used under the hood. 36 | + Someone may ask why there are duplicates for `keyPhrases` and `organizations`. It is unique per page, we are creating lots and lots of them, because on the Entity Recognition actual (December 2018) 4000 characters limit. All of it may change in the future, the limits and the uniqueness per page. 37 | 38 | ## Image Skills LAB 39 | 40 | + OCR: Expected performance is 3 seconds per image. For documents with multiple images, you can apply those 3 seconds for every one of them. The product performance is under constant optimizations and improvements are expected soon 41 | + Talk about normalized images. The lab has a "Note!" for that. All info you need is there 42 | + Highlight that now the skillset is merging and splitting the content 43 | 44 | ## Custom Skills LAB 45 | 46 | Important to comment in the Azure Functions Code: 47 | 48 | 1. language: eng (Content Moderator) x en (Azure Search) 49 | 1. For now, language is not dynamic (not using the document extracted language). So, we are not moderating spanish docs very well. 50 | 1. 1024 limit. 51 | 1. host x region. Without and with https 52 | 1. Complex types explanation: why we are transforming in boolean 53 | 1. You can use [this](https://github.com/Rodrigossz/AzureCognitiveSkill) Azure Functions solution to demo the complex type that is returned 54 | 1. Explanation: we are only using PII 55 | 56 | Important to comment about the skillset: 57 | 58 | 1. We could submit entities and organizations to content moderator 59 | 1. Content Moderator limit, 1024 characters, could be a smaller problem if we submit the pages instead of the merged text. Maybe in the next version of the training. You can ask those who finished early to do it. Extra Challenge. 60 | 61 | ## Bot LAB 62 | 63 | + You can demo searches for "linux" and "LearnAI". Ctrl+click the URL to open the IMAGES, not the other files. 64 | + Search for moderated documents 65 | + Explain details of Framework 4 code 66 | 67 | ## Final Case - Finished Solution 68 | 69 | Expected: 70 | 71 | + Complex Scenarios 72 | + Multiple datasets: 73 | + More than one datasource: product catalog, reviews, ERP, CRM 74 | + Data source is too big, data needs to be partitioned 75 | + Datasources updated in different times 76 | + Multiple Indexes 77 | + One for each region, in each languages 78 | + Each region demands different fields or ranking or Analyzer or suggester 79 | + Multiple Skillsets 80 | + Each product or region requires different schedules 81 | + Partition the data in 2: images and not images, to save processing time and money with specific skillset for each type of data. 82 | + External data coming from VIVINO/Logistics/Other custom skillset with a different schedule update - "runs once a day" 83 | 84 | + Sizing discussion: [Tier](https://azure.microsoft.com/en-us/pricing/details/search/) x [SLA](https://azure.microsoft.com/en-us/support/legal/sla/search/v1_0/), Units. For SLA is required 2 or more copies. Basic tier limit is 2 GB, Standard has 300 GB total. **Also, it is required at least Basic tier to have replicas. And the replica can be located in the Brazil South region, reducing latency for South America clients.** 85 | 86 | + Skills 87 | + Text Skills 88 | + OCR (text in images) 89 | + Image Analysis too (images scenes descriptions, Celebrity Detection) 90 | + Language detection 91 | + Entity Extraction (location, organizations) 92 | + Important to discuss the order of the transformations 93 | 94 | + Other Data & AI that could be used 95 | + Translation API 96 | + Personalization API (Private Preview in Jan 2019) 97 | + Entity Linking API for the detected entities 98 | + Bing Search in the Bot to improve the search experience 99 | + CosmosDB as a data source for the product catalog 100 | + AML for custom AI for published as an API for: price optimization, campaign optimization, etc 101 | 102 | + South America means 2 more languages after the original docs in English: Portuguese and Spanish. It is expected discussions like: 103 | + Save all fields in 3 languages? Storage costs. Write once and read many 104 | + 1 index in BR South Region with fields in Portuguese and Spanish + 1 index in the US in English 105 | + Translate on the fly? Data out and API usage costs, latency -------------------------------------------------------------------------------- /resources/md-files/enrichment-pipeline-details.md: -------------------------------------------------------------------------------- 1 | # Azure Cognitive Search - Enrichment Pipeline Details 2 | 3 | Details on how the Enrichment Pipeline works. 4 | 5 | ![1](../../resources/images/enrichment-pipeline-details/Slide1.PNG) 6 | 7 | ![1](../../resources/images/enrichment-pipeline-details/Slide2.PNG) 8 | 9 | ![1](../../resources/images/enrichment-pipeline-details/Slide3.PNG) 10 | 11 | ![1](../../resources/images/enrichment-pipeline-details/Slide4.PNG) 12 | 13 | ![1](../../resources/images/enrichment-pipeline-details/Slide5.PNG) 14 | 15 | ![1](../../resources/images/enrichment-pipeline-details/Slide6.PNG) 16 | 17 | ![1](../../resources/images/enrichment-pipeline-details/Slide7.PNG) 18 | 19 | ![1](../../resources/images/enrichment-pipeline-details/Slide8.PNG) 20 | 21 | ![1](../../resources/images/enrichment-pipeline-details/Slide9.PNG) 22 | 23 | ![1](../../resources/images/enrichment-pipeline-details/Slide10.PNG) 24 | 25 | ![1](../../resources/images/enrichment-pipeline-details/Slide11.PNG) 26 | 27 | ![1](../../resources/images/enrichment-pipeline-details/Slide12.PNG) 28 | 29 | ![1](../../resources/images/enrichment-pipeline-details/Slide13.PNG) 30 | 31 | ## Next Step 32 | 33 | [Return to the Image Skills Lab](../../labs/lab-04-image-skills.md) or 34 | [Back to Read Me](../../README.md) -------------------------------------------------------------------------------- /resources/md-files/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction - Presentation 2 | 3 | ![Slide](../../resources/slides/01.png) 4 | 5 | ![Slide](../../resources/slides/02.png) 6 | 7 | ![Slide](../../resources/slides/03.png) 8 | 9 | ![Slide](../../resources/slides/04.png) 10 | 11 | ![Slide](../../resources/slides/05.png) 12 | 13 | ![Slide](../../resources/slides/06.png) 14 | 15 | ![Slide](../../resources/slides/07.png) 16 | 17 | ![Slide](../../resources/slides/08.png) 18 | 19 | ![Slide](../../resources/slides/09.png) 20 | 21 | ![Slide](../../resources/slides/10.png) 22 | 23 | ![Slide](../../resources/slides/11.png) 24 | 25 | ![Slide](../../resources/slides/12.png) 26 | 27 | ![Slide](../../resources/slides/13.png) 28 | 29 | ![Slide](../../resources/slides/14.png) 30 | 31 | ![Slide](../../resources/slides/15.png) 32 | 33 | ![Slide](../../resources/slides/16.png) 34 | 35 | ![Slide](../../resources/slides/17.png) 36 | 37 | ![Slide](../../resources/slides/18.png) 38 | 39 | ![Slide](../../resources/slides/19.png) 40 | 41 | ![Slide](../../resources/slides/20.png) 42 | 43 | ![Slide](../../resources/slides/21.png) 44 | 45 | ![Slide](../../resources/slides/22.png) 46 | 47 | ![Slide](../../resources/slides/23_new.png) 48 | 49 | ![Slide](../../resources/slides/24.png) 50 | 51 | ![Slide](../../resources/slides/25.png) 52 | 53 | ![Slide](../../resources/slides/26.png) 54 | 55 | ![Slide](../../resources/slides/27.png) 56 | 57 | ![Slide](../../resources/slides/28.png) 58 | 59 | ![Slide](../../resources/slides/29.png) 60 | 61 | ![Slide](../../resources/slides/30.png) 62 | 63 | ![Slide](../../resources/slides/31.png) 64 | 65 | ![Slide](../../resources/slides/32.png) 66 | 67 | ![Slide](../../resources/slides/33.png) 68 | 69 | ![Slide](../../resources/slides/34.png) 70 | 71 | ![Slide](../../resources/slides/35.png) 72 | 73 | 74 | ## Next Step 75 | 76 | [Solution architecture](./solution-architecture.md) or [Back to Labs Menu](../../README.md) -------------------------------------------------------------------------------- /resources/md-files/qa-feedback-survey.md: -------------------------------------------------------------------------------- 1 | # Closing 2 | 3 | ## Questions and Answers 4 | 5 | If you are attending an ILT (Instructor Lead Training), now it is time for your final questions. 6 | 7 | ## Feedback 8 | 9 | Every feedback is welcome, please write to learnai@microsoft.com . 10 | 11 | ## Survey 12 | 13 | If you are attending an ILT, the Instructor will provide the link for a 5 minute survey. 14 | 15 | ## Next step 16 | 17 | [Back to Read Me](../../README.md) -------------------------------------------------------------------------------- /resources/md-files/solution-architecture.md: -------------------------------------------------------------------------------- 1 | # Solution Architecture 2 | 3 | This solution uses a variety of pre-built cognitive skills and extend the AI transformations with custom skills, based on Azure Functions. In this Architecture document you will see details of the solution created throughout the training labs. There are details about the target use case, the dataset, the labs, the cost, the tools, and the interface. 4 | 5 | To fully understand this document, It is expected that you have understood all the information presented in the [introduction](./Introduction.md)) of the training: **What is Cognitive Search, How it works, Why it is relevant for any company in the world, when to use it**. 6 | 7 | The labs have a progressive level of complexity and they will help you to understand how each aspect of the technology can be used for the search solution. 8 | 9 | ## Use Case 10 | 11 | Every company has business documents: contracts, memos, presentations, images, spreadsheets, business plans and so on. Usually these documents doesn't have the metadata necessary to be searchable, **as you can see in the image below**. Since documents don't have tags, categories and comments, they only can be found by name. This creates a poor search experience, slowing down business process and reducing productivity. 12 | 13 | ![Lack of Metadata](../../resources/images/sol-arch/no-meta.png) 14 | 15 | Azure Cognitive Search, the Microsoft product for Knowledge Mining, uses the most advanced cognitive capabilities, based on Microsoft's Azure AI Platform, to extract and create enriched metadata about your documents, vastly improving the overall search experience. This process also allow companies to enforce compliance, detect risks and detect policies violations. 16 | 17 | Enterprises may need to search for: 18 | 19 | + Words like "risk" and "fraud" in pdf/word contracts, when they are 10 or less words distant one from the other. 20 | + Specific people or objects in images. 21 | + Document content instead of its name, the only option for the situation of the image below. 22 | + Entities like companies or technologies in memos or reports. 23 | + Compliance violations like forbidden words or phrases in any document or image. 24 | + Forms content, handwritten or not. 25 | 26 | This Cognitive Search solution addresses these problems, extracting insights from multiple documents formats and languages. 27 | 28 | >Tip! Some other possible uses for the labs could be: 29 | > 30 | >+ Demos, you can keep this environment ready, loaded 31 | >+ POCs: You just need to upload some of the client's data and re-execute the enrichment pipeline. **You can prove the concept in front of the client, in minutes**. 32 | >+ Production: Since we are using PaaS, it has SLA and scalability by design. 33 | >+ Personal Use: If you have lots of documents or photos, you can use these labs to analyze them, too. 34 | 35 | ### Architecture 36 | 37 | ![Architecture](../../resources/images/sol-arch/architecture.png) 38 | 39 | ## Labs Details 40 | 41 | In the [First Lab](../../labs/lab-environment-creation.md) you will learn how to create the required environment for this training, including the business documents dataset upload into Azure Blob Storage. 42 | 43 | In the [Second Lab](../../labs/lab-02-azure-search.md) you will learn how index the business documents with "basic" Azure Search. The objective is teach how the standard features adds sophisticated search capabilities to your documents: natural language search, ranking, paging, suggestions and so on. This lab will use the Azure Portal only, no coding is required. 44 | 45 | In the [Third Lab](../../labs/lab-03-text-skills.md) you will learn the next level of data enrichment, using Cognitive Search. It will be clear for you how AI can **extend** the metadata created, enabling an advanced search experience. In this lab you will do some coding with Postman. 46 | 47 | In the [Fourth Lab](../../labs/lab-04-image-skills.md) you will learn how text skills don't work for images. You will detect and fix this situation, making your images queryable too. For this lab you will do some coding with Postman. 48 | 49 | In the [Fifth Lab](../../labs/lab-05-custom-skills.md) you will learn how to create a custom skill using Azure Content Moderator API and Azure Functions, connection this transformation into the enrichment pipeline. You will detect documents with incompliant content. For this lab you will do some coding with Postman and Visual Studio. The Azure Portal is also used, to create the Azure Function instance. 50 | 51 | In the [Sixth Lab](../../labs/lab-06-bot-business-documents.md) you will learn how to use a Bot to interact with the Azure Search Index, the Business Documents Bot. This lab uses the Bot Emulator and Visual Studio. 52 | 53 | In the [Seventh Lab](../../labs/lab-final-case.md) you are invited to, based on what you have learned, create the architecture of a Knowledge Mining solution for another use case. 54 | 55 | ## Dataset 56 | 57 | We will provide a sample dataset that contains documents with multiple languages and formats including HTML, doc, pdf, ppt, png and jpg. They were selected for a better learning experience, showcasing the technology capabilities. 58 | 59 | The dataset has 21 files and 15 MBs. It includes public Microsoft business documents. There is a document in spanish, so you can learn about language identification. There is also a document with anonymized Personal Identifiable Information (PII) for the Content Moderator lab. 60 | 61 | Since we are working with unstructured data, any set of files can be used. In other words, this could be a **Bring Your Own Data** solution; you can test later with any dataset you want. 62 | 63 | ## Demo - Cognitive Search Pipeline 64 | 65 | The [AI Sandbox](https://text-analytics-demo-dev.azurewebsites.net/) is an interesting demo of the Cognitive Search Pipeline, similar to what will be implemented. It is useful to understand how a cognitive skill output is input for another one, in the same pipeline. 66 | This demo is public and you can use with clients and partners. 67 | 68 | ## Costs 69 | 70 | Here you can see a list of the resources used in this training. The [Azure Calculator](https://azure.microsoft.com/en-us/pricing/calculator/) can be used for pricing estimation. 71 | Prices are estimates and are not intended as actual price quotes. Actual prices may vary depending upon the date of purchase, currency of payment, and type of agreement you enter with Microsoft. Contact a Microsoft sales representative for additional information on pricing. 72 | **The estimated monthly cost of this solution, with the provided dataset, is close to US$ 76.18 or US$2.54 per day.** 73 | 74 | ![Monthly Cost](../../resources/images/sol-arch/cost.png) 75 | 76 | >Note! Starting December 21, 2018, you will be able to associate a Cognitive Services resource with an Azure Search skillset. This will allow us to start charging for skillset execution. On this date, we will also begin charging for image extraction as part of the document-cracking stage. Text extraction from documents will continue to be offered at no additional cost. The execution of built-in skills will be charged at the existing [Cognitive Services pay-as-you go price](https://azure.microsoft.com/en-us/pricing/details/cognitive-services/). Image extraction pricing will be charged at preview pricing, and is described on the [Azure Search pricing page](https://azure.microsoft.com/en-us/pricing/details/search/). About images: You pay for the images extracted/normalized (even if it is a pdf), and then pay for any built-in skills you call (including OCR). [This](https://docs.microsoft.com/en-us/azure/search/cognitive-search-attach-cognitive-services#example-estimating-the-cost-of-document-cracking-and-enrichment) is an example of how that may work. 77 | 78 | ## Information Delivery - A Bot as User Interface 79 | 80 | Microsoft Azure Search provides an API for web or mobile applications, creating great search experiences for users. Another type of application that can benefit from Azure Search is a Bot, a trending technology from Microsoft. 81 | 82 | Although this is not a training on bots, you will learn how to integrate one with the [Azure Search Rest API](https://docs.microsoft.com/en-us/azure/search/search-query-rest-api). This Bot will be as simple as possible, running locally with the [Bot Emulator](https://github.com/Microsoft/BotFramework-Emulator). 83 | 84 | This [gif](../../resources/images/lab-bot/retrieving-cognitive-attrributes.gif) has the expected finished solution, but with a different dataset. Now you have idea of what we will be created by the end of the training. 85 | 86 | The Microsoft Learn AI Team has a 2 day [Computer Vision Bot Bootcamp](https://github.com/Azure/LearnAI-Bootcamp) that shows you how to create an intelligent bot using Azure Search, CosmosDB and Cognitive Services. 87 | 88 | ## Lab Tools for APIs 89 | 90 | Labs 3, 4, and 5 will use Postman for [REST API calls](https://docs.microsoft.com/en-us/azure/search/search-fiddler). You can use any other REST API tool that can formulate and send HTTP requests, but we suggest you to use Postman since the training was created with/for it. The image below shows a visual example of Postman being used for Cognitive Search. Please check the suggested Postman tutorial on [Pre-Reqs section of the initial page](./readme.md). 91 | 92 | ![Postman Example](../../resources/images/sol-arch/postman.png) 93 | 94 | > **Tip** Important details about Postman: 95 | > 96 | > + You can save your commands, which is useful for reuse, not only within this workshop, but also in your future projects. 97 | > + You need to create a free account. A confirmation message is emailed to you. 98 | > + You can export all your commands into json format. This file can then be saved into the storage account of the lab, into a cloud storage like OneDrive, or anywhere you like. This process helps you save, share, and reuse your work. 99 | > + These return codes indicate success after an API call request: 200, 201 and 204. 100 | > + Error messages and warnings are very clear. 101 | > + Besides the API URL and call type, we will use GET/PUT/POST (depending on what action we are taking), and you need to use the header for Content-Type and api-key. The json commands must be placed into the "body / raw" area. If you are struggling using Postman, here's a friendly reminder to [review the resource from the prerequisites](https://docs.microsoft.com/en-us/azure/search/search-fiddler). 102 | 103 | ## Next step 104 | 105 | [Environment Creation Lab](../../labs/lab-environment-creation.md) or [Back to Read Me](../../README.md) -------------------------------------------------------------------------------- /resources/resources/template.json: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/resources/template.json -------------------------------------------------------------------------------- /resources/slides/01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/slides/01.png -------------------------------------------------------------------------------- /resources/slides/02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/slides/02.png -------------------------------------------------------------------------------- /resources/slides/03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/slides/03.png -------------------------------------------------------------------------------- /resources/slides/04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/slides/04.png -------------------------------------------------------------------------------- /resources/slides/05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/slides/05.png -------------------------------------------------------------------------------- /resources/slides/06.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/slides/06.png -------------------------------------------------------------------------------- /resources/slides/07.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/slides/07.png -------------------------------------------------------------------------------- /resources/slides/08.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/slides/08.png -------------------------------------------------------------------------------- /resources/slides/09.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/slides/09.png -------------------------------------------------------------------------------- /resources/slides/10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/slides/10.png -------------------------------------------------------------------------------- /resources/slides/11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/slides/11.png -------------------------------------------------------------------------------- /resources/slides/12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/slides/12.png -------------------------------------------------------------------------------- /resources/slides/13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/slides/13.png -------------------------------------------------------------------------------- /resources/slides/14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/slides/14.png -------------------------------------------------------------------------------- /resources/slides/15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/slides/15.png -------------------------------------------------------------------------------- /resources/slides/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/slides/16.png -------------------------------------------------------------------------------- /resources/slides/17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/slides/17.png -------------------------------------------------------------------------------- /resources/slides/18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/slides/18.png -------------------------------------------------------------------------------- /resources/slides/19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/slides/19.png -------------------------------------------------------------------------------- /resources/slides/20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/slides/20.png -------------------------------------------------------------------------------- /resources/slides/21.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/slides/21.png -------------------------------------------------------------------------------- /resources/slides/22.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/slides/22.png -------------------------------------------------------------------------------- /resources/slides/23_new.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/slides/23_new.png -------------------------------------------------------------------------------- /resources/slides/24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/slides/24.png -------------------------------------------------------------------------------- /resources/slides/25.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/slides/25.png -------------------------------------------------------------------------------- /resources/slides/26.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/slides/26.png -------------------------------------------------------------------------------- /resources/slides/27.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/slides/27.png -------------------------------------------------------------------------------- /resources/slides/28.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/slides/28.png -------------------------------------------------------------------------------- /resources/slides/29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/slides/29.png -------------------------------------------------------------------------------- /resources/slides/30.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/slides/30.png -------------------------------------------------------------------------------- /resources/slides/31.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/slides/31.png -------------------------------------------------------------------------------- /resources/slides/32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/slides/32.png -------------------------------------------------------------------------------- /resources/slides/33.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/slides/33.png -------------------------------------------------------------------------------- /resources/slides/34.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/slides/34.png -------------------------------------------------------------------------------- /resources/slides/35.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/slides/35.png -------------------------------------------------------------------------------- /resources/slides/introduction-pdf/kmb-introduction-v1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/slides/introduction-pdf/kmb-introduction-v1.pdf -------------------------------------------------------------------------------- /resources/slides/introduction-pdf/readme.md: -------------------------------------------------------------------------------- 1 | # LearnAI: Build an Enterprise Knowledge Mining Solution using the Microsoft AI Platform 2 | 3 | This folder has the same slides in pdf format, if you want to download for offline presentations. -------------------------------------------------------------------------------- /resources/slides/introduction-ppt/README.md: -------------------------------------------------------------------------------- 1 | # LearnAI: Build an Enterprise Knowledge Mining Solution using the Microsoft AI Platform 2 | 3 | This folder has the same slides in PowerPoint format, if you want to download for offline presentations. -------------------------------------------------------------------------------- /resources/slides/introduction-ppt/kmb-introduction-v1.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MicrosoftLearning/LearnAI-KnowledgeMiningBootcamp/fa36415dcd1cd51760d3bff8add553f8b6559bab/resources/slides/introduction-ppt/kmb-introduction-v1.pptx --------------------------------------------------------------------------------