{"id":13169,"date":"2026-03-16T18:38:23","date_gmt":"2026-03-16T18:38:23","guid":{"rendered":"https:\/\/withcode.tech\/media\/?p=13169"},"modified":"2026-07-14T11:53:47","modified_gmt":"2026-07-14T11:53:47","slug":"langchain-webbaseloader-competitor-analysis","status":"publish","type":"post","link":"https:\/\/withcode.tech\/media\/langchain-webbaseloader-competitor-analysis\/","title":{"rendered":"LangChain WebBaseLoader\u3067\u7af6\u5408\u30b5\u30a4\u30c8\u3092\u81ea\u52d5\u5206\u6790\uff5cPython\u5b9f\u88c5\u30b3\u30fc\u30c9\u4ed8\u304d\u5b8c\u5168\u30ac\u30a4\u30c9"},"content":{"rendered":"<div class=\"swell-block-balloon\"><div class=\"c-balloon -bln-left\" data-col=\"gray\"><div class=\"c-balloon__icon -square\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/withcode.tech\/media\/wp-content\/uploads\/2025\/06\/\u30b9\u30af\u30ea\u30fc\u30f3\u30b7\u30e7\u30c3\u30c8-2025-06-15-14.48.08.jpg\" alt=\"\" class=\"c-balloon__iconImg\" width=\"80px\" height=\"80px\"><span class=\"c-balloon__iconName\">\u751f\u5f92<\/span><\/div><div class=\"c-balloon__body -speaking -border-none\"><div class=\"c-balloon__text\">\n  <p><strong>\u7af6\u5408\u30b5\u30a4\u30c8\u306e\u30b3\u30f3\u30c6\u30f3\u30c4\u3092\u5b9a\u671f\u7684\u306b\u30c1\u30a7\u30c3\u30af\u3059\u308b\u306e\u304c\u5927\u5909\u3067\u3059\u3002AI\u3067\u81ea\u52d5\u5206\u6790\u3067\u304d\u308c\u3070\u697d\u306a\u3093\u3067\u3059\u304c\u2026\u2026<\/strong><\/p>\n  <span class=\"c-balloon__shapes\"><span class=\"c-balloon__before\"><\/span><span class=\"c-balloon__after\"><\/span><\/span><\/div><\/div><\/div><\/div>\n\n  <div class=\"swell-block-balloon\"><div class=\"c-balloon -bln-right\" data-col=\"gray\"><div class=\"c-balloon__icon -square\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/withcode.tech\/media\/wp-content\/uploads\/2025\/06\/\u30b9\u30af\u30ea\u30fc\u30f3\u30b7\u30e7\u30c3\u30c8-2025-06-15-15.11.23.jpg\" alt=\"\" class=\"c-balloon__iconImg\" width=\"80px\" height=\"80px\"><span class=\"c-balloon__iconName\">\u30da\u30f3\u535a\u58eb<\/span><\/div><div class=\"c-balloon__body -speaking -border-none\"><div class=\"c-balloon__text\">\n  <p><strong>LangChain\u306eWebBaseLoader\u3092\u4f7f\u3048\u3070\u3001\u7af6\u5408\u30b5\u30a4\u30c8\u306e\u30c6\u30ad\u30b9\u30c8\u3092\u81ea\u52d5\u53ce\u96c6\u3057\u3066AI\u3067\u5206\u6790\u3059\u308b\u30c4\u30fc\u30eb\u304c\u4f5c\u308c\u308b\u3093\u3058\u3083\uff01URL\u3092\u6e21\u3059\u3060\u3051\u3067\u30b3\u30f3\u30c6\u30f3\u30c4\u62bd\u51fa\u30fb\u30ad\u30fc\u30ef\u30fc\u30c9\u5206\u6790\u30fb\u6bd4\u8f03\u30ec\u30dd\u30fc\u30c8\u751f\u6210\u307e\u3067\u81ea\u52d5\u5316\u3067\u304d\u308b\u305e\u3002\u4eca\u65e5\u306fPython\u5b9f\u88c5\u30b3\u30fc\u30c9\u3092\u5168\u6587\u63b2\u8f09\u3057\u3066\u5b8c\u5168\u89e3\u8aac\u3059\u308b\u305e\u3044\uff01<\/strong><\/p>\n  <span class=\"c-balloon__shapes\"><span class=\"c-balloon__before\"><\/span><span class=\"c-balloon__after\"><\/span><\/span><\/div><\/div><\/div><\/div>\n\n\n<div class=\"wp-block-group swl-box swl-box--border\"><div class=\"wp-block-group__inner-container\">\n<h2 class=\"wp-block-heading\">\u3053\u306e\u8a18\u4e8b\u3067\u308f\u304b\u308b\u3053\u3068<\/h2>\n<ul class=\"wp-block-list\">\n  <li>LangChain WebBaseLoader\u3092\u4f7f\u3063\u3066\u7af6\u5408\u30b5\u30a4\u30c8\u306e\u30c6\u30ad\u30b9\u30c8\u3092\u81ea\u52d5\u53d6\u5f97\u3059\u308b\u65b9\u6cd5<\/li>\n  <li>TextSplitter\u3067LLM\u306e\u30c8\u30fc\u30af\u30f3\u4e0a\u9650\u3092\u8d85\u3048\u305a\u306b\u9577\u6587\u3092\u51e6\u7406\u3059\u308b\u30c6\u30af\u30cb\u30c3\u30af<\/li>\n  <li>\u7af6\u5408\u30b5\u30a4\u30c8\u81ea\u52d5\u5206\u6790\u30c4\u30fc\u30eb\uff08\u8981\u7d04\u30fb\u30ad\u30fc\u30ef\u30fc\u30c9\u62bd\u51fa\u30fb\u6bd4\u8f03\u30ec\u30dd\u30fc\u30c8\uff09\u306e\u5b8c\u5168\u5b9f\u88c5\u30b3\u30fc\u30c9<\/li>\n  <li>Embeddings\u3068FAISS\u3067\u30b3\u30f3\u30c6\u30f3\u30c4\u30ae\u30e3\u30c3\u30d7\u3092\u6570\u5024\u5316\u3057\u3066\u767a\u898b\u3059\u308b\u65b9\u6cd5<\/li>\n  <li>GitHub Actions\u3067\u9031\u6b21\u5b9a\u671f\u5b9f\u884c\u30fbSlack\u901a\u77e5\u307e\u3067\u5b8c\u5168\u81ea\u52d5\u5316\u3059\u308b\u624b\u9806<\/li>\n<\/ul>\n<\/div><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">LangChain\u306eWebBaseLoader\u3092\u4f7f\u3048\u3070\u3001<strong>URL\u3092\u6e21\u3059\u3060\u3051\u3067\u7af6\u5408\u30b5\u30a4\u30c8\u306e\u30c6\u30ad\u30b9\u30c8\u3092\u62bd\u51fa\u3057\u3001OpenAI API\u3067\u8981\u7d04\u30fb\u30ad\u30fc\u30ef\u30fc\u30c9\u62bd\u51fa\u30fb\u6bd4\u8f03\u30ec\u30dd\u30fc\u30c8\u3092\u81ea\u52d5\u751f\u6210<\/strong>\u3067\u304d\u307e\u3059\u3002\u6bce\u9031\u6570\u6642\u9593\u304b\u304b\u3063\u3066\u3044\u305f\u7af6\u5408\u30ea\u30b5\u30fc\u30c1\u304c\u3001Python\u30b9\u30af\u30ea\u30d7\u30c8\u306e\u5b9f\u884c\u6570\u5206\u306b\u77ed\u7e2e\u3055\u308c\u307e\u3059\u3002<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u672c\u8a18\u4e8b\u3067\u306f\u3001<strong><span class=\"swl-marker mark_yellow\">LangChain\u306e\u6982\u8981\u30fbWebBaseLoader\u306e\u4f7f\u3044\u65b9\u30fb\u7af6\u5408\u30b5\u30a4\u30c8\u81ea\u52d5\u5206\u6790\u30c4\u30fc\u30eb\u306e\u5b9f\u88c5\u30b3\u30fc\u30c9\u30fb\u8907\u6570\u30b5\u30a4\u30c8\u6bd4\u8f03\u30fbEmbeddings\u6d3b\u7528\u30fbVectorStore\u30fb\u5b9a\u671f\u5b9f\u884c\u306e\u81ea\u52d5\u5316\u30fb\u30b3\u30b9\u30c8\u6700\u9069\u5316\u30fb\u30a8\u30e9\u30fc\u30cf\u30f3\u30c9\u30ea\u30f3\u30b0<\/span><\/strong>\u3092\u5b8c\u5168\u89e3\u8aac\u3057\u307e\u3059\u3002<\/p>\n\n\n<p><strong>\u3042\u308f\u305b\u3066\u8aad\u307f\u305f\u3044\uff1a<\/strong><br>\n  <a href=\"https:\/\/withcode.tech\/media\/\">RAG\u69cb\u6210\u3067ChatGPT API\u3092\u4f7f\u3063\u305f\u81ea\u793e\u30c7\u30fc\u30bf\u53c2\u7167\u30c1\u30e3\u30c3\u30c8\u30dc\u30c3\u30c8\u306e\u4f5c\u308a\u65b9<\/a>\uff08LangChain\u6d3b\u7528\u306e\u57fa\u790e\uff09\n<\/p>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">LangChain\u3068WebBaseLoader\u3068\u306f\uff5c\u7af6\u5408\u5206\u6790\u306b\u4f7f\u3048\u308b\u7406\u7531<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">LangChain\u306f\u3001ChatGPT\u306a\u3069\u306eLLM\uff08\u5927\u898f\u6a21\u8a00\u8a9e\u30e2\u30c7\u30eb\uff09\u3092\u6d3b\u7528\u3057\u305fAI\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3092\u52b9\u7387\u7684\u306b\u69cb\u7bc9\u3059\u308b\u305f\u3081\u306e\u30aa\u30fc\u30d7\u30f3\u30bd\u30fc\u30b9\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u3067\u3059\u3002Python\u3092\u4e2d\u5fc3\u306b\u3001\u5916\u90e8\u30c7\u30fc\u30bf\u3068LLM\u3092\u67d4\u8edf\u306b\u9023\u643a\u3055\u305b\u308b\u6a5f\u80fd\u3092\u591a\u6570\u6301\u3063\u3066\u3044\u307e\u3059\u30022022\u5e7410\u6708\u306bHarrison Chase\u6c0f\u306b\u3088\u3063\u3066\u516c\u958b\u3055\u308c\u3066\u4ee5\u6765\u3001\u308f\u305a\u304b\u6570\u5e74\u3067GitHub Star\u6570\u304c9\u4e07\u3092\u8d85\u3048\u308b\u6025\u6210\u9577\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306b\u306a\u308a\u307e\u3057\u305f\u3002<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">LangChain\u306e\u6700\u5927\u306e\u5f37\u307f\u306f\u300c<strong>\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u3068LLM\u3092\u3064\u306a\u3050\u30b0\u30eb\u30fc\uff08\u63a5\u7740\u5264\uff09\u3068\u3057\u3066\u306e\u6a5f\u80fd<\/strong>\u300d\u306b\u3042\u308a\u307e\u3059\u3002Web\u30da\u30fc\u30b8\u30fbPDF\u30fb\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30fbSlack\u30fbNotion\u306a\u3069\u591a\u69d8\u306a\u30c7\u30fc\u30bf\u30bd\u30fc\u30b9\u304b\u3089\u30c6\u30ad\u30b9\u30c8\u3092\u53d6\u308a\u8fbc\u307f\u3001\u305d\u308c\u3092OpenAI\u30fbAnthropic\u30fbGoogle Gemini\u306a\u3069\u8907\u6570\u306eLLM\u3067\u51e6\u7406\u3059\u308b\u30d1\u30a4\u30d7\u30e9\u30a4\u30f3\u3092\u3001\u6700\u5c0f\u9650\u306e\u30b3\u30fc\u30c9\u3067\u69cb\u7bc9\u3067\u304d\u307e\u3059\u3002\u7af6\u5408\u5206\u6790\u306b\u304a\u3044\u3066\u306f\u300cWeb\u30da\u30fc\u30b8\u306e\u81ea\u52d5\u53ce\u96c6 \u2192 \u30c6\u30ad\u30b9\u30c8\u6b63\u898f\u5316 \u2192 LLM\u306b\u3088\u308b\u5206\u6790 \u2192 \u30ec\u30dd\u30fc\u30c8\u751f\u6210\u300d\u3068\u3044\u3046\u30d5\u30ed\u30fc\u3092\u30b7\u30fc\u30e0\u30ec\u30b9\u306b\u5b9f\u73fe\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">WebBaseLoader\u3068\u306f<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">WebBaseLoader\u306fLangChain Community\u30d1\u30c3\u30b1\u30fc\u30b8\u306b\u542b\u307e\u308c\u308b\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u30ed\u30fc\u30c0\u30fc\u306e\u4e00\u7a2e\u3067\u3059\u3002\u5185\u90e8\u7684\u306b\u306fPython\u306e\u6709\u540d\u306aHTML\u30d1\u30fc\u30b5\u30fc\u30e9\u30a4\u30d6\u30e9\u30ea\u300cBeautiful Soup 4\uff08bs4\uff09\u300d\u3092\u4f7f\u7528\u3057\u3066\u3001\u6307\u5b9aURL\u306eHTML\u304b\u3089\u30c6\u30ad\u30b9\u30c8\u3092\u62bd\u51fa\u3057\u3001LangChain\u306e\u6a19\u6e96\u30c7\u30fc\u30bf\u69cb\u9020\u3067\u3042\u308b<code>Document<\/code>\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u306b\u5909\u63db\u3057\u307e\u3059\u3002<\/p>\n\n\n<div class=\"hcb_wrap\"><pre class=\"prism line-numbers lang-none\" data-lang=\"Code\"><code>\u3010WebBaseLoader\u306e\u5f79\u5272\u3011\n\nWebBaseLoader = LangChain\u306b\u7d44\u307f\u8fbc\u307e\u308c\u305fWeb\u30b9\u30af\u30ec\u30a4\u30d4\u30f3\u30b0\u6a5f\u80fd\n\n\u3067\u304d\u308b\u3053\u3068\uff1a\n\u2705 URL\u3092\u6e21\u3059\u3060\u3051\u3067Web\u30da\u30fc\u30b8\u306e\u30c6\u30ad\u30b9\u30c8\u3092\u62bd\u51fa\n\u2705 \u8907\u6570URL\u3092\u4e00\u62ec\u51e6\u7406\n\u2705 Beautiful Soup \u30d9\u30fc\u30b9\u306eHTML\u30d1\u30fc\u30b9\n\u2705 LangChain\u306eDocument\u5f62\u5f0f\u306b\u81ea\u52d5\u5909\u63db\uff08RAG\u3084Chain\u3068\u76f4\u63a5\u9023\u643a\u3067\u304d\u308b\uff09\n\u2705 BeautifulSoup\u306eSoupStrainer\u3067\u53d6\u5f97\u5bfe\u8c61\u8981\u7d20\u3092\u7d5e\u308a\u8fbc\u3081\u308b\n\u2705 \u30ab\u30b9\u30bf\u30e0HTTP\u30d8\u30c3\u30c0\u30fc\u3067User-Agent\u3092\u507d\u88c5\u3067\u304d\u308b\n\u2705 \u30d7\u30ed\u30ad\u30b7\u8a2d\u5b9a\u306b\u5bfe\u5fdc\n\n\u7af6\u5408\u5206\u6790\u3078\u306e\u6d3b\u7528\u30a4\u30e1\u30fc\u30b8\uff1a\nURL[] \u2192 WebBaseLoader \u2192 \u30c6\u30ad\u30b9\u30c8\u62bd\u51fa \u2192 LLM\u5206\u6790 \u2192 \u30ec\u30dd\u30fc\u30c8\u751f\u6210<\/code><\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">WebBaseLoader\u304c\u8fd4\u3059<code>Document<\/code>\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u306b\u306f\u3001<code>page_content<\/code>\uff08\u30c6\u30ad\u30b9\u30c8\uff09\u3068<code>metadata<\/code>\uff08\u30bd\u30fc\u30b9URL\u30fb\u30bf\u30a4\u30c8\u30eb\u306a\u3069\uff09\u304c\u683c\u7d0d\u3055\u308c\u3066\u3044\u307e\u3059\u3002\u3053\u306e\u30d5\u30a9\u30fc\u30de\u30c3\u30c8\u306fLangChain\u306e\u3059\u3079\u3066\u306e\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u3068\u4e92\u63db\u6027\u304c\u3042\u308b\u305f\u3081\u3001<strong>\u30c6\u30ad\u30b9\u30c8\u3092\u30ed\u30fc\u30c9\u3057\u305f\u3089\u3059\u3050\u306bChain\u30fbAgent\u30fbVectorStore\u3068\u7d44\u307f\u5408\u308f\u305b\u3089\u308c\u307e\u3059<\/strong>\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">LangChain\u306e\u4e3b\u8981\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8<\/h3>\n\n\n<table>\n  <thead><tr><th>\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8<\/th><th>\u5f79\u5272<\/th><th>\u7af6\u5408\u5206\u6790\u3067\u306e\u4f7f\u3044\u6240<\/th><\/tr><\/thead>\n  <tbody>\n    <tr><td><strong>WebBaseLoader<\/strong><\/td><td>Web\u30da\u30fc\u30b8\u306eHTML\u304b\u3089\u30c6\u30ad\u30b9\u30c8\u3092\u62bd\u51fa<\/td><td>\u7af6\u5408\u30b5\u30a4\u30c8\u306e\u30b3\u30f3\u30c6\u30f3\u30c4\u53ce\u96c6<\/td><\/tr>\n    <tr><td><strong>TextSplitter<\/strong><\/td><td>\u9577\u3044\u30c6\u30ad\u30b9\u30c8\u3092\u30c1\u30e3\u30f3\u30af\u306b\u5206\u5272<\/td><td>\u30c8\u30fc\u30af\u30f3\u5236\u9650\u3092\u8d85\u3048\u306a\u3044\u3088\u3046\u5206\u5272\u51e6\u7406<\/td><\/tr>\n    <tr><td><strong>Embeddings<\/strong><\/td><td>\u30c6\u30ad\u30b9\u30c8\u3092\u30d9\u30af\u30c8\u30eb\u306b\u5909\u63db<\/td><td>\u30b3\u30f3\u30c6\u30f3\u30c4\u306e\u985e\u4f3c\u5ea6\u6bd4\u8f03\u30fb\u91cd\u8907\u691c\u51fa<\/td><\/tr>\n    <tr><td><strong>VectorStore<\/strong><\/td><td>\u30d9\u30af\u30c8\u30eb\u3092DB\u306b\u4fdd\u5b58\u30fb\u691c\u7d22<\/td><td>\u5927\u91cf\u30da\u30fc\u30b8\u306e\u52b9\u7387\u7684\u306a\u7ba1\u7406\u30fb\u691c\u7d22<\/td><\/tr>\n    <tr><td><strong>Chains<\/strong><\/td><td>\u8907\u6570\u306e\u51e6\u7406\u3092\u30d1\u30a4\u30d7\u30e9\u30a4\u30f3\u5316<\/td><td>\u300c\u62bd\u51fa\u2192\u8981\u7d04\u2192\u6bd4\u8f03\u2192\u30ec\u30dd\u30fc\u30c8\u300d\u306e\u4e00\u62ec\u5b9f\u884c<\/td><\/tr>\n    <tr><td><strong>Agents<\/strong><\/td><td>AI\u304c\u81ea\u5f8b\u7684\u306b\u30c4\u30fc\u30eb\u3092\u9078\u629e\u30fb\u5b9f\u884c<\/td><td>\u300c\u3053\u306e\u7af6\u5408\u306e\u5f37\u307f\u306f\u4f55\u304b\uff1f\u300d\u3078\u306e\u81ea\u52d5\u56de\u7b54<\/td><\/tr>\n    <tr><td><strong>PromptTemplate<\/strong><\/td><td>\u5909\u6570\u4ed8\u304d\u30d7\u30ed\u30f3\u30d7\u30c8\u3092\u518d\u5229\u7528\u53ef\u80fd\u306a\u5f62\u3067\u5b9a\u7fa9<\/td><td>\u5206\u6790\u89b3\u70b9\u3092\u7d71\u4e00\u3057\u305f\u30d7\u30ed\u30f3\u30d7\u30c8\u7ba1\u7406<\/td><\/tr>\n  <\/tbody>\n<\/table>\n\n\n<h3 class=\"wp-block-heading\">\u306a\u305cWebBaseLoader\u3092\u7af6\u5408\u5206\u6790\u306b\u4f7f\u3046\u306e\u304b<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">\u7af6\u5408\u5206\u6790\u306e\u4f5c\u696d\u3092\u624b\u52d5\u3067\u884c\u3046\u5834\u5408\u3001\u5bfe\u8c61\u30b5\u30a4\u30c8\u3092\u4e00\u3064\u3072\u3068\u3064\u958b\u304d\u3001\u5185\u5bb9\u3092\u8aad\u3093\u3067\u3001\u30b9\u30d7\u30ec\u30c3\u30c9\u30b7\u30fc\u30c8\u306b\u8ee2\u8a18\u3057\u3066\u3001\u6bd4\u8f03\u3059\u308b\u2014\u2014\u3068\u3044\u3046\u5de5\u7a0b\u306b\u6bce\u56de\u6570\u6642\u9593\u304b\u304b\u308a\u307e\u3059\u3002\u3053\u308c\u3092Python\u30b9\u30af\u30ea\u30d7\u30c8\u306b\u843d\u3068\u3057\u8fbc\u3080\u3060\u3051\u306a\u3089\u901a\u5e38\u306e\u30b9\u30af\u30ec\u30a4\u30d4\u30f3\u30b0\u3067\u3082\u5bfe\u5fdc\u3067\u304d\u307e\u3059\u304c\u3001<strong>\u300c\u30c6\u30ad\u30b9\u30c8\u3092\u53d6\u5f97\u3057\u305f\u5f8c\u306bAI\u3067\u610f\u5473\u3092\u8aad\u307f\u53d6\u308b\u300d\u3068\u3044\u3046\u5de5\u7a0b\u3067LangChain\u304c\u5727\u5012\u7684\u306b\u52b9\u7387\u7684<\/strong>\u3067\u3059\u3002<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">BeautifulSoup\u3060\u3051\u3092\u4f7f\u3063\u305f\u30b9\u30af\u30ec\u30a4\u30d4\u30f3\u30b0\u3067\u306f\u3001\u62bd\u51fa\u3057\u305f\u30c6\u30ad\u30b9\u30c8\u3092OpenAI API\u306b\u6e21\u3059\u305f\u3081\u306e\u524d\u51e6\u7406\uff08\u30c8\u30fc\u30af\u30f3\u6570\u306e\u7ba1\u7406\u30fb\u30c1\u30e3\u30f3\u30af\u5206\u5272\u30fb\u30d7\u30ed\u30f3\u30d7\u30c8\u8a2d\u8a08\uff09\u3092\u81ea\u524d\u3067\u5b9f\u88c5\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002LangChain\u306eWebBaseLoader\u3092\u4f7f\u3048\u3070\u3001\u3053\u306e\u524d\u51e6\u7406\u304c\u65e2\u306b\u30d1\u30c3\u30b1\u30fc\u30b8\u5316\u3055\u308c\u3066\u304a\u308a\u3001<code>load_summarize_chain<\/code>\u306a\u3069\u306e\u9ad8\u30ec\u30d9\u30ebAPI\u3092\u547c\u3076\u3060\u3051\u3067\u300c\u8981\u7d04\u300d\u300c\u30ad\u30fc\u30ef\u30fc\u30c9\u62bd\u51fa\u300d\u300c\u6bd4\u8f03\u5206\u6790\u300d\u304c\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u74b0\u5883\u69cb\u7bc9\uff5cLangChain\u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3068\u8a2d\u5b9a<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">LangChain\u306fPython 3.9\u4ee5\u4e0a\u3092\u5bfe\u8c61\u3068\u3057\u3066\u3044\u307e\u3059\u30022024\u5e74\u4ee5\u964d\u306f\u30d1\u30c3\u30b1\u30fc\u30b8\u304c<code>langchain<\/code>\uff08\u30b3\u30a2\u30ed\u30b8\u30c3\u30af\uff09\u3068<code>langchain-community<\/code>\uff08\u5916\u90e8\u9023\u643a\uff09\u3068<code>langchain-openai<\/code>\uff08OpenAI\u5c02\u7528\uff09\u306b\u5206\u5272\u3055\u308c\u3066\u3044\u308b\u305f\u3081\u3001\u5fc5\u8981\u306a\u3082\u306e\u3092\u3059\u3079\u3066\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3057\u307e\u3059\u3002<\/p>\n\n\n<div class=\"hcb_wrap\"><pre class=\"prism line-numbers lang-bash\" data-lang=\"Bash\"><code># \u4eee\u60f3\u74b0\u5883\u3092\u4f5c\u6210\u3057\u3066\u6709\u52b9\u5316\npython -m venv venv\nsource venv\/bin\/activate  # Windows: venv\\Scripts\\activate\n\n# \u5fc5\u8981\u306a\u30d1\u30c3\u30b1\u30fc\u30b8\u3092\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\npip install langchain langchain-community langchain-openai \\\n            beautifulsoup4 requests python-dotenv openai \\\n            faiss-cpu schedule<\/code><\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><code>faiss-cpu<\/code>\u306fFacebook AI Research\u88fd\u306e\u30d9\u30af\u30c8\u30eb\u691c\u7d22\u30e9\u30a4\u30d6\u30e9\u30ea\u3067\u3059\u3002\u5f8c\u8ff0\u3059\u308bEmbeddings\u3092\u4f7f\u3063\u305f\u985e\u4f3c\u5ea6\u6bd4\u8f03\u306b\u4f7f\u3044\u307e\u3059\u3002GPU\u304c\u3042\u308b\u74b0\u5883\u3067\u306f<code>faiss-gpu<\/code>\u3092\u4f7f\u3046\u3068\u3055\u3089\u306b\u9ad8\u901f\u5316\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n<div class=\"hcb_wrap\"><pre class=\"prism line-numbers lang-none\" data-lang=\"Code\"><code># .env \u30d5\u30a1\u30a4\u30eb\u306b API\u30ad\u30fc\u3092\u8a2d\u5b9a\uff08Git\u306b\u542b\u3081\u306a\u3044\u3053\u3068\uff09\nOPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxx<\/code><\/pre><\/div>\n\n<div class=\"hcb_wrap\"><pre class=\"prism line-numbers lang-none\" data-lang=\"Code\"><code># \u30d5\u30a1\u30a4\u30eb\u69cb\u6210\ncompetitor-analyzer\/\n\u251c\u2500\u2500 main.py              # \u30e1\u30a4\u30f3\u51e6\u7406\u30fb\u5b9f\u884c\u30a8\u30f3\u30c8\u30ea\u30fc\u30dd\u30a4\u30f3\u30c8\n\u251c\u2500\u2500 analyzer.py          # \u5206\u6790\u30ed\u30b8\u30c3\u30af\uff08\u8981\u7d04\u30fb\u30ad\u30fc\u30ef\u30fc\u30c9\u62bd\u51fa\u30fb\u6bd4\u8f03\uff09\n\u251c\u2500\u2500 embeddings_search.py # Embeddings\u3092\u4f7f\u3063\u305f\u985e\u4f3c\u5ea6\u5206\u6790\n\u251c\u2500\u2500 notifier.py          # Slack\u901a\u77e5\n\u251c\u2500\u2500 schedule_analyzer.py # \u5b9a\u671f\u5b9f\u884c\u30b9\u30b1\u30b8\u30e5\u30fc\u30e9\n\u251c\u2500\u2500 .env                 # API\u30ad\u30fc\uff08Git\u306b\u542b\u3081\u306a\u3044\uff09\n\u251c\u2500\u2500 .gitignore           # .env\u30fbvenv\u30fbreports\/ \u3092\u9664\u5916\n\u251c\u2500\u2500 requirements.txt     # pip freeze \u3057\u305f\u5185\u5bb9\n\u2514\u2500\u2500 reports\/             # \u30ec\u30dd\u30fc\u30c8\u51fa\u529b\u5148\uff08.gitignore\u63a8\u5968\uff09<\/code><\/pre><\/div>\n\n\n<h3 class=\"wp-block-heading\">requirements.txt\u306e\u4f5c\u6210<\/h3>\n\n\n<div class=\"hcb_wrap\"><pre class=\"prism line-numbers lang-bash\" data-lang=\"Bash\"><code># requirements.txt\nlangchain&gt;=0.3.0\nlangchain-community&gt;=0.3.0\nlangchain-openai&gt;=0.2.0\nbeautifulsoup4&gt;=4.12.0\nrequests&gt;=2.31.0\npython-dotenv&gt;=1.0.0\nopenai&gt;=1.40.0\nfaiss-cpu&gt;=1.8.0\nschedule&gt;=1.2.0<\/code><\/pre><\/div>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">WebBaseLoader\u306e\u57fa\u672c\u7684\u306a\u4f7f\u3044\u65b9\uff5c1URL\u304b\u3089\u8907\u6570URL\u306e\u4e00\u62ec\u51e6\u7406\u307e\u3067<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">\u57fa\u672c\uff1a1\u3064\u306eURL\u304b\u3089\u30c6\u30ad\u30b9\u30c8\u3092\u62bd\u51fa\u3059\u308b<\/h3>\n\n\n<div class=\"hcb_wrap\"><pre class=\"prism line-numbers lang-python\" data-lang=\"Python\"><code># basic_loader.py\n\nfrom langchain_community.document_loaders import WebBaseLoader\n\n# URL\u3092\u6307\u5b9a\u3057\u3066\u30ed\u30fc\u30c0\u30fc\u3092\u4f5c\u6210\nloader = WebBaseLoader(\"https:\/\/example-competitor.com\/blog\/\")\n\n# \u30da\u30fc\u30b8\u3092\u8aad\u307f\u8fbc\u3093\u3067Document\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u306b\u5909\u63db\ndocuments = loader.load()\n\n# \u30c6\u30ad\u30b9\u30c8\u5185\u5bb9\u3092\u78ba\u8a8d\nfor doc in documents:\n    print(f\"URL: {doc.metadata['source']}\")\n    print(f\"\u30c6\u30ad\u30b9\u30c8\u9577: {len(doc.page_content)} \u6587\u5b57\")\n    print(f\"\u5192\u982d200\u6587\u5b57: {doc.page_content[:200]}\")\n    print(\"---\")<\/code><\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">\u4e0a\u8a18\u306e\u30b3\u30fc\u30c9\u3067<code>documents<\/code>\u306b\u306f<code>Document<\/code>\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u306e\u30ea\u30b9\u30c8\u304c\u8fd4\u308a\u307e\u3059\u3002<code>page_content<\/code>\u306b\u306fHTML\u30bf\u30b0\u3092\u9664\u53bb\u3057\u305f\u30c6\u30ad\u30b9\u30c8\u3001<code>metadata<\/code>\u306b\u306f<code>{'source': 'https:\/\/...'}<\/code>\u304c\u683c\u7d0d\u3055\u308c\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u8907\u6570URL\u3092\u4e00\u62ec\u51e6\u7406\u3059\u308b<\/h3>\n\n\n<div class=\"hcb_wrap\"><pre class=\"prism line-numbers lang-python\" data-lang=\"Python\"><code># multi_loader.py\n\nfrom langchain_community.document_loaders import WebBaseLoader\n\n# \u7af6\u5408\u30b5\u30a4\u30c8\u306eURL\u30ea\u30b9\u30c8\ncompetitor_urls = [\n    \"https:\/\/competitor-a.com\/services\/\",\n    \"https:\/\/competitor-b.com\/about\/\",\n    \"https:\/\/competitor-c.com\/blog\/\",\n]\n\n# \u8907\u6570URL\u3092\u4e00\u62ec\u30ed\u30fc\u30c9\nloader = WebBaseLoader(competitor_urls)\ndocuments = loader.load()\n\nprint(f\"{len(documents)} \u30da\u30fc\u30b8\u3092\u8aad\u307f\u8fbc\u307f\u307e\u3057\u305f\")\nfor i, doc in enumerate(documents):\n    print(f\"[{i+1}] {doc.metadata['source']} - {len(doc.page_content)}\u6587\u5b57\")<\/code><\/pre><\/div>\n\n\n<h3 class=\"wp-block-heading\">BeautifulSoup\u306e\u8a2d\u5b9a\u3067\u4e0d\u8981\u306a\u30bf\u30b0\u3092\u9664\u5916\u3059\u308b<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">\u30c7\u30d5\u30a9\u30eb\u30c8\u306eWebBaseLoader\u306f\u30ca\u30d3\u30b2\u30fc\u30b7\u30e7\u30f3\u30fb\u30d5\u30c3\u30bf\u30fc\u30fb\u5e83\u544a\u30c6\u30ad\u30b9\u30c8\u3082\u542b\u3081\u3066\u3059\u3079\u3066\u306e\u53ef\u8996\u30c6\u30ad\u30b9\u30c8\u3092\u53d6\u5f97\u3057\u307e\u3059\u3002\u7af6\u5408\u5206\u6790\u3067\u306f\u672c\u6587\u30c6\u30ad\u30b9\u30c8\u3060\u3051\u3092\u62bd\u51fa\u3057\u305f\u3044\u5834\u5408\u304c\u591a\u3044\u305f\u3081\u3001<code>bs_kwargs<\/code>\u3067<code>SoupStrainer<\/code>\u3092\u4f7f\u3063\u3066\u53d6\u5f97\u5bfe\u8c61\u8981\u7d20\u3092\u7d5e\u308a\u8fbc\u307f\u307e\u3059\u3002<\/p>\n\n\n<div class=\"hcb_wrap\"><pre class=\"prism line-numbers lang-none\" data-lang=\"Code\"><code># clean_loader.py\n\nimport bs4\nfrom langchain_community.document_loaders import WebBaseLoader\n\nloader = WebBaseLoader(\n    web_paths=[\"https:\/\/competitor-a.com\/services\/\"],\n    bs_kwargs={\n        \"parse_only\": bs4.SoupStrainer(\n            class_=(\"post-content\", \"article-body\", \"entry-content\")  # \u672c\u6587\u30a8\u30ea\u30a2\u306e\u307f\u53d6\u5f97\n        )\n    }\n)\n\ndocuments = loader.load()\n# \u30ca\u30d3\u30b2\u30fc\u30b7\u30e7\u30f3\u30fb\u30d5\u30c3\u30bf\u30fc\u30fb\u5e83\u544a\u30c6\u30ad\u30b9\u30c8\u3092\u9664\u5916\u3057\u305f\u672c\u6587\u306e\u307f\u3092\u53d6\u5f97\u3067\u304d\u308b<\/code><\/pre><\/div>\n\n\n<h3 class=\"wp-block-heading\">\u30ab\u30b9\u30bf\u30e0\u30d8\u30c3\u30c0\u30fc\u3068User-Agent\u306e\u8a2d\u5b9a<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">\u4e00\u90e8\u306eWeb\u30b5\u30a4\u30c8\u306f\u30c7\u30d5\u30a9\u30eb\u30c8\u306ePython User-Agent\uff08<code>python-requests\/x.x.x<\/code>\uff09\u3067\u30a2\u30af\u30bb\u30b9\u3059\u308b\u3068\u30d6\u30ed\u30c3\u30af\u3055\u308c\u308b\u5834\u5408\u304c\u3042\u308a\u307e\u3059\u3002<code>header_template<\/code>\u3067User-Agent\u3092\u8a2d\u5b9a\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n<div class=\"hcb_wrap\"><pre class=\"prism line-numbers lang-python\" data-lang=\"Python\"><code># custom_header_loader.py\n\nfrom langchain_community.document_loaders import WebBaseLoader\n\nloader = WebBaseLoader(\n    web_paths=[\"https:\/\/competitor-a.com\/blog\/\"],\n    header_template={\n        \"User-Agent\": \"Mozilla\/5.0 (Macintosh; Intel Mac OS X 10_15_7) \"\n                      \"AppleWebKit\/537.36 (KHTML, like Gecko) \"\n                      \"Chrome\/122.0.0.0 Safari\/537.36\",\n        \"Accept-Language\": \"ja,en-US;q=0.9,en;q=0.8\",\n    }\n)\n\ndocuments = loader.load()\nprint(f\"\u53d6\u5f97\u6210\u529f: {len(documents[0].page_content)} \u6587\u5b57\")<\/code><\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">\u306a\u304a\u3001User-Agent\u306e\u30ab\u30b9\u30bf\u30de\u30a4\u30ba\u306f\u30b5\u30a4\u30c8\u306e\u5229\u7528\u898f\u7d04\u3067\u7981\u6b62\u3055\u308c\u3066\u3044\u308b\u5834\u5408\u304c\u3042\u308a\u307e\u3059\u3002robots.txt\u306e\u78ba\u8a8d\u3068\u5408\u308f\u305b\u3066\u3001\u9069\u5207\u306a\u30ea\u30af\u30a8\u30b9\u30c8\u9593\u9694\uff08\u5f8c\u8ff0\uff09\u3092\u8a2d\u3051\u308b\u3053\u3068\u3092\u5f37\u304f\u63a8\u5968\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u30c6\u30ad\u30b9\u30c8\u5206\u5272\u6226\u7565\uff5cTextSplitter\u306e\u4f7f\u3044\u65b9<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">LLM\u306b\u306f\u30c8\u30fc\u30af\u30f3\u6570\u306e\u4e0a\u9650\u304c\u3042\u308a\u307e\u3059\uff08GPT-4o mini\u3067128K\u30c8\u30fc\u30af\u30f3\uff09\u3002Web\u30da\u30fc\u30b8\u306e\u30c6\u30ad\u30b9\u30c8\u304c\u9577\u3044\u5834\u5408\u3001\u305d\u306e\u307e\u307eAPI\u306b\u6e21\u3059\u3068\u4e0a\u9650\u3092\u8d85\u3048\u3066\u30a8\u30e9\u30fc\u306b\u306a\u308a\u307e\u3059\u3002LangChain\u306e<code>TextSplitter<\/code>\u3092\u4f7f\u3063\u3066\u30c6\u30ad\u30b9\u30c8\u3092\u30c1\u30e3\u30f3\u30af\u306b\u5206\u5272\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">RecursiveCharacterTextSplitter\uff08\u63a8\u5968\uff09<\/h3>\n\n\n<div class=\"hcb_wrap\"><pre class=\"prism line-numbers lang-python\" data-lang=\"Python\"><code># text_splitter_demo.py\n\nfrom langchain.text_splitter import RecursiveCharacterTextSplitter\n\n# \u7af6\u5408\u5206\u6790\u5411\u3051\u306e\u8a2d\u5b9a\u4f8b\nsplitter = RecursiveCharacterTextSplitter(\n    chunk_size=2000,        # 1\u30c1\u30e3\u30f3\u30af\u3042\u305f\u308a\u306e\u6700\u5927\u6587\u5b57\u6570\n    chunk_overlap=200,      # \u30c1\u30e3\u30f3\u30af\u9593\u306e\u30aa\u30fc\u30d0\u30fc\u30e9\u30c3\u30d7\uff08\u6587\u8108\u306e\u9023\u7d9a\u6027\u3092\u4fdd\u3064\uff09\n    separators=[\"\\n\\n\", \"\\n\", \"\u3002\", \"\u3001\", \" \", \"\"]\n    # \u65e5\u672c\u8a9e\u30b3\u30f3\u30c6\u30f3\u30c4\u306e\u5834\u5408\u3001\u53e5\u70b9\u30fb\u8aad\u70b9\u3092\u512a\u5148\u7684\u306a\u5206\u5272\u70b9\u3068\u3057\u3066\u8a2d\u5b9a\n)\n\n# Document\u3092\u5206\u5272\nchunks = splitter.split_documents(documents)\nprint(f\"\u5206\u5272\u5f8c\u306e\u30c1\u30e3\u30f3\u30af\u6570: {len(chunks)}\")\nfor i, chunk in enumerate(chunks[:3]):\n    print(f\"\\n--- \u30c1\u30e3\u30f3\u30af {i+1} ---\")\n    print(f\"\u6587\u5b57\u6570: {len(chunk.page_content)}\")\n    print(chunk.page_content[:200])<\/code><\/pre><\/div>\n\n\n<h3 class=\"wp-block-heading\">\u5206\u5272\u6226\u7565\u306e\u6bd4\u8f03<\/h3>\n\n\n<table>\n  <thead><tr><th>TextSplitter<\/th><th>\u5206\u5272\u65b9\u6cd5<\/th><th>\u5411\u3044\u3066\u3044\u308b\u30b1\u30fc\u30b9<\/th><\/tr><\/thead>\n  <tbody>\n    <tr><td><strong>RecursiveCharacterTextSplitter<\/strong><\/td><td>\u6bb5\u843d\u2192\u6539\u884c\u2192\u53e5\u70b9\u306e\u9806\u306b\u8a66\u307f\u3066\u5206\u5272<\/td><td>\u4e00\u822c\u7684\u306aWeb\u30da\u30fc\u30b8\u30fb\u30d6\u30ed\u30b0\u8a18\u4e8b\uff08\u63a8\u5968\uff09<\/td><\/tr>\n    <tr><td><strong>CharacterTextSplitter<\/strong><\/td><td>\u6307\u5b9a\u6587\u5b57\u3067\u5358\u7d14\u306b\u5206\u5272<\/td><td>\u533a\u5207\u308a\u6587\u5b57\u304c\u660e\u78ba\u306a\u30c6\u30ad\u30b9\u30c8<\/td><\/tr>\n    <tr><td><strong>TokenTextSplitter<\/strong><\/td><td>\u30c8\u30fc\u30af\u30f3\u6570\u3067\u5206\u5272<\/td><td>OpenAI\u306e\u30c8\u30fc\u30af\u30f3\u6570\u3092\u6b63\u78ba\u306b\u7ba1\u7406\u3057\u305f\u3044\u5834\u5408<\/td><\/tr>\n    <tr><td><strong>HTMLHeaderTextSplitter<\/strong><\/td><td>HTML\u306e\u898b\u51fa\u3057\u30bf\u30b0\u3067\u5206\u5272<\/td><td>\u69cb\u9020\u5316\u3055\u308c\u305fHTML\uff08\u898b\u51fa\u3057\u30d9\u30fc\u30b9\u306e\u5206\u5272\uff09<\/td><\/tr>\n    <tr><td><strong>MarkdownHeaderTextSplitter<\/strong><\/td><td>Markdown\u306e\u898b\u51fa\u3057\u3067\u5206\u5272<\/td><td>Markdown\u5f62\u5f0f\u306e\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8<\/td><\/tr>\n  <\/tbody>\n<\/table>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u7af6\u5408\u30b5\u30a4\u30c8\u81ea\u52d5\u5206\u6790\u30c4\u30fc\u30eb\u306e\u5b9f\u88c5\u30b3\u30fc\u30c9\u5168\u6587<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">analyzer.py\uff1a\u30b3\u30a2\u5206\u6790\u30ed\u30b8\u30c3\u30af<\/h3>\n\n\n<div class=\"hcb_wrap\"><pre class=\"prism line-numbers lang-python\" data-lang=\"Python\"><code># analyzer.py\n\nimport os\nimport time\nfrom dotenv import load_dotenv\nfrom langchain_community.document_loaders import WebBaseLoader\nfrom langchain_openai import ChatOpenAI\nfrom langchain.text_splitter import RecursiveCharacterTextSplitter\nfrom langchain.chains.summarize import load_summarize_chain\nfrom langchain.prompts import PromptTemplate\n\nload_dotenv()\n\nclass CompetitorAnalyzer:\n    \"\"\"\n    \u7af6\u5408\u30b5\u30a4\u30c8\u306e\u30b3\u30f3\u30c6\u30f3\u30c4\u3092\u81ea\u52d5\u53ce\u96c6\u30fb\u5206\u6790\u3059\u308b\u30af\u30e9\u30b9\n    \"\"\"\n\n    def __init__(self, model: str = \"gpt-4o-mini\"):\n        self.llm = ChatOpenAI(\n            model=model,\n            temperature=0.1,\n            openai_api_key=os.getenv(\"OPENAI_API_KEY\")\n        )\n        self.text_splitter = RecursiveCharacterTextSplitter(\n            chunk_size=2000,\n            chunk_overlap=200,\n            separators=[\"\\n\\n\", \"\\n\", \"\u3002\", \"\u3001\", \" \", \"\"]\n        )\n        self.request_delay = 2.0  # \u30ea\u30af\u30a8\u30b9\u30c8\u9593\u9694\uff08\u79d2\uff09\n\n    def load_competitor_content(self, url: str) -&gt; list:\n        \"\"\"URL\u304b\u3089\u7af6\u5408\u30b5\u30a4\u30c8\u306e\u30b3\u30f3\u30c6\u30f3\u30c4\u3092\u53d6\u5f97\u3059\u308b\"\"\"\n        try:\n            time.sleep(self.request_delay)  # \u30b5\u30fc\u30d0\u30fc\u8ca0\u8377\u8efd\u6e1b\u306e\u305f\u3081\u306e\u5f85\u6a5f\n            loader = WebBaseLoader(\n                web_paths=[url],\n                header_template={\n                    \"User-Agent\": \"Mozilla\/5.0 (compatible; CompetitorAnalyzer\/1.0)\"\n                }\n            )\n            documents = loader.load()\n            # \u9577\u3044\u30b3\u30f3\u30c6\u30f3\u30c4\u3092\u30c1\u30e3\u30f3\u30af\u5206\u5272\n            return self.text_splitter.split_documents(documents)\n        except Exception as e:\n            print(f\"\u26a0\ufe0f \u8aad\u307f\u8fbc\u307f\u30a8\u30e9\u30fc: {url} - {e}\")\n            return []\n\n    def summarize_content(self, url: str) -&gt; str:\n        \"\"\"\u7af6\u5408\u30b5\u30a4\u30c8\u306e\u30b3\u30f3\u30c6\u30f3\u30c4\u3092\u8981\u7d04\u3059\u308b\"\"\"\n        docs = self.load_competitor_content(url)\n        if not docs:\n            return \"\u30b3\u30f3\u30c6\u30f3\u30c4\u306e\u53d6\u5f97\u306b\u5931\u6557\u3057\u307e\u3057\u305f\"\n\n        # \u30de\u30c3\u30d7\u30ea\u30c7\u30e5\u30fc\u30b9\u65b9\u5f0f\u3067\u8981\u7d04\uff08\u9577\u6587\u3067\u3082\u5bfe\u5fdc\uff09\n        # map_reduce: \u5404\u30c1\u30e3\u30f3\u30af\u3092\u500b\u5225\u306b\u8981\u7d04\u3057\u3066\u304b\u3089\u6700\u7d42\u8981\u7d04\u3092\u751f\u6210\n        chain = load_summarize_chain(\n            self.llm,\n            chain_type=\"map_reduce\",\n            verbose=False\n        )\n        summary = chain.invoke({\"input_documents\": docs})\n        return summary[\"output_text\"]\n\n    def extract_keywords(self, url: str) -&gt; str:\n        \"\"\"\u7af6\u5408\u30b5\u30a4\u30c8\u306e\u4e3b\u8981\u30ad\u30fc\u30ef\u30fc\u30c9\u3092\u62bd\u51fa\u3059\u308b\"\"\"\n        docs = self.load_competitor_content(url)\n        if not docs:\n            return \"\u30ad\u30fc\u30ef\u30fc\u30c9\u306e\u53d6\u5f97\u306b\u5931\u6557\u3057\u307e\u3057\u305f\"\n\n        # \u6700\u521d\u306e\u6570\u30c1\u30e3\u30f3\u30af\u304b\u3089\u30ad\u30fc\u30ef\u30fc\u30c9\u3092\u62bd\u51fa\n        content = \"\\n\\n\".join([doc.page_content for doc in docs[:3]])\n\n        prompt = PromptTemplate(\n            input_variables=[\"content\"],\n            template=\"\"\"\n\u4ee5\u4e0b\u306eWeb\u30da\u30fc\u30b8\u306e\u30b3\u30f3\u30c6\u30f3\u30c4\u304b\u3089\u3001SEO\u30ad\u30fc\u30ef\u30fc\u30c9\u3068\u306a\u308a\u305d\u3046\u306a\u91cd\u8981\u8a9e\u53e5\u309220\u500b\u62bd\u51fa\u3057\u3066\u304f\u3060\u3055\u3044\u3002\n\u691c\u7d22\u610f\u56f3\u3092\u8003\u616e\u3057\u3001\u30d3\u30b8\u30cd\u30b9\u4fa1\u5024\u306e\u9ad8\u3044\u30ad\u30fc\u30ef\u30fc\u30c9\u3092\u512a\u5148\u3057\u3066\u304f\u3060\u3055\u3044\u3002\n\n\u30b3\u30f3\u30c6\u30f3\u30c4:\n{content}\n\n\u51fa\u529b\u5f62\u5f0f:\n- \u30ad\u30fc\u30ef\u30fc\u30c91\uff08\u691c\u7d22\u610f\u56f3: xxx\u3001\u6708\u9593\u691c\u7d22\u30dc\u30ea\u30e5\u30fc\u30e0\u60f3\u5b9a: xxx\uff09\n- \u30ad\u30fc\u30ef\u30fc\u30c92\uff08\u691c\u7d22\u610f\u56f3: xxx\u3001\u6708\u9593\u691c\u7d22\u30dc\u30ea\u30e5\u30fc\u30e0\u60f3\u5b9a: xxx\uff09\n...\n\"\"\"\n        )\n\n        response = self.llm.invoke(prompt.format(content=content[:3000]))\n        return response.content\n\n    def analyze_service_features(self, url: str) -&gt; str:\n        \"\"\"\u7af6\u5408\u30b5\u30a4\u30c8\u306e\u30b5\u30fc\u30d3\u30b9\u7279\u5fb4\u30fb\u5f37\u307f\u3092\u5206\u6790\u3059\u308b\"\"\"\n        docs = self.load_competitor_content(url)\n        if not docs:\n            return \"\u30b5\u30fc\u30d3\u30b9\u60c5\u5831\u306e\u53d6\u5f97\u306b\u5931\u6557\u3057\u307e\u3057\u305f\"\n\n        content = \"\\n\\n\".join([doc.page_content for doc in docs[:4]])\n\n        prompt = PromptTemplate(\n            input_variables=[\"content\", \"url\"],\n            template=\"\"\"\n\u4ee5\u4e0b\u306f {url} \u306eWeb\u30da\u30fc\u30b8\u30b3\u30f3\u30c6\u30f3\u30c4\u3067\u3059\u3002\n\u3053\u306e\u30b5\u30fc\u30d3\u30b9\u30fb\u4f01\u696d\u306e\u4ee5\u4e0b\u306e\u60c5\u5831\u3092\u5206\u6790\u3057\u3066\u65e5\u672c\u8a9e\u3067\u307e\u3068\u3081\u3066\u304f\u3060\u3055\u3044\uff1a\n\n1. \u4e3b\u8981\u30b5\u30fc\u30d3\u30b9\u30fb\u88fd\u54c1\n2. \u5f37\u307f\u3068\u30dd\u30b8\u30b7\u30e7\u30f3\n3. \u30bf\u30fc\u30b2\u30c3\u30c8\u9867\u5ba2\u5c64\n4. \u4fa1\u683c\u5e2f\u30fb\u6599\u91d1\u4f53\u7cfb\uff08\u8a18\u8f09\u304c\u3042\u308b\u5834\u5408\uff09\n5. \u5dee\u5225\u5316\u30dd\u30a4\u30f3\u30c8\n6. \u30b3\u30f3\u30c6\u30f3\u30c4\u30fb\u60c5\u5831\u767a\u4fe1\u306e\u50be\u5411\n7. \u5f31\u307f\u3068\u6539\u5584\u4f59\u5730\uff08\u63a8\u6e2c\u3092\u542b\u3080\uff09\n\n\u30b3\u30f3\u30c6\u30f3\u30c4:\n{content}\n\"\"\"\n        )\n\n        response = self.llm.invoke(\n            prompt.format(content=content[:4000], url=url)\n        )\n        return response.content\n\n    def analyze_content_strategy(self, url: str) -&gt; str:\n        \"\"\"\u7af6\u5408\u306e\u30b3\u30f3\u30c6\u30f3\u30c4\u6226\u7565\u3092\u5206\u6790\u3059\u308b\"\"\"\n        docs = self.load_competitor_content(url)\n        if not docs:\n            return \"\u30b3\u30f3\u30c6\u30f3\u30c4\u6226\u7565\u306e\u5206\u6790\u306b\u5931\u6557\u3057\u307e\u3057\u305f\"\n\n        content = \"\\n\\n\".join([doc.page_content for doc in docs[:5]])\n\n        prompt = f\"\"\"\n\u4ee5\u4e0b\u306eWeb\u30da\u30fc\u30b8\u306e\u30b3\u30f3\u30c6\u30f3\u30c4\u304b\u3089\u3001\u3053\u306e\u30b5\u30a4\u30c8\u306e\u30b3\u30f3\u30c6\u30f3\u30c4\u30de\u30fc\u30b1\u30c6\u30a3\u30f3\u30b0\u6226\u7565\u3092\u5206\u6790\u3057\u3066\u304f\u3060\u3055\u3044\u3002\n\n\u5206\u6790\u89b3\u70b9:\n1. \u30e1\u30a4\u30f3\u306e\u30bf\u30fc\u30b2\u30c3\u30c8\u30ad\u30fc\u30ef\u30fc\u30c9\u30fb\u30c8\u30d4\u30c3\u30af\n2. \u30b3\u30f3\u30c6\u30f3\u30c4\u306e\u66f4\u65b0\u983b\u5ea6\uff08\u63a8\u6e2c\uff09\n3. \u30b3\u30f3\u30c6\u30f3\u30c4\u306e\u6df1\u3055\u3068\u54c1\u8cea\n4. CTA\uff08Call to Action\uff09\u306e\u8a2d\u7f6e\u5834\u6240\u3068\u8a34\u6c42\u5185\u5bb9\n5. SEO\u5bfe\u7b56\u306e\u72b6\u6cc1\uff08\u898b\u51fa\u3057\u69cb\u9020\u30fb\u5185\u90e8\u30ea\u30f3\u30af\u306a\u3069\uff09\n6. \u30e6\u30fc\u30b6\u30fc\u30a8\u30f3\u30b2\u30fc\u30b8\u30e1\u30f3\u30c8\u3092\u9ad8\u3081\u308b\u5de5\u592b\n\n\u30b3\u30f3\u30c6\u30f3\u30c4:\n{content[:5000]}\n\"\"\"\n        response = self.llm.invoke(prompt)\n        return response.content\n\n    def compare_competitors(self, urls: list[str]) -&gt; str:\n        \"\"\"\u8907\u6570\u306e\u7af6\u5408\u30b5\u30a4\u30c8\u3092\u6bd4\u8f03\u5206\u6790\u3059\u308b\"\"\"\n        analyses = {}\n        for url in urls:\n            print(f\"  \u2192 \u5206\u6790\u4e2d: {url}\")\n            analyses[url] = self.analyze_service_features(url)\n\n        # \u6bd4\u8f03\u30d7\u30ed\u30f3\u30d7\u30c8\n        comparisons = \"\\n\\n\".join([\n            f\"\u3010{url}\u3011\\n{analysis}\"\n            for url, analysis in analyses.items()\n        ])\n\n        compare_prompt = f\"\"\"\n\u4ee5\u4e0b\u306e\u8907\u6570\u306e\u7af6\u5408\u30b5\u30fc\u30d3\u30b9\u306e\u5206\u6790\u7d50\u679c\u3092\u3082\u3068\u306b\u3001\u8a73\u7d30\u306a\u6bd4\u8f03\u30ec\u30dd\u30fc\u30c8\u3092\u4f5c\u6210\u3057\u3066\u304f\u3060\u3055\u3044\u3002\n\n{comparisons}\n\n\u6bd4\u8f03\u30ec\u30dd\u30fc\u30c8\u306e\u5f62\u5f0f\uff1a\n## \u6bd4\u8f03\u30b5\u30de\u30ea\u30fc\n\uff08\u5168\u4f53\u306e\u50be\u5411\u30fb\u5171\u901a\u70b9\u30fb\u5dee\u7570\u306e\u6982\u8981\uff09\n\n## \u5404\u793e\u306e\u5f37\u307f\u30fb\u5f31\u307f\n\uff08\u5404\u30b5\u30fc\u30d3\u30b9\u306e\u5f37\u307f\u3068\u5f31\u307f\u3092\u7b87\u6761\u66f8\u304d\u3067\uff09\n\n## \u5e02\u5834\u306e\u30dd\u30b8\u30b7\u30e7\u30cb\u30f3\u30b0\u30de\u30c3\u30d7\n\uff08\u4fa1\u683c\u5e2f\u00d7\u30b5\u30fc\u30d3\u30b9\u7bc4\u56f2\u306e\u89b3\u70b9\u3067\u6574\u7406\uff09\n\n## \u30b3\u30f3\u30c6\u30f3\u30c4\u6226\u7565\u306e\u6bd4\u8f03\n\uff08\u5404\u793e\u304c\u3069\u306e\u3088\u3046\u306a\u30c8\u30d4\u30c3\u30af\u30fb\u30ad\u30fc\u30ef\u30fc\u30c9\u3067\u60c5\u5831\u767a\u4fe1\u3057\u3066\u3044\u308b\u304b\uff09\n\n## \u7af6\u5408\u306b\u5bfe\u3059\u308b\u5dee\u5225\u5316\u6226\u7565\u306e\u793a\u5506\n\uff08\u81ea\u793e\u304c\u5dee\u5225\u5316\u3067\u304d\u308b\u4f59\u5730\u30fb\u30d6\u30eb\u30fc\u30aa\u30fc\u30b7\u30e3\u30f3\u3068\u306a\u308a\u3046\u308b\u9818\u57df\uff09\n\n## \u77ed\u671f\u30fb\u4e2d\u9577\u671f\u306e\u6226\u7565\u63d0\u6848\n\uff083\u30f6\u6708\u30fb1\u5e74\u3067\u5b9f\u65bd\u3059\u3079\u304d\u5177\u4f53\u7684\u306a\u30a2\u30af\u30b7\u30e7\u30f3\uff09\n\"\"\"\n        response = self.llm.invoke(compare_prompt)\n        return response.content<\/code><\/pre><\/div>\n\n\n<h3 class=\"wp-block-heading\">main.py\uff1a\u5b9f\u884c\u30b9\u30af\u30ea\u30d7\u30c8<\/h3>\n\n\n<div class=\"hcb_wrap\"><pre class=\"prism line-numbers lang-python\" data-lang=\"Python\"><code># main.py\n\nimport datetime\nimport os\nfrom analyzer import CompetitorAnalyzer\n\ndef main():\n    # \u5206\u6790\u5bfe\u8c61\u306e\u7af6\u5408\u30b5\u30a4\u30c8URL\u30ea\u30b9\u30c8\n    competitor_urls = [\n        \"https:\/\/competitor-a.com\/services\/\",\n        \"https:\/\/competitor-b.com\/pricing\/\",\n        \"https:\/\/competitor-c.com\/about\/\",\n    ]\n\n    print(\"=\" * 60)\n    print(\"\ud83d\udd0d \u7af6\u5408\u30b5\u30a4\u30c8\u81ea\u52d5\u5206\u6790\u30c4\u30fc\u30eb\")\n    print(f\"\u5b9f\u884c\u65e5\u6642: {datetime.datetime.now().strftime('%Y-%m-%d %H:%M')}\")\n    print(\"=\" * 60)\n\n    analyzer = CompetitorAnalyzer(model=\"gpt-4o-mini\")\n\n    # 1. \u5404\u7af6\u5408\u30b5\u30a4\u30c8\u306e\u8981\u7d04\n    print(\"\\n\ud83d\udcdd 1. \u30b3\u30f3\u30c6\u30f3\u30c4\u8981\u7d04\")\n    summaries = {}\n    for url in competitor_urls:\n        print(f\"  \u2192 \u8981\u7d04\u4e2d: {url}\")\n        summaries[url] = analyzer.summarize_content(url)\n\n    # 2. \u30ad\u30fc\u30ef\u30fc\u30c9\u62bd\u51fa\n    print(\"\\n\ud83d\udd11 2. SEO\u30ad\u30fc\u30ef\u30fc\u30c9\u62bd\u51fa\")\n    keywords = {}\n    for url in competitor_urls:\n        print(f\"  \u2192 \u30ad\u30fc\u30ef\u30fc\u30c9\u62bd\u51fa\u4e2d: {url}\")\n        keywords[url] = analyzer.extract_keywords(url)\n\n    # 3. \u30b3\u30f3\u30c6\u30f3\u30c4\u6226\u7565\u5206\u6790\n    print(\"\\n\ud83d\udcc8 3. \u30b3\u30f3\u30c6\u30f3\u30c4\u6226\u7565\u5206\u6790\")\n    content_strategies = {}\n    for url in competitor_urls:\n        print(f\"  \u2192 \u30b3\u30f3\u30c6\u30f3\u30c4\u6226\u7565\u5206\u6790\u4e2d: {url}\")\n        content_strategies[url] = analyzer.analyze_content_strategy(url)\n\n    # 4. \u7af6\u5408\u6bd4\u8f03\u30ec\u30dd\u30fc\u30c8\n    print(\"\\n\ud83d\udcca 4. \u7af6\u5408\u6bd4\u8f03\u30ec\u30dd\u30fc\u30c8\u751f\u6210\")\n    comparison_report = analyzer.compare_competitors(competitor_urls)\n\n    # 5. \u30ec\u30dd\u30fc\u30c8\u3092\u30d5\u30a1\u30a4\u30eb\u306b\u4fdd\u5b58\n    os.makedirs(\"reports\", exist_ok=True)\n    report_path = f\"reports\/competitor_analysis_{datetime.datetime.now().strftime('%Y%m%d_%H%M')}.md\"\n\n    with open(report_path, \"w\", encoding=\"utf-8\") as f:\n        f.write(f\"# \u7af6\u5408\u30b5\u30a4\u30c8\u5206\u6790\u30ec\u30dd\u30fc\u30c8\\n\\n\")\n        f.write(f\"\u5b9f\u884c\u65e5\u6642: {datetime.datetime.now().strftime('%Y\u5e74%m\u6708%d\u65e5 %H:%M')}\\n\\n\")\n\n        f.write(\"## \u5404\u30b5\u30a4\u30c8\u8981\u7d04\\n\\n\")\n        for url, summary in summaries.items():\n            f.write(f\"### {url}\\n{summary}\\n\\n\")\n\n        f.write(\"## SEO\u30ad\u30fc\u30ef\u30fc\u30c9\u5206\u6790\\n\\n\")\n        for url, kw in keywords.items():\n            f.write(f\"### {url}\\n{kw}\\n\\n\")\n\n        f.write(\"## \u30b3\u30f3\u30c6\u30f3\u30c4\u6226\u7565\u5206\u6790\\n\\n\")\n        for url, strategy in content_strategies.items():\n            f.write(f\"### {url}\\n{strategy}\\n\\n\")\n\n        f.write(\"## \u7af6\u5408\u6bd4\u8f03\u30ec\u30dd\u30fc\u30c8\\n\\n\")\n        f.write(comparison_report)\n\n    print(f\"\\n\u2705 \u30ec\u30dd\u30fc\u30c8\u3092\u4fdd\u5b58\u3057\u307e\u3057\u305f: {report_path}\")\n\nif __name__ == \"__main__\":\n    main()<\/code><\/pre><\/div>\n\n\n<h3 class=\"wp-block-heading\">\u5b9f\u884c\u65b9\u6cd5<\/h3>\n\n\n<div class=\"hcb_wrap\"><pre class=\"prism line-numbers lang-bash\" data-lang=\"Bash\"><code># \u5b9f\u884c\npython main.py\n\n# \u51fa\u529b\u4f8b\n# ============================================================\n# \ud83d\udd0d \u7af6\u5408\u30b5\u30a4\u30c8\u81ea\u52d5\u5206\u6790\u30c4\u30fc\u30eb\n# \u5b9f\u884c\u65e5\u6642: 2026-03-14 18:14\n# ============================================================\n# \ud83d\udcdd 1. \u30b3\u30f3\u30c6\u30f3\u30c4\u8981\u7d04\n#   \u2192 \u8981\u7d04\u4e2d: https:\/\/competitor-a.com\/services\/\n# ...\n# \u2705 \u30ec\u30dd\u30fc\u30c8\u3092\u4fdd\u5b58\u3057\u307e\u3057\u305f: reports\/competitor_analysis_20260314_1820.md<\/code><\/pre><\/div>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Embeddings\u3092\u4f7f\u3063\u305f\u30b3\u30f3\u30c6\u30f3\u30c4\u985e\u4f3c\u5ea6\u5206\u6790<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u30c6\u30ad\u30b9\u30c8\u306e\u8981\u7d04\u3084\u6bd4\u8f03\u3060\u3051\u3067\u306a\u304f\u3001<strong>Embeddings\u3092\u4f7f\u3046\u3053\u3068\u3067\u30b3\u30f3\u30c6\u30f3\u30c4\u306e\u300c\u610f\u5473\u7684\u306a\u985e\u4f3c\u5ea6\u300d\u3092\u6570\u5024\u3068\u3057\u3066\u8a08\u7b97<\/strong>\u3067\u304d\u307e\u3059\u3002\u300c\u81ea\u793e\u30b3\u30f3\u30c6\u30f3\u30c4\u3068\u7af6\u5408\u30b3\u30f3\u30c6\u30f3\u30c4\u306e\u91cd\u8907\u5ea6\u3092\u8abf\u3079\u308b\u300d\u300c\u7af6\u5408\u304c\u6271\u3063\u3066\u3044\u306a\u3044\u30c8\u30d4\u30c3\u30af\u3092\u767a\u898b\u3059\u308b\u300d\u3068\u3044\u3063\u305f\u5fdc\u7528\u304c\u53ef\u80fd\u3067\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Embeddings\u3068\u306f<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Embeddings\u306f\u30c6\u30ad\u30b9\u30c8\u3092N\u6b21\u5143\u306e\u6d6e\u52d5\u5c0f\u6570\u70b9\u30d9\u30af\u30c8\u30eb\u306b\u5909\u63db\u3059\u308b\u6280\u8853\u3067\u3059\u3002\u610f\u5473\u304c\u4f3c\u3066\u3044\u308b\u30c6\u30ad\u30b9\u30c8\u306f\u8fd1\u3044\u30d9\u30af\u30c8\u30eb\u306b\u306a\u308b\u305f\u3081\u3001\u30d9\u30af\u30c8\u30eb\u540c\u58eb\u306e\u30b3\u30b5\u30a4\u30f3\u985e\u4f3c\u5ea6\u3092\u8a08\u7b97\u3059\u308b\u3053\u3068\u3067\u300c\u30c6\u30ad\u30b9\u30c8\u306e\u985e\u4f3c\u6027\u300d\u3092\u6570\u5024\u5316\u3067\u304d\u307e\u3059\u3002\u4f8b\u3048\u3070\u300cPython\u3067\u30b9\u30af\u30ec\u30a4\u30d4\u30f3\u30b0\u3059\u308b\u65b9\u6cd5\u300d\u3068\u300cPython\u3092\u4f7f\u3063\u305fWeb\u30c7\u30fc\u30bf\u53ce\u96c6\u300d\u306f\u610f\u5473\u304c\u8fd1\u3044\u305f\u3081\u3001\u9ad8\u3044\u985e\u4f3c\u5ea6\u30b9\u30b3\u30a2\u306b\u306a\u308a\u307e\u3059\u3002<\/p>\n\n\n<div class=\"hcb_wrap\"><pre class=\"prism line-numbers lang-python\" data-lang=\"Python\"><code># embeddings_search.py\n\nimport numpy as np\nfrom langchain_openai import OpenAIEmbeddings\nfrom langchain_community.vectorstores import FAISS\nfrom langchain_community.document_loaders import WebBaseLoader\nfrom langchain.text_splitter import RecursiveCharacterTextSplitter\n\nclass ContentSimilarityAnalyzer:\n    \"\"\"\n    Embeddings\u3092\u4f7f\u3063\u305f\u30b3\u30f3\u30c6\u30f3\u30c4\u985e\u4f3c\u5ea6\u5206\u6790\u30af\u30e9\u30b9\n    \"\"\"\n\n    def __init__(self):\n        self.embeddings = OpenAIEmbeddings(model=\"text-embedding-3-small\")\n        self.splitter = RecursiveCharacterTextSplitter(\n            chunk_size=500, chunk_overlap=50\n        )\n\n    def build_vectorstore(self, urls: list[str]) -&gt; FAISS:\n        \"\"\"\u8907\u6570URL\u306e\u30b3\u30f3\u30c6\u30f3\u30c4\u304b\u3089VectorStore\u3092\u69cb\u7bc9\"\"\"\n        all_docs = []\n        for url in urls:\n            loader = WebBaseLoader(url)\n            docs = loader.load()\n            chunks = self.splitter.split_documents(docs)\n            all_docs.extend(chunks)\n\n        print(f\"\u2705 {len(all_docs)} \u30c1\u30e3\u30f3\u30af\u3092VectorStore\u306b\u683c\u7d0d\")\n        return FAISS.from_documents(all_docs, self.embeddings)\n\n    def find_gaps(\n        self,\n        my_url: str,\n        competitor_urls: list[str],\n        top_k: int = 5\n    ) -&gt; str:\n        \"\"\"\n        \u81ea\u793e\u30b3\u30f3\u30c6\u30f3\u30c4\u306b\u306a\u3044\u304c\u7af6\u5408\u306b\u3042\u308b\u30c8\u30d4\u30c3\u30af\u3092\u767a\u898b\u3059\u308b\n        \"\"\"\n        # \u7af6\u5408\u306eVectorStore\u3092\u69cb\u7bc9\n        competitor_store = self.build_vectorstore(competitor_urls)\n\n        # \u81ea\u793e\u30b3\u30f3\u30c6\u30f3\u30c4\u3092\u8aad\u307f\u8fbc\u307f\n        my_loader = WebBaseLoader(my_url)\n        my_docs = my_loader.load()\n        my_chunks = self.splitter.split_documents(my_docs)\n\n        gaps = []\n        for chunk in my_chunks[:20]:  # \u6700\u521d\u306e20\u30c1\u30e3\u30f3\u30af\u3092\u30af\u30a8\u30ea\u3068\u3057\u3066\u4f7f\u7528\n            # \u7af6\u5408\u306eVectorStore\u3067\u985e\u4f3c\u30c1\u30e3\u30f3\u30af\u3092\u691c\u7d22\n            similar = competitor_store.similarity_search_with_score(\n                chunk.page_content, k=top_k\n            )\n\n            for doc, score in similar:\n                # \u30b9\u30b3\u30a2\u304c\u4f4e\u3044\uff08\u985e\u4f3c\u5ea6\u304c\u4f4e\u3044\uff09\uff1d\u81ea\u793e\u306b\u306a\u3044\u30b3\u30f3\u30c6\u30f3\u30c4\n                if score &gt; 0.5:  # FAISS\u306eL2\u8ddd\u96e2\u3001\u5024\u304c\u5927\u304d\u3044\u307b\u3069\u975e\u985e\u4f3c\n                    gaps.append({\n                        \"competitor_content\": doc.page_content[:200],\n                        \"source\": doc.metadata.get(\"source\", \"\"),\n                        \"similarity_gap\": score\n                    })\n\n        # \u30ae\u30e3\u30c3\u30d7\u304c\u5927\u304d\u3044\u3082\u306e\u3092\u30bd\u30fc\u30c8\n        gaps.sort(key=lambda x: x[\"similarity_gap\"], reverse=True)\n\n        result = \"## \u30b3\u30f3\u30c6\u30f3\u30c4\u30ae\u30e3\u30c3\u30d7\u5206\u6790\u7d50\u679c\\n\\n\"\n        result += \"\u81ea\u793e\u306b\u306a\u3044\u304c\u7af6\u5408\u306b\u3042\u308b\u30c8\u30d4\u30c3\u30af\uff08\u985e\u4f3c\u5ea6\u304c\u4f4e\u3044\u3082\u306e\u4e0a\u4f4d\uff09:\\n\\n\"\n        for i, gap in enumerate(gaps[:10], 1):\n            result += f\"{i}. [{gap['source']}]\\n\"\n            result += f\"   {gap['competitor_content']}\\n\\n\"\n\n        return result\n\n    def calculate_content_overlap(\n        self, url_a: str, url_b: str\n    ) -&gt; float:\n        \"\"\"\n        2\u3064\u306e\u30b5\u30a4\u30c8\u306e\u30b3\u30f3\u30c6\u30f3\u30c4\u91cd\u8907\u7387\u3092\u8a08\u7b97\u3059\u308b\uff080.0\u301c1.0\uff09\n        \"\"\"\n        loader_a = WebBaseLoader(url_a)\n        loader_b = WebBaseLoader(url_b)\n\n        docs_a = self.splitter.split_documents(loader_a.load())\n        docs_b = self.splitter.split_documents(loader_b.load())\n\n        # \u5404\u30c6\u30ad\u30b9\u30c8\u306eEmbeddings\u3092\u53d6\u5f97\n        texts_a = [doc.page_content for doc in docs_a[:10]]\n        texts_b = [doc.page_content for doc in docs_b[:10]]\n\n        vectors_a = self.embeddings.embed_documents(texts_a)\n        vectors_b = self.embeddings.embed_documents(texts_b)\n\n        # \u30b3\u30b5\u30a4\u30f3\u985e\u4f3c\u5ea6\u306e\u5e73\u5747\u3092\u8a08\u7b97\n        similarities = []\n        for va in vectors_a:\n            for vb in vectors_b:\n                va_np = np.array(va)\n                vb_np = np.array(vb)\n                cos_sim = np.dot(va_np, vb_np) \/ (\n                    np.linalg.norm(va_np) * np.linalg.norm(vb_np)\n                )\n                similarities.append(cos_sim)\n\n        return float(np.mean(similarities))<\/code><\/pre><\/div>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u5fdc\u7528\uff1a\u5b9a\u671f\u5b9f\u884c\u306e\u81ea\u52d5\u5316\u3068Slack\u901a\u77e5<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Slack\u901a\u77e5\u306e\u5b9f\u88c5<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">\u5206\u6790\u30ec\u30dd\u30fc\u30c8\u304c\u751f\u6210\u3055\u308c\u305f\u3068\u304d\u306bSlack\u306e\u30c1\u30e3\u30f3\u30cd\u30eb\u306b\u901a\u77e5\u3092\u9001\u308b\u3053\u3068\u3067\u3001\u30c1\u30fc\u30e0\u5168\u4f53\u3067\u7af6\u5408\u60c5\u5831\u3092\u7d20\u65e9\u304f\u5171\u6709\u3067\u304d\u307e\u3059\u3002Slack API\u306eIncoming Webhook\u3092\u4f7f\u3044\u307e\u3059\u3002<\/p>\n\n\n<div class=\"hcb_wrap\"><pre class=\"prism line-numbers lang-python\" data-lang=\"Python\"><code># notifier.py\n\nimport os\nimport requests\nfrom dotenv import load_dotenv\n\nload_dotenv()\n\ndef send_slack_notification(report_summary: str, report_path: str) -&gt; bool:\n    \"\"\"\n    \u7af6\u5408\u5206\u6790\u30ec\u30dd\u30fc\u30c8\u3092Slack\u306b\u901a\u77e5\u3059\u308b\n\n    \u4e8b\u524d\u6e96\u5099:\n    1. Slack API\u306e\u300cIncoming Webhooks\u300d\u3067Webhook URL\u3092\u53d6\u5f97\n    2. .env\u306b SLACK_WEBHOOK_URL=https:\/\/hooks.slack.com\/services\/xxx \u3092\u8a2d\u5b9a\n    \"\"\"\n    webhook_url = os.getenv(\"SLACK_WEBHOOK_URL\")\n    if not webhook_url:\n        print(\"\u26a0\ufe0f SLACK_WEBHOOK_URL \u304c\u8a2d\u5b9a\u3055\u308c\u3066\u3044\u307e\u305b\u3093\")\n        return False\n\n    payload = {\n        \"blocks\": [\n            {\n                \"type\": \"header\",\n                \"text\": {\n                    \"type\": \"plain_text\",\n                    \"text\": \"\ud83d\udd0d \u7af6\u5408\u30b5\u30a4\u30c8\u81ea\u52d5\u5206\u6790\u30ec\u30dd\u30fc\u30c8\",\n                    \"emoji\": True\n                }\n            },\n            {\n                \"type\": \"section\",\n                \"text\": {\n                    \"type\": \"mrkdwn\",\n                    \"text\": f\"*\u30ec\u30dd\u30fc\u30c8\u30d5\u30a1\u30a4\u30eb:* `{report_path}`\"\n                }\n            },\n            {\n                \"type\": \"divider\"\n            },\n            {\n                \"type\": \"section\",\n                \"text\": {\n                    \"type\": \"mrkdwn\",\n                    \"text\": f\"*\u5206\u6790\u30b5\u30de\u30ea\u30fc:*\\n{report_summary[:500]}...\"\n                }\n            }\n        ]\n    }\n\n    response = requests.post(webhook_url, json=payload)\n    if response.status_code == 200:\n        print(\"\u2705 Slack\u901a\u77e5\u3092\u9001\u4fe1\u3057\u307e\u3057\u305f\")\n        return True\n    else:\n        print(f\"\u274c Slack\u901a\u77e5\u306e\u9001\u4fe1\u306b\u5931\u6557: {response.status_code}\")\n        return False<\/code><\/pre><\/div>\n\n\n<h3 class=\"wp-block-heading\">schedule\u30e9\u30a4\u30d6\u30e9\u30ea\u306b\u3088\u308b\u5b9a\u671f\u5b9f\u884c<\/h3>\n\n\n<div class=\"hcb_wrap\"><pre class=\"prism line-numbers lang-python\" data-lang=\"Python\"><code># schedule_analyzer.py - cron\u3084GitHub Actions\u3067\u5b9a\u671f\u5b9f\u884c\u3059\u308b\u4f8b\n\nimport schedule\nimport time\nfrom main import main\n\n# \u6bce\u9031\u6708\u66dc\u65e5\u306e\u671d9\u6642\u306b\u81ea\u52d5\u5b9f\u884c\nschedule.every().monday.at(\"09:00\").do(main)\n\nprint(\"\u23f0 \u7af6\u5408\u5206\u6790\u30b9\u30b1\u30b8\u30e5\u30fc\u30e9\u3092\u8d77\u52d5\u3057\u307e\u3057\u305f\uff08Ctrl+C\u3067\u505c\u6b62\uff09\")\nwhile True:\n    schedule.run_pending()\n    time.sleep(60)<\/code><\/pre><\/div>\n\n\n<h3 class=\"wp-block-heading\">GitHub Actions\u306b\u3088\u308b\u30af\u30e9\u30a6\u30c9\u5b9a\u671f\u5b9f\u884c<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">\u5e38\u6642\u8d77\u52d5\u306e\u30b5\u30fc\u30d0\u30fc\u304c\u306a\u3044\u5834\u5408\u306f\u3001GitHub Actions\u306e<code>schedule<\/code>\u30c8\u30ea\u30ac\u30fc\u3092\u4f7f\u3063\u3066\u7121\u6599\u3067\u30af\u30e9\u30a6\u30c9\u5b9f\u884c\u3067\u304d\u307e\u3059\u3002\u6bce\u9031\u6708\u66dc\u65e5\u306e\u671d9\u6642\uff08JST\uff09\u306b\u81ea\u52d5\u5b9f\u884c\u3057\u3001\u30ec\u30dd\u30fc\u30c8\u3092\u30a2\u30fc\u30c6\u30a3\u30d5\u30a1\u30af\u30c8\u3068\u3057\u3066\u4fdd\u5b58\u3057\u307e\u3059\u3002<\/p>\n\n\n<div class=\"hcb_wrap\"><pre class=\"prism line-numbers lang-yaml\" data-lang=\"YAML\"><code># .github\/workflows\/competitor-analysis.yml\n\nname: \u7af6\u5408\u30b5\u30a4\u30c8\u81ea\u52d5\u5206\u6790\non:\n  schedule:\n    - cron: '0 0 * * 1'  # \u6bce\u9031\u6708\u66dc\u65e5 09:00 JST\uff08UTC 0:00\uff09\n  workflow_dispatch:      # \u624b\u52d5\u5b9f\u884c\u3082\u53ef\u80fd\n\njobs:\n  analyze:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions\/checkout@v4\n      - uses: actions\/setup-python@v4\n        with:\n          python-version: '3.12'\n      - run: pip install -r requirements.txt\n      - run: python main.py\n        env:\n          OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}\n          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}\n      - uses: actions\/upload-artifact@v4\n        with:\n          name: competitor-report\n          path: reports\/\n          retention-days: 30  # 30\u65e5\u9593\u4fdd\u5b58<\/code><\/pre><\/div>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u30a8\u30e9\u30fc\u30cf\u30f3\u30c9\u30ea\u30f3\u30b0\u3068\u30ec\u30fc\u30c8\u5236\u9650\u5bfe\u7b56<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u7af6\u5408\u30b5\u30a4\u30c8\u306e\u30b9\u30af\u30ec\u30a4\u30d4\u30f3\u30b0\u3067\u306f\u3001\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u30a8\u30e9\u30fc\u30fbHTTP\u30a8\u30e9\u30fc\u30fb\u30b5\u30a4\u30c8\u69cb\u9020\u306e\u5909\u5316\u30fbOpenAI API\u306e\u30ec\u30fc\u30c8\u5236\u9650\u306a\u3069\u3001\u3055\u307e\u3056\u307e\u306a\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3059\u3002\u30d7\u30ed\u30c0\u30af\u30b7\u30e7\u30f3\u30ec\u30d9\u30eb\u306e\u5b9f\u88c5\u3067\u306f\u9069\u5207\u306a\u30a8\u30e9\u30fc\u30cf\u30f3\u30c9\u30ea\u30f3\u30b0\u304c\u4e0d\u53ef\u6b20\u3067\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u5805\u7262\u306a\u30ed\u30fc\u30c0\u30fc\u5b9f\u88c5<\/h3>\n\n\n<div class=\"hcb_wrap\"><pre class=\"prism line-numbers lang-python\" data-lang=\"Python\"><code># robust_loader.py\n\nimport time\nimport logging\nfrom typing import Optional\nfrom langchain_community.document_loaders import WebBaseLoader\n\nlogging.basicConfig(level=logging.INFO)\nlogger = logging.getLogger(__name__)\n\ndef load_with_retry(\n    url: str,\n    max_retries: int = 3,\n    delay: float = 2.0\n) -&gt; Optional[list]:\n    \"\"\"\n    \u30ea\u30c8\u30e9\u30a4\u6a5f\u80fd\u4ed8\u304d\u306eWebBaseLoader\n\n    Args:\n        url: \u30b9\u30af\u30ec\u30a4\u30d4\u30f3\u30b0\u5bfe\u8c61\u306eURL\n        max_retries: \u6700\u5927\u30ea\u30c8\u30e9\u30a4\u56de\u6570\n        delay: \u30ea\u30c8\u30e9\u30a4\u9593\u306e\u5f85\u6a5f\u6642\u9593\uff08\u79d2\uff09\n    \"\"\"\n    for attempt in range(max_retries + 1):\n        try:\n            time.sleep(delay)  # \u30ea\u30af\u30a8\u30b9\u30c8\u9593\u9694\n            loader = WebBaseLoader(url)\n            documents = loader.load()\n\n            if not documents or not documents[0].page_content.strip():\n                raise ValueError(f\"\u30b3\u30f3\u30c6\u30f3\u30c4\u304c\u7a7a\u3067\u3057\u305f: {url}\")\n\n            logger.info(f\"\u2705 \u53d6\u5f97\u6210\u529f: {url} ({len(documents[0].page_content)}\u6587\u5b57)\")\n            return documents\n\n        except Exception as e:\n            if attempt == max_retries:\n                logger.error(f\"\u274c \u6700\u5927\u30ea\u30c8\u30e9\u30a4\u56de\u6570\u306b\u9054\u3057\u307e\u3057\u305f: {url} - {e}\")\n                return None\n\n            wait_time = delay * (2 ** attempt)  # \u6307\u6570\u30d0\u30c3\u30af\u30aa\u30d5\n            logger.warning(\n                f\"\u26a0\ufe0f \u53d6\u5f97\u5931\u6557 (\u8a66\u884c {attempt + 1}\/{max_retries}): {e} \"\n                f\"\u2192 {wait_time}\u79d2\u5f8c\u306b\u30ea\u30c8\u30e9\u30a4\"\n            )\n            time.sleep(wait_time)\n\n    return None<\/code><\/pre><\/div>\n\n\n<h3 class=\"wp-block-heading\">OpenAI API\u306e\u30ec\u30fc\u30c8\u5236\u9650\u5bfe\u7b56<\/h3>\n\n\n<div class=\"hcb_wrap\"><pre class=\"prism line-numbers lang-python\" data-lang=\"Python\"><code># rate_limit_handler.py\n\nimport time\nimport openai\nfrom langchain_openai import ChatOpenAI\n\ndef create_llm_with_retry() -&gt; ChatOpenAI:\n    \"\"\"\n    \u30ec\u30fc\u30c8\u5236\u9650\u3092\u8003\u616e\u3057\u305fLLM\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u3092\u751f\u6210\u3059\u308b\n\n    OpenAI API\u306e\u30ec\u30fc\u30c8\u5236\u9650\uff082026\u5e743\u6708\u6642\u70b9\uff09:\n    - GPT-4o mini: 500 RPM\uff08\u30ea\u30af\u30a8\u30b9\u30c8\/\u5206\uff09\u3001150,000 TPM\uff08\u30c8\u30fc\u30af\u30f3\/\u5206\uff09\n    - GPT-4o:      500 RPM\u300130,000 TPM\uff08Tier 1\u306e\u5834\u5408\uff09\n    \"\"\"\n    return ChatOpenAI(\n        model=\"gpt-4o-mini\",\n        temperature=0.1,\n        max_retries=5,           # LangChain\u7d44\u307f\u8fbc\u307f\u306e\u30ea\u30c8\u30e9\u30a4\n        request_timeout=60,      # \u30bf\u30a4\u30e0\u30a2\u30a6\u30c8\u8a2d\u5b9a\n    )\n\ndef safe_llm_invoke(llm: ChatOpenAI, prompt: str, max_retries: int = 3) -&gt; str:\n    \"\"\"\n    \u30ec\u30fc\u30c8\u5236\u9650\u30a8\u30e9\u30fc\u3092\u51e6\u7406\u3057\u306a\u304c\u3089LLM\u3092\u547c\u3073\u51fa\u3059\n    \"\"\"\n    for attempt in range(max_retries):\n        try:\n            response = llm.invoke(prompt)\n            return response.content\n        except openai.RateLimitError as e:\n            if attempt == max_retries - 1:\n                raise\n            # \u30ec\u30fc\u30c8\u5236\u9650\u30a8\u30e9\u30fc\u306e\u5834\u5408\u306f60\u79d2\u5f85\u6a5f\n            wait_time = 60 * (attempt + 1)\n            print(f\"\u23f3 \u30ec\u30fc\u30c8\u5236\u9650\u306b\u9054\u3057\u307e\u3057\u305f\u3002{wait_time}\u79d2\u5f85\u6a5f\u3057\u307e\u3059...\")\n            time.sleep(wait_time)\n        except openai.APIConnectionError as e:\n            if attempt == max_retries - 1:\n                raise\n            print(f\"\ud83d\udd0c \u63a5\u7d9a\u30a8\u30e9\u30fc: {e}. 10\u79d2\u5f8c\u306b\u30ea\u30c8\u30e9\u30a4...\")\n            time.sleep(10)\n    return \"\"<\/code><\/pre><\/div>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u30b3\u30b9\u30c8\u7ba1\u7406\u3068\u6700\u9069\u5316<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u7af6\u5408\u5206\u6790\u30c4\u30fc\u30eb\u3092\u5b9f\u969b\u306b\u904b\u7528\u3059\u308b\u306b\u3042\u305f\u3063\u3066\u3001OpenAI API\u306e\u30b3\u30b9\u30c8\u306f\u91cd\u8981\u306a\u8003\u616e\u70b9\u3067\u3059\u3002\u7af6\u5408\u30b5\u30a4\u30c8\u3092\u6bce\u90315\u793e\u5206\u6790\u3057\u305f\u5834\u5408\u306e\u30b3\u30b9\u30c8\u3092\u8a66\u7b97\u3057\u3066\u307f\u307e\u3057\u3087\u3046\u3002<\/p>\n\n\n<table>\n  <thead><tr><th>\u51e6\u7406<\/th><th>\u4f7f\u7528\u30e2\u30c7\u30eb<\/th><th>\u60f3\u5b9a\u30c8\u30fc\u30af\u30f3\u6570<\/th><th>\u30b3\u30b9\u30c8\uff08\u9031\u6b21\uff09<\/th><\/tr><\/thead>\n  <tbody>\n    <tr><td>\u30b3\u30f3\u30c6\u30f3\u30c4\u8981\u7d04\uff085\u30b5\u30a4\u30c8\uff09<\/td><td>GPT-4o mini<\/td><td>10,000\u30c8\u30fc\u30af\u30f3<\/td><td>\u7d04$0.015<\/td><\/tr>\n    <tr><td>\u30ad\u30fc\u30ef\u30fc\u30c9\u62bd\u51fa\uff085\u30b5\u30a4\u30c8\uff09<\/td><td>GPT-4o mini<\/td><td>15,000\u30c8\u30fc\u30af\u30f3<\/td><td>\u7d04$0.023<\/td><\/tr>\n    <tr><td>\u30b5\u30fc\u30d3\u30b9\u5206\u6790\uff085\u30b5\u30a4\u30c8\uff09<\/td><td>GPT-4o mini<\/td><td>20,000\u30c8\u30fc\u30af\u30f3<\/td><td>\u7d04$0.030<\/td><\/tr>\n    <tr><td>\u6bd4\u8f03\u30ec\u30dd\u30fc\u30c8\u751f\u6210\uff081\u56de\uff09<\/td><td>GPT-4o mini<\/td><td>8,000\u30c8\u30fc\u30af\u30f3<\/td><td>\u7d04$0.012<\/td><\/tr>\n    <tr><td>Embeddings\uff085\u30b5\u30a4\u30c8\uff09<\/td><td>text-embedding-3-small<\/td><td>50,000\u30c8\u30fc\u30af\u30f3<\/td><td>\u7d04$0.005<\/td><\/tr>\n    <tr><td><strong>\u5408\u8a08\uff08\u9031\u6b21\uff09<\/strong><\/td><td>\u2014<\/td><td>103,000\u30c8\u30fc\u30af\u30f3<\/td><td><strong>\u7d04$0.085<\/strong><\/td><\/tr>\n  <\/tbody>\n<\/table>\n\n\n<p class=\"wp-block-paragraph\">\u6708\u6b21\u63db\u7b97\u3067\u7d04$0.34\uff08\u7d0450\u5186\uff09\u3002\u975e\u5e38\u306b\u4f4e\u30b3\u30b9\u30c8\u3067\u7af6\u5408\u5206\u6790\u306e\u81ea\u52d5\u5316\u304c\u5b9f\u73fe\u3067\u304d\u307e\u3059\u3002\u3082\u3057\u9ad8\u7cbe\u5ea6\u306a\u5206\u6790\u304c\u5fc5\u8981\u306a\u5834\u5408\u306fGPT-4o\u3092\u4f7f\u3063\u3066\u3082\u3001\u6708\u6b21\u30671,500\u301c3,000\u5186\u7a0b\u5ea6\u306b\u53ce\u307e\u308b\u306f\u305a\u3067\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u30b3\u30b9\u30c8\u524a\u6e1b\u306e\u30c6\u30af\u30cb\u30c3\u30af<\/h3>\n\n\n<div class=\"hcb_wrap\"><pre class=\"prism line-numbers lang-python\" data-lang=\"Python\"><code># cost_optimizer.py - \u30b3\u30b9\u30c8\u524a\u6e1b\u30c6\u30af\u30cb\u30c3\u30af\u96c6\n\nimport hashlib\nimport json\nimport os\nfrom datetime import datetime, timedelta\n\nclass CachedAnalyzer:\n    \"\"\"\n    \u30ad\u30e3\u30c3\u30b7\u30e5\u6a5f\u80fd\u4ed8\u304d\u306e\u7af6\u5408\u5206\u6790\u30af\u30e9\u30b9\n    \u540c\u3058URL\u306e\u5206\u6790\u7d50\u679c\u3092\u4e00\u5b9a\u671f\u9593\u30ad\u30e3\u30c3\u30b7\u30e5\u3057\u3066 API\u547c\u3073\u51fa\u3057\u3092\u6e1b\u3089\u3059\n    \"\"\"\n\n    CACHE_DIR = \".analysis_cache\"\n    CACHE_TTL_HOURS = 24  # \u30ad\u30e3\u30c3\u30b7\u30e5\u6709\u52b9\u671f\u9650\uff08\u6642\u9593\uff09\n\n    def __init__(self, analyzer):\n        self.analyzer = analyzer\n        os.makedirs(self.CACHE_DIR, exist_ok=True)\n\n    def _get_cache_key(self, url: str, analysis_type: str) -&gt; str:\n        return hashlib.md5(f\"{url}:{analysis_type}\".encode()).hexdigest()\n\n    def _load_cache(self, cache_key: str) -&gt; str | None:\n        cache_file = os.path.join(self.CACHE_DIR, f\"{cache_key}.json\")\n        if not os.path.exists(cache_file):\n            return None\n\n        with open(cache_file, \"r\", encoding=\"utf-8\") as f:\n            data = json.load(f)\n\n        # TTL\u30c1\u30a7\u30c3\u30af\n        created_at = datetime.fromisoformat(data[\"created_at\"])\n        if datetime.now() - created_at &gt; timedelta(hours=self.CACHE_TTL_HOURS):\n            return None\n\n        return data[\"result\"]\n\n    def _save_cache(self, cache_key: str, result: str):\n        cache_file = os.path.join(self.CACHE_DIR, f\"{cache_key}.json\")\n        with open(cache_file, \"w\", encoding=\"utf-8\") as f:\n            json.dump({\n                \"result\": result,\n                \"created_at\": datetime.now().isoformat()\n            }, f, ensure_ascii=False)\n\n    def analyze_with_cache(self, url: str, analysis_type: str) -&gt; str:\n        cache_key = self._get_cache_key(url, analysis_type)\n\n        # \u30ad\u30e3\u30c3\u30b7\u30e5\u30d2\u30c3\u30c8\u78ba\u8a8d\n        cached = self._load_cache(cache_key)\n        if cached:\n            print(f\"  \ud83d\udcbe \u30ad\u30e3\u30c3\u30b7\u30e5\u304b\u3089\u53d6\u5f97: {url} ({analysis_type})\")\n            return cached\n\n        # API\u3092\u547c\u3073\u51fa\u3057\u3066\u5206\u6790\n        if analysis_type == \"summary\":\n            result = self.analyzer.summarize_content(url)\n        elif analysis_type == \"keywords\":\n            result = self.analyzer.extract_keywords(url)\n        elif analysis_type == \"features\":\n            result = self.analyzer.analyze_service_features(url)\n        else:\n            raise ValueError(f\"\u672a\u77e5\u306e\u5206\u6790\u30bf\u30a4\u30d7: {analysis_type}\")\n\n        # \u30ad\u30e3\u30c3\u30b7\u30e5\u306b\u4fdd\u5b58\n        self._save_cache(cache_key, result)\n        return result<\/code><\/pre><\/div>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u5b9f\u969b\u306e\u30e6\u30fc\u30b9\u30b1\u30fc\u30b9\u3068\u6d3b\u7528\u4f8b<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">\u30e6\u30fc\u30b9\u30b1\u30fc\u30b91\uff1aSaaS\u306e\u7af6\u5408\u30e9\u30f3\u30c7\u30a3\u30f3\u30b0\u30da\u30fc\u30b8\u5206\u6790<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">SaaS\u4f01\u696d\u306e\u30de\u30fc\u30b1\u30c6\u30a3\u30f3\u30b0\u62c5\u5f53\u8005\u304c\u3001\u7af6\u5408\u4ed6\u793e\u306e\u30e9\u30f3\u30c7\u30a3\u30f3\u30b0\u30da\u30fc\u30b8\u3092\u6bce\u6708\u5206\u6790\u3057\u3066\u30ec\u30dd\u30fc\u30c8\u306b\u307e\u3068\u3081\u308b\u4f5c\u696d\u3092\u81ea\u52d5\u5316\u3057\u305f\u4f8b\u3067\u3059\u3002\u5f93\u6765\u306f1\u793e\u3042\u305f\u308a1\u301c2\u6642\u9593\u304b\u304b\u3063\u3066\u3044\u305f\u5206\u6790\u304c\u3001\u30b9\u30af\u30ea\u30d7\u30c8\u5b9f\u884c\u306e20\u301c30\u5206\u306b\u77ed\u7e2e\u3055\u308c\u307e\u3057\u305f\uff08API\u547c\u3073\u51fa\u3057\u6642\u9593\u3092\u542b\u3080\uff09\u3002<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u7279\u306b\u6709\u52b9\u3060\u3063\u305f\u306e\u304c\u300c\u30ad\u30e3\u30c3\u30c1\u30b3\u30d4\u30fc\u306e\u5909\u5316\u691c\u77e5\u300d\u3067\u3059\u3002\u524d\u9031\u3068\u4eca\u9031\u306e\u30b3\u30f3\u30c6\u30f3\u30c4\u3092\u6bd4\u8f03\u3059\u308b\u3053\u3068\u3067\u3001\u300c\u7af6\u5408\u304cA\/B\u30c6\u30b9\u30c8\u3092\u958b\u59cb\u3057\u305f\u300d\u300c\u4fa1\u683c\u8868\u306e\u8a34\u6c42\u3092\u5909\u66f4\u3057\u305f\u300d\u306a\u3069\u306e\u5909\u5316\u3092\u7d20\u65e9\u304f\u628a\u63e1\u3067\u304d\u308b\u3088\u3046\u306b\u306a\u308a\u307e\u3057\u305f\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u30e6\u30fc\u30b9\u30b1\u30fc\u30b92\uff1a\u30b3\u30f3\u30c6\u30f3\u30c4\u30de\u30fc\u30b1\u30c6\u30a3\u30f3\u30b0\u306e\u30ae\u30e3\u30c3\u30d7\u5206\u6790<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">\u30d6\u30ed\u30b0\u30e1\u30c7\u30a3\u30a2\u306e\u7de8\u96c6\u30c1\u30fc\u30e0\u304c\u3001\u7af6\u5408\u30e1\u30c7\u30a3\u30a2\u306e\u8a18\u4e8b\u4e00\u89a7\u30da\u30fc\u30b8\u3092\u5b9a\u671f\u7684\u306b\u30af\u30ed\u30fc\u30eb\u3057\u3066\u30ad\u30fc\u30ef\u30fc\u30c9\u30c8\u30ec\u30f3\u30c9\u3092\u5206\u6790\u3059\u308b\u7528\u9014\u306b\u3082\u6d3b\u7528\u3067\u304d\u307e\u3059\u3002\u7af6\u5408\u304c\u6700\u8fd1\u6ce8\u529b\u3057\u3066\u3044\u308b\u30c8\u30d4\u30c3\u30af\uff08Embeddings\u306e\u985e\u4f3c\u5ea6\u5206\u6790\u3067\u691c\u51fa\uff09\u3068\u81ea\u793e\u30b3\u30f3\u30c6\u30f3\u30c4\u306e\u91cd\u8907\u7387\u3092\u628a\u63e1\u3059\u308b\u3053\u3068\u3067\u3001<strong>\u300c\u7af6\u5408\u304c\u66f8\u3044\u3066\u3044\u306a\u3044\u304c\u691c\u7d22\u9700\u8981\u304c\u3042\u308b\u9818\u57df\u300d\u3092\u72d9\u3063\u305f\u8a18\u4e8b\u4f01\u753b<\/strong>\u304c\u7acb\u3066\u3084\u3059\u304f\u306a\u308a\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u30e6\u30fc\u30b9\u30b1\u30fc\u30b93\uff1a\u63a1\u7528\u60c5\u5831\u306e\u5909\u5316\u30e2\u30cb\u30bf\u30ea\u30f3\u30b0<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">\u7af6\u5408\u4ed6\u793e\u306e\u63a1\u7528\u30da\u30fc\u30b8\u3092\u30e2\u30cb\u30bf\u30ea\u30f3\u30b0\u3059\u308b\u3053\u3068\u3067\u3001\u300c\u30a8\u30f3\u30b8\u30cb\u30a2\u306e\u5927\u91cf\u63a1\u7528\u3092\u958b\u59cb\u3057\u305f\u300d\u300c\u65b0\u3057\u3044\u4e8b\u696d\u9818\u57df\uff08MLOps\uff09\u306e\u6c42\u4eba\u304c\u51fa\u305f\u300d\u306a\u3069\u306e\u6226\u7565\u7684\u306a\u5909\u5316\u3092\u65e9\u671f\u306b\u5bdf\u77e5\u3067\u304d\u307e\u3059\u3002\u3053\u306e\u60c5\u5831\u306f\u4e8b\u696d\u6226\u7565\u306e\u610f\u601d\u6c7a\u5b9a\u306b\u6d3b\u7528\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u3088\u304f\u3042\u308b\u8cea\u554f\uff08FAQ\uff09<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">JavaScript\u3067\u52d5\u7684\u306b\u751f\u6210\u3055\u308c\u308b\u30da\u30fc\u30b8\u3082\u53d6\u5f97\u3067\u304d\u307e\u3059\u304b\uff1f<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">WebBaseLoader\u306f\u9759\u7684HTML\u306e\u53d6\u5f97\u306b\u7279\u5316\u3057\u3066\u304a\u308a\u3001JavaScript\u30ec\u30f3\u30c0\u30ea\u30f3\u30b0\u304c\u5fc5\u8981\u306aSPA\u306b\u306f\u5bfe\u5fdc\u3057\u3066\u3044\u307e\u305b\u3093\u3002\u52d5\u7684\u30da\u30fc\u30b8\u306b\u306f <code>SeleniumURLLoader<\/code> \u3084 <code>PlaywrightURLLoader<\/code>\uff08LangChain Community \u306b\u542b\u307e\u308c\u308b\uff09\u3092\u4f7f\u3063\u3066\u304f\u3060\u3055\u3044\u3002<\/p>\n\n\n<div class=\"hcb_wrap\"><pre class=\"prism line-numbers lang-none\" data-lang=\"Code\"><code># PlaywrightURLLoader \u306e\u4f7f\u7528\u4f8b\uff08\u52d5\u7684\u30da\u30fc\u30b8\u5bfe\u5fdc\uff09\n# pip install playwright &amp;&amp; playwright install chromium\n\nfrom langchain_community.document_loaders import PlaywrightURLLoader\n\nloader = PlaywrightURLLoader(\n    urls=[\"https:\/\/spa-competitor.com\/services\/\"],\n    remove_selectors=[\"nav\", \"footer\", \".ads\"]  # \u9664\u5916\u3059\u308b\u8981\u7d20\n)\ndocuments = loader.load()<\/code><\/pre><\/div>\n\n\n<h3 class=\"wp-block-heading\">robots.txt\u3092\u7121\u8996\u3057\u3066\u30b9\u30af\u30ec\u30a4\u30d4\u30f3\u30b0\u3057\u3066\u3082\u3044\u3044\u3067\u3059\u304b\uff1f<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">robots.txt\u306e\u6307\u793a\u306b\u306f\u5f93\u3046\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002Disallow\u306b\u6307\u5b9a\u3055\u308c\u305fURL\u3078\u306e\u30a2\u30af\u30bb\u30b9\u306f\u5229\u7528\u898f\u7d04\u9055\u53cd\u3084\u4e0d\u6b63\u30a2\u30af\u30bb\u30b9\u3068\u307f\u306a\u3055\u308c\u308b\u53ef\u80fd\u6027\u304c\u3042\u308a\u307e\u3059\u3002\u307e\u305f\u3001\u77ed\u6642\u9593\u306b\u5927\u91cf\u306e\u30ea\u30af\u30a8\u30b9\u30c8\u3092\u9001\u308b\u3068\u30b5\u30fc\u30d0\u30fc\u306b\u8ca0\u8377\u3092\u304b\u3051\u308b\u305f\u3081\u3001\u30ea\u30af\u30a8\u30b9\u30c8\u9593\u9694\uff08<code>time.sleep()<\/code>\uff09\u3092\u8a2d\u3051\u308b\u3053\u3068\u3092\u5f37\u304f\u63a8\u5968\u3057\u307e\u3059\u3002\u81ea\u52d5\u5316\u30c4\u30fc\u30eb\u3092\u5b9f\u88c5\u3059\u308b\u969b\u306f\u3001robots.txt\u306e\u78ba\u8a8d\u30fb\u9069\u5207\u306a\u30ea\u30af\u30a8\u30b9\u30c8\u9593\u9694\u30fbUser-Agent\u306e\u6b63\u76f4\u306a\u8a2d\u5b9a\uff08\u81ea\u793e\u30c4\u30fc\u30eb\u3067\u3042\u308b\u3053\u3068\u3092\u793a\u3059\uff09\u306e3\u70b9\u3092\u5fb9\u5e95\u3057\u3066\u304f\u3060\u3055\u3044\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">LangChain\u3068LlamaIndex\u306e\u4f7f\u3044\u5206\u3051\u306f\uff1f<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">LangChain\u306fAgents\u30fbChains\u30fbTool\u9023\u643a\u306a\u3069\u300cLLM\u3092\u4f7f\u3063\u305f\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u5168\u822c\u300d\u3092\u69cb\u7bc9\u3059\u308b\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u3067\u3059\u3002LlamaIndex\u306fRAG\uff08\u6587\u66f8\u691c\u7d22\u00d7LLM\uff09\u306e\u69cb\u7bc9\u306b\u7279\u5316\u3057\u3066\u304a\u308a\u3001\u5927\u91cf\u6587\u66f8\u306e\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u7ba1\u7406\u304c\u5f97\u610f\u3067\u3059\u3002\u7af6\u5408\u5206\u6790\u306e\u3088\u3046\u306a\u300cWeb\u304b\u3089\u30c7\u30fc\u30bf\u3092\u53d6\u5f97\u2192LLM\u3067\u51e6\u7406\u300d\u3068\u3044\u3046\u30d5\u30ed\u30fc\u3067\u306fLangChain\u304c\u9069\u3057\u3066\u3044\u307e\u3059\u3002\u4e00\u65b9\u3001\u5927\u91cf\u306e\u793e\u5185\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u3092\u691c\u7d22\u53ef\u80fd\u306b\u3057\u3066LLM\u3067\u56de\u7b54\u3055\u305b\u308b\u30b7\u30b9\u30c6\u30e0\u306b\u306fLlamaIndex\u304c\u5411\u3044\u3066\u3044\u307e\u3059\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">OpenAI\u4ee5\u5916\u306eLLM\uff08Claude\u30fbGemini\u7b49\uff09\u3067\u3082\u4f7f\u3048\u307e\u3059\u304b\uff1f<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">\u4f7f\u3048\u307e\u3059\u3002LangChain\u306fAnthropic\u306eClaude\u30fbGoogle\u306eGemini\u30fbMeta Llama\u30fbMistral\u306a\u3069\u3055\u307e\u3056\u307e\u306aLLM\u306b\u5bfe\u5fdc\u3057\u3066\u3044\u307e\u3059\u3002<code>ChatOpenAI<\/code>\u306e\u90e8\u5206\u3092<code>ChatAnthropic<\/code>\u306a\u3069\u306b\u5dee\u3057\u66ff\u3048\u308b\u3060\u3051\u3067\u307b\u307c\u540c\u3058\u30b3\u30fc\u30c9\u304c\u52d5\u304d\u307e\u3059\u3002\u30ed\u30fc\u30ab\u30eb\u3067\u52d5\u4f5c\u3059\u308bOllama\u7d4c\u7531\u306e\u30e2\u30c7\u30eb\u3082\u5229\u7528\u3067\u304d\u308b\u305f\u3081\u3001API\u30b3\u30b9\u30c8\u3092\u5b8c\u5168\u306b\u30bc\u30ed\u306b\u3059\u308b\u3053\u3068\u3082\u53ef\u80fd\u3067\u3059\u3002<\/p>\n\n\n<div class=\"hcb_wrap\"><pre class=\"prism line-numbers lang-none\" data-lang=\"Code\"><code># Claude\u3092\u4f7f\u3046\u5834\u5408\n# pip install langchain-anthropic\nfrom langchain_anthropic import ChatAnthropic\n\nllm = ChatAnthropic(\n    model=\"claude-3-5-sonnet-20241022\",\n    temperature=0.1\n)\n\n# Ollama\u3067\u30ed\u30fc\u30ab\u30eb\u5b9f\u884c\u3059\u308b\u5834\u5408\uff08API\u30b3\u30b9\u30c80\u5186\uff09\n# ollama pull llama3.2 \u3067\u4e8b\u524d\u306b\u30e2\u30c7\u30eb\u3092\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\nfrom langchain_ollama import ChatOllama\n\nllm = ChatOllama(model=\"llama3.2\", temperature=0.1)<\/code><\/pre><\/div>\n\n\n<h3 class=\"wp-block-heading\">\u5206\u6790\u7d50\u679c\u306e\u7cbe\u5ea6\u3092\u4e0a\u3052\u308b\u306b\u306f\u3069\u3046\u3059\u308c\u3070\u3044\u3044\u3067\u3059\u304b\uff1f<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">\u7cbe\u5ea6\u5411\u4e0a\u306e\u305f\u3081\u306b\u306f\u4ee5\u4e0b\u306e\u30a2\u30d7\u30ed\u30fc\u30c1\u304c\u6709\u52b9\u3067\u3059\u3002\u2460\u30d7\u30ed\u30f3\u30d7\u30c8\u306e\u6539\u5584\uff1a\u5206\u6790\u89b3\u70b9\u3092\u5177\u4f53\u7684\u306b\u6307\u5b9a\u3057\u3001\u51fa\u529b\u30d5\u30a9\u30fc\u30de\u30c3\u30c8\u3092JSON\u3084\u7b87\u6761\u66f8\u304d\u3067\u5236\u7d04\u3059\u308b\u3002\u2461\u30e2\u30c7\u30eb\u306e\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\uff1aGPT-4o mini\u304b\u3089GPT-4o\u306b\u5909\u66f4\u3059\u308b\u3053\u3068\u3067\u5206\u6790\u306e\u6df1\u3055\u304c\u5411\u4e0a\u3057\u307e\u3059\u3002\u2462\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u306e\u5145\u5b9f\uff1a\u53d6\u5f97\u3059\u308b\u30c1\u30e3\u30f3\u30af\u6570\u3092\u5897\u3084\u3059\u304b\u3001\u81ea\u793e\u306e\u30b5\u30fc\u30d3\u30b9\u8aac\u660e\u3092\u30b7\u30b9\u30c6\u30e0\u30d7\u30ed\u30f3\u30d7\u30c8\u306b\u8ffd\u52a0\u3059\u308b\u3053\u3068\u3067\u3001\u3088\u308a\u6587\u8108\u3092\u8e0f\u307e\u3048\u305f\u5206\u6790\u306b\u306a\u308a\u307e\u3059\u3002\u2463Few-shot\u30d7\u30ed\u30f3\u30d7\u30c8\uff1a\u904e\u53bb\u306e\u5206\u6790\u30ec\u30dd\u30fc\u30c8\u306e\u4f8b\u3092\u30d7\u30ed\u30f3\u30d7\u30c8\u306b\u542b\u3081\u308b\u3053\u3068\u3067\u51fa\u529b\u54c1\u8cea\u304c\u5b89\u5b9a\u3057\u307e\u3059\u3002<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n<div class=\"swell-block-balloon\"><div class=\"c-balloon -bln-left\" data-col=\"gray\"><div class=\"c-balloon__icon -square\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/withcode.tech\/media\/wp-content\/uploads\/2025\/06\/\u30b9\u30af\u30ea\u30fc\u30f3\u30b7\u30e7\u30c3\u30c8-2025-06-15-14.48.08.jpg\" alt=\"\" class=\"c-balloon__iconImg\" width=\"80px\" height=\"80px\"><span class=\"c-balloon__iconName\">\u751f\u5f92<\/span><\/div><div class=\"c-balloon__body -speaking -border-none\"><div class=\"c-balloon__text\">\n<p><strong>\u7af6\u5408\u30b5\u30a4\u30c8\u306e\u5206\u6790\u3092AI\u3067\u81ea\u52d5\u5316\u3067\u304d\u308b\u3093\u3067\u3059\u306d\uff01\u9031\u6b21\u3067\u81ea\u52d5\u30ec\u30dd\u30fc\u30c8\u304c\u5c4a\u304f\u4ed5\u7d44\u307f\u3092\u4f5c\u308a\u305f\u3044\u3067\u3059\u3002Embeddings\u3067\u30b3\u30f3\u30c6\u30f3\u30c4\u30ae\u30e3\u30c3\u30d7\u3092\u767a\u898b\u3067\u304d\u308b\u306e\u3082\u9762\u767d\u3044\u3067\u3059\uff01<\/strong><\/p>\n<span class=\"c-balloon__shapes\"><span class=\"c-balloon__before\"><\/span><span class=\"c-balloon__after\"><\/span><\/span><\/div><\/div><\/div><\/div>\n\n<div class=\"swell-block-balloon\"><div class=\"c-balloon -bln-right\" data-col=\"gray\"><div class=\"c-balloon__icon -square\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/withcode.tech\/media\/wp-content\/uploads\/2025\/06\/\u30b9\u30af\u30ea\u30fc\u30f3\u30b7\u30e7\u30c3\u30c8-2025-06-15-15.11.23.jpg\" alt=\"\" class=\"c-balloon__iconImg\" width=\"80px\" height=\"80px\"><span class=\"c-balloon__iconName\">\u30da\u30f3\u535a\u58eb<\/span><\/div><div class=\"c-balloon__body -speaking -border-none\"><div class=\"c-balloon__text\">\n<p><strong>GitHub Actions\u3068\u7d44\u307f\u5408\u308f\u305b\u308c\u3070\u5b8c\u5168\u81ea\u52d5\u5316\u3067\u304d\u308b\u3093\u3058\u3083\uff01\u4e00\u5ea6\u8a2d\u5b9a\u3059\u308c\u3070\u6bce\u9031\u6708\u66dc\u65e5\u306b\u7af6\u5408\u30ec\u30dd\u30fc\u30c8\u304c\u751f\u6210\u3055\u308c\u3066\u304f\u308b\u306e\u3067\u3001\u6226\u7565\u7acb\u6848\u306b\u96c6\u4e2d\u3067\u304d\u308b\u3088\u3046\u306b\u306a\u308b\u305e\u3044\u3002\u30b3\u30b9\u30c8\u9762\u3067\u3082\u6708\u6570\u5341\u5186\u301c\u6570\u767e\u5186\u3067\u904b\u7528\u3067\u304d\u308b\u304b\u3089\u3001\u8cbb\u7528\u5bfe\u52b9\u679c\u306f\u629c\u7fa4\u3058\u3083\u3002WithCode\u3067Python\u3068API\u9023\u643a\u3092\u5b66\u3079\u3070\u3001\u3053\u306e\u3088\u3046\u306a\u81ea\u52d5\u5316\u30c4\u30fc\u30eb\u3092\u81ea\u5206\u3067\u4f5c\u308c\u308b\u3088\u3046\u306b\u306a\u308b\u3093\u3058\u3083\uff01<\/strong><\/p>\n<span class=\"c-balloon__shapes\"><span class=\"c-balloon__before\"><\/span><span class=\"c-balloon__after\"><\/span><\/span><\/div><\/div><\/div><\/div>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u307e\u3068\u3081<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n  <li><strong>WebBaseLoader<\/strong>\uff1aURL\u3092\u6e21\u3059\u3060\u3051\u3067\u30c6\u30ad\u30b9\u30c8\u62bd\u51fa\u3001LangChain\u306eDocument\u5f62\u5f0f\u306b\u81ea\u52d5\u5909\u63db\u3057\u3066RAG\u3084Chain\u3068\u76f4\u63a5\u9023\u643a\u3067\u304d\u308b\u3002<code>bs_kwargs<\/code>\u3067\u30b9\u30af\u30ec\u30a4\u30d4\u30f3\u30b0\u5bfe\u8c61\u8981\u7d20\u3092\u7d5e\u308a\u8fbc\u307f\u3001<code>header_template<\/code>\u3067User-Agent\u3092\u30ab\u30b9\u30bf\u30de\u30a4\u30ba\u3067\u304d\u308b\u3002<\/li>\n  <li><strong>TextSplitter<\/strong>\uff1aLLM\u306e\u30c8\u30fc\u30af\u30f3\u4e0a\u9650\u3092\u8d85\u3048\u306a\u3044\u3088\u3046\u306b\u30c6\u30ad\u30b9\u30c8\u3092\u30c1\u30e3\u30f3\u30af\u306b\u5206\u5272\u3059\u308b\u3002\u65e5\u672c\u8a9e\u30b3\u30f3\u30c6\u30f3\u30c4\u306b\u306f<code>separators<\/code>\u306b\u53e5\u70b9\u30fb\u8aad\u70b9\u3092\u6307\u5b9a\u3057\u305f<code>RecursiveCharacterTextSplitter<\/code>\u304c\u63a8\u5968\u3002<\/li>\n  <li><strong>\u5b9f\u88c5\u69cb\u6210<\/strong>\uff1aCompetitorAnalyzer\u30af\u30e9\u30b9\u306b\u8981\u7d04\u30fb\u30ad\u30fc\u30ef\u30fc\u30c9\u62bd\u51fa\u30fb\u6bd4\u8f03\u5206\u6790\u3092\u96c6\u7d04\u3057\u3001main.py\u304b\u3089\u547c\u3073\u51fa\u3059\u8a2d\u8a08\u3002\u30ad\u30e3\u30c3\u30b7\u30e5\u6a5f\u80fd\u3067API\u30b3\u30b9\u30c8\u3092\u524a\u6e1b\u3067\u304d\u308b\u3002<\/li>\n  <li><strong>Embeddings\u6d3b\u7528<\/strong>\uff1aFAISS VectorStore\u3068\u7d44\u307f\u5408\u308f\u305b\u308b\u3053\u3068\u3067\u3001\u81ea\u793e\u306b\u306a\u3044\u30b3\u30f3\u30c6\u30f3\u30c4\u30ae\u30e3\u30c3\u30d7\u3092\u767a\u898b\u3057\u305f\u308a\u30012\u30b5\u30a4\u30c8\u9593\u306e\u91cd\u8907\u7387\u3092\u6570\u5024\u5316\u3067\u304d\u308b\u3002<\/li>\n  <li><strong>\u81ea\u52d5\u5316<\/strong>\uff1aschedule\u30e9\u30a4\u30d6\u30e9\u30ea\u307e\u305f\u306fGitHub Actions\u3067\u9031\u6b21\u5b9f\u884c\u3059\u308b\u3053\u3068\u3067\u5b9a\u671f\u7684\u306a\u7af6\u5408\u30e2\u30cb\u30bf\u30ea\u30f3\u30b0\u3092\u5b8c\u5168\u81ea\u52d5\u5316\u3067\u304d\u308b\u3002Slack\u901a\u77e5\u3068\u306e\u7d44\u307f\u5408\u308f\u305b\u3067\u30c1\u30fc\u30e0\u5171\u6709\u3082\u30b9\u30e0\u30fc\u30ba\u3002<\/li>\n  <li><strong>\u30b3\u30b9\u30c8<\/strong>\uff1aGPT-4o mini\u3092\u4f7f\u3048\u3070\u9031\u6b215\u793e\u5206\u6790\u3067\u3082\u7d04$0.085\uff08\u6708$0.34\u225250\u5186\uff09\u3002\u30b3\u30b9\u30c8\u52b9\u7387\u306b\u512a\u308c\u305f\u81ea\u52d5\u5316\u304c\u5b9f\u73fe\u3067\u304d\u308b\u3002<\/li>\n  <li><strong>\u6ce8\u610f\u70b9<\/strong>\uff1arobots.txt\u306e\u9075\u5b88\u30fb\u30ea\u30af\u30a8\u30b9\u30c8\u9593\u9694\u306e\u78ba\u4fdd\u30fb\u52d5\u7684\u30da\u30fc\u30b8\u306b\u306fSelenium\/Playwright\u3092\u4f7f\u7528\u3059\u308b\u3002<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong><span class=\"swl-marker mark_yellow\">LangChain WebBaseLoader\u3067\u7af6\u5408\u5206\u6790\u3092\u81ea\u52d5\u5316\u3059\u308b\u3053\u3068\u3067\u3001\u6bce\u9031\u6570\u6642\u9593\u304b\u304b\u3063\u3066\u3044\u305f\u30ea\u30b5\u30fc\u30c1\u4f5c\u696d\u3092\u6570\u5206\u306b\u77ed\u7e2e\u3067\u304d\u307e\u3059\u3002Embeddings\u3092\u6d3b\u7528\u3057\u305f\u30b3\u30f3\u30c6\u30f3\u30c4\u30ae\u30e3\u30c3\u30d7\u5206\u6790\u3084\u3001GitHub Actions\u306b\u3088\u308b\u5b8c\u5168\u81ea\u52d5\u5316\u307e\u3067\u3001Python\u306e\u57fa\u790e\u304c\u3042\u308c\u3070\u4eca\u65e5\u304b\u3089\u5b9f\u88c5\u3067\u304d\u307e\u3059\u3002<\/span><\/strong><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<!-- withmedia-related -->\n<h2 class=\"wp-block-heading\">\u95a2\u9023\u8a18\u4e8b<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/withcode.tech\/media\/ai-era-freelance-work-style\/\">AI\u6642\u4ee3\u306e\u50cd\u304d\u65b9\uff5c\u30d5\u30ea\u30fc\u30e9\u30f3\u30b9\u304c\u300c\u4f7f\u308f\u308c\u308b\u5074\u300d\u304b\u3089\u300c\u4f7f\u3046\u5074\u300d\u306b\u306a\u308b\u305f\u3081\u306e\u6975\u610f\u3092\u5fb9\u5e95\u89e3\u8aac<\/a><\/li>\n<li><a href=\"https:\/\/withcode.tech\/media\/owasp-llm-top-10-guide\/\">OWASP Top 10 for LLM Applications \u89e3\u8aac\uff5c\u751f\u6210AI\u30a2\u30d7\u30ea\u306e\u4ee3\u8868\u7684\u30ea\u30b9\u30af\u3068\u5bfe\u7b56<\/a><\/li>\n<li><a href=\"https:\/\/withcode.tech\/media\/google-gemini-guide\/\">Google Gemini \u516c\u5f0f\u60c5\u5831\u307e\u3068\u3081\uff5c\u30e2\u30c7\u30eb\u30fb\u3067\u304d\u308b\u3053\u3068\u30fb\u6599\u91d1\u3092\u3084\u3055\u3057\u304f\u89e3\u8aac<\/a><\/li>\n<li><a href=\"https:\/\/withcode.tech\/media\/anthropic-claude-models-pricing\/\">Claude\u516c\u5f0f\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u3067\u898b\u308b\u30e2\u30c7\u30eb\u4ed5\u69d8\u3068\u6599\u91d1\uff5c\u696d\u52d9\u6d3b\u7528\u306e\u57fa\u790e\u30ac\u30a4\u30c9<\/a><\/li>\n<li><a href=\"https:\/\/withcode.tech\/media\/openai-models-pricing-guide\/\">OpenAI\u516c\u5f0f\u3067\u5b66\u3076\u30e2\u30c7\u30eb\u30fb\u6599\u91d1\u30fb\u5229\u7528\u898f\u7d04\uff5cChatGPT\/API\u6d3b\u7528\u306e\u57fa\u790e<\/a><\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<!-- withmedia-references -->\n<h2 class=\"wp-block-heading\">\u53c2\u8003\u30ea\u30f3\u30af\uff08\u516c\u5f0f\u30fb\u4e00\u6b21\u60c5\u5831\uff09<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/developer.mozilla.org\/ja\/docs\/Web\/JavaScript\" target=\"_blank\" rel=\"noopener noreferrer\">MDN Web Docs \u2014 JavaScript<\/a><\/li>\n<li><a href=\"https:\/\/git-scm.com\/doc\" target=\"_blank\" rel=\"noopener noreferrer\">Git \u516c\u5f0f\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8<\/a><\/li>\n<li><a href=\"https:\/\/platform.openai.com\/docs\/overview\" target=\"_blank\" rel=\"noopener noreferrer\">OpenAI \u516c\u5f0f\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8<\/a><\/li>\n<li><a href=\"https:\/\/docs.anthropic.com\/ja\/\" target=\"_blank\" rel=\"noopener noreferrer\">Anthropic\uff08Claude\uff09\u516c\u5f0f\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8<\/a><\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">WithCode\u3092\u4f53\u9a13\u3067\u304d\u308b\u521d\u7d1a\u30b3\u30fc\u30b9\u516c\u958b\u4e2d\uff01<\/h2>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"alignleft size-full\"><img decoding=\"async\" width=\"600\" height=\"500\" src=\"https:\/\/withcode.tech\/media\/wp-content\/uploads\/2024\/04\/\u30d0\u30ca\u30fc_300\u00d7250_20240425.png\" alt=\"WithCode\u3092\u4f53\u9a13\u3067\u304d\u308b\u521d\u7d1a\u30b3\u30fc\u30b9\u516c\u958b\u4e2d\uff01\" class=\"wp-image-2650\"\/><\/figure>\n<\/div>\n\n\n<h3 class=\"wp-block-heading\">\u521d\u7d1a\u30b3\u30fc\u30b9(\u00a549,800)\u304c\u5b8c\u5168\u7121\u6599\u306b\uff01<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u671f\u9593\uff1a1\u9031\u9593<\/strong><\/li>\n<li><strong>\u5b66\u7fd2\u5185\u5bb9\uff1a<\/strong><br><strong>\u30ed\u30fc\u30c9\u30de\u30c3\u30d7\/\u57fa\u790e\u77e5\u8b58\/\u74b0\u5883\u69cb\u7bc9\/HTML\/CSS\/LP\u30fb\u30dd\u30fc\u30c8\u30d5\u30a9\u30ea\u30aa\u4f5c\u6210<\/strong><br><strong>\u2192 <span class=\"swl-marker mark_yellow\">\u6b63\u3057\u3044\u5b66\u7fd2\u65b9\u6cd5\u3067\u300c\u78ba\u304b\u306a\u6210\u9577\u300d\u3092\u5b9f\u611f\u3067\u304d\u308b\u30ab\u30ea\u30ad\u30e5\u30e9\u30e0\u3002<\/span><\/strong><\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">\u526f\u696d\u30fb\u30d5\u30ea\u30fc\u30e9\u30f3\u30b9\u304c\u4e3b\u6d41\u306b\u306a\u3063\u3066\u3044\u308b\u4eca\u3053\u305d\u3001\u81ea\u3089\u306e\u30b9\u30ad\u30eb\u3067\u7a3c\u3052\u308b\u4eba\u6750\u3092\u76ee\u6307\u3057\u3066\u307f\u307e\u305b\u3093\u304b\uff1f<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u672a\u7d4c\u9a13\u3067\u3082\u5fc3\u914d\u3059\u308b\u3053\u3068\u306f\u3042\u308a\u307e\u305b\u3093\u3002\u521d\u7d1a\u30b3\u30fc\u30b9\u3092\u53d7\u8b1b\u3055\u308c\u308b\u65b9\u306e\u5927\u591a\u6570\u306f\u30d7\u30ed\u30b0\u30e9\u30df\u30f3\u30b0\u672a\u7d4c\u9a13\u3067\u3059\u3002\u307e\u305a\u306f\u7121\u6599\u30ab\u30a6\u30f3\u30bb\u30ea\u30f3\u30b0\u3067\u3001\u60a9\u307f\u3084\u4e0d\u5b89\u3092\u304a\u805e\u304b\u305b\u304f\u3060\u3055\u3044\uff01<\/p>\n\n\n\n<div class=\"wp-block-buttons is-layout-flex wp-block-buttons-is-layout-flex\">\n<div class=\"wp-block-button\"><a class=\"wp-block-button__link has-white-color has-text-color has-background has-link-color wp-element-button\" href=\"https:\/\/withcode.tech\/reservation\/\" style=\"background-color:#ffbf00\"><strong>\u516c\u5f0f\u30b5\u30a4\u30c8\u304b\u3089\u7121\u6599\u30ab\u30a6\u30f3\u30bb\u30ea\u30f3\u30b0\u306b\u7533\u3057\u8fbc\u3080 \u2192<\/strong><\/a><\/div>\n<\/div>\n\n\n\n<!-- withmedia-faq-schema -->\n<script type=\"application\/ld+json\">\n{\n  \"@context\": \"https:\/\/schema.org\",\n  \"@type\": \"FAQPage\",\n  \"mainEntity\": [\n    {\n      \"@type\": \"Question\",\n      \"name\": \"JavaScript\u3067\u52d5\u7684\u306b\u751f\u6210\u3055\u308c\u308b\u30da\u30fc\u30b8\u3082\u53d6\u5f97\u3067\u304d\u307e\u3059\u304b\uff1f\",\n      \"acceptedAnswer\": {\n        \"@type\": \"Answer\",\n        \"text\": \"WebBaseLoader\u306f\u9759\u7684HTML\u306e\u53d6\u5f97\u306b\u7279\u5316\u3057\u3066\u304a\u308a\u3001JavaScript\u30ec\u30f3\u30c0\u30ea\u30f3\u30b0\u304c\u5fc5\u8981\u306aSPA\u306b\u306f\u5bfe\u5fdc\u3057\u3066\u3044\u307e\u305b\u3093\u3002\u52d5\u7684\u30da\u30fc\u30b8\u306b\u306f SeleniumURLLoader \u3084 PlaywrightURLLoader\uff08LangChain Community \u306b\u542b\u307e\u308c\u308b\uff09\u3092\u4f7f\u3063\u3066\u304f\u3060\u3055\u3044\u3002\"\n      }\n    },\n    {\n      \"@type\": \"Question\",\n      \"name\": \"robots.txt\u3092\u7121\u8996\u3057\u3066\u30b9\u30af\u30ec\u30a4\u30d4\u30f3\u30b0\u3057\u3066\u3082\u3044\u3044\u3067\u3059\u304b\uff1f\",\n      \"acceptedAnswer\": {\n        \"@type\": \"Answer\",\n        \"text\": \"robots.txt\u306e\u6307\u793a\u306b\u306f\u5f93\u3046\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002Disallow\u306b\u6307\u5b9a\u3055\u308c\u305fURL\u3078\u306e\u30a2\u30af\u30bb\u30b9\u306f\u5229\u7528\u898f\u7d04\u9055\u53cd\u3084\u4e0d\u6b63\u30a2\u30af\u30bb\u30b9\u3068\u307f\u306a\u3055\u308c\u308b\u53ef\u80fd\u6027\u304c\u3042\u308a\u307e\u3059\u3002\u307e\u305f\u3001\u77ed\u6642\u9593\u306b\u5927\u91cf\u306e\u30ea\u30af\u30a8\u30b9\u30c8\u3092\u9001\u308b\u3068\u30b5\u30fc\u30d0\u30fc\u306b\u8ca0\u8377\u3092\u304b\u3051\u308b\u305f\u3081\u3001\u30ea\u30af\u30a8\u30b9\u30c8\u9593\u9694\uff08time.sleep()\uff09\u3092\u8a2d\u3051\u308b\u3053\u3068\u3092\u5f37\u304f\u63a8\u5968\u3057\u307e\u3059\u3002\u81ea\u52d5\u5316\u30c4\u30fc\u30eb\u3092\u5b9f\u88c5\u3059\u308b\u969b\u306f\u3001robots.txt\u306e\u78ba\u8a8d\u30fb\u9069\u5207\u306a\u30ea\u30af\u30a8\u30b9\u30c8\u9593\u9694\u30fbUser-Agent\u306e\u6b63\u76f4\u306a\u8a2d\u5b9a\uff08\u81ea\u793e\u30c4\u30fc\u30eb\u3067\u3042\u308b\u3053\u3068\u3092\u793a\u3059\uff09\u306e3\u70b9\u3092\u5fb9\u5e95\u3057\u3066\u304f\u3060\u3055\u3044\u3002\"\n      }\n    },\n    {\n      \"@type\": \"Question\",\n      \"name\": \"LangChain\u3068LlamaIndex\u306e\u4f7f\u3044\u5206\u3051\u306f\uff1f\",\n      \"acceptedAnswer\": {\n        \"@type\": \"Answer\",\n        \"text\": \"LangChain\u306fAgents\u30fbChains\u30fbTool\u9023\u643a\u306a\u3069\u300cLLM\u3092\u4f7f\u3063\u305f\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u5168\u822c\u300d\u3092\u69cb\u7bc9\u3059\u308b\u30d5\u30ec\u30fc\u30e0\u30ef\u30fc\u30af\u3067\u3059\u3002LlamaIndex\u306fRAG\uff08\u6587\u66f8\u691c\u7d22\u00d7LLM\uff09\u306e\u69cb\u7bc9\u306b\u7279\u5316\u3057\u3066\u304a\u308a\u3001\u5927\u91cf\u6587\u66f8\u306e\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u7ba1\u7406\u304c\u5f97\u610f\u3067\u3059\u3002\u7af6\u5408\u5206\u6790\u306e\u3088\u3046\u306a\u300cWeb\u304b\u3089\u30c7\u30fc\u30bf\u3092\u53d6\u5f97\u2192LLM\u3067\u51e6\u7406\u300d\u3068\u3044\u3046\u30d5\u30ed\u30fc\u3067\u306fLangChain\u304c\u9069\u3057\u3066\u3044\u307e\u3059\u3002\u4e00\u65b9\u3001\u5927\u91cf\u306e\u793e\u5185\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u3092\u691c\u7d22\u53ef\u80fd\u306b\u3057\u3066LLM\u3067\u56de\u7b54\u3055\u305b\u308b\u30b7\u30b9\u30c6\u30e0\u306b\u306fLlamaIndex\u304c\u5411\u3044\u3066\u3044\u307e\u3059\u3002\"\n      }\n    },\n    {\n      \"@type\": \"Question\",\n      \"name\": \"OpenAI\u4ee5\u5916\u306eLLM\uff08Claude\u30fbGemini\u7b49\uff09\u3067\u3082\u4f7f\u3048\u307e\u3059\u304b\uff1f\",\n      \"acceptedAnswer\": {\n        \"@type\": \"Answer\",\n        \"text\": \"\u4f7f\u3048\u307e\u3059\u3002LangChain\u306fAnthropic\u306eClaude\u30fbGoogle\u306eGemini\u30fbMeta Llama\u30fbMistral\u306a\u3069\u3055\u307e\u3056\u307e\u306aLLM\u306b\u5bfe\u5fdc\u3057\u3066\u3044\u307e\u3059\u3002ChatOpenAI\u306e\u90e8\u5206\u3092ChatAnthropic\u306a\u3069\u306b\u5dee\u3057\u66ff\u3048\u308b\u3060\u3051\u3067\u307b\u307c\u540c\u3058\u30b3\u30fc\u30c9\u304c\u52d5\u304d\u307e\u3059\u3002\u30ed\u30fc\u30ab\u30eb\u3067\u52d5\u4f5c\u3059\u308bOllama\u7d4c\u7531\u306e\u30e2\u30c7\u30eb\u3082\u5229\u7528\u3067\u304d\u308b\u305f\u3081\u3001API\u30b3\u30b9\u30c8\u3092\u5b8c\u5168\u306b\u30bc\u30ed\u306b\u3059\u308b\u3053\u3068\u3082\u53ef\u80fd\u3067\u3059\u3002\"\n      }\n    },\n    {\n      \"@type\": \"Question\",\n      \"name\": \"\u5206\u6790\u7d50\u679c\u306e\u7cbe\u5ea6\u3092\u4e0a\u3052\u308b\u306b\u306f\u3069\u3046\u3059\u308c\u3070\u3044\u3044\u3067\u3059\u304b\uff1f\",\n      \"acceptedAnswer\": {\n        \"@type\": \"Answer\",\n        \"text\": \"\u7cbe\u5ea6\u5411\u4e0a\u306e\u305f\u3081\u306b\u306f\u4ee5\u4e0b\u306e\u30a2\u30d7\u30ed\u30fc\u30c1\u304c\u6709\u52b9\u3067\u3059\u3002\u2460\u30d7\u30ed\u30f3\u30d7\u30c8\u306e\u6539\u5584\uff1a\u5206\u6790\u89b3\u70b9\u3092\u5177\u4f53\u7684\u306b\u6307\u5b9a\u3057\u3001\u51fa\u529b\u30d5\u30a9\u30fc\u30de\u30c3\u30c8\u3092JSON\u3084\u7b87\u6761\u66f8\u304d\u3067\u5236\u7d04\u3059\u308b\u3002\u2461\u30e2\u30c7\u30eb\u306e\u30a2\u30c3\u30d7\u30b0\u30ec\u30fc\u30c9\uff1aGPT-4o mini\u304b\u3089GPT-4o\u306b\u5909\u66f4\u3059\u308b\u3053\u3068\u3067\u5206\u6790\u306e\u6df1\u3055\u304c\u5411\u4e0a\u3057\u307e\u3059\u3002\u2462\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u306e\u5145\u5b9f\uff1a\u53d6\u5f97\u3059\u308b\u30c1\u30e3\u30f3\u30af\u6570\u3092\u5897\u3084\u3059\u304b\u3001\u81ea\u793e\u306e\u30b5\u30fc\u30d3\u30b9\u8aac\u660e\u3092\u30b7\u30b9\u30c6\u30e0\u30d7\u30ed\u30f3\u30d7\u30c8\u306b\u8ffd\u52a0\u3059\u308b\u3053\u3068\u3067\u3001\u3088\u308a\u6587\u8108\u3092\u8e0f\u307e\u3048\u305f\u5206\u6790\u306b\u306a\u308a\u307e\u3059\u3002\u2463Few-shot\u30d7\u30ed\u30f3\u30d7\u30c8\uff1a\u904e\u53bb\u306e\u5206\u6790\u30ec\u30dd\u30fc\u30c8\u306e\u4f8b\u3092\u30d7\u30ed\u30f3\u30d7\u30c8\u306b\u542b\u3081\u308b\u3053\u3068\u3067\u51fa\u529b\u54c1\u8cea\u304c\u5b89\u5b9a\u3057\u307e\u3059\u3002\"\n      }\n    }\n  ]\n}\n<\/script>\n\n\n\n<!-- withmedia-article-schema -->\n<script type=\"application\/ld+json\">\n{\n  \"@context\": \"https:\/\/schema.org\",\n  \"@graph\": [\n    {\n      \"@type\": \"Organization\",\n      \"@id\": \"https:\/\/withcode.tech\/media\/#organization\",\n      \"name\": \"WithCode\",\n      \"url\": \"https:\/\/withcode.tech\/\",\n      \"description\": \"\u300c\u76ee\u6307\u3059\u306a\u3089\u7a3c\u3052\u308b\u4eba\u6750\u300d\u3092\u30d3\u30b8\u30e7\u30f3\u306b\u7d2f\u8a08400\u540d\u4ee5\u4e0a\u306e\u30d5\u30ea\u30fc\u30e9\u30f3\u30b9\u3092\u8f29\u51fa\u3057\u305f\u5b9f\u8df5\u578b\u30d7\u30ed\u30b0\u30e9\u30df\u30f3\u30b0\u30b9\u30af\u30fc\u30eb\u3002150\u793e\u4ee5\u4e0a\u306e\u5b9f\u6848\u4ef6\u652f\u63f4\u306b\u57fa\u3065\u304dWeb\u5236\u4f5c\u30fbWeb\u30c7\u30b6\u30a4\u30f3\u306e\u60c5\u5831\u3092\u767a\u4fe1\u3002\",\n      \"logo\": {\n        \"@type\": \"ImageObject\",\n        \"url\": \"https:\/\/withcode.tech\/media\/wp-content\/uploads\/2023\/12\/WITHCODE_logo.png\"\n      },\n      \"sameAs\": [\n        \"https:\/\/withcode.tech\/\"\n      ]\n    },\n    {\n      \"@type\": \"WebSite\",\n      \"@id\": \"https:\/\/withcode.tech\/media\/#website\",\n      \"name\": \"WithMedia\",\n      \"url\": \"https:\/\/withcode.tech\/media\/\",\n      \"publisher\": {\n        \"@id\": \"https:\/\/withcode.tech\/media\/#organization\"\n      },\n      \"inLanguage\": \"ja\"\n    },\n    {\n      \"@id\": \"https:\/\/withcode.tech\/media\/author\/withcode-officialgmail-com\/#author\",\n      \"name\": \"WithCode \u7de8\u96c6\u90e8\",\n      \"url\": \"https:\/\/withcode.tech\/media\/author\/withcode-officialgmail-com\/\",\n      \"description\": \"WithCode\uff08\u30a6\u30a3\u30ba\u30b3\u30fc\u30c9\uff09\u306f\u300c\u76ee\u6307\u3059\u306a\u3089\u7a3c\u3052\u308b\u4eba\u6750\u300d\u3092\u30d3\u30b8\u30e7\u30f3\u306b\u3001\u7d2f\u8a08400\u540d\u4ee5\u4e0a\u306e\u30d5\u30ea\u30fc\u30e9\u30f3\u30b9\u3092\u8f29\u51fa\u3057\u3066\u304d\u305f\u8d85\u5b9f\u8df5\u578b\u30d7\u30ed\u30b0\u30e9\u30df\u30f3\u30b0\u30b9\u30af\u30fc\u30eb\u3067\u3059\u3002150\u793e\u4ee5\u4e0a\u306e\u5b9f\u6848\u4ef6\u652f\u63f4\u3092\u7279\u5fb4\u306bWeb\u5236\u4f5c\u30fbWeb\u30c7\u30b6\u30a4\u30f3\u306a\u3069\u306e\u5f79\u7acb\u3064\u60c5\u5831\u3092\u73fe\u5834\u306e\u30ce\u30a6\u30cf\u30a6\u306b\u57fa\u3065\u3044\u3066\u767a\u4fe1\u3057\u3066\u3044\u304d\u307e\u3059\u3002\",\n      \"worksFor\": {\n        \"@id\": \"https:\/\/withcode.tech\/media\/#organization\"\n      },\n      \"@type\": \"Organization\"\n    },\n    {\n      \"@type\": \"BlogPosting\",\n      \"@id\": \"https:\/\/withcode.tech\/media\/langchain-webbaseloader-competitor-analysis\/#article\",\n      \"headline\": \"LangChain WebBaseLoader\u3067\u7af6\u5408\u30b5\u30a4\u30c8\u3092\u81ea\u52d5\u5206\u6790\u3059\u308b\u65b9\u6cd5\u3010\u5b8c\u5168\u30ac\u30a4\u30c9\u3011\uff5cPython\u5b9f\u88c5\u30b3\u30fc\u30c9\u4ed8\u304d\u5fb9\u5e95\u89e3\u8aac\",\n      \"mainEntityOfPage\": {\n        \"@type\": \"WebPage\",\n        \"@id\": \"https:\/\/withcode.tech\/media\/langchain-webbaseloader-competitor-analysis\/\"\n      },\n      \"datePublished\": \"2026-03-16T18:38:23Z\",\n      \"dateModified\": \"2026-07-06T14:36:50Z\",\n      \"author\": {\n        \"@id\": \"https:\/\/withcode.tech\/media\/author\/withcode-officialgmail-com\/#author\"\n      },\n      \"publisher\": {\n        \"@id\": \"https:\/\/withcode.tech\/media\/#organization\"\n      },\n      \"isPartOf\": {\n        \"@id\": \"https:\/\/withcode.tech\/media\/#website\"\n      },\n      \"inLanguage\": \"ja\",\n      \"description\": \"LangChain\u306eWebBaseLoader\u3092\u4f7f\u3048\u3070\u3001URL\u3092\u6e21\u3059\u3060\u3051\u3067\u7af6\u5408\u30b5\u30a4\u30c8\u306e\u30c6\u30ad\u30b9\u30c8\u3092\u81ea\u52d5\u62bd\u51fa\u3057AI\u3067\u5206\u6790\u3067\u304d\u307e\u3059\u3002\u8981\u7d04\u30fb\u30ad\u30fc\u30ef\u30fc\u30c9\u62bd\u51fa\u30fb\u6bd4\u8f03\u30ec\u30dd\u30fc\u30c8\u751f\u6210\u306e\u5b8c\u5168\u5b9f\u88c5\u30b3\u30fc\u30c9\u3068GitHub Actions\u5b9a\u671f\u5b9f\u884c\u307e\u3067\u5fb9\u5e95\u89e3\u8aac\u3057\u307e\u3059\u3002\",\n      \"image\": \"https:\/\/withcode.tech\/media\/wp-content\/uploads\/2026\/07\/13169-eyecatch.jpg\"\n    },\n    {\n      \"@type\": \"BreadcrumbList\",\n      \"@id\": \"https:\/\/withcode.tech\/media\/langchain-webbaseloader-competitor-analysis\/#breadcrumb\",\n      \"itemListElement\": [\n        {\n          \"@type\": \"ListItem\",\n          \"position\": 1,\n          \"name\": \"\u30db\u30fc\u30e0\",\n          \"item\": \"https:\/\/withcode.tech\/media\/\"\n        },\n        {\n          \"@type\": \"ListItem\",\n          \"position\": 2,\n          \"name\": \"AI\",\n          \"item\": \"https:\/\/withcode.tech\/media\/category\/ai\/\"\n        },\n        {\n          \"@type\": \"ListItem\",\n          \"position\": 3,\n          \"name\": \"LangChain WebBaseLoader\u3067\u7af6\u5408\u30b5\u30a4\u30c8\u3092\u81ea\u52d5\u5206\u6790\u3059\u308b\u65b9\u6cd5\u3010\u5b8c\u5168\u30ac\u30a4\u30c9\u3011\uff5cPython\u5b9f\u88c5\u30b3\u30fc\u30c9\u4ed8\u304d\u5fb9\u5e95\u89e3\u8aac\",\n          \"item\": \"https:\/\/withcode.tech\/media\/langchain-webbaseloader-competitor-analysis\/\"\n        }\n      ]\n    }\n  ]\n}\n<\/script>\n\n","protected":false},"excerpt":{"rendered":"<p>LangChain\u306eWebBaseLoader\u3092\u4f7f\u3048\u3070\u3001URL\u3092\u6e21\u3059\u3060\u3051\u3067\u7af6\u5408\u30b5\u30a4\u30c8\u306e\u30c6\u30ad\u30b9\u30c8\u3092\u81ea\u52d5\u62bd\u51fa\u3057AI\u3067\u5206\u6790\u3067\u304d\u307e\u3059\u3002\u8981\u7d04\u30fb\u30ad\u30fc\u30ef\u30fc\u30c9\u62bd\u51fa\u30fb\u6bd4\u8f03\u30ec\u30dd\u30fc\u30c8\u751f\u6210\u306e\u5b8c\u5168\u5b9f\u88c5\u30b3\u30fc\u30c9\u3068GitHub Actions\u5b9a\u671f\u5b9f\u884c\u307e\u3067\u5fb9\u5e95\u89e3\u8aac\u3057\u307e\u3059\u3002<\/p>\n","protected":false},"author":2,"featured_media":14272,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"swell_btn_cv_data":"","footnotes":"","vk-ltc-link":"","vk-ltc-target":"0"},"categories":[408],"tags":[],"class_list":["post-13169","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ai"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/withcode.tech\/media\/wp-json\/wp\/v2\/posts\/13169","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/withcode.tech\/media\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/withcode.tech\/media\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/withcode.tech\/media\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/withcode.tech\/media\/wp-json\/wp\/v2\/comments?post=13169"}],"version-history":[{"count":17,"href":"https:\/\/withcode.tech\/media\/wp-json\/wp\/v2\/posts\/13169\/revisions"}],"predecessor-version":[{"id":17851,"href":"https:\/\/withcode.tech\/media\/wp-json\/wp\/v2\/posts\/13169\/revisions\/17851"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/withcode.tech\/media\/wp-json\/wp\/v2\/media\/14272"}],"wp:attachment":[{"href":"https:\/\/withcode.tech\/media\/wp-json\/wp\/v2\/media?parent=13169"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/withcode.tech\/media\/wp-json\/wp\/v2\/categories?post=13169"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/withcode.tech\/media\/wp-json\/wp\/v2\/tags?post=13169"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}