{"id":5130,"date":"2024-07-16T15:29:05","date_gmt":"2024-07-16T06:29:05","guid":{"rendered":"https:\/\/blog.since2020.jp\/?p=5130"},"modified":"2024-12-16T16:01:23","modified_gmt":"2024-12-16T07:01:23","slug":"make_chatbot_by_vertexai","status":"publish","type":"post","link":"https:\/\/since2020.jp\/media\/make_chatbot_by_vertexai\/","title":{"rendered":"Google Chat API\u3068Vertex AI\u3067\u4f5c\u308bGemini\u642d\u8f09Chatbot\u306e\u4f5c\u6210\u65b9\u6cd5"},"content":{"rendered":"\n<p>Vertex AI\u3092\u7528\u3044\u3066Google Chat\u306e\u30c1\u30e3\u30c3\u30c8\u30dc\u30c3\u30c8\u3092\u4f5c\u6210\u3059\u308b\u65b9\u6cd5\u3092\u7d39\u4ecb\u3057\u307e\u3059\u3002<\/p>\n\n\n<h2>\u306f\u3058\u3081\u306b<\/h2>\n<p>\u4eca\u56de\u306fVertex AI\u3092\u7528\u3044\u3066Google Chat\u306e\u30c1\u30e3\u30c3\u30c8\u30dc\u30c3\u30c8\u3092\u4f5c\u6210\u3057\u307e\u3057\u305f\u3002<\/p>\r\n<p>\u4f5c\u6210\u3059\u308b\u624b\u9806\u3067\u96e3\u3057\u3044\u3082\u306e\u304c\u3042\u3063\u305f\u305f\u3081\u3001\u3053\u306e\u30d6\u30ed\u30b0\u3067\u4e00\u304b\u3089\u7d30\u304b\u304f\u8aac\u660e\u3057\u3066\u304a\u308a\u307e\u3059\u3002<\/p>\n\n<h2>\u4f7f\u7528\u3059\u308b\u30c4\u30fc\u30eb\u306e\u8aac\u660e<\/h2>\n<p><strong>Vertex AI Agent Builder<\/strong>\u3068\u306f<\/p>\r\n<p>\u3000Vertex AI Agent Builder\u306f\u3001\u6a5f\u68b0\u5b66\u7fd2\u30e2\u30c7\u30eb\u3084AI\u30a8\u30fc\u30b8\u30a7\u30f3\u30c8\u3092\u7c21\u5358\u306b\u69cb\u7bc9\u3001\u30c7\u30d7\u30ed\u30a4\u3001\u7ba1\u7406\u3059\u308b\u305f\u3081\u306e\u30c4\u30fc\u30eb\u3067\u3001Google Cloud\u306e\u5f37\u529b\u306a\u30a4\u30f3\u30d5\u30e9\u3068AI\u6280\u8853\u3092\u6d3b\u7528\u3057\u307e\u3059\u3002<\/p>\r\n<p>&nbsp;<\/p>\r\n<p><strong>Google Chat API<\/strong>\u3068\u306f<\/p>\r\n<p>\u3000<span data-token-index=\"0\" class=\"notion-enable-hover\">Google Chat API<\/span>\u306f\u3001Google Chat\u3067\u52d5\u4f5c\u3059\u308b\u30dc\u30c3\u30c8\u3084\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3092\u4f5c\u6210\u3059\u308b\u305f\u3081\u306e\u30c4\u30fc\u30eb\u3067\u3042\u308a\u3001\u30e1\u30c3\u30bb\u30fc\u30b8\u306e\u9001\u53d7\u4fe1\u3084\u30a4\u30f3\u30bf\u30e9\u30af\u30c6\u30a3\u30d6\u306a\u30ab\u30fc\u30c9\u306e\u4f7f\u7528\u3092\u30b5\u30dd\u30fc\u30c8\u3057\u307e\u3059\u3002\u3000<!-- notionvc: d0e6b6e0-30fe-47de-bcea-6c051080d9c9 --><\/p>\n\n<h2>\u5b9f\u88c5\u624b\u9806<\/h2>\n<p>\u30c1\u30e3\u30c3\u30c8\u30dc\u30c3\u30c8\u306e\u4f5c\u6210\u624b\u9806\u306f\u4ee5\u4e0b\u306e\u901a\u308a\u3067\u3059\u3002<\/p>\r\n<p>3.1 \u30a2\u30d7\u30ea\u306e\u4f5c\u6210<\/p>\r\n<p>3.2 \u30a2\u30d7\u30ea\u3092\u30c7\u30d7\u30ed\u30a4<\/p>\r\n<p>3.3 Google Chat API\u306e\u8a2d\u5b9a<\/p>\r\n<p>\u3067\u306f\u3001\u9806\u306b\u8aac\u660e\u3057\u3066\u3044\u304d\u307e\u3059\u3002<\/p>\r\n<p>&nbsp;<\/p>\r\n<p>3.1 \u30a2\u30d7\u30ea\u306e\u4f5c\u6210\u624b\u9806<\/p>\r\n<p>\u2460Cloud Storage\u5185\u3067\u30d0\u30b1\u30c3\u30c8\u3092\u4f5c\u6210<\/p>\r\n<p>\u3000\uff11\uff0e\u30d0\u30b1\u30c3\u30c8\u3067\u300c\u4f5c\u6210\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\u3002<\/p>\r\n<p>\u3000\uff12\uff0e\u300c\u30d0\u30b1\u30c3\u30c8\u306b\u540d\u524d\u3092\u4ed8\u3051\u308b\u300d\u3067\u4efb\u610f\u306e\u540d\u524d\u3092\u4ed8\u3051\u3066\u304f\u3060\u3055\u3044<\/p>\r\n<p>\u3000\uff13\uff0e\u300c\u30c7\u30fc\u30bf\u306e\u4fdd\u5b58\u5834\u6240\u306e\u9078\u629e\u300d\u306e\u30ed\u30b1\u30fc\u30b7\u30e7\u30f3\u30bf\u30a4\u30d7\u3068\u3057\u3066\u300cMulti-region\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u3001\u300casia\u300d\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002<\/p>\r\n<p>\u3000\uff14\uff0e\u300c\u4f5c\u6210\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\u3002<\/p>\r\n<p>&nbsp;<\/p>\r\n<p>\u2461\u4f5c\u6210\u3057\u305f\u30d0\u30b1\u30c3\u30c8\u5185\u306b\u30c7\u30fc\u30bf\u3092\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9<\/p>\r\n<p>\u3000\uff11\uff0e\u30d0\u30b1\u30c3\u30c8\u5185\u304b\u3089\u5148\u307b\u3069\u4f5c\u6210\u3057\u305f\u30d0\u30b1\u30c3\u30c8\u3092\u9078\u629e\u3057\u307e\u3059\u3002<\/p>\r\n<p>\u3000\uff12\uff0e\u30d5\u30a1\u30a4\u30eb\u307e\u305f\u306f\u30d5\u30a9\u30eb\u30c0\u3092\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u3057\u307e\u3059\u3002<\/p>\r\n<p>&nbsp;<\/p>\r\n<p>\u2462Agent Builder\u3067\u30c7\u30fc\u30bf\u30b9\u30c8\u30a2\u3092\u4f5c\u6210<\/p>\r\n<p>\u3000\uff11\uff0e\u300c\u30c7\u30fc\u30bf\u30b9\u30c8\u30a2\u3092\u4f5c\u6210\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\u3002<\/p>\r\n<p>\u3000\uff12\uff0e\u30c7\u30fc\u30bf\u30b9\u30c8\u30a2\u3067\u300cCloud Storage\u300d\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002<\/p>\r\n<p><img decoding=\"async\" src=\"https:\/\/since2020.jp\/media\/wp-content\/uploads\/2024\/07\/\u30b9\u30af\u30ea\u30fc\u30f3\u30b7\u30e7\u30c3\u30c8-2024-07-09-173544.png\" alt=\"Vertex AI\" width=\"918\" height=\"431\" class=\"alignnone wp-image-5132 size-full\" srcset=\"https:\/\/since2020.jp\/media\/wp-content\/uploads\/2024\/07\/\u30b9\u30af\u30ea\u30fc\u30f3\u30b7\u30e7\u30c3\u30c8-2024-07-09-173544.png 918w, https:\/\/since2020.jp\/media\/wp-content\/uploads\/2024\/07\/\u30b9\u30af\u30ea\u30fc\u30f3\u30b7\u30e7\u30c3\u30c8-2024-07-09-173544-300x141.png 300w, https:\/\/since2020.jp\/media\/wp-content\/uploads\/2024\/07\/\u30b9\u30af\u30ea\u30fc\u30f3\u30b7\u30e7\u30c3\u30c8-2024-07-09-173544-768x361.png 768w\" sizes=\"(max-width: 918px) 100vw, 918px\" \/><\/p>\r\n<p>\u3000\uff13\uff0e\u30d0\u30b1\u30c3\u30c8\u306b\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u3057\u305f\u30c7\u30fc\u30bf\u306e\u30d5\u30a1\u30a4\u30eb\u5f62\u5f0f\u3068\u540c\u3058\u3082\u306e\u3092\u9078\u629e\u3057\u307e\u3059\u3002<\/p>\r\n<p>\u3000\uff14\uff0e\u2461\u306e\u30d0\u30b1\u30c3\u30c8\u3092\u30a4\u30f3\u30dd\u30fc\u30c8\u3057\u307e\u3059\u3002<\/p>\r\n<p>\u3000\uff15\uff0e\u30de\u30eb\u30c1\u30ea\u30fc\u30b8\u30e7\u30f3\u3092\u300cglobal\uff08\u30b0\u30ed\u30fc\u30d0\u30eb\uff09\u300d\u3068\u3057\u3001\u4efb\u610f\u306e\u30c7\u30fc\u30bf\u30b9\u30c8\u30a2\u540d\u3092\u3064\u3051\u3066\u300c\u4f5c\u6210\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\u3002<\/p>\r\n<p>&nbsp;<\/p>\r\n<p>\u2463Agent Builder\u3067\u30a2\u30d7\u30ea\u3092\u4f5c\u6210<\/p>\r\n<p>\u3000\uff11\uff0e\u300c\u30a2\u30d7\u30ea\u3092\u4f5c\u6210\u3059\u308b\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\u3002<\/p>\r\n<p>\u3000\uff12\uff0e\u300c\u691c\u7d22\u300d\u3092\u9078\u629e\u3057\u307e\u3059\u3002<\/p>\r\n<p><img decoding=\"async\" src=\"https:\/\/since2020.jp\/media\/wp-content\/uploads\/2024\/07\/\u30b9\u30af\u30ea\u30fc\u30f3\u30b7\u30e7\u30c3\u30c8-2024-07-09-174712.png\" alt=\"Vertex AI\" width=\"1021\" height=\"484\" class=\"alignnone wp-image-5131 size-full\" srcset=\"https:\/\/since2020.jp\/media\/wp-content\/uploads\/2024\/07\/\u30b9\u30af\u30ea\u30fc\u30f3\u30b7\u30e7\u30c3\u30c8-2024-07-09-174712.png 1021w, https:\/\/since2020.jp\/media\/wp-content\/uploads\/2024\/07\/\u30b9\u30af\u30ea\u30fc\u30f3\u30b7\u30e7\u30c3\u30c8-2024-07-09-174712-300x142.png 300w, https:\/\/since2020.jp\/media\/wp-content\/uploads\/2024\/07\/\u30b9\u30af\u30ea\u30fc\u30f3\u30b7\u30e7\u30c3\u30c8-2024-07-09-174712-768x364.png 768w\" sizes=\"(max-width: 1021px) 100vw, 1021px\" \/><\/p>\r\n<p>\u3000\uff13\uff0e\u4eca\u56de\u306e\u30c1\u30e3\u30c3\u30c8\u30dc\u30c3\u30c8\u3067\u306f\u3001\u8981\u7d04\u6587\u3092\u751f\u6210\u3059\u308b\u5fc5\u8981\u304c\u3042\u308b\u305f\u3081\u3001Advanced LLM features\u3092\u6709\u52b9\u5316\u3057\u307e\u3059\u3002<\/p>\r\n<p>\u3000\uff14\uff0e\u4efb\u610f\u306e\u30a2\u30d7\u30ea\u540d\u3001\u4f1a\u793e\u540d\u3092\u5165\u529b\u3057\u3001\u30de\u30eb\u30c1\u30ea\u30fc\u30b8\u30e7\u30f3\u3092\u300cglobal\uff08\u30b0\u30ed\u30fc\u30d0\u30eb\uff09\u300d\u306b\u3057\u307e\u3059\u3002<\/p>\r\n<p>\u3000\uff15\uff0e\u5148\u307b\u3069\u4f5c\u6210\u3057\u305f\u30c7\u30fc\u30bf\u30b9\u30c8\u30a2\u3092\u9078\u629e\u3057\u3001\u300c\u4f5c\u6210\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u3066\u304f\u3060\u3055\u3044\u3002<\/p>\r\n<p>&nbsp;<\/p>\r\n<p>\u4ee5\u4e0a\u307e\u3067\u304c\u30a2\u30d7\u30ea\u306e\u4f5c\u6210\u624b\u9806\u3067\u3059\u3002<\/p>\r\n<p>\u81ea\u8eab\u304c\u4f5c\u3063\u305f\u30a2\u30d7\u30ea\u3092\u9078\u629e\u3059\u308b\u3068\u691c\u7d22\u6a5f\u80fd\u3092\u4f7f\u3046\u3053\u3068\u304c\u3067\u304d\u308b\u306e\u3067\u3001\u6b63\u3057\u3044\u56de\u7b54\u304c\u8fd4\u3063\u3066\u304f\u308b\u304b\u3092\u30c6\u30b9\u30c8\u3057\u3066\u307f\u307e\u3057\u3087\u3046\u3002<\/p>\r\n<p>&nbsp;<\/p>\r\n<p>3.2 \u30a2\u30d7\u30ea\u3092\u30c7\u30d7\u30ed\u30a4\u3059\u308b\u624b\u9806<\/p>\r\n<p>\u2460\u30d5\u30a1\u30f3\u30af\u30b7\u30e7\u30f3\u3092\u4f5c\u6210<\/p>\r\n<p>\u3000\uff11\uff0eCloud Functions\u3067\u300c\u30d5\u30a1\u30f3\u30af\u30b7\u30e7\u30f3\u3092\u4f5c\u6210\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\u3002<\/p>\r\n<p>\u3000\uff12\uff0e\u30d1\u30e9\u30e1\u30fc\u30bf\u3092\u4ee5\u4e0b\u306e\u901a\u308a\u306b\u8a2d\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002<\/p>\r\n<p>\u3000\u74b0\u5883\uff1a\u7b2c\uff12\u4e16\u4ee3<\/p>\r\n<p>\u3000\u95a2\u6570\u540d\uff1a\u4efb\u610f\u306e\u95a2\u6570\u540d<\/p>\r\n<p>\u3000\u30ea\u30fc\u30b8\u30e7\u30f3\uff1aasia-northeast1\uff08\u6771\u4eac\uff09<\/p>\r\n<p>\u3000\u30c8\u30ea\u30ac\u30fc\u306e\u30bf\u30a4\u30d7\uff1aHTTPS<\/p>\r\n<p>\u3000\u203b\u672a\u8a8d\u8a3c\u306e\u547c\u3073\u51fa\u3057\u3092\u8a31\u53ef<\/p>\r\n<p>\u3000\u203b\u203b\u30b5\u30fc\u30d3\u30b9\u30a2\u30ab\u30a6\u30f3\u30c8\uff1a\u300c\u30c7\u30a3\u30b9\u30ab\u30d0\u30ea\u30fc\u30a8\u30f3\u30b8\u30f3\u95b2\u89a7\u8005\u300d\u3092\u4fdd\u6709\u3057\u3066\u3044\u308b\u3082\u306e\u3092\u6307\u5b9a<\/p>\r\n<p>\u3000<strong>\u30e9\u30f3\u30bf\u30a4\u30e0\u74b0\u5883\u5909\u6570\u306e\u5909\u6570\u3092\u8ffd\u52a0<\/strong><\/p>\r\n<p>\u3000\u3000PROJECT_ID\uff1a\u4eca\u56de\u4f7f\u7528\u3057\u3066\u3044\u308bGoogle Cloud\u306e\u30d7\u30ed\u30b8\u30a7\u30af\u30c8ID<\/p>\r\n<p>\u3000\u3000PROJECT_NUMBER\uff1a\u4eca\u56de\u4f7f\u7528\u3057\u3066\u3044\u308bGoogle Cloud\u306e\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u30ca\u30f3\u30d0\u30fc<\/p>\r\n<p>\u3000\u3000DATA_STORE\uff1a3.1\u3067\u4f5c\u6210\u3057\u305f\u30c7\u30fc\u30bf\u30b9\u30c8\u30a2\u306eID<\/p>\r\n<p>\u3000\u3000CHAT_ISSUER\uff1a\u300c<a href=\"mailto:chat@system.gserviceaccount.com\">chat@system.gserviceaccount.com\u300d<\/a><\/p>\r\n<p>PUBLIC_CERT_URL_PREFIX\uff1a\u300c<a href=\"https:\/\/www.googleapis.com\/service_accounts\/v1\/metadata\/x509\/%E3%80%8D\">https:\/\/www.googleapis.com\/service_accounts\/v1\/metadata\/x509\/\u300d<\/a><\/p>\r\n<p>&nbsp;<\/p>\r\n<p>\u203bGoogle Chat API \u3068 Cloud Funcitons \u306b\u3088\u308b\u5b9f\u88c5\u3067\u306f\u3001Cloud Functions \u306e\u8a8d\u8a3c\u30bf\u30a4\u30d7\u3092\u300c\u672a\u627f\u8a8d\u306e\u547c\u3073\u51fa\u3057\u3092\u8a31\u53ef\u300d\u306b\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002<\/p>\r\n<p>\u203b\u203b\u30b5\u30fc\u30d3\u30b9\u30a2\u30ab\u30a6\u30f3\u30c8\u3067\u300c\u30c7\u30a3\u30b9\u30ab\u30d0\u30ea\u30fc\u30a8\u30f3\u30b8\u30f3\u95b2\u89a7\u8005\u300d\u3092\u4fdd\u6709\u3057\u3066\u3044\u308b\u3082\u306e\u304c\u306a\u3044\u5834\u5408\uff08\u307e\u305f\u306f\u78ba\u8a8d\u65b9\u6cd5\u304c\u5206\u304b\u3089\u306a\u3044\u5834\u5408\uff09<\/p>\r\n<p>\u3000\u30fb\u30b5\u30fc\u30d3\u30b9\u30a2\u30ab\u30a6\u30f3\u30c8\u306e\u300c\u4f5c\u6210\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\u3002<\/p>\r\n<p>\u3000\u30fb\u4efb\u610f\u306e\u30b5\u30fc\u30d3\u30b9\u30a2\u30ab\u30a6\u30f3\u30c8\u540d\u3092\u5165\u529b\u3057\u3001\u300c\u4f5c\u6210\u3057\u3066\u5b9f\u884c\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\u3002<\/p>\r\n<p>\u3000\u30fb\u30ed\u30fc\u30eb\u3092\u9078\u629e\u3067\u300c\u30c7\u30a3\u30b9\u30ab\u30d0\u30ea\u30fc\u30a8\u30f3\u30b8\u30f3\u95b2\u89a7\u8005\u300d\u3092\u9078\u629e\u3057\u3001\u5b8c\u4e86<\/p>\r\n<p>&nbsp;<\/p>\r\n<p>\u4ee5\u4e0a\u306e\u30d1\u30e9\u30e1\u30fc\u30bf\u3092\u8a2d\u5b9a\u3057\u305f\u3089\u300c\u6b21\u3078\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\u3002<\/p>\r\n<p>&nbsp;<\/p>\r\n<p>\u3000\uff13\uff0e\u30e9\u30f3\u30bf\u30a4\u30e0\u3092\u300cPython 3.11\u300d\u3001\u30a8\u30f3\u30c8\u30ea\u30dd\u30a4\u30f3\u30c8\u3092\u300cchatbot\u300d\u3068\u3057\u307e\u3059\u3002<\/p>\r\n<p>\u3000\uff14\uff0e\u4ee5\u4e0b\u306b\u30bd\u30fc\u30b9\u30b3\u30fc\u30c9\u3092\u8a18\u8f09\u3057\u307e\u3059\u3002<\/p>\r\n<p>requirements.txt<\/p>\r\n<div class=\"hcb_wrap\">\r\n<pre class=\"prism line-numbers lang-json\" data-lang=\"JSON\"><code>functions-framework==3.*\r\ngoogle-cloud-discoveryengine==0.11.6\r\noauth2client==4.1.3<\/code><\/pre>\r\n<\/div>\r\n<p>main.py\u00a0<\/p>\r\n<div class=\"hcb_wrap\">\r\n<pre class=\"prism line-numbers lang-python\" data-lang=\"Python\"><code>from typing import Any, Mapping\r\nfrom google.cloud.discoveryengine_v1alpha import SearchServiceClient, SearchRequest\r\nfrom google.protobuf.json_format import MessageToDict\r\nfrom oauth2client import client\r\n\r\nimport functions_framework, flask, os\r\n\r\nPROJECT_ID = os.environ.get(\"PROJECT_ID\")\r\nPROJECT_NUMBER = os.environ.get(\"PROJECT_NUMBER\")\r\nDATA_STORE = os.environ.get(\"DATA_STORE\")\r\n\r\n<\/code>#Google Chat\u304b\u3089\u9001\u3089\u308c\u3066\u304f\u308bBearer Token\u306e\u6574\u5408\u306b\u4f7f\u7528 CHAT_ISSUER = os.environ.get(\"CHAT_ISSUER\") PUBLIC_CERT_URL_PREFIX = os.environ.get(\"PUBLIC_CERT_URL_PREFIX\") def search_document(text: str) -&gt; Mapping[str, Any]: \u3000 discov_client = SearchServiceClient() \u3000 #Vertex AI Search\u306e\u30a2\u30d7\u30ea\u7b49\u57fa\u672c\u7684\u306a\u5185\u5bb9\u3092\u8a2d\u5b9a \u3000 serving_config = discov_client.serving_config_path( \u3000 project=PROJECT_ID, \u3000 location=\"global\", \u3000 data_store=DATA_STORE, serving_config=\"default_config\" \u3000) #Vertex AI Search\u306e\u51fa\u529b\u5185\u5bb9\u306b\u95a2\u3059\u308b\u8a2d\u5b9a \u3000 content_search_spec = SearchRequest.ContentSearchSpec( \u3000 #\u30b9\u30cb\u30da\u30c3\u30c8\u3092\u51fa\u529b\u3055\u305b\u306a\u3044 snippet_spec=SearchRequest.ContentSearchSpec().SnippetSpec( \u3000 \u3000return_snippet=False ), #\u8981\u7d04\u6587\u3092\u51fa\u529b\u3055\u305b\u308b summary_spec=SearchRequest.ContentSearchSpec().SummarySpec( \u3000 summary_result_count=3, \u3000 include_citations=False, \u3000 #Gemini Pro\u3092\u7528\u3044\u308b\u3088\u3046\u306b\u6307\u5b9a \u3000 model_spec=SearchRequest.ContentSearchSpec().SummarySpec().ModelSpec( \u3000 version=\"preview\" \u3000 ) \u3000 ) ) \u3000 #Vertex AI Search\u306b\u30af\u30a8\u30ea\u3092\u6295\u3052\u308b \u3000 response = discov_client.search( \u3000 SearchRequest( \u3000 serving_config=serving_config, \u3000 query=text, \u3000 page_size=3, \u3000 content_search_spec=content_search_spec \u3000 ) \u3000 ) \u3000 #\u8981\u7d04\u6587\u53d6\u5f97 \u3000 summary = response.summary.summary_text.replace(\"<b>\", \"\").replace(\"<\/b>\", \"\") \u3000 #\u95a2\u9023\u30d5\u30a1\u30a4\u30eb\u53d6\u5f97 \u3000 references = [] \u3000 for r in response.results: \u3000 r_dct = MessageToDict(r._pb) \u3000 link = r_dct[\"document\"][\"derivedStructData\"][\"link\"] \u3000 references.append(link.split(\"\/\")[-1]) \u3000 result = { \u3000 \"summary\":summary, \u3000 \"references\":references \u3000 } \u3000 \u3000 return result #\u30c1\u30e3\u30c3\u30c8\u30dc\u30c3\u30c8\u304c\u5b9f\u969b\u306b\u51fa\u529b\u3059\u308b\u30e1\u30c3\u30bb\u30fc\u30b8\u3092\u4f5c\u6210\u3059\u308b def create_message(text: str) -&gt; Mapping[str, Any]: result = search_document(text=text) reference_sentence = \" \u30fb\".join(result[\"references\"]) #\u8fd4\u4fe1\u6587\u4f5c\u6210 cards = { \"cardsV2\": [ \u3000 { \u3000 \"cardId\": \"searchResults\", \u3000 \"card\": { \u3000 \"sections\": [ \u3000 { \u3000 \"collapsible\": False, \u3000 \"widgets\": [ { \"textParagraph\": { \"text\": \"<b>\u56de\u7b54\u6587<\/b>\" + result[\"summary\"] } }, { \"divider\": {} }, { \"textParagraph\": { \"text\": \"<b>\u95a2\u9023\u30d5\u30a1\u30a4\u30eb<\/b>\u30fb \" + reference_sentence } } ] } ] } } ] } return cards #\u30c1\u30e3\u30c3\u30c8\u30dc\u30c3\u30c8\u304b\u3089\u30e1\u30c3\u30bb\u30fc\u30b8\u3092\u53d7\u4fe1 #create_message() \u3067\u4f5c\u6210\u3057\u305f JSON \u3092\u8fd4\u3059 @functions_framework.http def chatbot(req: flask.Request): \"\"\" \u6b63\u3057\u3044Google Chat\u304b\u3089\u9001\u3089\u308c\u3066\u304d\u305f\u30ea\u30af\u30a8\u30b9\u30c8\u304b\u3092\u78ba\u8a8d \"\"\" if req.method == \"GET\": return flask.make_response(flask.jsonify({\"message\": \"Bad Request\"}), 400) auth_header = req.headers.get(\"Authorization\") #\u300cAuthorization\u300d\u30d8\u30c3\u30c0\u30fc\u304c\u5b58\u5728\u3059\u308b\u304b\u78ba\u8a8d if not auth_header: print(\"Missing Authorization header\") return flask.make_response(flask.jsonify({\"message\": \"Unauthorized\"}), 401) #\u300cAuthorization\u300d\u30d8\u30c3\u30c0\u30fc\u304c\u300cBearer\u300d\u304b\u3089\u59cb\u307e\u308b\u304b\u78ba\u8a8d if auth_header.split()[0] != \"Bearer\": print(\"Authorization header format is incorrect\") return flask.make_response(flask.jsonify({\"message\": \"Unauthorized\"}), 401) bearer_token = auth_header.split()[1] try: token = client.verify_id_token( bearer_token, PROJECT_NUMBER, cert_uri=PUBLIC_CERT_URL_PREFIX + CHAT_ISSUER) if token['iss'] != CHAT_ISSUER: print(\"Invalid issuee\") return flask.make_response(flask.jsonify({\"message\": \"Unauthorized\"}),401) except: print(\"Invalid token\") return flask.make_response(flask.jsonify({\"message\": \"Unauthorized\"}), 401) \"\"\" \u53d7\u3051\u53d6\u3063\u305f\u30e1\u30c3\u30bb\u30fc\u30b8\u3067Vertex AI Search\u306b\u691c\u7d22\u3092\u304b\u3051\u308b \u691c\u7d22\u7d50\u679c\u3092\u6574\u5f62\u3057\u9001\u4fe1\u3059\u308b \"\"\" request_json = req.get_json(silent=True) text = request_json[\"message\"][\"text\"] response = create_message(text=text) return response<\/pre>\r\n<\/div>\r\n<p>\u3000\uff15\uff0e\u30c7\u30d7\u30ed\u30a4\u3057\u307e\u3059\u3002<\/p>\r\n<p>&nbsp;<\/p>\r\n<p>3.3 Google Chat API\u306e\u8a2d\u5b9a\u65b9\u6cd5<\/p>\r\n<p>\u3000\uff11\uff0eGoogle Chat API\u3092\u6709\u52b9\u306b\u3059\u308b\u3002<\/p>\r\n<p>\u3000\uff12\uff0e\u30ca\u30d3\u30b2\u30fc\u30b7\u30e7\u30f3\u30e1\u30cb\u30e5\u30fc\u3067\u300cAPI\u3068\u30b5\u30fc\u30d3\u30b9\u300d\u306e\u300c\u6709\u52b9\u306aAPI\u3068\u30b5\u30fc\u30d3\u30b9\u300d\u3092\u9078\u629e\u3057\u307e\u3059\u3002<\/p>\r\n<p>\u3000\uff13\uff0eGoogle Chat API\u3092\u9078\u629e\u3057\u3001\u300c\u69cb\u6210\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\u3002<\/p>\r\n<p><img decoding=\"async\" src=\"https:\/\/since2020.jp\/media\/wp-content\/uploads\/2024\/07\/\u30b9\u30af\u30ea\u30fc\u30f3\u30b7\u30e7\u30c3\u30c8-2024-07-09-185354.png\" alt=\"\" width=\"729\" height=\"382\" class=\"alignnone size-full wp-image-5133\" srcset=\"https:\/\/since2020.jp\/media\/wp-content\/uploads\/2024\/07\/\u30b9\u30af\u30ea\u30fc\u30f3\u30b7\u30e7\u30c3\u30c8-2024-07-09-185354.png 729w, https:\/\/since2020.jp\/media\/wp-content\/uploads\/2024\/07\/\u30b9\u30af\u30ea\u30fc\u30f3\u30b7\u30e7\u30c3\u30c8-2024-07-09-185354-300x157.png 300w\" sizes=\"(max-width: 729px) 100vw, 729px\" \/><\/p>\r\n<p>\u3000\uff14\uff0e\u4ee5\u4e0b\u306e\u901a\u308a\u306b\u8a2d\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002<\/p>\r\n<p>\u3000\u30a2\u30d7\u30ea\u306e\u30b9\u30c6\u30fc\u30bf\u30b9<\/p>\r\n<p>\u3000\u3000\u30a2\u30d7\u30ea\u306e\u30b9\u30c6\u30fc\u30bf\u30b9\uff1a\u30e9\u30a4\u30d6-\u30e6\u30fc\u30b6\u304c\u5229\u7528\u53ef\u80fd<\/p>\r\n<p>\u3000\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u60c5\u5831<\/p>\r\n<p>\u3000\u3000\u30fb\u30a2\u30d7\u30ea\u540d\uff1a\u4efb\u610f\u306e\u30a2\u30d7\u30ea\u540d<\/p>\r\n<p>\u3000\u3000\u30fb\u30a2\u30d0\u30bf\u30fc\u306eURL\uff1a\u4efb\u610f\u306e\u5199\u771f\uff08\u30c1\u30e3\u30c3\u30c8\u30a2\u30d7\u30ea\u306e\u30a2\u30a4\u30b3\u30f3\uff09<\/p>\r\n<p>\u3000\u3000\u30fb\u8aac\u660e\uff1a\u30c1\u30e3\u30c3\u30c8\u30a2\u30d7\u30ea\u306e\u8aac\u660e\u6587<\/p>\r\n<p>\u3000\u30a4\u30f3\u30bf\u30e9\u30af\u30c6\u30a3\u30d6\u6a5f\u80fd<\/p>\r\n<p>\u3000\u3000\u30fb\u30a4\u30f3\u30bf\u30e9\u30af\u30c6\u30a3\u30d6\u6a5f\u80fd\u3092\u6709\u52b9\u306b\u3059\u308b\u3002<\/p>\r\n<p>\u3000\u3000\u30fb1:1\u306e\u30e1\u30c3\u30bb\u30fc\u30b8\u3092\u53d7\u4fe1\u3059\u308b<\/p>\r\n<p>\u3000\u3000\u30fb\u30b9\u30da\u30fc\u30b9\u3068\u30b0\u30eb\u30fc\u30d7\u306e\u4f1a\u8a71\u306b\u53c2\u52a0\u3059\u308b<\/p>\r\n<p>\u3000\u3000\u30fb\u63a5\u7d9a\u8a2d\u5b9a\uff1a\u30a2\u30d7\u30ea\u306eURL<\/p>\r\n<p>\u3000\u3000\u30fb\u30a2\u30d7\u30ea\u306eURL\uff1aCloud Functions\u3067\u30c7\u30d7\u30ed\u30a4\u3057\u305f\u30a2\u30d7\u30ea\u306eURL<\/p>\r\n<p>\u3000\u3000\u30fb\u516c\u958b\u8a2d\u5b9a\uff1a\u4efb\u610f\u306e\u30e6\u30fc\u30b6\u30fc\u306e\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9\u3092\u767b\u9332<\/p>\r\n<p>\u3000\u30ed\u30b0<\/p>\r\n<p>\u3000\u3000\u30fb\u30a8\u30e9\u30fc\u3092Logging\u306b\u8a18\u9332\u3059\u308b\u3002<\/p>\r\n<p>&nbsp;<\/p>\r\n<p>\u4ee5\u4e0a\u306e\u8a2d\u5b9a\u304c\u5b8c\u4e86\u3057\u305f\u3089\u300c\u4fdd\u5b58\u300d\u3057\u307e\u3059\u3002<\/p>\r\n<p>&nbsp;<\/p>\r\n<p><!-- notionvc: c8f284cb-7c78-4fd5-8c73-e57dbe89691a --><\/p>\n\n<h2>\u7d50\u679c<\/h2>\n<p>\u3067\u306f\u5b9f\u969b\u306b\u5b8c\u6210\u3057\u305f\u30c1\u30e3\u30c3\u30c8\u30dc\u30c3\u30c8\u3092\u4f7f\u3063\u3066\u307f\u307e\u3057\u3087\u3046\u3002<\/p>\r\n<p>\u3000\uff11\uff0eGoogle Chat\u3092\u958b\u304d\u307e\u3059\u3002<\/p>\r\n<p>\u3000\uff12\uff0e\u300c\u30c1\u30e3\u30c3\u30c8\u3092\u65b0\u898f\u4f5c\u6210\u300d\u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\u3002<\/p>\r\n<p><img decoding=\"async\" src=\"https:\/\/since2020.jp\/media\/wp-content\/uploads\/2024\/07\/\u30b9\u30af\u30ea\u30fc\u30f3\u30b7\u30e7\u30c3\u30c8-2024-07-09-190836.png\" alt=\"Google Chat\" width=\"395\" height=\"162\" class=\"alignnone wp-image-5134 size-full\" srcset=\"https:\/\/since2020.jp\/media\/wp-content\/uploads\/2024\/07\/\u30b9\u30af\u30ea\u30fc\u30f3\u30b7\u30e7\u30c3\u30c8-2024-07-09-190836.png 395w, https:\/\/since2020.jp\/media\/wp-content\/uploads\/2024\/07\/\u30b9\u30af\u30ea\u30fc\u30f3\u30b7\u30e7\u30c3\u30c8-2024-07-09-190836-300x123.png 300w\" sizes=\"(max-width: 395px) 100vw, 395px\" \/><\/p>\r\n<p>\u3000\uff13\uff0e\u4f5c\u6210\u3057\u305f\u30a2\u30d7\u30ea\u540d\u3092\u691c\u7d22\u3057\u3066\u304f\u3060\u3055\u3044\u3002<\/p>\r\n<p>\u3000<img decoding=\"async\" src=\"https:\/\/since2020.jp\/media\/wp-content\/uploads\/2024\/07\/\u30b9\u30af\u30ea\u30fc\u30f3\u30b7\u30e7\u30c3\u30c8-2024-07-09-191216.png\" alt=\"Gemini\u642d\u8f09Chatbot\" width=\"1379\" height=\"733\" class=\"alignnone wp-image-5135 size-full\" srcset=\"https:\/\/since2020.jp\/media\/wp-content\/uploads\/2024\/07\/\u30b9\u30af\u30ea\u30fc\u30f3\u30b7\u30e7\u30c3\u30c8-2024-07-09-191216.png 1379w, https:\/\/since2020.jp\/media\/wp-content\/uploads\/2024\/07\/\u30b9\u30af\u30ea\u30fc\u30f3\u30b7\u30e7\u30c3\u30c8-2024-07-09-191216-300x159.png 300w, https:\/\/since2020.jp\/media\/wp-content\/uploads\/2024\/07\/\u30b9\u30af\u30ea\u30fc\u30f3\u30b7\u30e7\u30c3\u30c8-2024-07-09-191216-1024x544.png 1024w, https:\/\/since2020.jp\/media\/wp-content\/uploads\/2024\/07\/\u30b9\u30af\u30ea\u30fc\u30f3\u30b7\u30e7\u30c3\u30c8-2024-07-09-191216-768x408.png 768w\" sizes=\"(max-width: 1379px) 100vw, 1379px\" \/><\/p>\r\n<p>\u3000\uff14\uff0e\u8cea\u554f\u3057\u305f\u3044\u5185\u5bb9\u3092\u30c1\u30e3\u30c3\u30c8\u3057\u3066\u304f\u3060\u3055\u3044\u3002<\/p>\r\n<p>\u3000\uff15\uff0e\u6b63\u3057\u304f\u56de\u7b54\u304c\u8fd4\u3063\u3066\u304d\u305f\u3089\u6210\u529f\u3067\u3059\u3002<\/p>\r\n<p>&nbsp;<\/p>\n\n<h2>\u307e\u3068\u3081<\/h2>\n<p>\u4eca\u56de\u306fGoogle Chat\u4e0a\u3067\u4f7f\u7528\u3067\u304d\u308b\u30c1\u30e3\u30c3\u30c8\u30dc\u30c3\u30c8\u3092\u4f5c\u6210\u3057\u307e\u3057\u305f\u3002<\/p>\r\n<p>\u4eca\u56de\u306fGoogle Chat\u3068\u9023\u643a\u3057\u307e\u3057\u305f\u304c\u3001\u4ed6\u306b\u3082\u69d8\u3005\u306a\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3068\u9023\u643a\u3055\u305b\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002<\/p>\r\n<p>\u307e\u305f\u3001Google Cloud Functions\u306emain.py\u306e\u30b3\u30fc\u30c9\u5185\u5bb9\u3092\u30ab\u30b9\u30bf\u30de\u30a4\u30ba\u3059\u308b\u3053\u3068\u3067\u3082\u3063\u3068\u4fbf\u5229\u306a\u30c1\u30e3\u30c3\u30c8\u30dc\u30c3\u30c8\u3092\u4f5c\u6210\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002<\/p>\r\n<p><span>\u3010\u95a2\u9023\u8a18\u4e8b\u3011<\/span><\/p>\r\n<p><a href=\"https:\/\/blog.since2020.jp\/bi\/bi%ef%bc%88%e3%83%87%e3%83%bc%e3%82%bf%ef%bc%89%e6%b4%bb%e7%94%a8%e4%bf%83%e9%80%b2%e3%81%97%e3%81%9f%e3%81%84%e7%b5%84%e7%b9%94%e3%81%abgemini-in-looker%e3%82%92%e3%81%8a%e3%81%99%e3%81%99%e3%82%81\/\">\u30fbGemini in Looker\u3067BI\u6d3b\u7528\u3092\u52a0\u901f\u3055\u305b\u307e\u305b\u3093\u304b\uff1f\u304a\u3059\u3059\u3081\u7406\u7531\u3092\u89e3\u8aac\uff01<\/a><\/p>","protected":false},"excerpt":{"rendered":"<p>Vertex AI\u3092\u7528\u3044\u3066Google Chat\u306e\u30c1\u30e3\u30c3\u30c8\u30dc\u30c3\u30c8\u3092\u4f5c\u6210\u3059\u308b\u65b9\u6cd5\u3092\u7d39\u4ecb\u3057\u307e\u3059\u3002 \u306f\u3058\u3081\u306b \u4eca\u56de\u306fVertex AI\u3092\u7528\u3044\u3066Google Chat\u306e\u30c1\u30e3\u30c3\u30c8\u30dc\u30c3\u30c8\u3092\u4f5c\u6210\u3057\u307e\u3057\u305f\u3002 \u4f5c\u6210\u3059\u308b\u624b\u9806\u3067\u96e3\u3057\u3044\u3082\u306e\u304c\u3042 [&hellip;]<\/p>\n","protected":false},"author":19,"featured_media":5138,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"content-type":"","swell_btn_cv_data":"","footnotes":"","_wp_rev_ctl_limit":""},"categories":[1249],"tags":[96,654,331,166],"class_list":["post-5130","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-knowledge","tag-ai","tag-google-chat","tag-python","tag-vertex-ai"],"_links":{"self":[{"href":"https:\/\/since2020.jp\/media\/wp-json\/wp\/v2\/posts\/5130","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/since2020.jp\/media\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/since2020.jp\/media\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/since2020.jp\/media\/wp-json\/wp\/v2\/users\/19"}],"replies":[{"embeddable":true,"href":"https:\/\/since2020.jp\/media\/wp-json\/wp\/v2\/comments?post=5130"}],"version-history":[{"count":1,"href":"https:\/\/since2020.jp\/media\/wp-json\/wp\/v2\/posts\/5130\/revisions"}],"predecessor-version":[{"id":5137,"href":"https:\/\/since2020.jp\/media\/wp-json\/wp\/v2\/posts\/5130\/revisions\/5137"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/since2020.jp\/media\/wp-json\/wp\/v2\/media\/5138"}],"wp:attachment":[{"href":"https:\/\/since2020.jp\/media\/wp-json\/wp\/v2\/media?parent=5130"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/since2020.jp\/media\/wp-json\/wp\/v2\/categories?post=5130"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/since2020.jp\/media\/wp-json\/wp\/v2\/tags?post=5130"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}