@intlayer/docs 5.8.1-canary.0 → 6.0.0-canary.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/blog/ar/rag_powered_documentation_assistant.md +282 -0
- package/blog/de/rag_powered_documentation_assistant.md +282 -0
- package/blog/en/rag_powered_documentation_assistant.md +289 -0
- package/blog/en-GB/rag_powered_documentation_assistant.md +284 -0
- package/blog/es/rag_powered_documentation_assistant.md +308 -0
- package/blog/fr/rag_powered_documentation_assistant.md +308 -0
- package/blog/hi/rag_powered_documentation_assistant.md +284 -0
- package/blog/it/rag_powered_documentation_assistant.md +284 -0
- package/blog/ja/rag_powered_documentation_assistant.md +284 -0
- package/blog/ko/rag_powered_documentation_assistant.md +283 -0
- package/blog/pt/rag_powered_documentation_assistant.md +284 -0
- package/blog/ru/rag_powered_documentation_assistant.md +284 -0
- package/blog/tr/index.md +69 -0
- package/blog/tr/internationalization_and_SEO.md +273 -0
- package/blog/tr/intlayer_with_i18next.md +162 -0
- package/blog/tr/intlayer_with_next-i18next.md +367 -0
- package/blog/tr/intlayer_with_next-intl.md +392 -0
- package/blog/tr/intlayer_with_react-i18next.md +346 -0
- package/blog/tr/intlayer_with_react-intl.md +345 -0
- package/blog/tr/list_i18n_technologies/CMS/drupal.md +143 -0
- package/blog/tr/list_i18n_technologies/CMS/wix.md +167 -0
- package/blog/tr/list_i18n_technologies/CMS/wordpress.md +188 -0
- package/blog/tr/list_i18n_technologies/frameworks/angular.md +125 -0
- package/blog/tr/list_i18n_technologies/frameworks/flutter.md +150 -0
- package/blog/tr/list_i18n_technologies/frameworks/react-native.md +217 -0
- package/blog/tr/list_i18n_technologies/frameworks/react.md +155 -0
- package/blog/tr/list_i18n_technologies/frameworks/svelte.md +129 -0
- package/blog/tr/list_i18n_technologies/frameworks/vue.md +130 -0
- package/blog/tr/next-i18next_vs_next-intl_vs_intlayer.md +170 -0
- package/blog/tr/rag_powered_documentation_assistant.md +284 -0
- package/blog/tr/react-i18next_vs_react-intl_vs_intlayer.md +162 -0
- package/blog/tr/vue-i18n_vs_intlayer.md +276 -0
- package/blog/tr/what_is_internationalization.md +166 -0
- package/blog/zh/rag_powered_documentation_assistant.md +284 -0
- package/dist/cjs/generated/blog.entry.cjs +212 -0
- package/dist/cjs/generated/blog.entry.cjs.map +1 -1
- package/dist/cjs/generated/docs.entry.cjs +660 -132
- package/dist/cjs/generated/docs.entry.cjs.map +1 -1
- package/dist/cjs/generated/frequentQuestions.entry.cjs +84 -0
- package/dist/cjs/generated/frequentQuestions.entry.cjs.map +1 -1
- package/dist/cjs/generated/legal.entry.cjs +6 -0
- package/dist/cjs/generated/legal.entry.cjs.map +1 -1
- package/dist/esm/generated/blog.entry.mjs +212 -0
- package/dist/esm/generated/blog.entry.mjs.map +1 -1
- package/dist/esm/generated/docs.entry.mjs +660 -132
- package/dist/esm/generated/docs.entry.mjs.map +1 -1
- package/dist/esm/generated/frequentQuestions.entry.mjs +84 -0
- package/dist/esm/generated/frequentQuestions.entry.mjs.map +1 -1
- package/dist/esm/generated/legal.entry.mjs +6 -0
- package/dist/esm/generated/legal.entry.mjs.map +1 -1
- package/dist/types/generated/blog.entry.d.ts +1 -0
- package/dist/types/generated/blog.entry.d.ts.map +1 -1
- package/dist/types/generated/docs.entry.d.ts +5 -2
- package/dist/types/generated/docs.entry.d.ts.map +1 -1
- package/dist/types/generated/frequentQuestions.entry.d.ts.map +1 -1
- package/dist/types/generated/legal.entry.d.ts.map +1 -1
- package/docs/ar/autoFill.md +41 -40
- package/docs/ar/configuration.md +202 -199
- package/docs/ar/dictionary/content_file.md +1059 -0
- package/docs/ar/intlayer_CMS.md +4 -4
- package/docs/ar/intlayer_with_nestjs.md +271 -0
- package/docs/ar/intlayer_with_nextjs_page_router.md +1 -1
- package/docs/ar/intlayer_with_react_router_v7.md +533 -0
- package/docs/ar/intlayer_with_tanstack.md +465 -299
- package/docs/ar/intlayer_with_vite+preact.md +7 -7
- package/docs/ar/intlayer_with_vite+react.md +7 -7
- package/docs/ar/intlayer_with_vite+vue.md +9 -9
- package/docs/ar/packages/vite-intlayer/index.md +3 -3
- package/docs/ar/readme.md +261 -0
- package/docs/ar/testing.md +199 -0
- package/docs/de/autoFill.md +42 -19
- package/docs/de/configuration.md +155 -147
- package/docs/de/dictionary/content_file.md +1059 -0
- package/docs/de/intlayer_CMS.md +4 -5
- package/docs/de/intlayer_with_nestjs.md +270 -0
- package/docs/de/intlayer_with_nextjs_page_router.md +1 -1
- package/docs/de/intlayer_with_react_router_v7.md +537 -0
- package/docs/de/intlayer_with_tanstack.md +469 -302
- package/docs/de/intlayer_with_vite+preact.md +7 -7
- package/docs/de/intlayer_with_vite+react.md +7 -7
- package/docs/de/intlayer_with_vite+vue.md +9 -9
- package/docs/de/packages/vite-intlayer/index.md +3 -3
- package/docs/de/readme.md +261 -0
- package/docs/de/testing.md +200 -0
- package/docs/en/CI_CD.md +4 -6
- package/docs/en/autoFill.md +25 -5
- package/docs/en/configuration.md +45 -54
- package/docs/en/dictionary/content_file.md +1054 -0
- package/docs/en/intlayer_CMS.md +8 -7
- package/docs/en/intlayer_cli.md +112 -5
- package/docs/en/intlayer_with_nestjs.md +268 -0
- package/docs/en/intlayer_with_nextjs_page_router.md +1 -1
- package/docs/en/intlayer_with_react_router_v7.md +531 -0
- package/docs/en/intlayer_with_tanstack.md +463 -294
- package/docs/en/intlayer_with_vite+preact.md +8 -8
- package/docs/en/intlayer_with_vite+react.md +8 -8
- package/docs/en/intlayer_with_vite+vue.md +8 -8
- package/docs/en/packages/intlayer/getLocalizedUrl.md +102 -25
- package/docs/en/packages/vite-intlayer/index.md +3 -3
- package/docs/en/readme.md +261 -0
- package/docs/en/testing.md +200 -0
- package/docs/en-GB/autoFill.md +29 -6
- package/docs/en-GB/configuration.md +79 -71
- package/docs/en-GB/dictionary/content_file.md +1084 -0
- package/docs/en-GB/intlayer_CMS.md +4 -5
- package/docs/en-GB/intlayer_with_nestjs.md +268 -0
- package/docs/en-GB/intlayer_with_nextjs_page_router.md +1 -1
- package/docs/en-GB/intlayer_with_react_router_v7.md +533 -0
- package/docs/en-GB/intlayer_with_tanstack.md +466 -299
- package/docs/en-GB/intlayer_with_vite+preact.md +7 -7
- package/docs/en-GB/intlayer_with_vite+react.md +7 -7
- package/docs/en-GB/intlayer_with_vite+vue.md +9 -9
- package/docs/en-GB/packages/vite-intlayer/index.md +3 -3
- package/docs/en-GB/readme.md +261 -0
- package/docs/en-GB/testing.md +200 -0
- package/docs/es/autoFill.md +45 -23
- package/docs/es/configuration.md +171 -167
- package/docs/es/dictionary/content_file.md +1088 -0
- package/docs/es/intlayer_CMS.md +4 -5
- package/docs/es/intlayer_with_nestjs.md +268 -0
- package/docs/es/intlayer_with_nextjs_page_router.md +1 -1
- package/docs/es/intlayer_with_react_router_v7.md +533 -0
- package/docs/es/intlayer_with_tanstack.md +469 -280
- package/docs/es/intlayer_with_vite+preact.md +7 -7
- package/docs/es/intlayer_with_vite+react.md +7 -7
- package/docs/es/intlayer_with_vite+vue.md +9 -9
- package/docs/es/packages/vite-intlayer/index.md +3 -3
- package/docs/es/readme.md +261 -0
- package/docs/es/testing.md +200 -0
- package/docs/fr/autoFill.md +47 -24
- package/docs/fr/configuration.md +213 -198
- package/docs/fr/dictionary/content_file.md +1054 -0
- package/docs/fr/intlayer_CMS.md +4 -5
- package/docs/fr/intlayer_with_nestjs.md +268 -0
- package/docs/fr/intlayer_with_nextjs_page_router.md +1 -1
- package/docs/fr/intlayer_with_react_router_v7.md +549 -0
- package/docs/fr/intlayer_with_tanstack.md +465 -279
- package/docs/fr/intlayer_with_vite+preact.md +7 -7
- package/docs/fr/intlayer_with_vite+react.md +7 -7
- package/docs/fr/intlayer_with_vite+vue.md +9 -9
- package/docs/fr/packages/vite-intlayer/index.md +3 -3
- package/docs/fr/readme.md +261 -0
- package/docs/fr/testing.md +200 -0
- package/docs/hi/autoFill.md +47 -25
- package/docs/hi/configuration.md +194 -189
- package/docs/hi/dictionary/content_file.md +1056 -0
- package/docs/hi/intlayer_CMS.md +4 -5
- package/docs/hi/intlayer_with_nestjs.md +269 -0
- package/docs/hi/intlayer_with_nextjs_page_router.md +1 -1
- package/docs/hi/intlayer_with_react_router_v7.md +533 -0
- package/docs/hi/intlayer_with_tanstack.md +467 -282
- package/docs/hi/intlayer_with_vite+preact.md +7 -7
- package/docs/hi/intlayer_with_vite+react.md +7 -7
- package/docs/hi/intlayer_with_vite+vue.md +9 -9
- package/docs/hi/packages/vite-intlayer/index.md +3 -3
- package/docs/hi/readme.md +261 -0
- package/docs/hi/testing.md +200 -0
- package/docs/it/autoFill.md +46 -24
- package/docs/it/configuration.md +169 -161
- package/docs/it/dictionary/content_file.md +1061 -0
- package/docs/it/intlayer_CMS.md +4 -5
- package/docs/it/intlayer_with_nestjs.md +268 -0
- package/docs/it/intlayer_with_nextjs_page_router.md +1 -1
- package/docs/it/intlayer_with_react_router_v7.md +535 -0
- package/docs/it/intlayer_with_tanstack.md +467 -301
- package/docs/it/intlayer_with_vite+preact.md +7 -7
- package/docs/it/intlayer_with_vite+react.md +7 -7
- package/docs/it/intlayer_with_vite+vue.md +9 -9
- package/docs/it/packages/vite-intlayer/index.md +3 -3
- package/docs/it/readme.md +261 -0
- package/docs/it/testing.md +200 -0
- package/docs/ja/autoFill.md +45 -23
- package/docs/ja/configuration.md +243 -204
- package/docs/ja/dictionary/content_file.md +1064 -0
- package/docs/ja/intlayer_CMS.md +4 -5
- package/docs/ja/intlayer_with_nestjs.md +268 -0
- package/docs/ja/intlayer_with_nextjs_page_router.md +1 -1
- package/docs/ja/intlayer_with_react_router_v7.md +534 -0
- package/docs/ja/intlayer_with_tanstack.md +467 -303
- package/docs/ja/intlayer_with_vite+preact.md +7 -7
- package/docs/ja/intlayer_with_vite+react.md +7 -7
- package/docs/ja/intlayer_with_vite+vue.md +9 -9
- package/docs/ja/packages/vite-intlayer/index.md +3 -3
- package/docs/ja/readme.md +263 -0
- package/docs/ja/testing.md +200 -0
- package/docs/ko/autoFill.md +39 -16
- package/docs/ko/configuration.md +217 -197
- package/docs/ko/dictionary/content_file.md +1060 -0
- package/docs/ko/intlayer_CMS.md +4 -5
- package/docs/ko/intlayer_with_nestjs.md +268 -0
- package/docs/ko/intlayer_with_nextjs_page_router.md +1 -1
- package/docs/ko/intlayer_with_react_router_v7.md +540 -0
- package/docs/ko/intlayer_with_tanstack.md +466 -302
- package/docs/ko/intlayer_with_vite+preact.md +7 -7
- package/docs/ko/intlayer_with_vite+react.md +7 -7
- package/docs/ko/intlayer_with_vite+vue.md +9 -9
- package/docs/ko/packages/vite-intlayer/index.md +3 -3
- package/docs/ko/readme.md +261 -0
- package/docs/ko/testing.md +200 -0
- package/docs/pt/autoFill.md +39 -15
- package/docs/pt/configuration.md +165 -147
- package/docs/pt/dictionary/content_file.md +1062 -0
- package/docs/pt/intlayer_CMS.md +4 -5
- package/docs/pt/intlayer_with_nestjs.md +271 -0
- package/docs/pt/intlayer_with_nextjs_page_router.md +1 -1
- package/docs/pt/intlayer_with_react_router_v7.md +535 -0
- package/docs/pt/intlayer_with_tanstack.md +469 -300
- package/docs/pt/intlayer_with_vite+preact.md +7 -7
- package/docs/pt/intlayer_with_vite+react.md +7 -7
- package/docs/pt/intlayer_with_vite+vue.md +9 -9
- package/docs/pt/packages/vite-intlayer/index.md +3 -3
- package/docs/pt/readme.md +261 -0
- package/docs/pt/testing.md +200 -0
- package/docs/ru/autoFill.md +52 -30
- package/docs/ru/configuration.md +164 -117
- package/docs/ru/dictionary/content_file.md +1064 -0
- package/docs/ru/intlayer_CMS.md +4 -4
- package/docs/ru/intlayer_with_nestjs.md +270 -0
- package/docs/ru/intlayer_with_nextjs_page_router.md +1 -1
- package/docs/ru/intlayer_with_react_router_v7.md +534 -0
- package/docs/ru/intlayer_with_tanstack.md +470 -305
- package/docs/ru/intlayer_with_vite+preact.md +7 -7
- package/docs/ru/intlayer_with_vite+react.md +7 -7
- package/docs/ru/intlayer_with_vite+vue.md +9 -9
- package/docs/ru/packages/vite-intlayer/index.md +3 -3
- package/docs/ru/readme.md +261 -0
- package/docs/ru/testing.md +202 -0
- package/docs/tr/CI_CD.md +198 -0
- package/docs/tr/autoFill.md +201 -0
- package/docs/tr/configuration.md +585 -0
- package/docs/tr/dictionary/condition.md +243 -0
- package/docs/tr/dictionary/content_file.md +1055 -0
- package/docs/tr/dictionary/enumeration.md +251 -0
- package/docs/tr/dictionary/file.md +228 -0
- package/docs/tr/dictionary/function_fetching.md +218 -0
- package/docs/tr/dictionary/gender.md +279 -0
- package/docs/tr/dictionary/insertion.md +191 -0
- package/docs/tr/dictionary/markdown.md +385 -0
- package/docs/tr/dictionary/nesting.md +279 -0
- package/docs/tr/dictionary/translation.md +315 -0
- package/docs/tr/formatters.md +618 -0
- package/docs/tr/how_works_intlayer.md +254 -0
- package/docs/tr/index.md +168 -0
- package/docs/tr/interest_of_intlayer.md +288 -0
- package/docs/tr/intlayer_CMS.md +347 -0
- package/docs/tr/intlayer_cli.md +570 -0
- package/docs/tr/intlayer_visual_editor.md +269 -0
- package/docs/tr/intlayer_with_angular.md +694 -0
- package/docs/tr/intlayer_with_create_react_app.md +1218 -0
- package/docs/tr/intlayer_with_express.md +415 -0
- package/docs/tr/intlayer_with_lynx+react.md +511 -0
- package/docs/tr/intlayer_with_nestjs.md +268 -0
- package/docs/tr/intlayer_with_nextjs_14.md +1029 -0
- package/docs/tr/intlayer_with_nextjs_15.md +1506 -0
- package/docs/tr/intlayer_with_nextjs_page_router.md +1484 -0
- package/docs/tr/intlayer_with_nuxt.md +773 -0
- package/docs/tr/intlayer_with_react_native+expo.md +660 -0
- package/docs/tr/intlayer_with_react_router_v7.md +531 -0
- package/docs/tr/intlayer_with_tanstack.md +452 -0
- package/docs/tr/intlayer_with_vite+preact.md +1673 -0
- package/docs/tr/intlayer_with_vite+react.md +1632 -0
- package/docs/tr/intlayer_with_vite+solid.md +288 -0
- package/docs/tr/intlayer_with_vite+svelte.md +288 -0
- package/docs/tr/intlayer_with_vite+vue.md +1042 -0
- package/docs/tr/introduction.md +209 -0
- package/docs/tr/locale_mapper.md +244 -0
- package/docs/tr/mcp_server.md +207 -0
- package/docs/tr/packages/@intlayer/api/index.md +58 -0
- package/docs/tr/packages/@intlayer/chokidar/index.md +57 -0
- package/docs/tr/packages/@intlayer/cli/index.md +47 -0
- package/docs/tr/packages/@intlayer/config/index.md +142 -0
- package/docs/tr/packages/@intlayer/core/index.md +51 -0
- package/docs/tr/packages/@intlayer/design-system/index.md +47 -0
- package/docs/tr/packages/@intlayer/dictionary-entry/index.md +53 -0
- package/docs/tr/packages/@intlayer/editor/index.md +47 -0
- package/docs/tr/packages/@intlayer/editor-react/index.md +47 -0
- package/docs/tr/packages/@intlayer/webpack/index.md +61 -0
- package/docs/tr/packages/angular-intlayer/index.md +59 -0
- package/docs/tr/packages/express-intlayer/index.md +258 -0
- package/docs/tr/packages/express-intlayer/t.md +459 -0
- package/docs/tr/packages/intlayer/getConfiguration.md +151 -0
- package/docs/tr/packages/intlayer/getEnumeration.md +165 -0
- package/docs/tr/packages/intlayer/getHTMLTextDir.md +127 -0
- package/docs/tr/packages/intlayer/getLocaleLang.md +87 -0
- package/docs/tr/packages/intlayer/getLocaleName.md +124 -0
- package/docs/tr/packages/intlayer/getLocalizedUrl.md +324 -0
- package/docs/tr/packages/intlayer/getMultilingualUrls.md +225 -0
- package/docs/tr/packages/intlayer/getPathWithoutLocale.md +81 -0
- package/docs/tr/packages/intlayer/getTranslation.md +196 -0
- package/docs/tr/packages/intlayer/getTranslationContent.md +195 -0
- package/docs/tr/packages/intlayer/index.md +505 -0
- package/docs/tr/packages/intlayer-cli/index.md +71 -0
- package/docs/tr/packages/intlayer-editor/index.md +139 -0
- package/docs/tr/packages/lynx-intlayer/index.md +85 -0
- package/docs/tr/packages/next-intlayer/index.md +154 -0
- package/docs/tr/packages/next-intlayer/t.md +354 -0
- package/docs/tr/packages/next-intlayer/useDictionary.md +270 -0
- package/docs/tr/packages/next-intlayer/useIntlayer.md +265 -0
- package/docs/tr/packages/next-intlayer/useLocale.md +133 -0
- package/docs/tr/packages/nuxt-intlayer/index.md +59 -0
- package/docs/tr/packages/preact-intlayer/index.md +55 -0
- package/docs/tr/packages/react-intlayer/index.md +148 -0
- package/docs/tr/packages/react-intlayer/t.md +304 -0
- package/docs/tr/packages/react-intlayer/useDictionary.md +554 -0
- package/docs/tr/packages/react-intlayer/useI18n.md +478 -0
- package/docs/tr/packages/react-intlayer/useIntlayer.md +253 -0
- package/docs/tr/packages/react-intlayer/useLocale.md +212 -0
- package/docs/tr/packages/react-native-intlayer/index.md +85 -0
- package/docs/tr/packages/react-scripts-intlayer/index.md +82 -0
- package/docs/tr/packages/solid-intlayer/index.md +56 -0
- package/docs/tr/packages/svelte-intlayer/index.md +55 -0
- package/docs/tr/packages/vite-intlayer/index.md +82 -0
- package/docs/tr/packages/vue-intlayer/index.md +59 -0
- package/docs/tr/per_locale_file.md +321 -0
- package/docs/tr/readme.md +261 -0
- package/docs/tr/roadmap.md +338 -0
- package/docs/tr/testing.md +200 -0
- package/docs/tr/vs_code_extension.md +154 -0
- package/docs/zh/autoFill.md +40 -18
- package/docs/zh/configuration.md +245 -226
- package/docs/zh/dictionary/content_file.md +1064 -0
- package/docs/zh/intlayer_CMS.md +4 -5
- package/docs/zh/intlayer_with_nestjs.md +268 -0
- package/docs/zh/intlayer_with_nextjs_page_router.md +1 -1
- package/docs/zh/intlayer_with_react_router_v7.md +535 -0
- package/docs/zh/intlayer_with_tanstack.md +468 -278
- package/docs/zh/intlayer_with_vite+preact.md +7 -7
- package/docs/zh/intlayer_with_vite+react.md +7 -7
- package/docs/zh/intlayer_with_vite+vue.md +7 -7
- package/docs/zh/packages/vite-intlayer/index.md +3 -3
- package/docs/zh/readme.md +261 -0
- package/docs/zh/testing.md +198 -0
- package/frequent_questions/tr/SSR_Next_no_[locale].md +105 -0
- package/frequent_questions/tr/array_as_content_declaration.md +72 -0
- package/frequent_questions/tr/build_dictionaries.md +59 -0
- package/frequent_questions/tr/build_error_CI_CD.md +75 -0
- package/frequent_questions/tr/customized_locale_list.md +65 -0
- package/frequent_questions/tr/domain_routing.md +114 -0
- package/frequent_questions/tr/esbuild_error.md +30 -0
- package/frequent_questions/tr/get_locale_cookie.md +142 -0
- package/frequent_questions/tr/intlayer_command_undefined.md +156 -0
- package/frequent_questions/tr/locale_incorect_in_url.md +74 -0
- package/frequent_questions/tr/static_rendering.md +45 -0
- package/frequent_questions/tr/translated_path_url.md +56 -0
- package/frequent_questions/tr/unknown_command.md +98 -0
- package/legal/tr/privacy_notice.md +83 -0
- package/legal/tr/terms_of_service.md +55 -0
- package/package.json +13 -13
- package/src/generated/blog.entry.ts +212 -0
- package/src/generated/docs.entry.ts +663 -135
- package/src/generated/frequentQuestions.entry.ts +85 -1
- package/src/generated/legal.entry.ts +7 -1
- package/docs/ar/dictionary/content_extention_customization.md +0 -100
- package/docs/ar/dictionary/get_started.md +0 -527
- package/docs/de/dictionary/content_extention_customization.md +0 -100
- package/docs/de/dictionary/get_started.md +0 -531
- package/docs/en/dictionary/content_extention_customization.md +0 -102
- package/docs/en/dictionary/get_started.md +0 -529
- package/docs/en-GB/dictionary/content_extention_customization.md +0 -100
- package/docs/en-GB/dictionary/get_started.md +0 -591
- package/docs/es/dictionary/content_extention_customization.md +0 -100
- package/docs/es/dictionary/get_started.md +0 -527
- package/docs/fr/dictionary/content_extention_customization.md +0 -100
- package/docs/fr/dictionary/get_started.md +0 -527
- package/docs/hi/dictionary/content_extention_customization.md +0 -100
- package/docs/hi/dictionary/get_started.md +0 -527
- package/docs/it/dictionary/content_extention_customization.md +0 -113
- package/docs/it/dictionary/get_started.md +0 -573
- package/docs/ja/dictionary/content_extention_customization.md +0 -113
- package/docs/ja/dictionary/get_started.md +0 -576
- package/docs/ko/dictionary/content_extention_customization.md +0 -100
- package/docs/ko/dictionary/get_started.md +0 -530
- package/docs/pt/dictionary/content_extention_customization.md +0 -100
- package/docs/pt/dictionary/get_started.md +0 -532
- package/docs/ru/dictionary/content_extention_customization.md +0 -100
- package/docs/ru/dictionary/get_started.md +0 -575
- package/docs/zh/dictionary/content_extention_customization.md +0 -117
- package/docs/zh/dictionary/get_started.md +0 -533
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
---
|
|
2
|
+
createdAt: 2025-09-10
|
|
3
|
+
updatedAt: 2025-09-10
|
|
4
|
+
title: RAG搭載ドキュメントアシスタントの構築(チャンク分割、埋め込み、検索)
|
|
5
|
+
description: RAG搭載ドキュメントアシスタントの構築(チャンク分割、埋め込み、検索)
|
|
6
|
+
keywords:
|
|
7
|
+
- RAG
|
|
8
|
+
- ドキュメント
|
|
9
|
+
- アシスタント
|
|
10
|
+
- チャンク分割
|
|
11
|
+
- 埋め込み
|
|
12
|
+
- 検索
|
|
13
|
+
slugs:
|
|
14
|
+
- blog
|
|
15
|
+
- rag-powered-documentation-assistant
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
# RAG搭載ドキュメントアシスタントの構築(チャンク分割、埋め込み、検索)
|
|
19
|
+
|
|
20
|
+
## 得られるもの
|
|
21
|
+
|
|
22
|
+
私はRAG搭載のドキュメントアシスタントを構築し、すぐに使えるボイラープレートとしてパッケージ化しました。
|
|
23
|
+
|
|
24
|
+
- すぐに使えるアプリケーション(Next.js + OpenAI API)付き
|
|
25
|
+
- 動作するRAGパイプライン(チャンク分割、埋め込み、コサイン類似度)を含む
|
|
26
|
+
- Reactで構築された完全なチャットボットUIを提供
|
|
27
|
+
- すべてのUIコンポーネントはTailwind CSSで完全に編集可能
|
|
28
|
+
- すべてのユーザークエリをログに記録し、欠落しているドキュメント、ユーザーの問題点、製品の機会を特定するのに役立てる
|
|
29
|
+
|
|
30
|
+
👉 [ライブデモ](https://intlayer.org/doc/why) 👉 [コードボイラープレート](https://github.com/aymericzip/smart_doc_RAG)
|
|
31
|
+
|
|
32
|
+
## はじめに
|
|
33
|
+
|
|
34
|
+
ドキュメントの中で迷子になり、答えを探して延々とスクロールしたことがあるなら、その苦痛はよくわかるでしょう。ドキュメントは役に立ちますが、静的であり、検索も使いづらいことが多いです。
|
|
35
|
+
|
|
36
|
+
そこで登場するのが**RAG(Retrieval-Augmented Generation、検索強化生成)**です。ユーザーにテキストを掘り下げさせる代わりに、**検索**(ドキュメントの適切な部分を見つける)と**生成**(LLMが自然に説明する)を組み合わせることができます。
|
|
37
|
+
|
|
38
|
+
この投稿では、私がどのようにしてRAG搭載のドキュメントチャットボットを構築したか、そしてそれがユーザーがより速く答えを見つけるのを助けるだけでなく、プロダクトチームがユーザーの課題を理解する新しい方法を提供するかを説明します。
|
|
39
|
+
|
|
40
|
+
## なぜドキュメントにRAGを使うのか?
|
|
41
|
+
|
|
42
|
+
RAGが人気のアプローチになったのには理由があります。それは、大規模言語モデルを実際に役立てる最も実用的な方法の一つだからです。
|
|
43
|
+
|
|
44
|
+
ドキュメントにおける利点は明確です:
|
|
45
|
+
|
|
46
|
+
- 即時回答:ユーザーは自然言語で質問し、関連する回答を得られます。
|
|
47
|
+
- より良いコンテキスト:モデルは最も関連性の高いドキュメントの部分だけを参照するため、幻覚(誤情報)が減ります。
|
|
48
|
+
- 人間らしい検索体験:Algolia + FAQ + チャットボットを一つにまとめたような感覚です。
|
|
49
|
+
- フィードバックループ:クエリを保存することで、ユーザーが本当に困っていることを明らかにします。
|
|
50
|
+
|
|
51
|
+
その最後のポイントは非常に重要です。RAGシステムは単に質問に答えるだけでなく、人々が何を尋ねているのかを教えてくれます。つまり:
|
|
52
|
+
|
|
53
|
+
- ドキュメントに不足している情報を発見できます。
|
|
54
|
+
- 新たな機能リクエストが浮かび上がってきます。
|
|
55
|
+
- 製品戦略を導くパターンを見つけることもできます。
|
|
56
|
+
|
|
57
|
+
ですから、RAGは単なるサポートツールではありません。**プロダクト発見エンジン**でもあるのです。
|
|
58
|
+
|
|
59
|
+
## RAGパイプラインの仕組み
|
|
60
|
+
|
|
61
|
+

|
|
62
|
+
|
|
63
|
+
大まかに言うと、私が使ったレシピは以下の通りです:
|
|
64
|
+
|
|
65
|
+
1. **ドキュメントのチャンク分割** 大きなMarkdownファイルをチャンクに分割します。チャンク分割により、ドキュメントの関連部分だけをコンテキストとして提供できます。
|
|
66
|
+
2. **埋め込みの生成** 各チャンクをOpenAIの埋め込みAPI(text-embedding-3-large)やベクターデータベース(Chroma、Qdrant、Pinecone)を使ってベクトルに変換します。
|
|
67
|
+
3. **インデックス作成と保存** 埋め込みはシンプルなJSONファイルに保存されます(デモ用)が、本番環境ではベクターデータベースを使用することが多いでしょう。
|
|
68
|
+
4. **検索(RAGのR)** ユーザーのクエリを埋め込み、コサイン類似度を計算し、最もマッチするチャンクを取得します。
|
|
69
|
+
5. **拡張と生成(RAGのAG)** 取得したチャンクをChatGPTのプロンプトに注入し、モデルが実際のドキュメントの文脈を踏まえて回答します。
|
|
70
|
+
6. **フィードバックのためのクエリのログ記録** すべてのユーザークエリを保存します。これは問題点の把握、ドキュメントの不足、新たな機会の発見に非常に役立ちます。
|
|
71
|
+
|
|
72
|
+
## ステップ1: ドキュメントの読み込み
|
|
73
|
+
|
|
74
|
+
最初のステップはシンプルでした:docs/フォルダ内のすべての.mdファイルをスキャンする方法が必要でした。Node.jsとglobを使って、各Markdownファイルの内容をメモリに取得しました。
|
|
75
|
+
|
|
76
|
+
これによりパイプラインは柔軟になります。Markdownの代わりに、データベースやCMS、さらにはAPIからドキュメントを取得することも可能です。
|
|
77
|
+
|
|
78
|
+
## ステップ 2: ドキュメントのチャンク分割
|
|
79
|
+
|
|
80
|
+
なぜチャンク分割をするのか?それは言語モデルには**コンテキストの制限**があるからです。ドキュメント全体を一度に与えることはできません。
|
|
81
|
+
|
|
82
|
+
そこで、テキストを扱いやすいチャンク(例:各500トークン)に分割し、重複部分(例:100トークン)を設けます。重複部分は連続性を保ち、チャンクの境界で意味が失われないようにします。
|
|
83
|
+
|
|
84
|
+
**例:**
|
|
85
|
+
|
|
86
|
+
- チャンク1 → 「…多くの人が忘れていた古い図書館。そのそびえ立つ棚は本でいっぱいだった…」
|
|
87
|
+
- チャンク2 → 「…棚はあらゆるジャンルの本で満たされており、それぞれが物語をささやいていた…」
|
|
88
|
+
|
|
89
|
+
重複部分により、両方のチャンクが共通のコンテキストを含むため、検索時の一貫性が保たれます。
|
|
90
|
+
|
|
91
|
+
このトレードオフ(チャンクサイズとオーバーラップのバランス)は、RAGの効率性にとって重要です:
|
|
92
|
+
|
|
93
|
+
- 小さすぎると → ノイズが増えます。
|
|
94
|
+
- 大きすぎると → コンテキストサイズが膨れ上がります。
|
|
95
|
+
|
|
96
|
+
## ステップ3:埋め込みの生成
|
|
97
|
+
|
|
98
|
+
ドキュメントをチャンクに分割したら、各チャンクを表す高次元ベクトルである**埋め込み**を生成します。
|
|
99
|
+
|
|
100
|
+
私はOpenAIのtext-embedding-3-largeモデルを使用しましたが、任意の最新の埋め込みモデルを使うことができます。
|
|
101
|
+
|
|
102
|
+
**埋め込みの例:**
|
|
103
|
+
|
|
104
|
+
```js
|
|
105
|
+
[
|
|
106
|
+
-0.0002630692, -0.029749284, 0.010225477, -0.009224428, -0.0065269712,
|
|
107
|
+
-0.002665544, 0.003214777, 0.04235309, -0.033162255, -0.00080789323,
|
|
108
|
+
//...+1533 elements
|
|
109
|
+
];
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
各ベクトルはテキストの数学的な指紋であり、類似検索を可能にします。
|
|
113
|
+
|
|
114
|
+
## ステップ4:埋め込みのインデックス作成と保存
|
|
115
|
+
|
|
116
|
+
埋め込みを何度も再生成しないように、embeddings.jsonに保存しました。
|
|
117
|
+
|
|
118
|
+
本番環境では、以下のようなベクトルデータベースを使用することが一般的です:
|
|
119
|
+
|
|
120
|
+
- Chroma
|
|
121
|
+
- Qdrant
|
|
122
|
+
- Pinecone
|
|
123
|
+
- FAISS、Weaviate、Milvusなど
|
|
124
|
+
|
|
125
|
+
ベクトルDBはインデックス作成、スケーラビリティ、高速検索を処理します。しかし、私のプロトタイプではローカルのJSONで十分でした。
|
|
126
|
+
|
|
127
|
+
## ステップ5:コサイン類似度による検索
|
|
128
|
+
|
|
129
|
+
ユーザーが質問をしたとき:
|
|
130
|
+
|
|
131
|
+
1. クエリの埋め込みを生成する。
|
|
132
|
+
2. すべてのドキュメント埋め込みと**コサイン類似度**で比較する。
|
|
133
|
+
3. 最も類似度の高い上位N個のチャンクだけを保持する。
|
|
134
|
+
|
|
135
|
+
コサイン類似度は2つのベクトル間の角度を測定します。完全一致は**1.0**のスコアです。
|
|
136
|
+
|
|
137
|
+
この方法で、システムはクエリに最も近いドキュメントの部分を見つけます。
|
|
138
|
+
|
|
139
|
+
## ステップ6:拡張+生成
|
|
140
|
+
|
|
141
|
+
ここで魔法が始まります。上位のチャンクを取り出し、それらをChatGPTの**システムプロンプト**に注入します。
|
|
142
|
+
|
|
143
|
+
それは、モデルがまるでそれらのチャンクが会話の一部であるかのように回答することを意味します。
|
|
144
|
+
|
|
145
|
+
結果:正確で、**ドキュメントに基づいた応答**。
|
|
146
|
+
|
|
147
|
+
## ステップ7:ユーザークエリのログ記録
|
|
148
|
+
|
|
149
|
+
これが隠れたスーパーパワーです。
|
|
150
|
+
|
|
151
|
+
ユーザーが尋ねたすべての質問が保存されます。時間が経つにつれて、以下のようなデータセットが構築されます:
|
|
152
|
+
|
|
153
|
+
- 最も頻繁に尋ねられる質問(FAQに最適)
|
|
154
|
+
- 未回答の質問(ドキュメントが不足しているか不明瞭)
|
|
155
|
+
- 質問に偽装された機能リクエスト(「Xと統合できますか?」など)
|
|
156
|
+
- 予期していなかった新たなユースケース
|
|
157
|
+
|
|
158
|
+
これにより、あなたのRAGアシスタントは**継続的なユーザーリサーチツール**に変わります。
|
|
159
|
+
|
|
160
|
+
## コストはどのくらいかかるのか?
|
|
161
|
+
|
|
162
|
+
RAGに対する一般的な反論の一つはコストですが、実際には驚くほど安価です:
|
|
163
|
+
|
|
164
|
+
- 約200件のドキュメントの埋め込み生成は約**5分**で、費用は**1〜2ユーロ**程度です。
|
|
165
|
+
- ドキュメント検索機能は100%無料です。
|
|
166
|
+
- クエリには「thinking」モードなしで gpt-4o-latest を使用しています。Intlayer では、月に約 **300 件のチャットクエリ** があり、OpenAI API の請求額はめったに **10ドル** を超えません。
|
|
167
|
+
|
|
168
|
+
その上に、ホスティングコストを含めることができます。
|
|
169
|
+
|
|
170
|
+
## 実装の詳細
|
|
171
|
+
|
|
172
|
+
スタック:
|
|
173
|
+
|
|
174
|
+
- モノレポ: pnpm ワークスペース
|
|
175
|
+
- ドキュメントパッケージ: Node.js / TypeScript / OpenAI API
|
|
176
|
+
- フロントエンド: Next.js / React / Tailwind CSS
|
|
177
|
+
- バックエンド: Node.js API ルート / OpenAI API
|
|
178
|
+
|
|
179
|
+
`@smart-doc/docs` パッケージはドキュメント処理を担当する TypeScript パッケージです。Markdown ファイルが追加または変更されると、このパッケージには各言語のドキュメントリストを再構築し、埋め込みを生成し、それらを `embeddings.json` ファイルに保存する `build` スクリプトが含まれています。
|
|
180
|
+
|
|
181
|
+
フロントエンドには、以下を提供する Next.js アプリケーションを使用しています:
|
|
182
|
+
|
|
183
|
+
- MarkdownをHTMLにレンダリングする機能
|
|
184
|
+
- 関連するドキュメントを検索するための検索バー
|
|
185
|
+
- ドキュメントに関する質問を行うためのチャットボットインターフェース
|
|
186
|
+
|
|
187
|
+
ドキュメント検索を実行するために、Next.jsアプリケーションにはAPIルートが含まれており、`@smart-doc/docs`パッケージの関数を呼び出してクエリに一致するドキュメントチャンクを取得します。これらのチャンクを使用して、ユーザーの検索に関連するドキュメントページのリストを返すことができます。
|
|
188
|
+
|
|
189
|
+
チャットボット機能については、同じ検索プロセスを踏みますが、取得したドキュメントチャンクをChatGPTに送信するプロンプトに追加で注入します。
|
|
190
|
+
|
|
191
|
+
以下はChatGPTに送信されるプロンプトの例です:
|
|
192
|
+
|
|
193
|
+
システムプロンプト:
|
|
194
|
+
|
|
195
|
+
```txt
|
|
196
|
+
あなたはIntlayerのドキュメントに関する質問に答えることができる有用なアシスタントです。
|
|
197
|
+
|
|
198
|
+
関連チャンク:
|
|
199
|
+
|
|
200
|
+
-----
|
|
201
|
+
docName: "getting-started"
|
|
202
|
+
docChunk: "1/3"
|
|
203
|
+
docUrl: "https://example.com/docs/ja/getting-started"
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
# はじめに
|
|
207
|
+
|
|
208
|
+
...
|
|
209
|
+
|
|
210
|
+
-----
|
|
211
|
+
docName: "another-doc"
|
|
212
|
+
docChunk: "1/5"
|
|
213
|
+
docUrl: "https://example.com/docs/ja/another-doc"
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
# 別のドキュメント
|
|
217
|
+
|
|
218
|
+
...
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
ユーザーのクエリ:
|
|
222
|
+
|
|
223
|
+
```txt
|
|
224
|
+
はじめにどうすればいいですか?
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
APIルートからのレスポンスはSSEを使ってストリーミングします。
|
|
228
|
+
|
|
229
|
+
前述の通り、"thinking"モードなしでgpt-4-turboを使用しています。応答は関連性が高く、レイテンシも低いです。
|
|
230
|
+
gpt-5も試しましたが、レイテンシが高すぎました(返信に最大15秒かかることもありました)。しかし将来的に再検討する予定です。
|
|
231
|
+
|
|
232
|
+
👉 [ここでデモを試す](https://intlayer.org/doc/why) 👉 [GitHubでコードテンプレートを確認](https://github.com/aymericzip/smart_doc_RAG)
|
|
233
|
+
|
|
234
|
+
## さらに進むために
|
|
235
|
+
|
|
236
|
+
このプロジェクトは最小限の実装です。しかし、以下のように多くの方法で拡張できます:
|
|
237
|
+
|
|
238
|
+
- MCPサーバー → ドキュメント検索機能をMCPサーバーに移行し、ドキュメントをあらゆるAIアシスタントに接続可能にする
|
|
239
|
+
|
|
240
|
+
- ベクターデータベース → 数百万のドキュメントチャンクにスケール可能
|
|
241
|
+
- LangChain / LlamaIndex → RAGパイプライン用の既製フレームワーク
|
|
242
|
+
- 分析ダッシュボード → ユーザーのクエリや問題点を可視化
|
|
243
|
+
- マルチソース検索 → ドキュメントだけでなく、データベースのエントリ、ブログ投稿、チケットなども取得可能
|
|
244
|
+
- 改良されたプロンプティング → 再ランキング、フィルタリング、ハイブリッド検索(キーワード+セマンティック)
|
|
245
|
+
|
|
246
|
+
## 直面した制限事項
|
|
247
|
+
|
|
248
|
+
- チャンク分割と重複は経験則に基づく。適切なバランス(チャンクサイズ、重複率、取得チャンク数)は反復とテストが必要。
|
|
249
|
+
- ドキュメントが変更されても埋め込みは自動再生成されない。システムは、保存されているチャンク数と異なる場合にのみファイルの埋め込みをリセットする。
|
|
250
|
+
- このプロトタイプでは、埋め込みはJSONに保存されています。これはデモには適していますが、Gitを汚染します。本番環境では、データベースや専用のベクターストアの方が適しています。
|
|
251
|
+
|
|
252
|
+
## ドキュメントを超えて重要な理由
|
|
253
|
+
|
|
254
|
+
興味深いのは単なるチャットボットだけではありません。**フィードバックループ**です。
|
|
255
|
+
|
|
256
|
+
RAGを使うと、単に答えるだけではなく:
|
|
257
|
+
|
|
258
|
+
- ユーザーが何に混乱しているかを学びます。
|
|
259
|
+
- 彼らがどの機能を期待しているかを発見します。
|
|
260
|
+
- 実際のクエリに基づいて製品戦略を適応させます。
|
|
261
|
+
|
|
262
|
+
**例:**
|
|
263
|
+
|
|
264
|
+
新機能をリリースしてすぐに以下がわかると想像してください:
|
|
265
|
+
|
|
266
|
+
- 質問の50%が同じ不明瞭なセットアップ手順に関するもの
|
|
267
|
+
- ユーザーがまだサポートしていない統合を繰り返し求める
|
|
268
|
+
- 新しいユースケースを示す用語で検索される
|
|
269
|
+
|
|
270
|
+
それがユーザーから直接得られる**プロダクトインテリジェンス**です。
|
|
271
|
+
|
|
272
|
+
## 結論
|
|
273
|
+
|
|
274
|
+
RAGは、LLMを実用的にする最もシンプルで強力な方法の一つです。**検索(retrieval)+生成(generation)**を組み合わせることで、静的なドキュメントを**スマートアシスタント**に変え、同時に継続的な製品インサイトの流れを得ることができます。
|
|
275
|
+
|
|
276
|
+
私にとって、このプロジェクトはRAGが単なる技術的なトリックではないことを示しました。RAGはドキュメントを以下のように変革する方法です:
|
|
277
|
+
|
|
278
|
+
- インタラクティブなサポートシステム
|
|
279
|
+
- フィードバックチャネル
|
|
280
|
+
- 製品戦略ツール
|
|
281
|
+
|
|
282
|
+
👉 [ここでデモを試す](https://intlayer.org/doc/why) 👉 [GitHubでコードテンプレートを確認する](https://github.com/aymericzip/smart_doc_RAG)
|
|
283
|
+
|
|
284
|
+
もしあなたもRAGを試しているなら、どのように使っているかぜひ教えてください。
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
---
|
|
2
|
+
createdAt: 2025-09-10
|
|
3
|
+
updatedAt: 2025-09-10
|
|
4
|
+
title: RAG 기반 문서 지원 도우미 구축하기 (청킹, 임베딩, 검색)
|
|
5
|
+
description: RAG 기반 문서 지원 도우미 구축하기 (청킹, 임베딩, 검색)
|
|
6
|
+
keywords:
|
|
7
|
+
- RAG
|
|
8
|
+
- 문서
|
|
9
|
+
- 도우미
|
|
10
|
+
- 청킹
|
|
11
|
+
- 임베딩
|
|
12
|
+
- 검색
|
|
13
|
+
slugs:
|
|
14
|
+
- blog
|
|
15
|
+
- rag-powered-documentation-assistant
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
# RAG 기반 문서 지원 도우미 구축하기 (청킹, 임베딩, 검색)
|
|
19
|
+
|
|
20
|
+
## 제공 내용
|
|
21
|
+
|
|
22
|
+
저는 RAG 기반 문서 지원 도우미를 구축하고, 즉시 사용할 수 있는 보일러플레이트로 패키징했습니다.
|
|
23
|
+
|
|
24
|
+
- 즉시 사용 가능한 애플리케이션 포함 (Next.js + OpenAI API)
|
|
25
|
+
- 작동하는 RAG 파이프라인 포함 (청킹, 임베딩, 코사인 유사도)
|
|
26
|
+
- React로 구축된 완전한 챗봇 UI 제공
|
|
27
|
+
- 모든 UI 컴포넌트는 Tailwind CSS로 완전히 편집 가능합니다.
|
|
28
|
+
- 모든 사용자 쿼리를 기록하여 누락된 문서, 사용자 불편 사항 및 제품 기회를 식별하는 데 도움을 줍니다.
|
|
29
|
+
|
|
30
|
+
👉 [라이브 데모](https://intlayer.org/doc/why) 👉 [코드 보일러플레이트](https://github.com/aymericzip/smart_doc_RAG)
|
|
31
|
+
|
|
32
|
+
## 소개
|
|
33
|
+
|
|
34
|
+
문서에서 답을 찾으려고 끝없이 스크롤하다가 길을 잃은 적이 있다면, 그 고통이 얼마나 큰지 아실 겁니다. 문서는 유용하지만 정적이고, 검색하는 것이 종종 불편하게 느껴집니다.
|
|
35
|
+
|
|
36
|
+
바로 이때 **RAG (검색 증강 생성, Retrieval-Augmented Generation)** 이 등장합니다. 사용자가 텍스트를 뒤지도록 강요하는 대신, **검색** (문서의 적절한 부분 찾기)과 **생성** (LLM이 자연스럽게 설명하기)을 결합할 수 있습니다.
|
|
37
|
+
|
|
38
|
+
이 글에서는 제가 어떻게 RAG 기반 문서 챗봇을 만들었는지, 그리고 그것이 단순히 사용자가 더 빠르게 답을 찾도록 돕는 것뿐만 아니라 제품 팀이 사용자 고충을 이해하는 새로운 방법을 제공하는지 설명하겠습니다.
|
|
39
|
+
|
|
40
|
+
## 왜 문서에 RAG를 사용할까?
|
|
41
|
+
|
|
42
|
+
RAG가 인기 있는 접근법이 된 데는 이유가 있습니다. 대형 언어 모델을 실제로 유용하게 만드는 가장 실용적인 방법 중 하나이기 때문입니다.
|
|
43
|
+
|
|
44
|
+
문서에 있어서 그 이점은 명확합니다:
|
|
45
|
+
|
|
46
|
+
- 즉각적인 답변: 사용자가 자연어로 질문하면 관련된 답변을 받습니다.
|
|
47
|
+
- 더 나은 맥락: 모델은 가장 관련성 높은 문서 부분만 보기 때문에 환각 현상이 줄어듭니다.
|
|
48
|
+
- 인간적인 검색 경험: Algolia + FAQ + 챗봇이 하나로 합쳐진 느낌입니다.
|
|
49
|
+
- 피드백 루프: 쿼리를 저장함으로써 사용자가 실제로 어려워하는 점을 파악할 수 있습니다.
|
|
50
|
+
|
|
51
|
+
그 마지막 점이 매우 중요합니다. RAG 시스템은 단순히 질문에 답하는 것뿐만 아니라 사람들이 무엇을 묻고 있는지 알려줍니다. 이는 다음을 의미합니다:
|
|
52
|
+
|
|
53
|
+
- 문서에서 누락된 정보를 발견할 수 있습니다.
|
|
54
|
+
- 기능 요청이 나타나는 것을 볼 수 있습니다.
|
|
55
|
+
- 제품 전략을 안내할 수 있는 패턴을 발견할 수 있습니다.
|
|
56
|
+
|
|
57
|
+
따라서 RAG는 단순한 지원 도구가 아닙니다. 그것은 또한 **제품 발견 엔진**입니다.
|
|
58
|
+
|
|
59
|
+
## RAG 파이프라인 작동 방식
|
|
60
|
+
|
|
61
|
+

|
|
62
|
+
|
|
63
|
+
전체적인 개요는 다음과 같습니다:
|
|
64
|
+
|
|
65
|
+
1. **문서 청킹(Chunking)** 큰 마크다운 파일을 여러 청크로 분할합니다. 청킹은 문서의 관련된 부분만 컨텍스트로 제공할 수 있게 합니다.
|
|
66
|
+
2. **임베딩 생성(Generating embeddings)** 각 청크는 OpenAI의 임베딩 API(text-embedding-3-large) 또는 벡터 데이터베이스(Chroma, Qdrant, Pinecone)를 사용해 벡터로 변환됩니다.
|
|
67
|
+
3. **인덱싱 및 저장** 임베딩은 간단한 JSON 파일에 저장됩니다(데모용). 하지만 실제 운영 환경에서는 벡터 DB를 사용할 가능성이 높습니다.
|
|
68
|
+
4. **검색 (RAG의 R)** 사용자 쿼리를 임베딩하고, 코사인 유사도를 계산하여 가장 일치하는 청크들을 검색합니다.
|
|
69
|
+
5. **증강 및 생성 (RAG의 AG)** 해당 청크들을 ChatGPT 프롬프트에 주입하여, 모델이 실제 문서 컨텍스트를 기반으로 답변하도록 합니다.
|
|
70
|
+
6. **피드백을 위한 쿼리 기록** 모든 사용자 쿼리를 저장합니다. 이는 문제점 파악, 누락된 문서, 새로운 기회를 이해하는 데 매우 중요합니다.
|
|
71
|
+
|
|
72
|
+
## 1단계: 문서 읽기
|
|
73
|
+
|
|
74
|
+
첫 번째 단계는 간단했습니다: docs/ 폴더 내 모든 .md 파일을 스캔할 방법이 필요했습니다. Node.js와 glob을 사용하여 각 마크다운 파일의 내용을 메모리로 가져왔습니다.
|
|
75
|
+
|
|
76
|
+
이것은 파이프라인을 유연하게 유지합니다: Markdown 대신 데이터베이스, CMS, 또는 API에서 문서를 가져올 수도 있습니다.
|
|
77
|
+
|
|
78
|
+
## 2단계: 문서 청킹(Chunking)
|
|
79
|
+
|
|
80
|
+
왜 청킹을 할까요? 언어 모델에는 **컨텍스트 제한**이 있기 때문입니다. 전체 문서 책을 한 번에 입력하는 것은 불가능합니다.
|
|
81
|
+
|
|
82
|
+
그래서 텍스트를 관리 가능한 청크(예: 각 500 토큰)로 나누고, 겹치는 부분(예: 100 토큰)을 둡니다. 겹치는 부분은 청크 경계에서 의미가 끊기지 않도록 연속성을 보장합니다.
|
|
83
|
+
|
|
84
|
+
**예시:**
|
|
85
|
+
|
|
86
|
+
- 청크 1 → “…많은 이들이 잊어버린 오래된 도서관. 그 높이 솟은 선반들은 책들로 가득 차 있었다…”
|
|
87
|
+
- 청크 2 → “…선반들은 상상할 수 있는 모든 장르의 책들로 가득 차 있었고, 각각이 이야기를 속삭이고 있었다…”
|
|
88
|
+
|
|
89
|
+
이 겹침은 두 청크가 공유된 컨텍스트를 포함하도록 하여, 검색 시 일관성을 유지하게 합니다.
|
|
90
|
+
|
|
91
|
+
이 절충안(청크 크기 대 중첩)은 RAG 효율성에 매우 중요합니다:
|
|
92
|
+
|
|
93
|
+
- 너무 작으면 → 노이즈가 발생합니다.
|
|
94
|
+
- 너무 크면 → 컨텍스트 크기가 너무 커집니다.
|
|
95
|
+
|
|
96
|
+
## 3단계: 임베딩 생성
|
|
97
|
+
|
|
98
|
+
문서가 청크로 나뉘면, 각 청크를 나타내는 고차원 벡터인 **임베딩**을 생성합니다.
|
|
99
|
+
|
|
100
|
+
저는 OpenAI의 text-embedding-3-large 모델을 사용했지만, 최신 임베딩 모델이라면 어떤 것이든 사용할 수 있습니다.
|
|
101
|
+
|
|
102
|
+
**임베딩 예시:**
|
|
103
|
+
|
|
104
|
+
```js
|
|
105
|
+
[
|
|
106
|
+
-0.0002630692, -0.029749284, 0.010225477, -0.009224428, -0.0065269712,
|
|
107
|
+
-0.002665544, 0.003214777, 0.04235309, -0.033162255, -0.00080789323,
|
|
108
|
+
//...+1533 elements
|
|
109
|
+
];
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
각 벡터는 텍스트의 수학적 지문으로, 유사도 검색을 가능하게 합니다.
|
|
113
|
+
|
|
114
|
+
## 4단계: 임베딩 인덱싱 및 저장
|
|
115
|
+
|
|
116
|
+
임베딩을 여러 번 다시 생성하지 않도록, 저는 이를 embeddings.json에 저장했습니다.
|
|
117
|
+
|
|
118
|
+
프로덕션 환경에서는 다음과 같은 벡터 데이터베이스를 사용하는 것이 좋습니다:
|
|
119
|
+
|
|
120
|
+
- Chroma
|
|
121
|
+
- Qdrant
|
|
122
|
+
- Pinecone
|
|
123
|
+
- FAISS, Weaviate, Milvus 등
|
|
124
|
+
|
|
125
|
+
벡터 DB는 인덱싱, 확장성, 빠른 검색을 처리합니다. 하지만 제 프로토타입에서는 로컬 JSON으로도 충분했습니다.
|
|
126
|
+
|
|
127
|
+
## 5단계: 코사인 유사도를 이용한 검색
|
|
128
|
+
|
|
129
|
+
사용자가 질문을 하면:
|
|
130
|
+
|
|
131
|
+
1. 쿼리에 대한 임베딩을 생성합니다.
|
|
132
|
+
2. 모든 문서 임베딩과 **코사인 유사도**를 사용해 비교합니다.
|
|
133
|
+
3. 가장 유사한 상위 N개의 청크만 유지합니다.
|
|
134
|
+
|
|
135
|
+
코사인 유사도는 두 벡터 사이의 각도를 측정합니다. 완벽한 일치는 **1.0** 점수를 받습니다.
|
|
136
|
+
|
|
137
|
+
이렇게 시스템은 쿼리와 가장 가까운 문서 구간을 찾습니다.
|
|
138
|
+
|
|
139
|
+
## 6단계: 증강 + 생성
|
|
140
|
+
|
|
141
|
+
이제 마법이 시작됩니다. 상위 청크들을 가져와 ChatGPT의 **시스템 프롬프트**에 주입합니다.
|
|
142
|
+
|
|
143
|
+
그것은 모델이 마치 해당 청크들이 대화의 일부인 것처럼 답변한다는 의미입니다.
|
|
144
|
+
|
|
145
|
+
결과: 정확하고, **문서 기반의 응답**.
|
|
146
|
+
|
|
147
|
+
## 7단계: 사용자 쿼리 기록
|
|
148
|
+
|
|
149
|
+
이것이 숨겨진 슈퍼파워입니다.
|
|
150
|
+
|
|
151
|
+
모든 질문이 저장됩니다. 시간이 지나면서 다음과 같은 데이터셋을 구축할 수 있습니다:
|
|
152
|
+
|
|
153
|
+
- 가장 빈번한 질문들 (FAQ에 매우 유용)
|
|
154
|
+
- 답변되지 않은 질문들 (문서가 없거나 불명확한 경우)
|
|
155
|
+
- 질문으로 위장된 기능 요청 (“X와 통합되나요?”)
|
|
156
|
+
- 예상치 못한 새로운 사용 사례
|
|
157
|
+
|
|
158
|
+
이로써 당신의 RAG 어시스턴트는 **지속적인 사용자 조사 도구**가 됩니다.
|
|
159
|
+
|
|
160
|
+
## 비용은 얼마나 들까?
|
|
161
|
+
|
|
162
|
+
RAG에 대한 흔한 반대 의견 중 하나는 비용입니다. 실제로는 놀라울 정도로 저렴합니다:
|
|
163
|
+
|
|
164
|
+
- 약 200개의 문서에 대한 임베딩 생성은 약 **5분**이 걸리며 비용은 **1~2 유로**입니다.
|
|
165
|
+
- 문서 검색 기능은 100% 무료입니다.
|
|
166
|
+
- 쿼리의 경우, “thinking” 모드 없이 gpt-4o-latest를 사용합니다. Intlayer에서는 한 달에 약 **300건의 채팅 쿼리**가 발생하며, OpenAI API 요금은 거의 **$10**를 넘지 않습니다.
|
|
167
|
+
|
|
168
|
+
여기에 호스팅 비용을 포함할 수 있습니다.
|
|
169
|
+
|
|
170
|
+
## 구현 세부사항
|
|
171
|
+
|
|
172
|
+
스택:
|
|
173
|
+
|
|
174
|
+
- 모노레포: pnpm 워크스페이스
|
|
175
|
+
- 문서 패키지: Node.js / TypeScript / OpenAI API
|
|
176
|
+
- 프론트엔드: Next.js / React / Tailwind CSS
|
|
177
|
+
- 백엔드: Node.js API 라우트 / OpenAI API
|
|
178
|
+
|
|
179
|
+
`@smart-doc/docs` 패키지는 문서 처리를 담당하는 TypeScript 패키지입니다. 마크다운 파일이 추가되거나 수정되면, 이 패키지는 각 언어별 문서 목록을 재구성하고 임베딩을 생성하여 `embeddings.json` 파일에 저장하는 `build` 스크립트를 포함합니다.
|
|
180
|
+
|
|
181
|
+
프론트엔드에는 다음 기능을 제공하는 Next.js 애플리케이션을 사용합니다:
|
|
182
|
+
|
|
183
|
+
- 마크다운을 HTML로 렌더링
|
|
184
|
+
- 관련 문서를 찾기 위한 검색 바
|
|
185
|
+
- 문서에 대한 질문을 할 수 있는 챗봇 인터페이스
|
|
186
|
+
|
|
187
|
+
문서 검색을 수행하기 위해, Next.js 애플리케이션은 쿼리에 맞는 문서 청크를 검색하는 `@smart-doc/docs` 패키지의 함수를 호출하는 API 라우트를 포함합니다. 이 청크들을 사용하여 사용자의 검색과 관련된 문서 페이지 목록을 반환할 수 있습니다.
|
|
188
|
+
|
|
189
|
+
챗봇 기능의 경우, 동일한 검색 과정을 따르지만 추가로 검색된 문서 청크를 ChatGPT에 보내는 프롬프트에 주입합니다.
|
|
190
|
+
|
|
191
|
+
다음은 ChatGPT에 보내는 프롬프트 예시입니다:
|
|
192
|
+
|
|
193
|
+
시스템 프롬프트:
|
|
194
|
+
|
|
195
|
+
```txt
|
|
196
|
+
당신은 Intlayer 문서에 관한 질문에 답변할 수 있는 유용한 도우미입니다.
|
|
197
|
+
|
|
198
|
+
관련 청크:
|
|
199
|
+
|
|
200
|
+
-----
|
|
201
|
+
docName: "getting-started"
|
|
202
|
+
docChunk: "1/3"
|
|
203
|
+
docUrl: "https://example.com/docs/ko/getting-started"
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
# 시작하는 방법
|
|
207
|
+
|
|
208
|
+
...
|
|
209
|
+
|
|
210
|
+
-----
|
|
211
|
+
docName: "another-doc"
|
|
212
|
+
docChunk: "1/5"
|
|
213
|
+
docUrl: "https://example.com/docs/ko/another-doc"
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
# 다른 문서
|
|
217
|
+
|
|
218
|
+
...
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
사용자 질의 :
|
|
222
|
+
|
|
223
|
+
```txt
|
|
224
|
+
시작하는 방법은?
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
우리는 API 경로에서 응답을 스트리밍하기 위해 SSE를 사용합니다.
|
|
228
|
+
|
|
229
|
+
앞서 언급했듯이, 우리는 "생각하는" 모드 없이 gpt-4-turbo를 사용합니다. 응답은 관련성이 높고 지연 시간이 낮습니다.
|
|
230
|
+
gpt-5도 실험해 보았지만, 지연 시간이 너무 길었고(때로는 응답에 최대 15초까지 걸림) 앞으로 다시 검토할 예정입니다.
|
|
231
|
+
|
|
232
|
+
👉 [여기에서 데모를 시도해 보세요](https://intlayer.org/doc/why) 👉 [GitHub에서 코드 템플릿 확인하기](https://github.com/aymericzip/smart_doc_RAG)
|
|
233
|
+
|
|
234
|
+
## 더 나아가기
|
|
235
|
+
|
|
236
|
+
이 프로젝트는 최소한의 구현입니다. 하지만 여러 가지 방법으로 확장할 수 있습니다:
|
|
237
|
+
|
|
238
|
+
- MCP 서버 → 문서 검색 기능을 MCP 서버로 확장하여 문서를 모든 AI 어시스턴트에 연결
|
|
239
|
+
- 벡터 DB → 수백만 개의 문서 청크로 확장
|
|
240
|
+
- LangChain / LlamaIndex → RAG 파이프라인을 위한 기성 프레임워크
|
|
241
|
+
- 분석 대시보드 → 사용자 쿼리와 문제점을 시각화
|
|
242
|
+
- 다중 소스 검색 → 문서뿐만 아니라 데이터베이스 항목, 블로그 게시물, 티켓 등도 검색
|
|
243
|
+
- 향상된 프롬프트 → 재순위화, 필터링, 하이브리드 검색(키워드 + 의미 기반)
|
|
244
|
+
|
|
245
|
+
## 우리가 직면한 한계
|
|
246
|
+
|
|
247
|
+
- 청크 분할과 중첩은 경험적입니다. 적절한 균형(청크 크기, 중첩 비율, 검색된 청크 수)은 반복과 테스트가 필요합니다.
|
|
248
|
+
- 문서가 변경될 때 임베딩이 자동으로 재생성되지 않습니다. 우리 시스템은 저장된 청크 수와 다를 때만 파일의 임베딩을 재설정합니다.
|
|
249
|
+
- 이 프로토타입에서는 임베딩이 JSON에 저장됩니다. 이는 데모에는 적합하지만 Git을 오염시킵니다. 실제 운영 환경에서는 데이터베이스나 전용 벡터 스토어가 더 적합합니다.
|
|
250
|
+
|
|
251
|
+
## 문서를 넘어 중요한 이유
|
|
252
|
+
|
|
253
|
+
흥미로운 부분은 단순한 챗봇이 아닙니다. 바로 **피드백 루프**입니다.
|
|
254
|
+
|
|
255
|
+
RAG를 사용하면 단순히 답변하는 것에 그치지 않습니다:
|
|
256
|
+
|
|
257
|
+
- 사용자가 무엇에 혼란스러워하는지 알게 됩니다.
|
|
258
|
+
- 사용자가 기대하는 기능을 발견합니다.
|
|
259
|
+
- 실제 쿼리를 기반으로 제품 전략을 조정합니다.
|
|
260
|
+
|
|
261
|
+
**예시:**
|
|
262
|
+
|
|
263
|
+
새로운 기능을 출시하고 즉시 다음과 같은 상황을 상상해 보세요:
|
|
264
|
+
|
|
265
|
+
- 질문의 50%가 동일한 불명확한 설정 단계에 관한 것
|
|
266
|
+
- 사용자가 아직 지원하지 않는 통합 기능을 반복적으로 요청
|
|
267
|
+
- 사람들이 새로운 사용 사례를 드러내는 용어를 검색
|
|
268
|
+
|
|
269
|
+
이것이 바로 사용자로부터 직접 얻는 **제품 인텔리전스**입니다.
|
|
270
|
+
|
|
271
|
+
## 결론
|
|
272
|
+
|
|
273
|
+
RAG는 LLM을 실용적으로 만드는 가장 간단하면서도 강력한 방법 중 하나입니다. **검색(retrieval) + 생성(generation)**을 결합함으로써 정적인 문서를 **스마트 어시스턴트**로 전환할 수 있으며, 동시에 지속적인 제품 인사이트 흐름을 얻을 수 있습니다.
|
|
274
|
+
|
|
275
|
+
저에게 이 프로젝트는 RAG가 단순한 기술적 트릭이 아님을 보여주었습니다. RAG는 문서를 다음과 같이 변환하는 방법입니다:
|
|
276
|
+
|
|
277
|
+
- 상호작용하는 지원 시스템
|
|
278
|
+
- 피드백 채널
|
|
279
|
+
- 제품 전략 도구
|
|
280
|
+
|
|
281
|
+
👉 [여기서 데모를 시도해보세요](https://intlayer.org/doc/why) 👉 [GitHub에서 코드 템플릿을 확인하세요](https://github.com/aymericzip/smart_doc_RAG)
|
|
282
|
+
|
|
283
|
+
그리고 만약 여러분도 RAG를 실험하고 있다면, 어떻게 사용하고 있는지 듣고 싶습니다.
|