ã¯ããã«
ãã®èšäºã¯ Google ADK ã«ãããã«ããšãŒãžã§ã³ã瀟å ITãã«ããã¹ã¯æ§ç¯ ãããŒãã«ããå š4åã·ãªãŒãºã®ç¬¬3åã§ãã
| å | ããŒã |
|---|---|
| 第1å | Gemini CLI ã§ãšãŒãžã§ã³ããåãããŠã¿ã |
| 第2å | ADK ã§ãã«ããšãŒãžã§ã³ããæ§ç¯ã Google Cloud ã«ãããã€ãã |
| 第3åïŒæ¬èšäºïŒ | ADK ãã«ããšãŒãžã§ã³ãã BigQuery ãšé£æºããã |
| 第4å | Gen AI evaluation service ã§ ADK ãã«ããšãŒãžã§ã³ãã®å¿çåè³ªãæž¬ã |
第2åãŸã§ã§äœã£ããšãŒãžã§ã³ãã¯ãFAQ ããŒã¿ã Python ã®ãªã¹ããšããŠçŽæ¥ã³ãŒãã«æžããŠããŸããã
ãã¢ã«ã¯ååã§ãããå®éçšãèãããšããã€ãå°ããšãããåºãŠããŸãã
- FAQ ã 1 件远å ãããã³ã«ã³ãŒããæžãæããŠãããã€ãçŽãå¿ èŠããã
- ã©ããªåãåãããã©ãåŠçããããã®å±¥æŽãã©ãã«ãæ®ããªã
- FAQ ãå¢ããŠãããšãã«ã«ããŽãªå¥ã®åŸåãåæã§ããªã
æ¬èšäºã§ã¯ãããã®èª²é¡ã解決ãããããããŒã¿ãœãŒã¹ãBigQueryã«ç§»ããŸãã
äœãäœã£ãã
å šäœæ§æ
第2åãŸã§ãšåã 3 ã€ã®ãšãŒãžã§ã³ãæ§æã¯ç¶æãã€ã€ãããŒã¿ã®çœ®ãå ŽæããPython ã®ãªã¹ããã BigQuery ãžãšåãæ¿ããŸãã
ãŠãŒã¶ãŒåãåãã
â
ã«ãŒã¿ãŒãšãŒãžã§ã³ã
â
FAQ æ€çŽ¢ãšãŒãžã§ã³ã ââ[SELECT]ââ> faq_master ããŒãã«
â
ââ FAQ ããã â èªåãåç ââ[INSERT resolved=true]ââ> inquiry_log ããŒãã«
â
ââ FAQ ãªã
â
ãšã¹ã«ã¬ãŒã·ã§ã³ãšãŒãžã§ã³ã
â ãã±ããæ
å ±ãè¿ã
ââ[INSERT resolved=false]ââ> inquiry_log ããŒãã«
çšæãã 2 ã€ã®ããŒãã«
| ããŒãã« | åœ¹å² | äžèº« |
|---|---|---|
faq_master |
FAQ ãã¹ã¿ãŒ | 8 ä»¶ã® FAQãIDã»ã«ããŽãªã»è³ªåã»åçã»ããŒã¯ãŒãã»æŽæ°æ¥æ |
inquiry_log |
åãåãããã° | ãšãŒãžã§ã³ããå¿çãããã³ã« 1 è¡ãã€èšé²ãããã誰ãäœãèããã©ã®ãšãŒãžã§ã³ããäœãšçãã解決ããããæ®ã |
inquiry_log ã«ã¯satisfaction_scoreïŒæºè¶³åºŠã¹ã³ã¢ïŒã«ã©ã ãäºåã«çšæããŠãããŸãã
æ¬èšäºã§ã¯ NULL ã®ãŸãŸã§ããã第4åïŒè©äŸ¡ïŒã§æŽ»çšããŸãã
第2åããã®å€æŽç¹
| é ç® | 第2å | 第3åïŒæ¬èšäºïŒ |
|---|---|---|
| FAQ ããŒã¿ | Python ã®ãªã¹ãïŒã³ãŒãã«çŽæžãïŒ | BigQuery faq_master ããŒãã« |
| FAQ ã®è¿œå | ã³ãŒã倿ŽïŒåããã〠| ããŒãã«ã«è¡ã远å ããã ã |
| åãåããå±¥æŽ | æ®ããªã | inquiry_log ã«1è¡ãã€èªåèšé² |
| ãšãŒãžã§ã³ãæ§æ | router / faq_searcher / escalation | åãïŒããŒã«é¢æ°ã ãå·®ãæ¿ãïŒ |
| ãããã€æ¹æ³ | Vertex AI Agent Engine | åã |
èšèšã®ãã€ã³ã
â ããŒã¯ãŒãã¯ãåºæãªè€åèªãã«ãã
faq_master ã® keywords ã«ã©ã ã«ã¯ãå FAQ ã«ã²ãã¥ãæ€çŽ¢ã¯ãŒããã«ã³ãåºåãã§å
¥ããŸãã
æåã¯çŽ çŽã«ãã¢ã«ãŠã³ããããã°ã€ã³ãã®ãããªåèªãå
¥ããŠããã®ã§ãããããã ãšç¡é¢ä¿ãªåãåãããŸã§ãããããŠããŸãåé¡ãçºçããŸããã
ãŠãŒã¶ãŒã®è³ªå: ãèªåã®ã¢ã«ãŠã³ãã§èº«ã«èŠãã®ãªããã°ã€ã³å±¥æŽããããŸãã â æ¬æ¥ã¯ã»ãã¥ãªãã£ã€ã³ã·ãã³ããšããŠãšã¹ã«ã¬ãŒã·ã§ã³ãã¹ã â ãšããããã¢ã«ãŠã³ããããã°ã€ã³ããšããããŒã¯ãŒãã«åŒã£ãããã ãã¹ã¯ãŒããªã»ãã FAQ ããããããŠããŸã
ããã§ãããŒã¯ãŒãããã¢ã«ãŠã³ãããã¯ããVPNæ¥ç¶ãããã¹ã¯ãŒããå¿ããã®ãããªåºæãªè€åèªã«æžãæããŸãããããã ãã§èª€ããããæžå°ããŸãã
åèªãã®ãã®ããããã® FAQ ã§ããåºãŠããªãèšãåãããéžã¶ãšç²ŸåºŠãäžãããŸãã
â¡ FAQ æ€çŽ¢ã¯ããŠãŒã¶ãŒå ¥åã«ããŒã¯ãŒããå«ãŸããããã§å€å®
ãŠãŒã¶ãŒããVPN ã«æ¥ç¶ããããšãããšèªèšŒãšã©ãŒãâŠããšé·æã§è³ªåããŠãããšããfaq_master ã®ã©ã®è¡ãè¿ãã¹ããã
æ¬èšäºã§ã¯ãkeywords ã®ååèªããŠãŒã¶ãŒå
¥åã«å«ãŸããŠããã°ããã® FAQ ãè¿ãããšããã·ã³ãã«ãªä»æ§ã«ããŸãããSQL ã§æžããšãkeywords ãã«ã³ãã§åå²ããåããŒã¯ãŒãããŠãŒã¶ãŒå
¥åã«éšåäžèŽãããã STRPOS ã§å€å®ãã圢ã«ãªããŸãã
SELECT faq_id, category, question, answer FROM faq_master, UNNEST(SPLIT(keywords, ',')) AS kw WHERE STRPOS(LOWER(@q), LOWER(TRIM(kw))) > 0 ORDER BY LENGTH(kw) DESC LIMIT 1
ORDER BY LENGTH(kw) DESC ã§ãããé·ãïŒå
·äœçãªïŒããŒã¯ãŒããã«äžèŽãã FAQ ãåªå
ããŠããŸãã
ããã§ãã¢ã«ãŠã³ãããã¯ãããããã¯ããããå
ã«è©äŸ¡ãããŸãã
BigQuery ã®å šææ€çŽ¢
SEARCH颿°ãæ€èšããŸããããããã©ã«ãã®ã¢ãã©ã€ã¶ã¯æ¥æ¬èªã®åœ¢æ çŽ è§£æã«å¯Ÿå¿ããŠããããèªç¶æã¯ãšãªã§æåŸ ã©ããã«ãããããŸããã§ãããä»åã¯ä»æ§ãã·ã³ãã«ãªUNNEST+STRPOSæ¹åŒãæ¡çšããŸããã
⢠ãã°éè€ãé²ãã責ååé¢ã
inquiry_log ãžã®æžã蟌ã¿ã¯ãäž¡æ¹ã®ãšãŒãžã§ã³ããäœã®å¶éããªãè¡ããš1 ã€ã®åãåããã§ 2 è¡ã®ãã°ãæ®ã£ãŠããŸããŸãïŒFAQ æ€çŽ¢ãšãŒãžã§ã³ããæžããåŸããšã¹ã«ã¬ãŒã·ã§ã³ãšãŒãžã§ã³ããæžãïŒã
ããã§ããšãŒãžã§ã³ãã® instructionïŒæç€ºæžïŒã§æžãåããŸããã
- FAQ æ€çŽ¢ãšãŒãžã§ã³ã: FAQ ããããããŠèªåãåçããå Žå ã®ã¿ ãã°ãæžãïŒ
resolved=trueïŒ - ãšã¹ã«ã¬ãŒã·ã§ã³ãšãŒãžã§ã³ã: å¿
ããã°ãæžãïŒ
resolved=falseïŒ
ãæçµå¿çãè¿ãããšãŒãžã§ã³ãã 1 åã ããã°ãæžãããšããã«ãŒã«ã«ããããšã§ã1 åãåããïŒ1 ã¬ã³ãŒã ãæ ä¿ããŠããŸãã
å®è£ ã®ãã¢
æ¬èšäºã§ã¯èšèšå€æãçŸãããã€ã³ããæç²ããŸãïŒãšã©ãŒãã³ããªã³ã°ã现ããæŽåœ¢åŠçã¯çç¥ïŒã
FAQ æ€çŽ¢ããŒã«ïŒagents/faq_searcher.pyïŒ
search_faq() ã®äžèº«ã¯ãäžã§èª¬æãã SQL ã BigQuery ã«æããŠããããã 1 è¡ãæŽåœ¢ããŠè¿ãã ãã§ãã
_BQ_CLIENT = bigquery.Client() # ã¢ãžã¥ãŒã«ãããã§åæåïŒåå©çšãããïŒ
def search_faq(query: str) -> str:
sql = """
SELECT faq_id, category, question, answer
FROM `helpdesk_demo.faq_master`,
UNNEST(SPLIT(keywords, ',')) AS kw
WHERE STRPOS(LOWER(@q), LOWER(TRIM(kw))) > 0
ORDER BY LENGTH(kw) DESC
LIMIT 1
"""
# ... ã¯ãšãªãå®è¡ããŠçµæãæŽåœ¢ããŠè¿ã
第2åã§ã¯åã颿°ã®äžã§ for faq in MOCK_FAQ_DATA: ... ãš Python ã«ãŒãããŠããéšåããBigQuery ãžã® SELECT ã¯ãšãªã«çœ®ãæãã£ãã ãã§ãã
ãšãŒãžã§ã³ãã®å®çŸ©åŽïŒinstructionãtools ã®æž¡ãæ¹ãªã©ïŒã¯ã»ãšãã©å€æŽããŠããŸããã
ãã°æžã蟌ã¿ããŒã«ïŒagents/inquiry_logger.pyïŒ
æ°èŠãã¡ã€ã«ã§ããBigQuery ã® inquiry_log ããŒãã«ã« 1 è¡ INSERT ããã ãã®ã·ã³ãã«ãªããŒã«ã
def log_inquiry(user_question, category, routed_to, agent_response, resolved):
row = {
"inquiry_id": str(uuid.uuid4()),
"timestamp": datetime.now(timezone.utc).isoformat(),
"user_question": user_question,
"category": category,
"routed_to": routed_to,
"agent_response": agent_response,
"resolved": resolved,
"satisfaction_score": None,
}
_BQ_CLIENT.insert_rows_json(_TABLE_ID, [row])
satisfaction_score ã¯æ¬èšäºã§ã¯ None ã®ãŸãŸå
¥ããŠããŸããã第4åïŒè©äŸ¡ïŒã§å€ãæŽæ°ããŠäœ¿ããŸãã
ãã®ããŒã«ã faq_searcher_agent ãš escalation_agent ã®äž¡æ¹ã® tools ã«ç»é²ããããããã® instruction ã§ããã€åŒã¶ãããæžãåããããšã§ãLLM ãå¿çãè¿ããããšã«ãæèãã倿ããŠãã°ãæ®ãä»çµã¿ã«ãªããŸãã
åäœç¢ºèª
ããŒã«ã«å®è¡
demo.py ãå®è¡ãããšã4 ã±ãŒã¹ã®åãåãããããããæ£ããæ¯ãåããããŠå¿çãè¿ããŸãïŒåºåã¯åé·ãªã®ã§äžéšçç¥ïŒã
[åãåãã 1] VPN ã«æ¥ç¶ããããšãããšèªèšŒãšã©ãŒãåºãŠæ¥ç¶ã§ããŸãã â FAQ æ€çŽ¢ãšãŒãžã§ã³ãã NW-001 ãè¿ãïŒã«ããŽãªïŒãããã¯ãŒã¯ç³»ïŒ [åãåãã 2] ãã¹ã¯ãŒããå¿ããŠããŸããŸãã â FAQ æ€çŽ¢ãšãŒãžã§ã³ãã AC-001 ãè¿ãïŒã«ããŽãªïŒã¢ã«ãŠã³ãç³»ïŒ [åãåãã 3] èªåã®ã¢ã«ãŠã³ãã§èº«ã«èŠãã®ãªããã°ã€ã³å±¥æŽããããŸã â FAQ ããããªã â ãšã¹ã«ã¬ãŒã·ã§ã³ïŒã«ããŽãªïŒã»ãã¥ãªãã£ãç·æ¥åºŠïŒé«ïŒ [åãåãã 4] 瀟å ã®æ¥åã·ã¹ãã ãå šå¡äœ¿ããªããªã£ãŠããŸã â FAQ ããããªã â ãšã¹ã«ã¬ãŒã·ã§ã³ïŒã«ããŽãªïŒã·ã¹ãã é害ãç·æ¥åºŠïŒé«ïŒ
inquiry_log ã«äœãèšé²ãããã
å®è¡åŸã« inquiry_log ã SELECT ãããšã4 ä»¶åã®ã¬ã³ãŒããæ®ã£ãŠããŸããã
| user_question | category | routed_to | resolved |
|---|---|---|---|
| VPN ã«æ¥ç¶ããããšãããšèªèšŒãšã©ãŒãåºãŠæ¥ç¶ã§ããŸãã | ãããã¯ãŒã¯ç³» | faq_searcher_agent | true |
| ãã¹ã¯ãŒããå¿ããŠããŸããŸããããªã»ããããæ¹æ³ãæããŠãã ãã | ã¢ã«ãŠã³ãç³» | faq_searcher_agent | true |
| èªåã®ã¢ã«ãŠã³ãã§èº«ã«èŠãã®ãªããã°ã€ã³å±¥æŽããããŸã | ã»ãã¥ãªã㣠| escalation_agent | false |
| 瀟å ã®æ¥åã·ã¹ãã ãå šå¡äœ¿ããªããªã£ãŠããŸã | ã·ã¹ãã é害 | escalation_agent | false |
ååãåããã 1 è¡ãã€ã»æçµå¿çãããšãŒãžã§ã³ãã®èšé²ãšããŠæ®ã£ãŠããŸãã
ããã§éèŠãªã®ã¯ãFAQ ãããã±ãŒã¹ã¯ resolved=trueããšã¹ã«ã¬ãŒã·ã§ã³ã±ãŒã¹ã¯ resolved=false ã§èšé²ãããŠããç¹ã§ãã
ããã«ãã£ãŠãéçšãå§ãŸã£ãããšã«ãã©ããããã®åãåããã FAQ ã§èªå解決ã§ããŠããããã SQL ã²ãšã€ã§éèšã§ããããã«ãªããŸããã
ã¯ã©ãŠãïŒVertex AI Agent EngineïŒãžã®åãããã€
第2åã§ãããã€ãããšãŒãžã§ã³ãããBigQuery 飿ºçã«å·®ãæ¿ããŸããã³ãŒãäžã®å€æŽã¯ requirements ã« google-cloud-bigquery ã远å ããã ã ã§ãã
ãã ãããããã€åã«ã²ãšã€ã ãæºåãèŠããŸãã
Reasoning Engine ã® SA ã« BigQuery æš©éãä»äž
Vertex AI ã«ã¯ããªãœãŒã¹ç®¡ççšã®æ±çšãµãŒãã¹ã¢ã«ãŠã³ãïŒgcp-sa-aiplatformïŒãšãReasoning Engine äžã§ãŠãŒã¶ãŒã³ãŒããå®è¡ããå°çšãµãŒãã¹ã¢ã«ãŠã³ãïŒgcp-sa-aiplatform-reïŒããããŸããBigQuery ã«ã¢ã¯ã»ã¹ããã®ã¯åŸè
ãªã®ã§ãæš©éã¯ãã¡ãã«ä»äžããå¿
èŠããããŸãã
å
·äœçã«ã¯ service-<çªå·>@gcp-sa-aiplatform-re.iam.gserviceaccount.comïŒ-re ãµãã£ãã¯ã¹ïŒã§ãããã® SA ã« BigQuery ãžã®ã¢ã¯ã»ã¹æš©éã 2 ã€ä»äžããªããšããšãŒãžã§ã³ããã faq_master ãèªãã ã inquiry_log ã«æžã蟌ãã ããã§ããŸããã
| ããŒã« | çšé |
|---|---|
roles/bigquery.jobUser |
ã¯ãšãªãžã§ããçºè¡ããæš©éïŒfaq_master ã® SELECT ã«å¿ èŠïŒ |
roles/bigquery.dataEditor |
ããŒãã«ã«ããŒã¿ãæžãèŸŒãæš©éïŒinquiry_log ã® INSERT ã«å¿ èŠïŒ |
æš©éããä»äžã§ããã°ãpython deploy.py ã§çŽ 5 åã»ã©ã§åãããã€ãå®äºããŸãã
ã¯ã©ãŠãåŽã§ãåãåäœã確èª
ã¯ã©ãŠãã«ãããã€ãããšãŒãžã§ã³ãã«åã 4 åãåãããéã£ããšãããããŒã«ã«ãšåãå¿çãè¿ããinquiry_log ã«ãåãã¹ããŒãã§ 4 è¡ã®ã¬ã³ãŒãã远å ãããŠããŸããã
| user_question | category | routed_to | resolved |
|---|---|---|---|
| VPN ã«æ¥ç¶ããããšãããšèªèšŒãšã©ãŒãåºãŠæ¥ç¶ã§ããŸãã | ãããã¯ãŒã¯ç³» | faq_searcher_agent | true |
| ãã¹ã¯ãŒããå¿ããŠããŸããŸããããªã»ããããæ¹æ³ãæããŠãã ãã | ã¢ã«ãŠã³ãç³» | faq_searcher_agent | true |
| èªåã®ã¢ã«ãŠã³ãã§èº«ã«èŠãã®ãªããã°ã€ã³å±¥æŽããããŸã | ã»ãã¥ãªã㣠| escalation_agent | false |
| 瀟å ã®æ¥åã·ã¹ãã ãå šå¡äœ¿ããªããªã£ãŠããŸã | ã·ã¹ãã é害 | escalation_agent | false |
ããŒã«ã«ãšã¯ã©ãŠãã§åãããŒã¿ãåãã¹ããŒãã§è²¯ãŸã£ãŠããç¶æ ã宿ããŸããã
ãããã©ãã
| ã€ãŸãããã€ã³ã | å¯ŸåŠ |
|---|---|
| Reasoning Engine ã® SA ãééãã | Vertex AI å
šäœã® SAïŒgcp-sa-aiplatformïŒã§ã¯ãªããgcp-sa-aiplatform-re ã«æš©éä»äžãã |
extra_packages=["agents"] ãå¿ãã |
æ°èŠè¿œå ãã inquiry_logger.py ã忢±ããããã³ã³ããèµ·åæã« ModuleNotFoundError |
| ãã°ã 1 åãåããã§ 2 è¡æ®ã | ãšãŒãžã§ã³ãã® instruction ã§ãFAQ ãããæã®ã¿ãããšã¹ã«ã¬ãŒã·ã§ã³æã®ã¿ããšæžãåãã |
| ããŒã¯ãŒãã®ç²åºŠãç²ã | ãã¢ã«ãŠã³ãããããã¢ã«ãŠã³ãããã¯ãã®ãããª åºæãªè€åèª ã«ãã |
ãŸãšããšæ¬¡åã«ã€ããŠ
第3åã§éæããã®ã¯ãèŠãç®ã®æŽŸæãã¯å°ãªããã®ã®éçšã«è¿ã¥ãããã®å°å³ã§éèŠãªå€æŽã§ãã
- FAQ ãã³ãŒãããåãé¢ãããããŒãã«ã®è¡ã远å ããã ãã§å¢ããã
- ã©ããªåãåãããã©ãåŠçãããããããã¹ãŠ SQL ã§éèšã§ããåœ¢ã§æ®ã
- ããŒã«ã«ã§ãã¯ã©ãŠãã§ããåãã¹ããŒãã§ããŒã¿ã貯ãŸã
ãã㧠第4åïŒVertex AI Evaluation ã§ãã«ããšãŒãžã§ã³ãã®å¿çåè³ªãæž¬ãïŒ ã«é²ãåå°ãæŽããŸãããæ¬¡åã¯inquiry_logã«è²¯ãŸã£ãããŒã¿ãè©äŸ¡ã®ãµã³ãã«ãšããŠäœ¿ããã«ãŒãã£ã³ã°ã»åçã»ãã©ãŒã«ããã¯ã®3軞ã§ãšãŒãžã§ã³ãã®å¿çå質ãå®éçã«æž¬ããŸãã