{"id":50626,"date":"2023-09-27T00:48:24","date_gmt":"2023-12-25T01:36:44","guid":{"rendered":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%9c%a8%e6%80%9d%e8%80%83solid%e5%8e%9f%e5%88%99%e7%ad%89%e7%9a%84%e6%83%85%e5%86%b5%e4%b8%8b%ef%bc%8c%e6%b5%8f%e8%a7%88langchain%e7%9a%84%e6%ba%90%e4%bb%a3%e7%a0%81%e3%80%82\/"},"modified":"2024-05-04T01:44:58","modified_gmt":"2024-05-03T17:44:58","slug":"%e5%9c%a8%e6%80%9d%e8%80%83solid%e5%8e%9f%e5%88%99%e7%ad%89%e7%9a%84%e6%83%85%e5%86%b5%e4%b8%8b%ef%bc%8c%e6%b5%8f%e8%a7%88langchain%e7%9a%84%e6%ba%90%e4%bb%a3%e7%a0%81%e3%80%82","status":"publish","type":"post","link":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%9c%a8%e6%80%9d%e8%80%83solid%e5%8e%9f%e5%88%99%e7%ad%89%e7%9a%84%e6%83%85%e5%86%b5%e4%b8%8b%ef%bc%8c%e6%b5%8f%e8%a7%88langchain%e7%9a%84%e6%ba%90%e4%bb%a3%e7%a0%81%e3%80%82\/","title":{"rendered":"\u5728\u601d\u8003SOLID\u539f\u5219\u7b49\u7684\u60c5\u51b5\u4e0b\uff0c\u6d4f\u89c8LangChain\u7684\u6e90\u4ee3\u7801"},"content":{"rendered":"<p>\u5728\u8fd9\u91cc\uff0c\u6211\u4eec\u8bd5\u56fe\u901a\u8fc7\u5728LangChain\u7684\u5b9e\u73b0\u4e2d\u627e\u51fa\u8fd9\u4e9b\u8981\u7d20\u6765\u89e3\u91caSOLID\u539f\u5219\u548c\u5951\u7ea6\u5f0f\u7f16\u7a0b\u3002<\/p>\n<h1>SOLID\u539f\u5247\u53ef\u4ee5\u88ab\u63cf\u8ff0\u4e3a\u4e00\u4e2a\u9762\u5411\u5bf9\u8c61\u7f16\u7a0b\u7684\u6307\u5bfc\u539f\u5219\u96c6\uff0c\u5b83\u7531\u4e94\u4e2a\u539f\u5219\u7ec4\u6210\uff0c\u5206\u522b\u662f\u5355\u4e00\u8d23\u4efb\u539f\u5219\u3001\u5f00\u95ed\u539f\u5219\u3001\u91cc\u6c0f\u66ff\u6362\u539f\u5219\u3001\u63a5\u53e3\u9694\u79bb\u539f\u5219\u548c\u4f9d\u8d56\u5012\u7f6e\u539f\u5219\u3002<\/h1>\n<p>SOLID\u539f\u5219\u662f\u9762\u5411\u5bf9\u8c61\u7f16\u7a0b\uff08OOP\uff09\u8bbe\u8ba1\u6307\u5357\u4e4b\u4e00\u3002\u5982\u524d\u6240\u8ff0\uff0c\u5b83\u662f\u5173\u4e8e\u8bbe\u8ba1\u7c7b\u548c\u51fd\u6570\u7684\u5177\u4f53\u65b9\u6cd5\uff0c\u65e8\u5728\u5b9e\u73b0\u9ad8\u5185\u805a\u3001\u4f4e\u8026\u5408\u7684\u6a21\u5757\u8bbe\u8ba1\u3002<\/p>\n<p>\u5177\u4f53\u800c\u8a00\uff0cSOLID\u539f\u5219\u5305\u62ec\u4e94\u4e2a\u8981\u7d20\u3002<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">S &#8211; Single Responsibility Principle (\u5358\u4e00\u8cac\u4efb\u306e\u539f\u5247): \u5909\u66f4\u3059\u308b\u305f\u3081\u306e\u7406\u7531\u304c\u3001\u4e00\u3064\u306e\u30af\u30e9\u30b9\u306b\u5bfe\u3057\u3066\u4e00\u3064\u4ee5\u4e0a\u3042\u3063\u3066\u306f\u306a\u3089\u306a\u3044<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">O &#8211; Open\/Closed Principle (\u958b\u653e\/\u9589\u9396\u306e\u539f\u5247): \u30bd\u30d5\u30c8\u30a6\u30a7\u30a2\u306e\u5b9f\u4f53\uff08\u30af\u30e9\u30b9\u3001\u30e2\u30b8\u30e5\u30fc\u30eb\u3001\u95a2\u6570\u306a\u3069\uff09\u306f\u3001\u62e1\u5f35\u306b\u5bfe\u3057\u3066\u958b\u304b\u308c\u3066\u3044\u308b\u3079\u304d\u3067\u3042\u308a\u3001\u4fee\u6b63\u306b\u5bfe\u3057\u3066\u9589\u3058\u3066\u3044\u306a\u3051\u308c\u3070\u306a\u3089\u306a\u3044<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">L &#8211; Liskov Substitution Principle (\u30ea\u30b9\u30b3\u30d5\u306e\u7f6e\u63db\u539f\u5247): \u3042\u308b\u57fa\u5e95\u30af\u30e9\u30b9\u3078\u306e\u30dd\u30a4\u30f3\u30bf\u306a\u3044\u3057\u53c2\u7167\u3092\u6271\u3063\u3066\u3044\u308b\u95a2\u6570\u7fa4\u306f\u3001\u305d\u306e\u6d3e\u751f\u30af\u30e9\u30b9\u306e\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u306e\u8a73\u7d30\u3092\u77e5\u3089\u306a\u304f\u3066\u3082\u6271\u3048\u308b\u3088\u3046\u306b\u3057\u306a\u3051\u308c\u3070\u306a\u3089\u306a\u3044<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">I &#8211; Interface Segregation Principle (\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30fc\u30b9\u5206\u96e2\u306e\u539f\u5247): \u6c4e\u7528\u306a\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30fc\u30b9\u304c\u4e00\u3064\u3042\u308b\u3088\u308a\u3082\u3001\u5404\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u306b\u7279\u5316\u3057\u305f\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30fc\u30b9\u304c\u305f\u304f\u3055\u3093\u3042\u3063\u305f\u65b9\u304c\u3088\u3044<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">D &#8211; Dependency Inversion Principle (\u4f9d\u5b58\u6027\u9006\u8ee2\u306e\u539f\u5247): \u4e0a\u4f4d\u30e2\u30b8\u30e5\u30fc\u30eb\u306f\u3044\u304b\u306a\u308b\u3082\u306e\u3082\u4e0b\u4f4d\u30e2\u30b8\u30e5\u30fc\u30eb\u304b\u3089\u6301\u3061\u8fbc\u3093\u3067\u306f\u306a\u3089\u306a\u3044\u3002\u53cc\u65b9\u3068\u3082\u5177\u8c61\u3067\u306f\u306a\u304f\u3001\u62bd\u8c61\uff08\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30fc\u30b9\u306a\u3069\uff09\u306b\u4f9d\u5b58\u3059\u308b\u3079\u304d\u3067\u3042\u308b<\/ul>\n<p>\u73b0\u5728\u9664\u4e86\u8fd9\u4e9b\u539f\u5219\u4e4b\u5916\uff0c\u8fd8\u5b58\u5728\u7740\u591a\u79cd\u8bbe\u8ba1\u6307\u5bfc\uff0c\u5982\u8bbe\u8ba1\u6a21\u5f0f\u548c\u591a\u6001\u6027\u7b49\u3002\u8fd9\u4e9b\u6307\u5bfc\u4ee5\u4e0d\u540c\u7684\u65b9\u5f0f\u91cd\u590d\u8868\u8fbe\u7740\u76f8\u540c\u7684\u4e3b\u9898\u3002<\/p>\n<p>SOLID\u539f\u5219\u662f\u5c06\u5df2\u77e5\u7684\u6982\u5ff5\u5de7\u5999\u5730\u603b\u7ed3\u8d77\u6765\uff0c\u5176\u6613\u4e8e\u7406\u89e3\u5e76\u4e0d\u4f1a\u51cf\u5f31\u5176\u91cd\u8981\u6027\u3002\u5c31\u50cf\u4e2d\u5b66\u751f\u4e5f\u80fd\u7406\u89e3\u5e73\u65b9\u7684\u5b9a\u7406\u4e00\u6837\uff0c\u4f46\u5176\u91cd\u8981\u6027\u4e0d\u4f1a\u6539\u53d8\u3002\u56e0\u6b64\uff0c\u4f5c\u4e3a\u7f16\u7a0b\u8bbe\u8ba1\u7684\u57fa\u672c\u800c\u91cd\u8981\u7684\u51c6\u5219\uff0c\u7406\u89e3\u548c\u5e94\u7528SOLID\u539f\u5219\u662f\u503c\u5f97\u7684\u3002<\/p>\n<h1>\u4e3a\u4ec0\u4e48\u9009\u62e9 LangChain<\/h1>\n<p>\u6717\u88c5\u662f\u4e00\u4e2a\u56f4\u7ed5\u76ee\u524d\u6d41\u884c\u7684LLM\u7684\u6846\u67b6\u3002\u53ef\u4ee5\u8f7b\u677e\u521b\u5efa\u57fa\u4e8eLLM\u7684\u5e94\u7528\u7a0b\u5e8f\u3002<\/p>\n<p>\u5728\u8fd9\u91cc\uff0c\u6211\u60f3\u8981\u4e13\u6ce8\u4e8eLangChain\u7684\u6e90\u4ee3\u7801\u3002\u56e0\u4e3a\u6211\u8ba4\u4e3a\u6709\u4ee5\u4e0b\u51e0\u4e2a\u503c\u5f97\u5173\u6ce8\u7684\u539f\u56e0\uff1a<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">2022\u5e74\u306e10\u6708\u306b\u3067\u304d\u305f\u3001\u65b0\u3057\u3044\u3082\u306e\u306a\u4e0a\u3067\u3001<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">Python \u3067\u4f5c\u3089\u308c\u3066\u3066\u3001<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">\u591a\u304f\u306e committer \u304c\u3044\u308b\u3002 1900 \u4eba\u304f\u3089\u3044\u3002<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">\u591a\u304f\u306e\u4eba\u306b\u4f7f\u308f\u308c\u3066\u3044\u308b\u3002<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\u66f4\u65b0\u983b\u5ea6\u304c\u901f\u3044\u3002<\/ul>\n<p>\u5c3d\u7ba1LangChain\u5907\u53d7\u4e89\u8bae\uff0c\u4f46\u4ec5\u51ed\u4e0a\u8ff0\u539f\u56e0\uff0c\u5c31\u5e94\u8be5\u5173\u6ce8\u5176\u5185\u90e8\u8bbe\u8ba1\u3002<\/p>\n<p>\u4e8b\u5b9e\u4e0a\uff0c\u53ef\u4ee5\u4eceLangChain\u7684\u4ee3\u7801\u4e2d\u627e\u5230SOLID\u539f\u5219\u3002 \u5728Python\u7684\u5b9e\u73b0\u793a\u4f8b\u4e2d\u770b\u5230\u8fd9\u4e00\u70b9\u975e\u5e38\u4ee4\u4eba\u9ad8\u5174\u3002<\/p>\n<p>\u56e0\u6b64\uff0c\u6211\u6253\u7b97\u5728\u63a5\u4e0b\u6765\u7684\u5185\u5bb9\u4e2d\u5f15\u7528LangChain\u7684\u4ee3\u7801\uff0c\u4ee5\u89e3\u91caSOLID\u539f\u5219\u7b49\u5185\u5bb9\u3002<\/p>\n<h1>\u4f7f\u7528LangChain\u7684\u5b9e\u73b0\u793a\u4f8b<\/h1>\n<p>\u5728\u67e5\u770bLangChain\u7684\u4ee3\u7801\u4e4b\u524d\uff0c\u5148\u5c55\u793a\u4e00\u4e2a\u4f7f\u7528LangChain\u7684\u6837\u4f8b\u3002\u901a\u8fc7\u8fd9\u4e2a\u6837\u4f8b\uff0c\u5e0c\u671b\u80fd\u591f\u7406\u89e3\u5b83\u7684\u884c\u4e3a\u3002<\/p>\n<p>\u4ee5\u4e0b\u662f\u6240\u8b02\u7684RAG\u7684\u5be6\u73fe\u3002<\/p>\n<pre class=\"post-pre\"><code>pip <span class=\"nb\">install <\/span>langchain chromadb tiktoken openai\r\n<\/code><\/pre>\n<pre class=\"post-pre\"><code><span class=\"kn\">from<\/span> <span class=\"n\">langchain.chains<\/span> <span class=\"kn\">import<\/span> <span class=\"n\">RetrievalQA<\/span>\r\n<span class=\"kn\">from<\/span> <span class=\"n\">langchain.chat_models<\/span> <span class=\"kn\">import<\/span> <span class=\"n\">ChatOpenAI<\/span>\r\n<span class=\"kn\">from<\/span> <span class=\"n\">langchain.document_loaders<\/span> <span class=\"kn\">import<\/span> <span class=\"n\">TextLoader<\/span>\r\n<span class=\"kn\">from<\/span> <span class=\"n\">langchain.embeddings.openai<\/span> <span class=\"kn\">import<\/span> <span class=\"n\">OpenAIEmbeddings<\/span>\r\n<span class=\"kn\">from<\/span> <span class=\"n\">langchain.text_splitter<\/span> <span class=\"kn\">import<\/span> <span class=\"n\">CharacterTextSplitter<\/span>\r\n<span class=\"kn\">from<\/span> <span class=\"n\">langchain.vectorstores.chroma<\/span> <span class=\"kn\">import<\/span> <span class=\"n\">Chroma<\/span>\r\n\r\n<span class=\"n\">loader<\/span> <span class=\"o\">=<\/span> <span class=\"nc\">TextLoader<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">\u65e5\u672c\u56fd\u61b2\u6cd5.txt<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\r\n<span class=\"n\">documents<\/span> <span class=\"o\">=<\/span> <span class=\"n\">loader<\/span><span class=\"p\">.<\/span><span class=\"nf\">load<\/span><span class=\"p\">()<\/span>\r\n<span class=\"n\">text_splitter<\/span> <span class=\"o\">=<\/span> <span class=\"nc\">CharacterTextSplitter<\/span><span class=\"p\">()<\/span>\r\n<span class=\"n\">texts<\/span> <span class=\"o\">=<\/span> <span class=\"n\">text_splitter<\/span><span class=\"p\">.<\/span><span class=\"nf\">split_documents<\/span><span class=\"p\">(<\/span><span class=\"n\">documents<\/span><span class=\"p\">)<\/span>\r\n<span class=\"n\">embeddings<\/span> <span class=\"o\">=<\/span> <span class=\"nc\">OpenAIEmbeddings<\/span><span class=\"p\">()<\/span>\r\n<span class=\"n\">docsearch<\/span> <span class=\"o\">=<\/span> <span class=\"n\">Chroma<\/span><span class=\"p\">.<\/span><span class=\"nf\">from_documents<\/span><span class=\"p\">(<\/span><span class=\"n\">texts<\/span><span class=\"p\">,<\/span> <span class=\"n\">embeddings<\/span><span class=\"p\">)<\/span>\r\n<span class=\"n\">retriever<\/span> <span class=\"o\">=<\/span> <span class=\"n\">docsearch<\/span><span class=\"p\">.<\/span><span class=\"nf\">as_retriever<\/span><span class=\"p\">()<\/span>\r\n<span class=\"n\">llm<\/span> <span class=\"o\">=<\/span> <span class=\"nc\">ChatOpenAI<\/span><span class=\"p\">(<\/span><span class=\"n\">model_name<\/span><span class=\"o\">=<\/span><span class=\"sh\">\"<\/span><span class=\"s\">gpt-4<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"n\">api_key<\/span><span class=\"o\">=<\/span><span class=\"sh\">\"<\/span><span class=\"s\">YOUR_API_KEY<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\r\n<span class=\"n\">qa<\/span> <span class=\"o\">=<\/span> <span class=\"n\">RetrievalQA<\/span><span class=\"p\">.<\/span><span class=\"nf\">from_chain_type<\/span><span class=\"p\">(<\/span><span class=\"n\">llm<\/span><span class=\"o\">=<\/span><span class=\"n\">llm<\/span><span class=\"p\">,<\/span> <span class=\"n\">retriever<\/span><span class=\"o\">=<\/span><span class=\"n\">retriever<\/span><span class=\"p\">)<\/span>\r\n<\/code><\/pre>\n<p>\u4ee5\u4e0b\u662f\u65e5\u672c\u56fd\u5baa\u6cd5.txt\u3002<\/p>\n<p>&nbsp;<\/p>\n<p>\u95ee\u95ee\u9898\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"n\">answer<\/span> <span class=\"o\">=<\/span> <span class=\"n\">qa<\/span><span class=\"p\">.<\/span><span class=\"nf\">run<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">\u30c6\u30ad\u30b9\u30c8\u306b\u306f\u306a\u3093\u3068\u66f8\u3044\u3066\u3042\u308b\uff1f<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\r\n<span class=\"nf\">print<\/span><span class=\"p\">(<\/span><span class=\"n\">answer<\/span><span class=\"p\">)<\/span>\r\n<\/code><\/pre>\n<p>\u53d1\u6325\u6f5c\u529b<\/p>\n<blockquote><p>\u8fd9\u6bb5\u6587\u5b57\u662f\u5173\u4e8e\u65e5\u672c\u5baa\u6cd5\u7684\u5185\u5bb9\uff0c\u6d89\u53ca\u7687\u5ba4\u3001\u653e\u5f03\u6218\u4e89\u4ee5\u53ca\u56fd\u6c11\u6743\u5229\u548c\u4e49\u52a1\u7684\u8bba\u8ff0\u3002<br \/>\n\u5bf9\u4e8e\u7687\u5ba4\u6765\u8bf4\uff0c\u6d89\u53ca\u5230\u6444\u653f\u7684\u5b89\u6392\u3001\u5929\u7687\u7684\u4efb\u547d\u884c\u4e3a\u3001\u56fd\u5bb6\u4e8b\u52a1\u7684\u6267\u884c&#8230; (\u7701\u7565)<\/p><\/blockquote>\n<h2>DIP &#8211; \u4f9d\u8d56\u5012\u7f6e\u539f\u5219<\/h2>\n<h2>\u89e3\u91ca<\/h2>\n<p>\u6211\u4f1a\u76f4\u63a5\u4eceSOLID\u539f\u5219\u7684D\u6765\u89e3\u91ca\u3002\u56e0\u4e3a\u5728SOLID\u539f\u5219\u4e2d\uff0c\u6211\u8ba4\u4e3a\u8fd9\u662f\u6700\u91cd\u8981\u7684\u3002\u5982\u679c\u6ca1\u6709\u8fd9\u4e2a\uff0c\u89e3\u91ca\u5176\u4ed6\u539f\u5219\u4e5f\u4f1a\u53d8\u5f97\u56f0\u96be\u3002<\/p>\n<p>DIP \u662f\u6307\u5f15\u7528\u7ef4\u57fa\u767e\u79d1\u7684\u5b9a\u4e49\u3002<\/p>\n<blockquote><p>\u4e0a\u7ea7\u6a21\u5757\u4e0d\u5f97\u4ece\u4e0b\u7ea7\u6a21\u5757\u5f15\u5165\u4efb\u4f55\u5185\u5bb9\u3002\u53cc\u65b9\u90fd\u5e94\u8be5\u4f9d\u8d56\u4e8e\u62bd\u8c61\uff08\u5982\u63a5\u53e3\uff09\uff0c\u800c\u4e0d\u662f\u5177\u4f53\u5b9e\u73b0\u3002<\/p><\/blockquote>\n<p>\u8fd9\u6837\u7684\u4e1c\u897f\u3002<\/p>\n<p>\u8ba9\u6211\u4eec\u7528\u4ee3\u7801\u6765\u5c55\u793a\u5427\u3002<\/p>\n<p>\u9996\u5148\uff0c\u9019\u662f\u4e00\u500b\u9055\u53cd\u4e86DIP\u7684\u6848\u4f8b\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"k\">class<\/span> <span class=\"nc\">MySQLDatabase<\/span><span class=\"p\">:<\/span>\r\n    <span class=\"k\">def<\/span> <span class=\"nf\">connect<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">):<\/span>\r\n        <span class=\"k\">return<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">MySQL\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u63a5\u7d9a<\/span><span class=\"sh\">\"<\/span>\r\n\r\n    <span class=\"k\">def<\/span> <span class=\"nf\">fetch_data<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">):<\/span>\r\n        <span class=\"k\">return<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">\u30c7\u30fc\u30bf\u3092\u53d6\u5f97<\/span><span class=\"sh\">\"<\/span>\r\n\r\n<span class=\"k\">class<\/span> <span class=\"nc\">ReportGenerator<\/span><span class=\"p\">:<\/span>\r\n    <span class=\"k\">def<\/span> <span class=\"nf\">__init__<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">):<\/span>\r\n        <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">database<\/span> <span class=\"o\">=<\/span> <span class=\"nc\">MySQLDatabase<\/span><span class=\"p\">()<\/span>\r\n\r\n    <span class=\"k\">def<\/span> <span class=\"nf\">create_report<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">):<\/span>\r\n        <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">database<\/span><span class=\"p\">.<\/span><span class=\"nf\">connect<\/span><span class=\"p\">()<\/span>\r\n        <span class=\"n\">data<\/span> <span class=\"o\">=<\/span> <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">database<\/span><span class=\"p\">.<\/span><span class=\"nf\">fetch_data<\/span><span class=\"p\">()<\/span>\r\n        <span class=\"k\">return<\/span> <span class=\"sa\">f<\/span><span class=\"sh\">\"<\/span><span class=\"s\">\u30ec\u30dd\u30fc\u30c8: <\/span><span class=\"si\">{<\/span><span class=\"n\">data<\/span><span class=\"si\">}<\/span><span class=\"sh\">\"<\/span>\r\n\r\n<span class=\"c1\"># \u4f7f\u7528\u4f8b\r\n<\/span><span class=\"n\">report_generator<\/span> <span class=\"o\">=<\/span> <span class=\"nc\">ReportGenerator<\/span><span class=\"p\">()<\/span>\r\n<span class=\"nf\">print<\/span><span class=\"p\">(<\/span><span class=\"n\">report_generator<\/span><span class=\"p\">.<\/span><span class=\"nf\">create_report<\/span><span class=\"p\">())<\/span>\r\n<\/code><\/pre>\n<p>\u5982\u679c\u7ed8\u5236\u6210\u7c7b\u56fe\uff0c\u5b83\u4f1a\u662f\u8fd9\u6837\u7684\u3002<\/p>\n<p><iframe>\u8bf7\u4f7f\u7528\u4e2d\u56fd\u6bcd\u8bed\u5c06\u4ee5\u4e0b\u5185\u5bb9\u6539\u5199\u6210\u4e2d\u6587\uff0c\u53ea\u9700\u63d0\u4f9b\u4e00\u79cd\u9009\u9879\uff1a\u8bf7\u4f7f\u7528\u4e2d\u56fd\u6bcd\u8bed\u5c06\u4ee5\u4e0b\u5185\u5bb9\u6539\u5199\u6210\u4e2d\u6587\uff0c\u53ea\u9700\u63d0\u4f9b\u4e00\u79cd\u9009\u9879\u3002<\/p>\n<p><\/iframe><\/p>\n<p>\u8fd9\u662f\u4e00\u4e2a\u5e38\u89c1\u7684\u5b9e\u73b0\u65b9\u5f0f\u3002\u5728 ReportGenerator \u4e2d\uff0cMySQLDatabase \u88ab\u5b9e\u4f8b\u5316\u3002<\/p>\n<p>\u8fd9\u662f\u6709\u95ee\u9898\u7684\u3002<\/p>\n<p>\u9996\u5148\uff0c\u5728\u8fd9\u4e2a\u9636\u6bb5\uff0c\u5b9e\u65bd\u5355\u5143\u6d4b\u8bd5\u975e\u5e38\u56f0\u96be\u3002\u6211\u5e0c\u671b MySQLDatabase \u7684\u5b9e\u4f8b\u80fd\u591f\u6b63\u5e38\u8fd0\u884c\u3002\u6bcf\u6b21\u90fd\u8981\u542f\u52a8 Docker \u5bb9\u5668\uff0c\u51c6\u5907\u9002\u5f53\u7684\u6570\u636e\u6765\u8fdb\u884c&#8221;\u5355\u5143\u6d4b\u8bd5&#8221;\uff1f\u8fd9\u592a\u611a\u8822\u4e86\u3002<\/p>\n<p>\u8fd8\u6709\u4e00\u4e2a\u5e38\u89c1\u7684\u4e60\u60ef\u3002\u4e0e\u4e0a\u8ff0\u7684\u672c\u8d28\u4e0a\u6ca1\u6709\u592a\u5927\u533a\u522b\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"k\">class<\/span> <span class=\"nc\">C<\/span><span class=\"p\">:<\/span>\r\n    <span class=\"k\">def<\/span> <span class=\"nf\">operation_c<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">):<\/span>\r\n        <span class=\"k\">return<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">C\u306e\u64cd\u4f5c<\/span><span class=\"sh\">\"<\/span>\r\n\r\n<span class=\"k\">class<\/span> <span class=\"nc\">B<\/span><span class=\"p\">:<\/span>\r\n    <span class=\"k\">def<\/span> <span class=\"nf\">__init__<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">):<\/span>\r\n        <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">c<\/span> <span class=\"o\">=<\/span> <span class=\"nc\">C<\/span><span class=\"p\">()<\/span>\r\n\r\n    <span class=\"k\">def<\/span> <span class=\"nf\">operation_b<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">):<\/span>\r\n        <span class=\"k\">return<\/span> <span class=\"sa\">f<\/span><span class=\"sh\">\"<\/span><span class=\"s\">B\u306e\u64cd\u4f5c\u3068 <\/span><span class=\"si\">{<\/span><span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">c<\/span><span class=\"p\">.<\/span><span class=\"nf\">operation_c<\/span><span class=\"p\">()<\/span><span class=\"si\">}<\/span><span class=\"sh\">\"<\/span>\r\n\r\n<span class=\"k\">class<\/span> <span class=\"nc\">A<\/span><span class=\"p\">:<\/span>\r\n    <span class=\"k\">def<\/span> <span class=\"nf\">__init__<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">):<\/span>\r\n        <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">b<\/span> <span class=\"o\">=<\/span> <span class=\"nc\">B<\/span><span class=\"p\">()<\/span>\r\n\r\n    <span class=\"k\">def<\/span> <span class=\"nf\">operation_a<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">):<\/span>\r\n        <span class=\"k\">return<\/span> <span class=\"sa\">f<\/span><span class=\"sh\">\"<\/span><span class=\"s\">A\u306e\u64cd\u4f5c\u3068 <\/span><span class=\"si\">{<\/span><span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">b<\/span><span class=\"p\">.<\/span><span class=\"nf\">operation_b<\/span><span class=\"p\">()<\/span><span class=\"si\">}<\/span><span class=\"sh\">\"<\/span>\r\n\r\n<span class=\"c1\"># \u4f7f\u7528\u4f8b\r\n<\/span><span class=\"n\">a<\/span> <span class=\"o\">=<\/span> <span class=\"nc\">A<\/span><span class=\"p\">()<\/span>\r\n<span class=\"nf\">print<\/span><span class=\"p\">(<\/span><span class=\"n\">a<\/span><span class=\"p\">.<\/span><span class=\"nf\">operation_a<\/span><span class=\"p\">())<\/span>\r\n<\/code><\/pre>\n<p>\u7c7b\u56fe<\/p>\n<p><iframe>\u8bf7\u7528\u4e2d\u6587\u5c06\u4ee5\u4e0b\u5185\u5bb9\u6539\u8ff0\uff0c\u53ea\u9700\u8981\u7ed9\u51fa\u4e00\u4e2a\u9009\u9879\uff1a&#8221;There are many ways to improve your English language skills, such as practicing speaking with native speakers, reading books or articles in English, watching movies or TV shows in English, and using language learning apps or websites. Consistency and practice are key in becoming fluent in any language.&#8221;<\/p>\n<p><\/iframe><\/p>\n<p>\u8fd9\u4e24\u4e2a\u4f8b\u5b50\u4e2d\uff0c\u7c7b\u4e4b\u95f4\u5b58\u5728\u7d27\u5bc6\u7684\u8026\u5408\u3002\u5728\u8fd9\u4e2a\u4f8b\u5b50\u4e2d\uff0c\u6211\u4eec\u60f3\u8981\u89e3\u51b3\u7c7b C \u7684\u95ee\u9898\uff0c\u4f46\u5374\u4e0d\u5f97\u4e0d\u8003\u8651\u5230\u4f9d\u8d56\u4e8e\u5b83\u7684\u7c7b B\u3002\u800c\u4e14\uff0c\u968f\u4e4b\u800c\u6765\u7684\u662f\uff0c\u5982\u679c\u4fee\u6539\u4e86 B \u7684\u4ee3\u7801\uff0c\u5c31\u5fc5\u987b\u540c\u65f6\u5904\u7406 A \u7684\u76f8\u5173\u95ee\u9898\u3002<\/p>\n<p>\u5982\u679c\u7d27\u5bc6\u7ed3\u5408\uff0c\u4f1a\u5b58\u5728\u4ee5\u4e0b\u95ee\u9898\u3002<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">\u30c6\u30b9\u30c8\u304c\u56f0\u96e3<\/ul>\n<\/li>\n<\/ul>\n<p>\u62e1\u5f35\u304c\u56f0\u96e3\u3002 MySQL \u3092 Postgres \u306b\u5909\u3048\u3088\u3046\u304b\u306a\u3068\u601d\u3063\u305f\u3089\u3001\u305d\u308c\u306b\u4f9d\u5b58\u3057\u3066\u3044\u308b\u4eba\u5168\u54e1\u304c\u300c\u5927\u4e08\u592b\u304b\u306a\u300d\u300c\u5f71\u97ff\u306a\u3044\u304b\u306a\u300d\u3068\u601d\u308f\u306d\u3070\u306a\u3089\u306a\u3044\u3002<\/p>\n<p>\u7528 DIP \u8fdb\u884c\u91cd\u5199\u540e\uff0c\u5b83\u53d8\u6210\u4e86\u8fd9\u6837\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"kn\">from<\/span> <span class=\"n\">abc<\/span> <span class=\"kn\">import<\/span> <span class=\"n\">ABC<\/span><span class=\"p\">,<\/span> <span class=\"n\">abstractmethod<\/span>\r\n\r\n<span class=\"k\">class<\/span> <span class=\"nc\">IDatabase<\/span><span class=\"p\">(<\/span><span class=\"n\">ABC<\/span><span class=\"p\">):<\/span>\r\n    <span class=\"nd\">@abstractmethod<\/span>\r\n    <span class=\"k\">def<\/span> <span class=\"nf\">connect<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">):<\/span>\r\n        <span class=\"k\">pass<\/span>\r\n\r\n    <span class=\"nd\">@abstractmethod<\/span>\r\n    <span class=\"k\">def<\/span> <span class=\"nf\">fetch_data<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">):<\/span>\r\n        <span class=\"k\">pass<\/span>\r\n\r\n<span class=\"k\">class<\/span> <span class=\"nc\">MySQLDatabase<\/span><span class=\"p\">(<\/span><span class=\"n\">IDatabase<\/span><span class=\"p\">):<\/span>\r\n    <span class=\"k\">def<\/span> <span class=\"nf\">connect<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">):<\/span>\r\n        <span class=\"k\">return<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">MySQL\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u63a5\u7d9a<\/span><span class=\"sh\">\"<\/span>\r\n\r\n    <span class=\"k\">def<\/span> <span class=\"nf\">fetch_data<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">):<\/span>\r\n        <span class=\"k\">return<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">\u30c7\u30fc\u30bf\u3092\u53d6\u5f97<\/span><span class=\"sh\">\"<\/span>\r\n\r\n<span class=\"k\">class<\/span> <span class=\"nc\">ReportGenerator<\/span><span class=\"p\">:<\/span>\r\n    <span class=\"k\">def<\/span> <span class=\"nf\">__init__<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">,<\/span> <span class=\"n\">database<\/span><span class=\"p\">:<\/span> <span class=\"n\">IDatabase<\/span><span class=\"p\">):<\/span>\r\n        <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">database<\/span> <span class=\"o\">=<\/span> <span class=\"n\">database<\/span>\r\n\r\n    <span class=\"k\">def<\/span> <span class=\"nf\">create_report<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">):<\/span>\r\n        <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">database<\/span><span class=\"p\">.<\/span><span class=\"nf\">connect<\/span><span class=\"p\">()<\/span>\r\n        <span class=\"n\">data<\/span> <span class=\"o\">=<\/span> <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">database<\/span><span class=\"p\">.<\/span><span class=\"nf\">fetch_data<\/span><span class=\"p\">()<\/span>\r\n        <span class=\"k\">return<\/span> <span class=\"sa\">f<\/span><span class=\"sh\">\"<\/span><span class=\"s\">\u30ec\u30dd\u30fc\u30c8: <\/span><span class=\"si\">{<\/span><span class=\"n\">data<\/span><span class=\"si\">}<\/span><span class=\"sh\">\"<\/span>\r\n\r\n<span class=\"c1\"># \u4f7f\u7528\u4f8b\r\n# MySQL\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u4f7f\u7528\r\n<\/span><span class=\"n\">mysql_db<\/span> <span class=\"o\">=<\/span> <span class=\"nc\">MySQLDatabase<\/span><span class=\"p\">()<\/span>\r\n<span class=\"n\">report_generator<\/span> <span class=\"o\">=<\/span> <span class=\"nc\">ReportGenerator<\/span><span class=\"p\">(<\/span><span class=\"n\">mysql_db<\/span><span class=\"p\">)<\/span>\r\n<span class=\"nf\">print<\/span><span class=\"p\">(<\/span><span class=\"n\">report_generator<\/span><span class=\"p\">.<\/span><span class=\"nf\">create_report<\/span><span class=\"p\">())<\/span>\r\n<\/code><\/pre>\n<p><iframe>\u8bf7\u7528\u4e2d\u6587\u5c06\u4ee5\u4e0b\u53e5\u5b50\u8fdb\u884c\u7ffb\u8bd1\uff1a\u53ea\u9700\u4e00\u79cd\u9009\u62e9\u3002\u53ea\u9700\u8981\u4e00\u79cd\u9009\u62e9\u3002<\/p>\n<p><\/iframe><\/p>\n<p>ReportGenerator\u4f9d\u8d56\u4e8e\u4f5c\u4e3a\u62bd\u8c61\u7c7b\u5b9e\u73b0\u7684IDatabase\u3002\u91cd\u8981\u7684\u662f\u5b83\u4ec5\u4f9d\u8d56\u4e8eIDatabase\u3002\u800c\u4e14MySQLDatabase\u662fIDatabase\u7684\u5b9e\u73b0\u3002\u4e5f\u5c31\u662f\u8bf4\uff0cReportGenerator\u4e0d\u4f9d\u8d56\u4e8eMySQLDatabase\u3002\u6362\u53e5\u8bdd\u8bf4\uff0c\u5b83\u662f\u677e\u6563\u8026\u5408\u7684\u3002<\/p>\n<p>\u8fd9\u8ba9\u4f60\u89c9\u5f97\u5f00\u5fc3\u7684\u662f\u4ec0\u4e48\uff1f<\/p>\n<p>\u4e3e\u4e2a\u4f8b\u5b50\uff0c\u8003\u8bd5\u95ee\u9898\u5f97\u5230\u89e3\u51b3\u3002<\/p>\n<p>\u53ea\u9700\u6309\u7167\u4e0b\u9762\u7684\u65b9\u5f0f\u5b9e\u65bd\u5373\u53ef\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"kn\">import<\/span> <span class=\"n\">pytest<\/span>\r\n<span class=\"kn\">from<\/span> <span class=\"n\">unittest.mock<\/span> <span class=\"kn\">import<\/span> <span class=\"n\">MagicMock<\/span>\r\n\r\n<span class=\"k\">def<\/span> <span class=\"nf\">test_create_report<\/span><span class=\"p\">():<\/span>\r\n    <span class=\"c1\"># IDatabase\u306e\u30e2\u30c3\u30af\u3092\u4f5c\u6210\r\n<\/span>    <span class=\"n\">mock_database<\/span> <span class=\"o\">=<\/span> <span class=\"nc\">MagicMock<\/span><span class=\"p\">(<\/span><span class=\"n\">spec<\/span><span class=\"o\">=<\/span><span class=\"n\">IDatabase<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"n\">mock_database<\/span><span class=\"p\">.<\/span><span class=\"n\">fetch_data<\/span><span class=\"p\">.<\/span><span class=\"n\">return_value<\/span> <span class=\"o\">=<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">\u30c6\u30b9\u30c8\u30c7\u30fc\u30bf<\/span><span class=\"sh\">\"<\/span>\r\n\r\n    <span class=\"c1\"># ReportGenerator\u306e\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3092\u4f5c\u6210\r\n<\/span>    <span class=\"n\">report_generator<\/span> <span class=\"o\">=<\/span> <span class=\"nc\">ReportGenerator<\/span><span class=\"p\">(<\/span><span class=\"n\">mock_database<\/span><span class=\"p\">)<\/span>\r\n\r\n    <span class=\"c1\"># \u30ec\u30dd\u30fc\u30c8\u3092\u751f\u6210\r\n<\/span>    <span class=\"n\">report<\/span> <span class=\"o\">=<\/span> <span class=\"n\">report_generator<\/span><span class=\"p\">.<\/span><span class=\"nf\">create_report<\/span><span class=\"p\">()<\/span>\r\n\r\n    <span class=\"c1\"># \u30e1\u30bd\u30c3\u30c9\u547c\u3073\u51fa\u3057\u3092\u691c\u8a3c\r\n<\/span>    <span class=\"n\">mock_database<\/span><span class=\"p\">.<\/span><span class=\"n\">connect<\/span><span class=\"p\">.<\/span><span class=\"nf\">assert_called_once<\/span><span class=\"p\">()<\/span>\r\n    <span class=\"n\">mock_database<\/span><span class=\"p\">.<\/span><span class=\"n\">fetch_data<\/span><span class=\"p\">.<\/span><span class=\"nf\">assert_called_once<\/span><span class=\"p\">()<\/span>\r\n\r\n    <span class=\"c1\"># \u751f\u6210\u3055\u308c\u305f\u30ec\u30dd\u30fc\u30c8\u3092\u691c\u8a3c\r\n<\/span>    <span class=\"k\">assert<\/span> <span class=\"n\">report<\/span> <span class=\"o\">==<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">\u30ec\u30dd\u30fc\u30c8: \u30c6\u30b9\u30c8\u30c7\u30fc\u30bf<\/span><span class=\"sh\">\"<\/span>\r\n<\/code><\/pre>\n<p>\u53ea\u9700\u8981\u51c6\u5907\u4e00\u4e2a\u884c\u4e3a\u7c7b\u4f3c\u7684\u6a21\u62df Mock \u7528\u4e8e\u6d4b\u8bd5\u3002<\/p>\n<p>\u540c\u65f6\uff0c\u6269\u5c55\u4e5f\u53d8\u5f97\u66f4\u52a0\u7b80\u5355\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"k\">class<\/span> <span class=\"nc\">PostgreSQLDatabase<\/span><span class=\"p\">(<\/span><span class=\"n\">IDatabase<\/span><span class=\"p\">):<\/span>\r\n    <span class=\"k\">def<\/span> <span class=\"nf\">connect<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">):<\/span>\r\n        <span class=\"k\">return<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">PostgreSQL\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u63a5\u7d9a<\/span><span class=\"sh\">\"<\/span>\r\n\r\n    <span class=\"k\">def<\/span> <span class=\"nf\">fetch_data<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">):<\/span>\r\n        <span class=\"k\">return<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">\u30c7\u30fc\u30bf\u3092\u53d6\u5f97<\/span><span class=\"sh\">\"<\/span>\r\n\r\n<span class=\"c1\"># PostgreSQL\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u5207\u308a\u66ff\u3048\u308b\u5834\u5408\r\n<\/span><span class=\"n\">postgresql_db<\/span> <span class=\"o\">=<\/span> <span class=\"nc\">PostgreSQLDatabase<\/span><span class=\"p\">()<\/span>\r\n<span class=\"n\">report_generator<\/span> <span class=\"o\">=<\/span> <span class=\"nc\">ReportGenerator<\/span><span class=\"p\">(<\/span><span class=\"n\">postgresql_db<\/span><span class=\"p\">)<\/span>\r\n<span class=\"nf\">print<\/span><span class=\"p\">(<\/span><span class=\"n\">report_generator<\/span><span class=\"p\">.<\/span><span class=\"nf\">create_report<\/span><span class=\"p\">())<\/span>\r\n<\/code><\/pre>\n<p>\u6211\u4eec\u8fd8\u9700\u8981\u6309\u7167 DIP \u539f\u5219\u5bf9\u53e6\u4e00\u4e2a\u4f8b\u5b50\u8fdb\u884c\u91cd\u6784\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"kn\">from<\/span> <span class=\"n\">abc<\/span> <span class=\"kn\">import<\/span> <span class=\"n\">ABC<\/span><span class=\"p\">,<\/span> <span class=\"n\">abstractmethod<\/span>\r\n\r\n<span class=\"k\">class<\/span> <span class=\"nc\">IC<\/span><span class=\"p\">(<\/span><span class=\"n\">ABC<\/span><span class=\"p\">):<\/span>\r\n    <span class=\"nd\">@abstractmethod<\/span>\r\n    <span class=\"k\">def<\/span> <span class=\"nf\">operation_c<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">):<\/span>\r\n        <span class=\"k\">pass<\/span>\r\n\r\n<span class=\"k\">class<\/span> <span class=\"nc\">IB<\/span><span class=\"p\">(<\/span><span class=\"n\">ABC<\/span><span class=\"p\">):<\/span>\r\n    <span class=\"nd\">@abstractmethod<\/span>\r\n    <span class=\"k\">def<\/span> <span class=\"nf\">operation_b<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">):<\/span>\r\n        <span class=\"k\">pass<\/span>\r\n\r\n<span class=\"k\">class<\/span> <span class=\"nc\">C<\/span><span class=\"p\">(<\/span><span class=\"n\">IC<\/span><span class=\"p\">):<\/span>\r\n    <span class=\"k\">def<\/span> <span class=\"nf\">operation_c<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">):<\/span>\r\n        <span class=\"k\">return<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">C\u306e\u64cd\u4f5c<\/span><span class=\"sh\">\"<\/span>\r\n\r\n<span class=\"k\">class<\/span> <span class=\"nc\">B<\/span><span class=\"p\">(<\/span><span class=\"n\">IB<\/span><span class=\"p\">):<\/span>\r\n    <span class=\"k\">def<\/span> <span class=\"nf\">__init__<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">,<\/span> <span class=\"n\">c<\/span><span class=\"p\">:<\/span> <span class=\"n\">IC<\/span><span class=\"p\">):<\/span>\r\n        <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">c<\/span> <span class=\"o\">=<\/span> <span class=\"n\">c<\/span>\r\n\r\n    <span class=\"k\">def<\/span> <span class=\"nf\">operation_b<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">):<\/span>\r\n        <span class=\"k\">return<\/span> <span class=\"sa\">f<\/span><span class=\"sh\">\"<\/span><span class=\"s\">B\u306e\u64cd\u4f5c\u3068 <\/span><span class=\"si\">{<\/span><span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">c<\/span><span class=\"p\">.<\/span><span class=\"nf\">operation_c<\/span><span class=\"p\">()<\/span><span class=\"si\">}<\/span><span class=\"sh\">\"<\/span>\r\n\r\n<span class=\"k\">class<\/span> <span class=\"nc\">A<\/span><span class=\"p\">:<\/span>\r\n    <span class=\"k\">def<\/span> <span class=\"nf\">__init__<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">,<\/span> <span class=\"n\">b<\/span><span class=\"p\">:<\/span> <span class=\"n\">IB<\/span><span class=\"p\">):<\/span>\r\n        <span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">b<\/span> <span class=\"o\">=<\/span> <span class=\"n\">b<\/span>\r\n\r\n    <span class=\"k\">def<\/span> <span class=\"nf\">operation_a<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">):<\/span>\r\n        <span class=\"k\">return<\/span> <span class=\"sa\">f<\/span><span class=\"sh\">\"<\/span><span class=\"s\">A\u306e\u64cd\u4f5c\u3068 <\/span><span class=\"si\">{<\/span><span class=\"n\">self<\/span><span class=\"p\">.<\/span><span class=\"n\">b<\/span><span class=\"p\">.<\/span><span class=\"nf\">operation_b<\/span><span class=\"p\">()<\/span><span class=\"si\">}<\/span><span class=\"sh\">\"<\/span>\r\n\r\n<span class=\"c1\"># \u4f7f\u7528\u4f8b\r\n<\/span><span class=\"n\">c<\/span> <span class=\"o\">=<\/span> <span class=\"nc\">C<\/span><span class=\"p\">()<\/span>\r\n<span class=\"n\">b<\/span> <span class=\"o\">=<\/span> <span class=\"nc\">B<\/span><span class=\"p\">(<\/span><span class=\"n\">c<\/span><span class=\"p\">)<\/span>\r\n<span class=\"n\">a<\/span> <span class=\"o\">=<\/span> <span class=\"nc\">A<\/span><span class=\"p\">(<\/span><span class=\"n\">b<\/span><span class=\"p\">)<\/span>\r\n<span class=\"nf\">print<\/span><span class=\"p\">(<\/span><span class=\"n\">a<\/span><span class=\"p\">.<\/span><span class=\"nf\">operation_a<\/span><span class=\"p\">())<\/span>\r\n<\/code><\/pre>\n<p>\u8bfe\u7a0b\u56fe\u5c06\u5982\u4e0b\u6240\u793a\u3002<\/p>\n<p><iframe>\u8bf7\u4ee5\u4e2d\u6587\u672c\u5730\u5316\u5730\u91cd\u8ff0\u4ee5\u4e0b\u5185\u5bb9\uff08\u53ea\u9700\u4e00\u4e2a\u9009\u9879\uff09\uff1a<\/iframe><\/p>\n<p>\u987a\u4fbf\u8bf4\u4e00\u4e0b\uff0c\u8fd9\u4e5f\u53ef\u4ee5\u79f0\u4e3a\u754c\u9762\u8bbe\u8ba1\u3002<\/p>\n<p>\u6709\u4ec0\u4e48\u7f3a\u70b9\uff1f<\/p>\n<p>\u7531\u4e8e\u5b9e\u73b0\u4f9d\u8d56\u4e8e\u62bd\u8c61\uff0c\u56e0\u6b64\u4ee3\u7801\u53d8\u5f97\u96be\u4ee5\u76f4\u89c2\u9605\u8bfb\u3002<\/p>\n<p>\u5c3d\u7ba1\u5982\u6b64\uff0c\u6211\u4eec\u5e94\u8be5\u5c06\u5176\u89c6\u4e3a\u4e00\u79cd\u6743\u8861\u5417\uff1f\u8fd9\u5e76\u4e0d\u610f\u5473\u7740\u6211\u4eec\u5e94\u8be5\u5bb9\u5fcd\u96be\u4ee5\u9605\u8bfb\u800c\u65e0\u6cd5\u8fdb\u884c\u5355\u5143\u6d4b\u8bd5\u7684\u4ee3\u7801\u3002<\/p>\n<h2>DI \u548c DI \u5bb9\u5668<\/h2>\n<p>\u5728\u8fd9\u91cc\u5f15\u5165\u53e6\u4e00\u4e2a\u672f\u8bed\u3002 DI &#8211; \u4f9d\u8d56\u6ce8\u5165\u3002<\/p>\n<p>\u5982\u679c\u7528\u4e0a\u8ff0\u7684\u4ee3\u7801\u8868\u793a\uff0cDI\u5c31\u662f\u6307\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"n\">mysql_db<\/span> <span class=\"o\">=<\/span> <span class=\"nc\">MySQLDatabase<\/span><span class=\"p\">()<\/span>\r\n<span class=\"n\">report_generator<\/span> <span class=\"o\">=<\/span> <span class=\"nc\">ReportGenerator<\/span><span class=\"p\">(<\/span><span class=\"n\">mysql_db<\/span><span class=\"p\">)<\/span>\r\n<\/code><\/pre>\n<p>\u6211<\/p>\n<pre class=\"post-pre\"><code><span class=\"n\">c<\/span> <span class=\"o\">=<\/span> <span class=\"nc\">C<\/span><span class=\"p\">()<\/span>\r\n<span class=\"n\">b<\/span> <span class=\"o\">=<\/span> <span class=\"nc\">B<\/span><span class=\"p\">(<\/span><span class=\"n\">c<\/span><span class=\"p\">)<\/span>\r\n<span class=\"n\">a<\/span> <span class=\"o\">=<\/span> <span class=\"nc\">A<\/span><span class=\"p\">(<\/span><span class=\"n\">b<\/span><span class=\"p\">)<\/span>\r\n<\/code><\/pre>\n<p>\u8fd9\u90e8\u5206\u3002<\/p>\n<p>\u4f9d\u8d56\u4e8e\u4e0a\u8ff0\u62bd\u8c61\u7c7b\u7684\u7c7b\u5b9a\u4e49\uff0c\u5982\u679c\u4fdd\u6301\u539f\u6837\u81ea\u7136\u4e0d\u80fd\u8fd0\u884c\u3002\u6700\u7ec8\uff0c\u5fc5\u987b\u5728\u67d0\u5904\u4f9d\u8d56\u5177\u4f53\u7c7b\uff0c\u624d\u80fd\u4f7f\u5176\u8fd0\u884c\u3002<\/p>\n<p>\u5b9e\u9645\u8fdb\u884c\u8be5\u4f9d\u5b58\u7684\u64cd\u4f5c\uff0c\u5c31\u662f\u6240\u8c13\u7684\u4f9d\u8d56\u6ce8\u5165\u3002<\/p>\n<p>\u5728\u8fd9\u91cc\uff0c\u6211\u4eec\u8fd8\u9700\u8981\u8c08\u8bba\u53e6\u4e00\u4e2a\u8bdd\u9898\uff0c\u90a3\u5c31\u662f DI \u5bb9\u5668\u7684\u5b58\u5728\u3002<\/p>\n<p>\u5e0c\u671b\u4f60\u80fd\u591f\u60f3\u8c61\u4e00\u4e0b\u3002\u4e00\u4e2a\u4ea7\u54c1\u7c7b\u522b\u6709\u51e0\u5341\u4e2a\u3002\u6bcf\u4e2a\u7c7b\u522b\u90fd\u4f9d\u8d56\u590d\u6742\u7684\u62bd\u8c61\u7c7b\u6765\u8fd0\u4f5c\u3002\u90a3\u4e48\uff0c\u5bf9\u8fd9\u51e0\u5341\u4e2a\u7c7b\u522b\uff0c\u5fc5\u987b\u8fdb\u884c\u4f9d\u8d56\u6ce8\u5165\u3002\u8fd9\u610f\u5473\u7740\u4f9d\u8d56\u6ce8\u5165\u7684\u7ba1\u7406\u4f1a\u5e26\u6765\u75db\u82e6\u3002<\/p>\n<p>\u770b\u8d77\u6765\u5f88\u68d8\u624b\u3002\u6709\u4e00\u4e2a\u7cfb\u7edf\u53ef\u4ee5\u89e3\u51b3\u8fd9\u4e2a\u95ee\u9898\uff0c\u90a3\u5c31\u662f\u88ab\u79f0\u4e3a DI \u5bb9\u5668\u7684\u673a\u5236\u3002<\/p>\n<p>\u5982\u679c\u4f7f\u7528\u5bcc\u6709\u529f\u80fd\u7684 DI \u5bb9\u5668\uff0c\u5373\u4f7f\u4e0d\u7f16\u5199\u4efb\u4f55\u4e0e DI \u76f8\u5173\u7684\u4ee3\u7801\uff0cDI \u4e5f\u80fd\u591f\u5b9e\u73b0\u3002\u4f8b\u5982\uff0cJava \u7684 Spring Framework\u3002DI \u5bb9\u5668\u975e\u5e38\u806a\u660e\uff0c\u53ea\u8981\u7c7b\u578b\u8bbe\u7f6e\u6b63\u786e\uff0c\u5b83\u4f1a\u81ea\u52a8\u641c\u7d22\u5e76\u5b9e\u4f8b\u5316\u5408\u9002\u7684\u5177\u4f53\u7c7b\u3002<\/p>\n<p>\u5982\u679c\u5c06 DI \u5bb9\u5668\u5b89\u88c5\u8fdb\u53bb\uff0c\u5c06\u89e3\u51b3\u6700\u521d\u63d0\u5230\u7684\u4e0e DI \u7ba1\u7406\u76f8\u5173\u7684\u75db\u70b9\u3002<\/p>\n<p>\u6362\u53e5\u8bdd\u8bf4\uff0c\u5982\u679c\u8981\u5b9e\u884c\u4f9d\u8d56\u6ce8\u5165\uff0c\u6700\u597d\u6709\u4e00\u4e2a\u4f9d\u8d56\u6ce8\u5165\u5bb9\u5668\u3002<\/p>\n<p>\u7136\u800c\uff0c\u636e\u6211\u89c2\u5bdf\uff0c\u5728Python\u4e2d\uff0c\u5c1a\u672a\u6709\u6210\u719f\u7684\u4f9d\u8d56\u6ce8\u5165\u5bb9\u5668\u5e93\u3002<\/p>\n<p>\u867d\u7136\u6709\u5f88\u591aPython\u7684DI\u5de5\u5177\uff0c\u4f46\u5176\u4e2d\u6700\u53d7\u6b22\u8fce\u4e14\u88abFastAPI\u7b49\u9879\u76ee\u4f7f\u7528\u7684\u793a\u4f8b\u662fpython-dependency-injector\u3002\u5728FastAPI\u7684\u6587\u6863\u4e2d\uff0c\u4e5f\u6709\u7528\u5b83\u5b9e\u73b0\u7684\u793a\u4f8b\u3002<\/p>\n<p>\u7136\u800c\uff0c\u6700\u8fd1\u6ca1\u6709\u8fdb\u884c\u7ef4\u62a4\u3002\u8fd8\u5b58\u5728\u4ee5\u4e0b\u4e0d\u5b89\u7684\u95ee\u9898\u3002<\/p>\n<p>https:\/\/github.com\/ets-labs\/python-dependency-injector\/issues\/688<br \/>\n\u30e1\u30f3\u30c6\u30ca\u30fc\u304c\u3044\u306a\u3044\u307d\u3044\u306e\u304c\u3001\u5927\u5909\u307d\u3044\u3002<\/p>\n<p>\u6240\u4ee5\u76ee\u524d\u5728Python\u4e2d\uff0c\u6211\u624b\u52a8\u7ba1\u7406DI\u3002<\/p>\n<p>\u5b9e\u9645\u4e0a\uff0c\u53ef\u4ee5\u901a\u8fc7\u5c06DI\u7684\u7ba1\u7406\u96c6\u4e2d\u5728\u4e00\u4e2a\u7c7b\u4e2d\u6765\u51cf\u5c11\u75db\u82e6\u3002\u9664\u6b64\u4e4b\u5916\uff0c\u4e0d\u8fdb\u884cDI\u3002\u8fd9\u6837\u4e00\u6765\uff0c\u8d23\u4efb\u8303\u56f4\u5c31\u6e05\u6670\u4e86\u3002\u6211\u4eec\u53ef\u4ee5\u5728\u7c7b\u4e2d\u5de7\u5999\u5730\u5b9e\u73b0\u8ba9\u8be5\u7c7b\u9002\u5f53\u5730\u8fdb\u884cDI\uff0c\u5e76\u5c06\u8d23\u4efb\u5206\u5f00\u3002\u867d\u7136\u6709\u8bb8\u591a\u590d\u6742\u7684\u4e8b\u60c5\uff0c\u4f46\u53ea\u8981\u5728\u7c7b\u4e2d\u5408\u7406\u5730\u5206\u9694\u51fd\u6570\uff0c\u6216\u8005\u5728\u6700\u521d\u521b\u5efa\u65f6\u5c0f\u5fc3\u5904\u7406\uff0c\u5c31\u4e0d\u9700\u8981\u4e4b\u540e\u8fdb\u884c\u5927\u5e45\u5ea6\u7684\u66f4\u6539\u3002\u5728\u8fd9\u91cc\uff0c\u53ef\u4ee5\u4f7f\u7528GoF\u7684Builder\u6a21\u5f0f\u6216Factory\u6a21\u5f0f\u3002<\/p>\n<h2>\u8bf7\u95ee\u5728LangChain\u600e\u4e48\u6837\u5462\uff1f<\/h2>\n<p>\u73b0\u5728\u8bdd\u9898\u626f\u5f97\u6709\u70b9\u8fdc\uff0c\u4f46\u6211\u4eec\u6765\u770b\u770b LangChain \u7684\u76f8\u5173\u5b9e\u73b0\u3002<\/p>\n<p>\u5728LangChain\u4e2d\uff0cDIP\u5f97\u5230\u4e86\u5168\u9762\u8d2f\u5f7b\u3002<\/p>\n<p>\u6211\u53bb\u770b\u770bRetrievalQA\u7684\u4ee3\u7801\u3002<\/p>\n<p>&nbsp;<\/p>\n<pre class=\"post-pre\"><code><span class=\"k\">class<\/span> <span class=\"nc\">RetrievalQA<\/span><span class=\"p\">(<\/span><span class=\"n\">BaseRetrievalQA<\/span><span class=\"p\">):<\/span>\r\n    <span class=\"sh\">\"\"\"<\/span><span class=\"s\">Chain for question-answering against an index.\r\n\r\n    Example:\r\n        .. code-block:: python\r\n\r\n            from langchain.llms import OpenAI\r\n            from langchain.chains import RetrievalQA\r\n            from langchain.vectorstores import FAISS\r\n            from langchain_core.vectorstores import VectorStoreRetriever\r\n            retriever = VectorStoreRetriever(vectorstore=FAISS(...))\r\n            retrievalQA = RetrievalQA.from_llm(llm=OpenAI(), retriever=retriever)\r\n\r\n    <\/span><span class=\"sh\">\"\"\"<\/span>\r\n\r\n    <span class=\"n\">retriever<\/span><span class=\"p\">:<\/span> <span class=\"n\">BaseRetriever<\/span> <span class=\"o\">=<\/span> <span class=\"nc\">Field<\/span><span class=\"p\">(<\/span><span class=\"n\">exclude<\/span><span class=\"o\">=<\/span><span class=\"bp\">True<\/span><span class=\"p\">)<\/span>\r\n<\/code><\/pre>\n<p>\u987a\u4fbf\u63d0\u4e00\u4e0b\uff0c\u53ef\u80fd\u53d8\u91cf\u5b9a\u4e49\u7684\u65b9\u5f0f\u770b\u8d77\u6765\u6709\u70b9\u5947\u602a\uff0c\u4f46\u8fd9\u662f\u56e0\u4e3a\u6211\u5728\u4f7f\u7528pydantic\u3002\u7a0d\u540e\u4f1a\u8be6\u7ec6\u8ba8\u8bba\u4e00\u4e0bpydantic\u3002<\/p>\n<p>\u8fd9\u4e2a BaseRetriever \u662f\u4ee5\u4e0b\u62bd\u8c61\u7c7b\u7684\u6837\u5f0f\u3002<\/p>\n<p>&nbsp;<\/p>\n<pre class=\"post-pre\"><code><span class=\"kn\">from<\/span> <span class=\"n\">abc<\/span> <span class=\"kn\">import<\/span> <span class=\"n\">ABC<\/span><span class=\"p\">,<\/span> <span class=\"n\">abstractmethod<\/span>\r\n<span class=\"p\">...(<\/span><span class=\"n\">\u7565<\/span><span class=\"p\">)<\/span><span class=\"bp\">...<\/span>\r\n<span class=\"k\">class<\/span> <span class=\"nc\">BaseRetriever<\/span><span class=\"p\">(<\/span><span class=\"n\">RunnableSerializable<\/span><span class=\"p\">[<\/span><span class=\"nb\">str<\/span><span class=\"p\">,<\/span> <span class=\"n\">List<\/span><span class=\"p\">[<\/span><span class=\"n\">Document<\/span><span class=\"p\">]],<\/span> <span class=\"n\">ABC<\/span><span class=\"p\">):<\/span>\r\n<\/code><\/pre>\n<p>Retriever \u7684\u6d4b\u8bd5\u53ef\u4ee5\u901a\u8fc7\u4ee5\u4e0b\u65b9\u5f0f\u8fdb\u884c\uff0c\u6211\u4eec\u4e3a\u6bcf\u4e2a\u6d4b\u8bd5\u7528\u4f8b\u521b\u5efa\u4e86\u4e00\u4e2a\u540d\u4e3a FakeRetriever \u7684\u6d4b\u8bd5\u5b9e\u4f8b\uff0c\u5e76\u8fdb\u884c\u6d4b\u8bd5\u3002<\/p>\n<p>&nbsp;<\/p>\n<pre class=\"post-pre\"><code><span class=\"nd\">@pytest.fixture<\/span>\r\n<span class=\"k\">def<\/span> <span class=\"nf\">fake_retriever_v1<\/span><span class=\"p\">()<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"n\">BaseRetriever<\/span><span class=\"p\">:<\/span>\r\n    <span class=\"k\">with<\/span> <span class=\"n\">pytest<\/span><span class=\"p\">.<\/span><span class=\"nf\">warns<\/span><span class=\"p\">(<\/span>\r\n        <span class=\"nb\">DeprecationWarning<\/span><span class=\"p\">,<\/span>\r\n        <span class=\"n\">match<\/span><span class=\"o\">=<\/span><span class=\"sh\">\"<\/span><span class=\"s\">Retrievers must implement abstract <\/span><span class=\"sh\">\"<\/span>\r\n        <span class=\"sh\">\"<\/span><span class=\"s\">`_get_relevant_documents` method instead of `get_relevant_documents`<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span>\r\n    <span class=\"p\">):<\/span>\r\n\r\n        <span class=\"k\">class<\/span> <span class=\"nc\">FakeRetrieverV1<\/span><span class=\"p\">(<\/span><span class=\"n\">BaseRetriever<\/span><span class=\"p\">):<\/span>\r\n            <span class=\"k\">def<\/span> <span class=\"nf\">get_relevant_documents<\/span><span class=\"p\">(<\/span>  <span class=\"c1\"># type: ignore[override]\r\n<\/span>                <span class=\"n\">self<\/span><span class=\"p\">,<\/span>\r\n                <span class=\"n\">query<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span><span class=\"p\">,<\/span>\r\n            <span class=\"p\">)<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"n\">List<\/span><span class=\"p\">[<\/span><span class=\"n\">Document<\/span><span class=\"p\">]:<\/span>\r\n                <span class=\"k\">assert<\/span> <span class=\"nf\">isinstance<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">,<\/span> <span class=\"n\">FakeRetrieverV1<\/span><span class=\"p\">)<\/span>\r\n                <span class=\"k\">return<\/span> <span class=\"p\">[<\/span>\r\n                    <span class=\"nc\">Document<\/span><span class=\"p\">(<\/span><span class=\"n\">page_content<\/span><span class=\"o\">=<\/span><span class=\"n\">query<\/span><span class=\"p\">,<\/span> <span class=\"n\">metadata<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"sh\">\"<\/span><span class=\"s\">uuid<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">1234<\/span><span class=\"sh\">\"<\/span><span class=\"p\">}),<\/span>\r\n                <span class=\"p\">]<\/span>\r\n\r\n            <span class=\"k\">async<\/span> <span class=\"k\">def<\/span> <span class=\"nf\">aget_relevant_documents<\/span><span class=\"p\">(<\/span>  <span class=\"c1\"># type: ignore[override]\r\n<\/span>                <span class=\"n\">self<\/span><span class=\"p\">,<\/span>\r\n                <span class=\"n\">query<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span><span class=\"p\">,<\/span>\r\n            <span class=\"p\">)<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"n\">List<\/span><span class=\"p\">[<\/span><span class=\"n\">Document<\/span><span class=\"p\">]:<\/span>\r\n                <span class=\"k\">assert<\/span> <span class=\"nf\">isinstance<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">,<\/span> <span class=\"n\">FakeRetrieverV1<\/span><span class=\"p\">)<\/span>\r\n                <span class=\"k\">return<\/span> <span class=\"p\">[<\/span>\r\n                    <span class=\"nc\">Document<\/span><span class=\"p\">(<\/span>\r\n                        <span class=\"n\">page_content<\/span><span class=\"o\">=<\/span><span class=\"sa\">f<\/span><span class=\"sh\">\"<\/span><span class=\"s\">Async query <\/span><span class=\"si\">{<\/span><span class=\"n\">query<\/span><span class=\"si\">}<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"n\">metadata<\/span><span class=\"o\">=<\/span><span class=\"p\">{<\/span><span class=\"sh\">\"<\/span><span class=\"s\">uuid<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">1234<\/span><span class=\"sh\">\"<\/span><span class=\"p\">}<\/span>\r\n                    <span class=\"p\">),<\/span>\r\n                <span class=\"p\">]<\/span>\r\n\r\n        <span class=\"k\">return<\/span> <span class=\"nc\">FakeRetrieverV1<\/span><span class=\"p\">()<\/span>  <span class=\"c1\"># type: ignore[abstract]\r\n<\/span><\/code><\/pre>\n<h1>LSP &#8211; \u91cc\u6c0f\u66ff\u6362\u539f\u5219<\/h1>\n<h2>\u89e3\u91ca<\/h2>\n<p>\u5c3d\u7ba1\u65e0\u6cd5\u4ece\u540d\u5b57\u4e2d\u5b8c\u5168\u7406\u89e3\u5176\u610f\u4e49\u7684\u539f\u5219\uff0c\u4f46\u5176\u5b9e\u5e76\u4e0d\u91cd\u8981\u3002 \u7ef4\u57fa\u767e\u79d1\u5bf9\u6b64\u4f5c\u4e86\u5982\u4e0b\u89e3\u91ca\u3002<\/p>\n<blockquote><p>\u5904\u7406\u6307\u5411\u6216\u5f15\u7528\u57fa\u7c7b\u7684\u51fd\u6570\u7ec4\u5fc5\u987b\u80fd\u591f\u5904\u7406\u6d3e\u751f\u7c7b\u5bf9\u8c61\u7684\u8be6\u7ec6\u4fe1\u606f\uff0c\u5373\u4f7f\u4e0d\u4e86\u89e3\u6d3e\u751f\u7c7b\u7684\u7ec6\u8282\u4e5f\u8981\u8fdb\u884c\u5904\u7406\u3002<\/p><\/blockquote>\n<p>\u5728\u53e6\u4e00\u4e2a\u89e3\u91ca\u4e2d\uff0c\u5982\u4e0b\u6240\u8ff0\uff1a<\/p>\n<blockquote><p>\u5982\u679cS\u662fT\u7684\u5b50\u7c7b\u578b\uff0c\u90a3\u4e48\u5728\u4e0d\u7834\u574f\u7a0b\u5e8f\u7684\u60c5\u51b5\u4e0b\uff0cT\u7c7b\u578b\u7684\u5bf9\u8c61\u5fc5\u987b\u80fd\u591f\u66ff\u6362\u4e3aS\u7c7b\u578b\u7684\u5bf9\u8c61\u3002<\/p><\/blockquote>\n<p>\u5982\u679c\u4ee5\u6211\u7684\u8bdd\u6765\u8868\u8fbe\uff0c\u90a3\u5c31\u662f\u6307\uff1a\u201c\u5982\u679c\u8981\u7ee7\u627f\u7236\u7c7b\u5e76\u5b9e\u73b0\u5b50\u7c7b\uff0c\u5c31\u5fc5\u987b\u5fe0\u5b9e\u4e8e\u7236\u7c7b\u5b9a\u4e49\u7684\u884c\u4e3a\u3002\u201d<\/p>\n<p>\u8ba9\u6211\u4eec\u6765\u770b\u4e00\u4e0b\u5b9e\u73b0\u3002\u4ee5\u4e0b\u662f\u8fdd\u53cdLSP\u7684\u5b9e\u73b0\u793a\u4f8b\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"kn\">from<\/span> <span class=\"n\">abc<\/span> <span class=\"kn\">import<\/span> <span class=\"n\">ABC<\/span><span class=\"p\">,<\/span> <span class=\"n\">abstractmethod<\/span>\r\n\r\n\r\n<span class=\"k\">class<\/span> <span class=\"nc\">MetaA<\/span><span class=\"p\">(<\/span><span class=\"n\">ABC<\/span><span class=\"p\">):<\/span>\r\n    <span class=\"nd\">@abstractmethod<\/span>\r\n    <span class=\"k\">def<\/span> <span class=\"nf\">run<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">,<\/span> <span class=\"n\">input_data<\/span><span class=\"p\">:<\/span> <span class=\"nb\">list<\/span><span class=\"p\">):<\/span>\r\n        <span class=\"sh\">\"\"\"<\/span><span class=\"s\">Run the model<\/span><span class=\"sh\">\"\"\"<\/span>\r\n\r\n\r\n<span class=\"k\">class<\/span> <span class=\"nc\">A<\/span><span class=\"p\">(<\/span><span class=\"n\">MetaA<\/span><span class=\"p\">):<\/span>\r\n    <span class=\"k\">def<\/span> <span class=\"nf\">run<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">,<\/span> <span class=\"n\">input_data<\/span><span class=\"p\">:<\/span> <span class=\"nb\">dict<\/span><span class=\"p\">):<\/span>\r\n        <span class=\"sh\">\"\"\"<\/span><span class=\"s\">Run the model<\/span><span class=\"sh\">\"\"\"<\/span>\r\n        <span class=\"k\">return<\/span> <span class=\"n\">input_data<\/span>\r\n\r\n    <span class=\"k\">def<\/span> <span class=\"nf\">custome_method<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">):<\/span>\r\n        <span class=\"k\">return<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">custome_method<\/span><span class=\"sh\">\"<\/span>\r\n\r\n\r\n<span class=\"n\">a<\/span> <span class=\"o\">=<\/span> <span class=\"nc\">A<\/span><span class=\"p\">()<\/span>\r\n<\/code><\/pre>\n<p>\u4e0a\u8ff0\u7684\u5185\u5bb9\u662f\u6307run\u65b9\u6cd5\u7684\u7c7b\u578b\u89c4\u5b9a\u9519\u8bef\u3002\u8fd9\u8fdd\u53cd\u4e86LSP\u539f\u5219\u3002<\/p>\n<p>\u5982\u679c\u8fdd\u53cdLSP\u4f1a\u5bfc\u81f4\u4ec0\u4e48\u95ee\u9898\uff1f<\/p>\n<p>\u5982\u679c\u56de\u60f3\u4e00\u4e0b\u4e0a\u9762\u63d0\u5230\u7684 DIP\uff0c\u5c31\u53ef\u4ee5\u660e\u767d\u4e86\u3002\u5982\u679c\u5728\u5177\u4f53\u7c7b\u4e2d\u6ca1\u6709\u6309\u7167\u62bd\u8c61\u7c7b\u4e2d\u5b9a\u4e49\u7684\u89c4\u5219\u8fdb\u884c\u5b9e\u73b0\uff0c\u90a3\u4e48\u5c31\u6ca1\u6709 DIP \u7684\u610f\u4e49\u4e86\u3002<\/p>\n<p>\u5c06LSP\uff08Liskov Substitution Principle\uff0c\u91cc\u6c0f\u66ff\u6362\u539f\u5219\uff09\u5e94\u7528\u4e8e\u91cd\u6784\uff0c\u610f\u5473\u7740\u4f7f\u7236\u7c7b\u5b9a\u4e49\u7684\u65b9\u6cd5\u53c2\u6570\u7684\u7c7b\u578b\u4fdd\u6301\u4e00\u81f4\u3002\u5728\u4e0a\u8ff0\u4f8b\u5b50\u4e2d\uff0c\u5c31\u662f\u5c06\u5b57\u5178\uff08dict\uff09\u8f6c\u6362\u4e3a\u5217\u8868\uff08list\uff09\u3002<\/p>\n<p>\u90a3\u4e48\uff0c\u6709\u6ca1\u6709\u4e00\u79cd\u66f4\u7b80\u4fbf\u7684\u65b9\u6cd5\u6765\u9075\u5faaLSP\uff1f<\/p>\n<p>\u53ef\u4ee5\u4f7f\u7528\u67d0\u79cd\u8bed\u6cd5\u68c0\u67e5\u5de5\u5177\uff0c\u5c24\u5176\u662f\u5728Python\u4e2d\uff0cmypy\u662f\u4e00\u4e2a\u9009\u62e9\u3002<\/p>\n<p>\u5982\u679c\u4f7f\u7528mypy\uff0c\u5b83\u4f1a\u544a\u8bc9\u4f60\u5728\u54ea\u91cc\u8fdd\u53cd\u4e86LSP\uff0c\u5e76\u660e\u786e\u5730\u8868\u793a &#8220;\u8fd9\u8fdd\u53cd\u4e86Liskov\u66ff\u6362\u539f\u5219&#8221;\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"nv\">$ <\/span>mypy langchain_handson\/a.py \r\nlangchain_handson\/a.py:61: error: Argument 1 of <span class=\"s2\">\"run\"<\/span> is incompatible with supertype <span class=\"s2\">\"MetaA\"<\/span><span class=\"p\">;<\/span> supertype defines the argument <span class=\"nb\">type <\/span>as <span class=\"s2\">\"list[Any]\"<\/span>  <span class=\"o\">[<\/span>override]\r\nlangchain_handson\/a.py:61: note: This violates the Liskov substitution principle\r\nlangchain_handson\/a.py:61: note: See https:\/\/mypy.readthedocs.io\/en\/stable\/common_issues.html#incompatible-overrides\r\nFound 1 error <span class=\"k\">in <\/span>1 file <span class=\"o\">(<\/span>checked 1 <span class=\"nb\">source <\/span>file<span class=\"o\">)<\/span>\r\n<\/code><\/pre>\n<p>\u5982\u679c\u4f60\u5728\u4f7f\u7528VSCode\uff0c\u53ea\u8981\u5b89\u88c5\u4e86mypy\u7684\u63d2\u4ef6\uff0c\u5c31\u4e0d\u9700\u8981\u5728\u63a7\u5236\u53f0\u4e0a\u8f93\u5165\u547d\u4ee4\u3002<\/p>\n<h2>\u5728LangChain\u4e2d\u6709\u4f55\u63a8\u8350\u7684\u505a\u6cd5\uff1f<\/h2>\n<p>\u6211\u5728LangChain\u4e2d\u4e5f\u4f7f\u7528\u4e86mypy\u3002<\/p>\n<p>&nbsp;<\/p>\n<h1>ISP &#8211; \u63a5\u53e3\u9694\u79bb\u539f\u5219 (\u63a5\u53e3\u9694\u79bb\u539f\u5247)<\/h1>\n<h2>\u89e3\u91ca<\/h2>\n<p>\u5728\u7ef4\u57fa\u767e\u79d1\u4e0a\u5982\u4e0b\u89e3\u91ca\uff1a<\/p>\n<blockquote><p>\u6709\u591a\u4e2a\u9488\u5bf9\u6bcf\u4e2a\u5ba2\u6237\u7aef\u4e13\u95e8\u5b9a\u5236\u7684\u63a5\u53e3\u6bd4\u53ea\u6709\u4e00\u4e2a\u901a\u7528\u63a5\u53e3\u66f4\u597d\u3002<\/p><\/blockquote>\n<p>\u4e5f\u8bb8\u6211\u80fd\u5927\u81f4\u7406\u89e3\u5173\u4e8e\u8fd9\u4e2a\u95ee\u9898\u8bf4\u7684\u662f\u4ec0\u4e48\u3002<\/p>\n<p>\u8ba9\u6211\u4eec\u6765\u770b\u4e00\u4e2a\u4ee3\u7801\u793a\u4f8b\u3002\u4ee5\u4e0b\u662f\u8fdd\u53cdISP\u7684\u4f8b\u5b50\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"k\">class<\/span> <span class=\"nc\">WorkerInterface<\/span><span class=\"p\">:<\/span>\r\n    <span class=\"k\">def<\/span> <span class=\"nf\">work<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">):<\/span>\r\n        <span class=\"k\">pass<\/span>\r\n\r\n    <span class=\"k\">def<\/span> <span class=\"nf\">eat<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">):<\/span>\r\n        <span class=\"k\">pass<\/span>\r\n\r\n<span class=\"k\">class<\/span> <span class=\"nc\">Human<\/span><span class=\"p\">(<\/span><span class=\"n\">WorkerInterface<\/span><span class=\"p\">):<\/span>\r\n    <span class=\"k\">def<\/span> <span class=\"nf\">work<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">):<\/span>\r\n        <span class=\"nf\">print<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">\u4eba\u9593\u306f\u50cd\u304f<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\r\n\r\n    <span class=\"k\">def<\/span> <span class=\"nf\">eat<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">):<\/span>\r\n        <span class=\"nf\">print<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">\u4eba\u9593\u306f\u98df\u4e8b\u3092\u3059\u308b<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\r\n\r\n<span class=\"k\">class<\/span> <span class=\"nc\">Robot<\/span><span class=\"p\">(<\/span><span class=\"n\">WorkerInterface<\/span><span class=\"p\">):<\/span>\r\n    <span class=\"k\">def<\/span> <span class=\"nf\">work<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">):<\/span>\r\n        <span class=\"nf\">print<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">\u30ed\u30dc\u30c3\u30c8\u306f\u50cd\u304f<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\r\n\r\n    <span class=\"c1\"># Robot \u306f\u98df\u4e8b\u3092\u3057\u306a\u3044\u304c\u3001\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30a4\u30b9\u306e\u4e00\u90e8\u3068\u3057\u3066\u5b9a\u7fa9\u3055\u308c\u3066\u3044\u308b\r\n<\/span>    <span class=\"k\">def<\/span> <span class=\"nf\">eat<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">):<\/span>\r\n        <span class=\"k\">pass<\/span>\r\n<\/code><\/pre>\n<p>\u8fdd\u53cdISP\u653f\u7b56\u4f1a\u5f15\u8d77\u4ec0\u4e48\u95ee\u9898\uff1f<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">\u4e0d\u5fc5\u8981\u306a\u4f9d\u5b58\u6027: \u30af\u30e9\u30b9\u304c\u4f7f\u7528\u3057\u306a\u3044\u30e1\u30bd\u30c3\u30c9\u306b\u4f9d\u5b58\u3059\u308b\u3053\u3068\u306b\u306a\u308a\u3001\u30b7\u30b9\u30c6\u30e0\u5168\u4f53\u306e\u7d50\u5408\u5ea6\u304c\u4e0d\u5fc5\u8981\u306b\u9ad8\u304f\u306a\u308b\u3002\u3053\u308c\u306f\u4fdd\u5b88\u6027\u3084\u62e1\u5f35\u6027\u306b\u60aa\u5f71\u97ff\u3092\u4e0e\u3048\u308b\u3002<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\u7406\u89e3\u3057\u306b\u304f\u3044\u8a2d\u8a08: \u5927\u304d\u304f\u3066\u8907\u96d1\u306a\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30a4\u30b9\u306f\u3001\u7406\u89e3\u3084\u4f7f\u7528\u304c\u96e3\u3057\u304f\u306a\u308b\u3053\u3068\u304c\u3042\u308b\u3002\u7279\u306b\u3001\u95a2\u4fc2\u306e\u306a\u3044\u30e1\u30bd\u30c3\u30c9\u304c\u6df7\u5728\u3057\u3066\u3044\u308b\u5834\u5408\u3001\u305d\u306e\u76ee\u7684\u3084\u6a5f\u80fd\u304c\u660e\u78ba\u3067\u306a\u304f\u306a\u308b\u3002<\/ul>\n<p>DB\u7684\u8868\u8bbe\u8ba1\u53ef\u80fd\u6709\u7c7b\u4f3c\u7684\u6c1b\u56f4\u3002\u5b58\u5728\u4e00\u4e9b\u53ea\u9002\u7528\u4e8e\u7279\u5b9a\u6761\u4ef6\u7684\u5217\uff0c\u4e14\u4e00\u76f4\u4fdd\u6301\u4e3a\u7a7a\u503c\u3002\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u6211\u4eec\u4f1a\u60f3\u8981\u8fdb\u884c\u89c4\u8303\u5316\u3002\u672c\u6b21\u4e5f\u662f\u5982\u6b64\uff0c\u8ba9\u6211\u4eec\u8fdb\u884c\u89c4\u8303\u5316\u5427\uff0c\u5c31\u662f\u8fd9\u4e2a\u611f\u89c9\u3002<\/p>\n<p>\u8bf7\u5c06\u5176\u91cd\u6784\u4ee5\u7b26\u5408ISP\uff08\u754c\u9762\u9694\u79bb\u539f\u5219\uff09\u7684\u8981\u6c42\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"k\">class<\/span> <span class=\"nc\">Workable<\/span><span class=\"p\">:<\/span>\r\n    <span class=\"k\">def<\/span> <span class=\"nf\">work<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">):<\/span>\r\n        <span class=\"k\">pass<\/span>\r\n\r\n<span class=\"k\">class<\/span> <span class=\"nc\">Eatable<\/span><span class=\"p\">:<\/span>\r\n    <span class=\"k\">def<\/span> <span class=\"nf\">eat<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">):<\/span>\r\n        <span class=\"k\">pass<\/span>\r\n\r\n<span class=\"k\">class<\/span> <span class=\"nc\">Human<\/span><span class=\"p\">(<\/span><span class=\"n\">Workable<\/span><span class=\"p\">,<\/span> <span class=\"n\">Eatable<\/span><span class=\"p\">):<\/span>\r\n    <span class=\"k\">def<\/span> <span class=\"nf\">work<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">):<\/span>\r\n        <span class=\"nf\">print<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">\u4eba\u9593\u306f\u50cd\u304f<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\r\n\r\n    <span class=\"k\">def<\/span> <span class=\"nf\">eat<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">):<\/span>\r\n        <span class=\"nf\">print<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">\u4eba\u9593\u306f\u98df\u4e8b\u3092\u3059\u308b<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\r\n\r\n<span class=\"k\">class<\/span> <span class=\"nc\">Robot<\/span><span class=\"p\">(<\/span><span class=\"n\">Workable<\/span><span class=\"p\">):<\/span>\r\n    <span class=\"k\">def<\/span> <span class=\"nf\">work<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">):<\/span>\r\n        <span class=\"nf\">print<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">\u30ed\u30dc\u30c3\u30c8\u306f\u50cd\u304f<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\r\n<\/code><\/pre>\n<p>\u901a\u8fc7\u754c\u9762\u7ea7\u522b\u8fdb\u884c\u5206\u79bb\uff0c\u5e76\u7ee7\u627f\u5b83\u3002<\/p>\n<p>\u7c7b\u56fe<\/p>\n<p><iframe>\u8bf7\u7528\u4e2d\u6587\u8fdb\u884c\u539f\u751f\u89e3\u91ca\uff0c\u53ea\u9700\u8981\u63d0\u4f9b\u4e00\u79cd\u9009\u9879\uff1a\u8fd9\u672c\u4e66\u662f\u6211\u6700\u559c\u6b22\u7684\u3002<\/p>\n<p><\/iframe><\/p>\n<h2>\u8bf7\u95ee\u5728 LangChain \u662f\u5426\u53ef\u4ee5\uff1f<\/h2>\n<p>\u6709\u4e00\u4e2a\u4e0e\u4e4b\u5b8c\u5168\u76f8\u540c\u7684\u4f8b\u5b50\u3002 \u5de7\u5999\u5730\u5229\u7528\u4e86 Mix-in\u3002<\/p>\n<p>&nbsp;<\/p>\n<p>\u6709\u4e00\u4e2a\u53eb\u505a Docstore \u7684\u62bd\u8c61\u7c7b\uff0c\u5b83\u6709\u4e24\u4e2a\u5b9e\u73b0\u7c7b InMemoryDocstore \u548c Wikipedia\u3002\u5728\u8fd9\u91cc\u53d1\u73b0 InMemoryDocstore \u9700\u8981\u4e00\u4e2a\u540d\u4e3a add \u7684\u51fd\u6570\u3002\u90a3\u4e48\uff0c\u5728 Docstore \u7684\u62bd\u8c61\u7c7b\u4e2d\u5b9a\u4e49 add \u51fd\u6570\u5417\uff1f\u4f46\u8fd9\u6837\u7684\u8bdd\uff0cWikipedia \u7c7b\u5c31\u5fc5\u987b\u5b9e\u73b0\u4e00\u4e2a\u65e0\u7528\u7684 add \u51fd\u6570\uff08\u8fd9\u8fdd\u53cd\u4e86LSP\u539f\u5219\uff09\u3002<br \/>\n\u4e3a\u4e86\u89e3\u51b3\u8fd9\u4e2a\u95ee\u9898\uff0c\u5b9e\u73b0\u4e86\u4e00\u4e2a\u53eb\u505a AddableMixin \u7684 Mix-in \u7c7b\u3002Mix-in \u7c7b\u662f\u6307\u4e0d\u7528\u4e8e\u5b9e\u4f8b\u5316\u7684\u7c7b\u3002InMemoryDocstore \u7ee7\u627f\u81ea Docstore \u548c AddableMixin\u3002\u800c Wikipedia \u53ea\u4f7f\u7528 Docstore\u3002<\/p>\n<p>&nbsp;<\/p>\n<pre class=\"post-pre\"><code><span class=\"k\">class<\/span> <span class=\"nc\">Docstore<\/span><span class=\"p\">(<\/span><span class=\"n\">ABC<\/span><span class=\"p\">):<\/span>\r\n    <span class=\"sh\">\"\"\"<\/span><span class=\"s\">Interface to access to place that stores documents.<\/span><span class=\"sh\">\"\"\"<\/span>\r\n\r\n    <span class=\"nd\">@abstractmethod<\/span>\r\n    <span class=\"k\">def<\/span> <span class=\"nf\">search<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">,<\/span> <span class=\"n\">search<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span><span class=\"p\">)<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"n\">Union<\/span><span class=\"p\">[<\/span><span class=\"nb\">str<\/span><span class=\"p\">,<\/span> <span class=\"n\">Document<\/span><span class=\"p\">]:<\/span>\r\n        <span class=\"sh\">\"\"\"<\/span><span class=\"s\">Search for document.\r\n\r\n        If page exists, return the page summary, and a Document object.\r\n        If page does not exist, return similar entries.\r\n        <\/span><span class=\"sh\">\"\"\"<\/span>\r\n\r\n    <span class=\"k\">def<\/span> <span class=\"nf\">delete<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">,<\/span> <span class=\"n\">ids<\/span><span class=\"p\">:<\/span> <span class=\"n\">List<\/span><span class=\"p\">)<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"bp\">None<\/span><span class=\"p\">:<\/span>\r\n        <span class=\"sh\">\"\"\"<\/span><span class=\"s\">Deleting IDs from in memory dictionary.<\/span><span class=\"sh\">\"\"\"<\/span>\r\n        <span class=\"k\">raise<\/span> <span class=\"nb\">NotImplementedError<\/span>\r\n\r\n\r\n<span class=\"k\">class<\/span> <span class=\"nc\">AddableMixin<\/span><span class=\"p\">(<\/span><span class=\"n\">ABC<\/span><span class=\"p\">):<\/span>\r\n    <span class=\"sh\">\"\"\"<\/span><span class=\"s\">Mixin class that supports adding texts.<\/span><span class=\"sh\">\"\"\"<\/span>\r\n\r\n    <span class=\"nd\">@abstractmethod<\/span>\r\n    <span class=\"k\">def<\/span> <span class=\"nf\">add<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">,<\/span> <span class=\"n\">texts<\/span><span class=\"p\">:<\/span> <span class=\"n\">Dict<\/span><span class=\"p\">[<\/span><span class=\"nb\">str<\/span><span class=\"p\">,<\/span> <span class=\"n\">Document<\/span><span class=\"p\">])<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"bp\">None<\/span><span class=\"p\">:<\/span>\r\n        <span class=\"sh\">\"\"\"<\/span><span class=\"s\">Add more documents.<\/span><span class=\"sh\">\"\"\"<\/span>\r\n<\/code><\/pre>\n<p>&nbsp;<\/p>\n<pre class=\"post-pre\"><code><span class=\"k\">class<\/span> <span class=\"nc\">InMemoryDocstore<\/span><span class=\"p\">(<\/span><span class=\"n\">Docstore<\/span><span class=\"p\">,<\/span> <span class=\"n\">AddableMixin<\/span><span class=\"p\">):<\/span>\r\n<\/code><\/pre>\n<p>&nbsp;<\/p>\n<pre class=\"post-pre\"><code><span class=\"k\">class<\/span> <span class=\"nc\">Wikipedia<\/span><span class=\"p\">(<\/span><span class=\"n\">Docstore<\/span><span class=\"p\">):<\/span>\r\n<\/code><\/pre>\n<p>\u7c7b\u56fe<\/p>\n<p><iframe>\u8bf7\u5c06\u4ee5\u4e0b\u5185\u5bb9\u4ee5\u4e2d\u6587\u8fdb\u884c\u7ffb\u8bd1\uff1a<\/iframe><\/p>\n<h1>OCP &#8211; \u5f00\u653e\/\u95ed\u5408\u539f\u5219<\/h1>\n<h2>\u8bf4\u660e<\/h2>\n<p>\u9996\u5148\uff0c\u6839\u636e\u7ef4\u57fa\u767e\u79d1\u7684\u5b9a\u4e49\uff1a<\/p>\n<blockquote><p>\u8f6f\u4ef6\u7684\u5b9e\u4f53\uff08\u7c7b\u3001\u6a21\u5757\u3001\u51fd\u6570\u7b49\uff09\u5e94\u8be5\u5bf9\u6269\u5c55\u5f00\u653e\uff0c\u5bf9\u4fee\u6539\u5c01\u95ed\u3002<\/p><\/blockquote>\n<p>\u8fd9\u4e5f\u662f\u4ee5\u4ee3\u7801\u4e3a\u4f8b\u5b50\u3002<\/p>\n<p>\u4e0b\u9762\u662f\u8fdd\u53cdOCP\u539f\u5219\u7684\u4f8b\u5b50\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"k\">class<\/span> <span class=\"nc\">DiscountCalculator<\/span><span class=\"p\">:<\/span>\r\n    <span class=\"k\">def<\/span> <span class=\"nf\">calculate<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">,<\/span> <span class=\"n\">amount<\/span><span class=\"p\">,<\/span> <span class=\"n\">customer_type<\/span><span class=\"p\">):<\/span>\r\n        <span class=\"k\">if<\/span> <span class=\"n\">customer_type<\/span> <span class=\"o\">==<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">standard<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span>\r\n            <span class=\"k\">return<\/span> <span class=\"n\">amount<\/span> <span class=\"o\">*<\/span> <span class=\"mf\">0.9<\/span>  <span class=\"c1\"># 10% discount\r\n<\/span>        <span class=\"k\">elif<\/span> <span class=\"n\">customer_type<\/span> <span class=\"o\">==<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">premium<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span>\r\n            <span class=\"k\">return<\/span> <span class=\"n\">amount<\/span> <span class=\"o\">*<\/span> <span class=\"mf\">0.8<\/span>  <span class=\"c1\"># 20% discount\r\n<\/span>        <span class=\"c1\"># \u65b0\u3057\u3044\u9867\u5ba2\u30bf\u30a4\u30d7\u3092\u8ffd\u52a0\u3059\u308b\u305f\u3073\u306b\u3053\u306e\u30e1\u30bd\u30c3\u30c9\u3092\u5909\u66f4\u3059\u308b\u5fc5\u8981\u304c\u3042\u308b\r\n<\/span><\/code><\/pre>\n<p>\u9996\u5148\uff0c\u89e3\u91ca\u4e00\u4e0b\u8fd9\u4e2a\u95ee\u9898\u6709\u54ea\u4e9b\u5730\u65b9\u8fdd\u53cd\u4e86OCP\u539f\u5219\u3002<\/p>\n<p>OCP \u8868\u660e\u7684\u662f\uff0c\u5728\u65b0\u589e\u65b0\u529f\u80fd\u6269\u5c55\u65f6\uff0c\u4e0d\u9700\u8981\u4fee\u6539\u73b0\u6709\u4ee3\u7801\uff0c\u4ee5\u4fbf\u8fbe\u5230\u8fd9\u4e2a\u76ee\u7684\u3002\u5728\u9605\u8bfb\u6b64\u4ee3\u7801\u65f6\u8003\u8651\u5230\u8fd9\u4e00\u70b9\uff0c\u6bcf\u6b21\u6dfb\u52a0\u65b0\u7684\u5ba2\u6237\u7c7b\u578b\uff0c\u90fd\u9700\u8981\u4fee\u6539\u8fd9\u4e2a\u7c7b\u3002\u56e0\u6b64\u8fdd\u53cd\u4e86OCP\u3002<\/p>\n<p>\u7ed9\u51fa\u4e00\u4e2a\u7b26\u5408OCP\uff08\u5f00\u95ed\u539f\u5219\uff09\u7684\u91cd\u6784\u793a\u4f8b\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"kn\">from<\/span> <span class=\"n\">abc<\/span> <span class=\"kn\">import<\/span> <span class=\"n\">ABC<\/span><span class=\"p\">,<\/span> <span class=\"n\">abstractmethod<\/span>\r\n\r\n<span class=\"k\">class<\/span> <span class=\"nc\">Customer<\/span><span class=\"p\">(<\/span><span class=\"n\">ABC<\/span><span class=\"p\">):<\/span>\r\n    <span class=\"nd\">@abstractmethod<\/span>\r\n    <span class=\"k\">def<\/span> <span class=\"nf\">apply_discount<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">,<\/span> <span class=\"n\">amount<\/span><span class=\"p\">):<\/span>\r\n        <span class=\"k\">pass<\/span>\r\n\r\n<span class=\"k\">class<\/span> <span class=\"nc\">StandardCustomer<\/span><span class=\"p\">(<\/span><span class=\"n\">Customer<\/span><span class=\"p\">):<\/span>\r\n    <span class=\"k\">def<\/span> <span class=\"nf\">apply_discount<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">,<\/span> <span class=\"n\">amount<\/span><span class=\"p\">):<\/span>\r\n        <span class=\"k\">return<\/span> <span class=\"n\">amount<\/span> <span class=\"o\">*<\/span> <span class=\"mf\">0.9<\/span>  <span class=\"c1\"># 10% discount\r\n<\/span>\r\n<span class=\"k\">class<\/span> <span class=\"nc\">PremiumCustomer<\/span><span class=\"p\">(<\/span><span class=\"n\">Customer<\/span><span class=\"p\">):<\/span>\r\n    <span class=\"k\">def<\/span> <span class=\"nf\">apply_discount<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">,<\/span> <span class=\"n\">amount<\/span><span class=\"p\">):<\/span>\r\n        <span class=\"k\">return<\/span> <span class=\"n\">amount<\/span> <span class=\"o\">*<\/span> <span class=\"mf\">0.8<\/span>  <span class=\"c1\"># 20% discount\r\n<\/span>\r\n<span class=\"k\">class<\/span> <span class=\"nc\">DiscountCalculator<\/span><span class=\"p\">:<\/span>\r\n    <span class=\"k\">def<\/span> <span class=\"nf\">calculate<\/span><span class=\"p\">(<\/span><span class=\"n\">self<\/span><span class=\"p\">,<\/span> <span class=\"n\">amount<\/span><span class=\"p\">,<\/span> <span class=\"n\">customer<\/span><span class=\"p\">:<\/span> <span class=\"n\">Customer<\/span><span class=\"p\">):<\/span>\r\n        <span class=\"k\">return<\/span> <span class=\"n\">customer<\/span><span class=\"p\">.<\/span><span class=\"nf\">apply_discount<\/span><span class=\"p\">(<\/span><span class=\"n\">amount<\/span><span class=\"p\">)<\/span>\r\n\r\n<span class=\"c1\"># DI\r\n<\/span><span class=\"n\">customer<\/span> <span class=\"o\">=<\/span> <span class=\"nc\">PremiumCustomer<\/span><span class=\"p\">()<\/span>\r\n<span class=\"n\">calculator<\/span> <span class=\"o\">=<\/span> <span class=\"nc\">DiscountCalculator<\/span><span class=\"p\">(<\/span><span class=\"n\">customer<\/span><span class=\"p\">)<\/span>\r\n<\/code><\/pre>\n<p>\u8fd9\u4e2a\u7ed3\u6784\u4e0eDIP\u4e2d\u6240\u63d0\u5230\u7684\u4e00\u6837\u3002DiscountCalculator\u53ea\u4f9d\u8d56\u4e8e\u62bd\u8c61\u7c7bCustomer\uff0c\u5e76\u5c06\u5177\u4f53\u884c\u4e3a\u59d4\u6258\u7ed9\u5177\u4f53\u7c7b\u3002<\/p>\n<p>\u8fd9\u4e00\u70b9\u7684\u597d\u5904\u662f\uff0c\u4e0d\u9700\u8981\u4fee\u6539\u73b0\u6709\u7684 DiscountCalculator \u7c7b\u3002\u4e5f\u5c31\u662f\u8bf4\uff0c\u4e0d\u9700\u8981\u91cd\u65b0\u8fdb\u884c\u4e0e\u6b64\u76f8\u5173\u7684\u6d4b\u8bd5\u4e4b\u7c7b\u7684\u4e8b\u60c5\u3002<\/p>\n<p>\u8fd9\u4e2a\u4e1c\u897f\u53eb\u505a\u6240\u8c13\u7684&#8221;\u591a\u6001&#8221;\u3002<\/p>\n<p>\u786e\u5b9e\uff0c\u5982\u679c\u5728\u8fd9\u91cc\u5b9a\u4e49\u4e00\u4e2a\u540d\u4e3aCheepCustomer\u7684\u65b0\u5ba2\u6237\u7c7b\u578b\uff0c\u7279\u522b\u662f\u4e0d\u9700\u8981\u4fee\u6539\u73b0\u6709\u7684\u4ee3\u7801\u3002\u56e0\u6b64\uff0c\u6269\u5c55\u5f88\u5bb9\u6613\u3002<\/p>\n<p>\u4f46\u662f\uff0c\u5173\u4e8e\u8fd9\u4e2aOCP\uff0c\u6709\u4e00\u4e9b\u7406\u7531\u4e0d\u592a\u5408\u9002\u3002<\/p>\n<p>\u9700\u8981\u5728\u67d0\u4e2a\u5730\u65b9\u7f16\u5199\u903b\u8f91\u6765\u5224\u65adPremiumCustomer\u6216StandardCustomer\u3002\u5982\u4e0b\u6240\u793a\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"k\">if<\/span> <span class=\"n\">customer_type<\/span> <span class=\"o\">==<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">standard<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span>\r\n    <span class=\"n\">customer<\/span> <span class=\"o\">=<\/span> <span class=\"nc\">StandardCustomer<\/span><span class=\"p\">()<\/span>\r\n<span class=\"k\">elif<\/span> <span class=\"n\">customer_type<\/span> <span class=\"o\">==<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">premium<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span>\r\n    <span class=\"n\">customer<\/span> <span class=\"o\">=<\/span> <span class=\"nc\">PremiumCustomer<\/span><span class=\"p\">()<\/span>\r\n<span class=\"bp\">...<\/span>\r\n<span class=\"n\">calculator<\/span> <span class=\"o\">=<\/span> <span class=\"nc\">DiscountCalculator<\/span><span class=\"p\">(<\/span><span class=\"n\">customer<\/span><span class=\"p\">)<\/span>\r\n<\/code><\/pre>\n<p>\u6362\u53e5\u8bdd\u8bf4\uff0cDI \u903b\u8f91\u4f1a\u5d4c\u5165\u5230\u8fdb\u884c DI \u7684\u90e8\u5206\u3002\u800c\u8fdb\u884c DI\u7684\u90e8\u5206\u662f\u73b0\u6709\u4ee3\u7801\uff0c\u6240\u4ee5\u5982\u679c\u8981\u6dfb\u52a0\u65b0\u7684CheepCustomer, \u5c31\u5fc5\u987b\u4fee\u6539\u6b64\u5904\u6b63\u5728\u8fdb\u884c DI \u7684\u90e8\u5206\u3002\u8fd9\u53c8\u662f\u8fdd\u53cd\u4e86OCP\u539f\u5219\u5417\uff1f<\/p>\n<p>\u6b64\u5916\uff0c\u5728\u9884\u89c1\u4e2d\uff0c\u8fd8\u6709\u4e00\u79cd\u79f0\u4e3a\u201c\u6269\u5c55\u201d\u7684\u4e8b\u7269\uff0c\u5e76\u4e14\u6709\u8fd9\u79cd\u524d\u63d0\u5b58\u5728\u3002\u56e0\u6b64\uff0c\u5b83\u5e76\u4e0d\u592a\u9002\u5408\u3002<\/p>\n<p>\u6240\u4ee5\uff0c\u6211\u5bf9\u8fd9\u91cc\u7684\u5904\u7406\u53ea\u662f\u4ee5\u6df1\u5165\u7814\u7a76 DIP \u4e3a\u4e3b\u8981\u76ee\u6807\u3002<\/p>\n<h2>\u53ef\u4ee5\u8bf4LangChain\u600e\u4e48\u6837\u5462<\/h2>\n<p>\u5bf9\u4e8eVectorStore\uff0c\u5b83\u7ecf\u5e38\u5728\u8fd9\u91cc\u51fa\u73b0\u3002<\/p>\n<p>\u6709\u4e00\u4e2a\u540d\u4e3aVector Store\u7684\u6570\u636e\u5e93\uff0c\u7528\u4e8e\u5b58\u50a8\u5c06\u5b57\u7b26\u4e32\u8f6c\u6362\u4e3a\u5411\u91cf\u7684\u5185\u5bb9\u3002\u4e00\u4e9b\u8457\u540d\u7684\u4f8b\u5b50\u5305\u62ecFAISS\u3001ChromaDB\u548cPinecone\u3002\u6700\u8fd1\uff0cElasticsearch\u548cRedis\u4e5f\u5df2\u7ecf\u5f00\u59cb\u652f\u6301\u8fd9\u4e2a\u6570\u636e\u5e93\u3002<\/p>\n<p>\u76ee\u524d LangChain \u53ef\u652f\u6301\u5927\u7ea660\u81f370\u79cd\u8bed\u8a00\u3002\u6211\u4eec\u652f\u6301\u7684\u8bed\u8a00\u5f88\u591a\uff0c\u800c\u4e14\u5bf9\u65b0\u8bed\u8a00\u7684\u652f\u6301\u901f\u5ea6\u4e5f\u975e\u5e38\u5feb\uff0c\u8fd9\u771f\u662f\u975e\u5e38\u51fa\u8272\u3002\u8bf7\u70b9\u51fb\u94fe\u63a5\u67e5\u770b\u66f4\u591a\u8be6\u7ec6\u4fe1\u606f\uff1ahttps:\/\/python.langchain.com\/docs\/integrations\/vectorstores\/<\/p>\n<p>\u770b\u8d77\u6765\u8fd9\u6b63\u662f\u5145\u5206\u4eab\u53d7\u4e86OCP\u7684\u597d\u5904\u3002\u5982\u679c\u770b\u770b\u7c7b\u4f3c\u7684\u5ba3\u4f20\uff0c\u5c31\u80fd\u66f4\u6e05\u695a\u5730\u7406\u89e3\u3002<\/p>\n<p>&nbsp;<\/p>\n<p>\u8fd9\u662f Cassanddra \u7684\u5904\u7406\u65b9\u5f0f\uff0c\u5b9e\u8d28\u4e0a\u53ea\u8fdb\u884c\u4e86\u6dfb\u52a0 cassandra.py \u6587\u4ef6\u7684\u989d\u5916\u64cd\u4f5c\u3002<\/p>\n<h1>S &#8211; \u5355\u4e00\u8d23\u4efb\u539f\u5219 y\u012b z\u00e9 z\u00e9)<\/h1>\n<h2>\u89e3\u91ca<\/h2>\n<p>SOLID \u7684\u7ec8\u70b9\u3002<\/p>\n<p>\u7ef4\u57fa\u767e\u79d1\u7684\u5b9a\u4e49:<\/p>\n<blockquote><p>\u6bcf\u4e2a\u73ed\u7ea7\u4e0d\u80fd\u6709\u4e00\u4e2a\u4ee5\u4e0a\u7684\u7406\u7531\u6765\u8fdb\u884c\u66f4\u6539<\/p><\/blockquote>\n<p>\u5728SOLID\u539f\u5219\u4e2d\uff0c\u4ed6\u6240\u8bf4\u7684\u662f\u6700\u5bb9\u6613\u7406\u89e3\u7684\u3002<\/p>\n<p>\u8fd9\u5b9e\u9645\u4e0a\u53ea\u662f\u4e00\u4e2a\u8bf4\u201c\u8981\u9ad8\u5ea6\u51dd\u805a\u201d\u7684\u4fe1\u606f\u3002<\/p>\n<p>\u6211\u5011\u9047\u5230\u4e86\u4e00\u500b\u96e3\u984c\uff0c\u5c31\u662f\u5982\u4f55\u5efa\u7acb\u9ad8\u805a\u5408\u5ea6\u7684\u6a21\u584a\u3002\u7136\u800c\uff0c\u55ae\u4e00\u8077\u8cac\u539f\u5247 (SRP) \u7d66\u51fa\u4e86\u4e00\u500b\u89e3\u6c7a\u65b9\u6848\u7684\u6307\u5357\u3002<\/p>\n<p>&#8220;\u53ea\u9700\u505a\u8fd9\u4e00\u4ef6\u4e8b&#8221;\u7684\u4fe1\u606f\u4e0d\u65ad\u5728\u5404\u4e2a\u5730\u65b9\u51fa\u73b0\u3002<\/p>\n<p>\u4f8b\u5982\uff0c\u5c31\u7b97\u662fUNIX\u54f2\u5b66\uff0c\u4e5f\u4f1a\u4ee5\u4ee5\u4e0b\u65b9\u5f0f\u88ab\u8ff0\u8bf4\u3002<\/p>\n<blockquote><p>\u5199\u4e00\u4e2a\u80fd\u591f\u6267\u884c\u4e00\u4e2a\u4efb\u52a1\u5e76\u4e14\u6210\u529f\u5b8c\u6210\u7684\u7a0b\u5e8f\u3002<br \/>\n\u5199\u4e00\u4e2a\u80fd\u591f\u534f\u8c03\u8fd0\u884c\u7684\u7a0b\u5e8f\u3002<br \/>\n\u5199\u4e00\u4e2a\u5904\u7406\u6807\u51c6\u8f93\u5165\u8f93\u51fa\uff08\u6587\u672c\u6d41\uff09\u7684\u7a0b\u5e8f\u3002\u6807\u51c6\u8f93\u5165\u8f93\u51fa\u662f\u4e00\u79cd\u901a\u7528\u63a5\u53e3\u3002<\/p><\/blockquote>\n<p>&nbsp;<\/p>\n<p>\u5728\u300c\u53ef\u8bfb\u4ee3\u7801\u300d\u4e2d\uff0c\u4e5f\u4ee5\u7c7b\u4f3c\u300c\u4e00\u6b21\u53ea\u505a\u4e00\u4ef6\u4e8b\u300d\u7684\u65b9\u5f0f\u8868\u8fbe\u4e86\u7c7b\u4f3c\u7684\u6982\u5ff5\u3002<\/p>\n<p>&nbsp;<\/p>\n<p>\u5982\u679c\u5c1d\u8bd5\u521b\u5efa\u4e00\u4e2a\u4ec5\u627f\u62c5\u4e00\u4e2a\u804c\u8d23\u7684\u73ed\u7ea7\uff0c\u5f88\u5bb9\u6613\u60f3\u8c61\u73ed\u7ea7\u89c4\u6a21\u5c06\u4f1a\u53d8\u5f97&#8221;\u5c0f&#8221;\u3002<\/p>\n<p>\u6362\u8a00\u4e4b\uff0c\u5982\u679c\u4e00\u4e2a\u73ed\u7ea7\u7ed9\u4eba\u4e00\u79cd\u201c\u5e9e\u5927\u201d\u7684\u611f\u89c9\uff0c\u90a3\u4e48\u6216\u8bb8\u662f\u56e0\u4e3a\u8fd9\u4e2a\u73ed\u7ea7\u53ef\u80fd\u627f\u62c5\u4e86\u8fc7\u591a\u7684\u89d2\u8272\u3002<\/p>\n<p>\u6709\u65f6\u5019\u6211\u4eec\u7528\u201c\u77f3\u72ee\u201d\u6765\u5f62\u5bb9\u4e00\u4e2a\u5de8\u5927\u7684\u6a21\u5757\u3002<\/p>\n<p>\u518d\u8aaa\u4e00\u6b21\uff0c\u4e26\u4e0d\u4e00\u5b9a\u80fd\u5920\u5f9e\u4e00\u958b\u59cb\u5c31\u5b8c\u7f8e\u5730\u5b9a\u7fa9\u73ed\u7d1a\u7684\u8cac\u4efb\u3002<\/p>\n<p>\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u521d\u671f\u53ef\u4ee5\u91c7\u7528\u5355\u4f53\u7ed3\u6784\u4e5f\u53ef\u4ee5\u3002\u4e5f\u7ecf\u5e38\u770b\u5230\u672f\u8bed&#8221;Monolithic First&#8221;\u3002<\/p>\n<p>&nbsp;<\/p>\n<p>\u5982\u679c\u5206\u5272\u4f1a\u4f7f\u5f97\u7c7b\u4e4b\u95f4\u7684\u8026\u5408\u5ea6\u5bc6\u96c6\uff0c\u90a3\u4e48\u5b81\u53ef\u8ba9\u4e00\u4e2a\u7c7b\u53d8\u5f97\u7a0d\u5927\u4e00\u4e9b\uff0c\u4ee5\u4fbf\u6539\u53d8\u4ec5\u9650\u4e8e\u4e00\u4e2a\u7c7b\uff0c\u4e5f\u53ef\u4ee5\u63a5\u53d7\u8fd9\u79cd\u65b9\u5f0f\u7684\u60f3\u6cd5\u3002<\/p>\n<p>\u7136\u540e\uff0c\u7a0d\u540e\u8fdb\u884c\u91cd\u6784\u5c31\u53ef\u4ee5\u4e86\u3002<\/p>\n<h2>\u8bf7\u95ee\u60a8\u5bf9LangChain\u7684\u770b\u6cd5\u5982\u4f55\uff1f<\/h2>\n<p>\u6717\u8db3\u94fe\u5e76\u4e0d\u5b8c\u5168\u987a\u5229\uff0c\u5df2\u8fdb\u884c\u4e00\u4e9b\u7834\u574f\u6027\u7684\u6539\u53d8\u3002<\/p>\n<p>\u7ecf\u8fc7\u4e00\u5e74\u7684\u65f6\u95f4\uff0c\u7ec8\u4e8e\u770b\u5230\u4e86\u4e00\u4e2a\u76f8\u5bf9\u7a33\u5b9a\u7684\u73ed\u7ea7\u7ed3\u6784\u3002\u56e0\u6b64\uff0c\u5c06\u8fd9\u79cd\u7a33\u5b9a\u7684\u8bbe\u8ba1\u7684\u73ed\u7ea7\u5206\u79bb\u5230\u53e6\u4e00\u4e2a\u5730\u65b9\uff0c\u79f0\u4e3alangchain-core\uff0c\u5e76\u5728\u8fd9\u4e2a\u5206\u79bb\u7684\u5730\u65b9\u7f16\u5199\u4e86\u51e0\u4e4e\u4e0d\u9700\u8981\u9891\u7e41\u66f4\u65b0\u7684\u4ee3\u7801\uff0c\u540c\u65f6\u4ee5LangChain\u7684\u7a33\u5b9a\u7248\u672c\u4f5c\u4e3a\u76ee\u6807\u8fdb\u884c\u8c03\u6574\u3002<\/p>\n<p>&nbsp;<\/p>\n<h1>\u8bbe\u8ba1\u7531\u5951\u7ea6\u786e\u5b9a (DbC &#8211; Design by Contract)<\/h1>\n<h2>\u89e3\u91ca<\/h2>\n<p>SOLID\u539f\u5219\u7684\u8ba8\u8bba\u5df2\u7ecf\u7ed3\u675f\u4e86\u3002\u6700\u540e\u8ba9\u6211\u4eec\u8c08\u8c08\u4e0e\u6b64\u65e0\u5173\u7684 DbC\u3002<\/p>\n<p>&nbsp;<\/p>\n<p>\u7ef4\u57fa\u767e\u79d1\u4e0d\u591f\u7b80\u660e\u6613\u61c2\uff0c\u4ee5\u4e0b\u662f\u5176\u6458\u8981\uff1a<\/p>\n<blockquote><p>\u901a\u8fc7\u660e\u786e\u6307\u5b9a\u5404\u7ec4\u4ef6\uff08\u5982\u51fd\u6570\u3001\u65b9\u6cd5\u3001\u7c7b\u7b49\uff09\u5e94\u6ee1\u8db3\u7684\u524d\u63d0\u6761\u4ef6\u3001\u540e\u6761\u4ef6\u548c\u4e0d\u53d8\u6761\u4ef6\uff0c\u6765\u63d0\u9ad8\u7cfb\u7edf\u7684\u51c6\u786e\u6027\u548c\u53ef\u9760\u6027\u7684\u7f16\u7a0b\u65b9\u6cd5\u3002<\/p><\/blockquote>\n<p>\u603b\u7684\u6765\u8bf4\uff0c\u5bf9\u4e8e\u4f7f\u7528\u7ec4\u4ef6\u7684\u4eba\u548c\u63d0\u4f9b\u7ec4\u4ef6\u7684\u4eba\u6765\u8bf4\uff0c\u5927\u5bb6\u90fd\u6709\u5404\u81ea\u9700\u8981\u9075\u5b88\u7684\u627f\u8bfa\uff0c\u6240\u4ee5\u7528\u5951\u7ea6\u8fd9\u4e2a\u8bcd\u6765\u8868\u8fbe\u5927\u5bb6\u5e94\u8be5\u9075\u5b88\u8fd9\u4e9b\u627f\u8bfa\u7684\u610f\u601d\u3002<\/p>\n<p>\u7528\u7f16\u7801\u6765\u89e3\u91ca\u3002\u4ee5\u4e0b\u662f\u8fdd\u53cd\u8bbe\u8ba1\u6309\u5951\u7ea6\u7f16\u7a0b\uff08DbC\uff09\u7684\u4f8b\u5b50\u3002<\/p>\n<p>\u5047\u8bbe\u6709\u4e00\u4e2a\u540d\u4e3a User \u7684\u7c7b\uff0c\u5176\u4e2d\u5305\u542b\u8868\u793a\u5e74\u9f84\u7684\u5c5e\u6027 age\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"kn\">from<\/span> <span class=\"n\">dataclasses<\/span> <span class=\"kn\">import<\/span> <span class=\"n\">dataclass<\/span>\r\n\r\n\r\n<span class=\"nd\">@dataclass<\/span>\r\n<span class=\"k\">class<\/span> <span class=\"nc\">User<\/span><span class=\"p\">:<\/span>\r\n    <span class=\"nb\">id<\/span><span class=\"p\">:<\/span> <span class=\"nb\">int<\/span>\r\n    <span class=\"n\">name<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span>\r\n    <span class=\"n\">age<\/span><span class=\"p\">:<\/span> <span class=\"nb\">int<\/span>\r\n\r\n\r\n<span class=\"n\">u<\/span> <span class=\"o\">=<\/span> <span class=\"nc\">User<\/span><span class=\"p\">(<\/span><span class=\"nb\">id<\/span><span class=\"o\">=<\/span><span class=\"mi\">1<\/span><span class=\"p\">,<\/span> <span class=\"n\">name<\/span><span class=\"o\">=<\/span><span class=\"sh\">\"<\/span><span class=\"s\">John Doe<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"n\">age<\/span><span class=\"o\">=-<\/span><span class=\"mi\">1<\/span><span class=\"p\">)<\/span>\r\n<\/code><\/pre>\n<p>\u5047\u8bbe\u521b\u5efa\u8fd9\u4e2aUser\u7c7b\u7684\u4eba\u5fc3\u91cc\u60f3\u7740\u201c\u4e0d\u5e0c\u671bage\u88ab\u8d4b\u4e88\u8d1f\u6570\u3002\u201d<\/p>\n<p>\u56e0\u4e3aage\u7684\u503c\u4e3a\u8d1f\u6570\uff0c\u6240\u4ee5\u4e0a\u9762\u7684u\u662f\u4e0d\u5408\u6cd5\u7684\u3002\u8fd9\u8fdd\u53cd\u4e86DbC\u7684\u524d\u7f6e\u6761\u4ef6\u3002<\/p>\n<p>\u5728DbC\u4e2d\u63d0\u5230\u7684\u5176\u4e2d\u4e00\u4e2a\u524d\u63d0\u6761\u4ef6\u662f\uff0c\u201c\u4f7f\u7528\u7c7b\u7684\u4eba\u6709\u8d23\u4efb\u6b63\u786e\u5730\u8f93\u5165\u53c2\u6570\u201d\u3002<\/p>\n<p>\u73b0\u5728\uff0c\u6211\u60f3\u8981\u9075\u5b88DbC\u3002\u6240\u4ee5\uff0c\u4f5c\u4e3aUser\u7c7b\u7684\u63d0\u4f9b\u8005\uff0c\u5982\u679c\u51fa\u73b0\u4e86\u4e0d\u5408\u6cd5\u7684\u8f93\u5165\uff0c\u6211\u5e0c\u671b\u80fd\u591f\u5bf9\u5176\u8fdb\u884c\u9a8c\u8bc1\u5e76\u5c06\u8fd9\u4e00\u8fdd\u89c4\u884c\u4e3a\u901a\u77e5\u7ed9\u8fdd\u89c4\u8005\u3002<\/p>\n<p>\u9700\u8981\u9010\u4e00\u5b9e\u73b0\u5b83\u5417\uff1f\u4e0d\u9700\u8981\u3002\u56e0\u4e3a\u8fd9\u91cc\u6709pydantic\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"kn\">from<\/span> <span class=\"n\">pydantic<\/span> <span class=\"kn\">import<\/span> <span class=\"n\">BaseModel<\/span><span class=\"p\">,<\/span> <span class=\"n\">PositiveInt<\/span><span class=\"p\">,<\/span> <span class=\"n\">ValidationError<\/span>\r\n\r\n\r\n<span class=\"k\">class<\/span> <span class=\"nc\">User<\/span><span class=\"p\">(<\/span><span class=\"n\">BaseModel<\/span><span class=\"p\">):<\/span>\r\n    <span class=\"nb\">id<\/span><span class=\"p\">:<\/span> <span class=\"nb\">int<\/span>\r\n    <span class=\"n\">name<\/span><span class=\"p\">:<\/span> <span class=\"nb\">str<\/span>\r\n    <span class=\"n\">age<\/span><span class=\"p\">:<\/span> <span class=\"n\">PositiveInt<\/span>\r\n\r\n\r\n<span class=\"c1\"># \u6b63\u3057\u3044\u30c7\u30fc\u30bf\u3092\u4f7f\u7528\r\n<\/span><span class=\"k\">try<\/span><span class=\"p\">:<\/span>\r\n    <span class=\"n\">user<\/span> <span class=\"o\">=<\/span> <span class=\"nc\">User<\/span><span class=\"p\">(<\/span><span class=\"nb\">id<\/span><span class=\"o\">=<\/span><span class=\"mi\">123<\/span><span class=\"p\">,<\/span> <span class=\"n\">name<\/span><span class=\"o\">=<\/span><span class=\"sh\">\"<\/span><span class=\"s\">John Doe<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"n\">age<\/span><span class=\"o\">=<\/span><span class=\"mi\">30<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"nf\">print<\/span><span class=\"p\">(<\/span><span class=\"n\">user<\/span><span class=\"p\">)<\/span>\r\n<span class=\"k\">except<\/span> <span class=\"n\">ValidationError<\/span> <span class=\"k\">as<\/span> <span class=\"n\">e<\/span><span class=\"p\">:<\/span>\r\n    <span class=\"nf\">print<\/span><span class=\"p\">(<\/span><span class=\"n\">e<\/span><span class=\"p\">)<\/span>\r\n\r\n<span class=\"c1\"># \u4e0d\u6b63\u306a\u30c7\u30fc\u30bf\u3092\u4f7f\u7528\uff08\u4f8b: \u5e74\u9f62\u306b\u6587\u5b57\u5217\u3092\u6e21\u3059\uff09\r\n<\/span><span class=\"k\">try<\/span><span class=\"p\">:<\/span>\r\n    <span class=\"n\">user<\/span> <span class=\"o\">=<\/span> <span class=\"nc\">User<\/span><span class=\"p\">(<\/span><span class=\"nb\">id<\/span><span class=\"o\">=<\/span><span class=\"mi\">123<\/span><span class=\"p\">,<\/span> <span class=\"n\">name<\/span><span class=\"o\">=<\/span><span class=\"sh\">\"<\/span><span class=\"s\">John Doe<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"n\">age<\/span><span class=\"o\">=<\/span><span class=\"sh\">\"<\/span><span class=\"s\">thirty<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\r\n<span class=\"k\">except<\/span> <span class=\"n\">ValidationError<\/span> <span class=\"k\">as<\/span> <span class=\"n\">e<\/span><span class=\"p\">:<\/span>\r\n    <span class=\"nf\">print<\/span><span class=\"p\">(<\/span><span class=\"n\">e<\/span><span class=\"p\">)<\/span>\r\n\r\n<span class=\"c1\"># \u4e0d\u6b63\u306a\u30c7\u30fc\u30bf\u3092\u4f7f\u7528\uff08\u4f8b: \u5e74\u9f62\u306b\u8ca0\u306e\u6570\u3092\u6e21\u3059\uff09\r\n<\/span><span class=\"k\">try<\/span><span class=\"p\">:<\/span>\r\n    <span class=\"n\">user<\/span> <span class=\"o\">=<\/span> <span class=\"nc\">User<\/span><span class=\"p\">(<\/span><span class=\"nb\">id<\/span><span class=\"o\">=<\/span><span class=\"mi\">1<\/span><span class=\"p\">,<\/span> <span class=\"n\">name<\/span><span class=\"o\">=<\/span><span class=\"sh\">\"<\/span><span class=\"s\">John Doe<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"n\">age<\/span><span class=\"o\">=-<\/span><span class=\"mi\">1<\/span><span class=\"p\">)<\/span>\r\n<span class=\"k\">except<\/span> <span class=\"n\">ValidationError<\/span> <span class=\"k\">as<\/span> <span class=\"n\">e<\/span><span class=\"p\">:<\/span>\r\n    <span class=\"nf\">print<\/span><span class=\"p\">(<\/span><span class=\"n\">e<\/span><span class=\"p\">)<\/span>\r\n<\/code><\/pre>\n<pre class=\"post-pre\"><code>id=123 name='John Doe' age=30\r\n1 validation error for User\r\nage\r\n  Input should be a valid integer, unable to parse string as an integer [type=int_parsing, input_value='thirty', input_type=str]\r\n    For further information visit https:\/\/errors.pydantic.dev\/2.5\/v\/int_parsing\r\n1 validation error for User\r\nage\r\n  Input should be greater than 0 [type=greater_than, input_value=-1, input_type=int]\r\n    For further information visit https:\/\/errors.pydantic.dev\/2.5\/v\/greater_than\r\n<\/code><\/pre>\n<p>\u5f53\u67e5\u770bPydantic\u7684HP\u65f6\uff0c\u53ef\u4ee5\u770b\u5230\u5b83\u4e5f\u88ab\u7528\u4e8eTransformer\u548cFastAPI\u3002\u4e0emypy\u4e00\u8d77\uff0c\u5b83\u4e3aPython\u63d0\u4f9b\u4e86\u5b9e\u73b0\u57fa\u4e8e\u7c7b\u578b\u7684\u65b0\u9c9c\u5065\u58ee\u6027\u7684\u65b9\u5f0f\u3002<\/p>\n<h2>\u8bf7\u95ee\uff0cLangChain \u600e\u4e48\u6837\u5462\uff1f<\/h2>\n<p>\u6240\u6709\u7684\u7c7b\u90fd\u4f7f\u7528\u4e86 pydantic\u3002\u786e\u5207\u5730\u8bf4\uff0c\u53ea\u8981\u6309\u7167\u7ee7\u627f\u5173\u7cfb\u8ffd\u6eaf\uff0c\u5c31\u4e00\u5b9a\u4f1a\u5230\u8fbe BaseModel\u3002<\/p>\n<p>&nbsp;<\/p>\n<h2>\u6700\u540e<\/h2>\n<p>\u603b\u7ed3\u4e00\u4e0b<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">\u307e\u305a DIP \u304c\u672c\u8cea\u7684\u3002 DIP \u3092\u3084\u3063\u3066\u304b\u3089\u4ed6\u3092\u30b1\u30a2\u3057\u3066\u3044\u304f\u3002<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">mypy, pydantic \u3092\u4f7f\u304a\u3046<\/ul>\n<p>\u8fd9\u5c31\u662f\u610f\u601d\u3002\u6211\u6709\u70b9\u7d2f\uff0c\u6240\u4ee5\u5c31\u5728\u8fd9\u91cc\u7ed3\u675f\u5427\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u5728\u8fd9\u91cc\uff0c\u6211\u4eec\u8bd5\u56fe\u901a\u8fc7\u5728LangChain\u7684\u5b9e\u73b0\u4e2d\u627e\u51fa\u8fd9\u4e9b\u8981\u7d20\u6765\u89e3\u91caSOLID\u539f\u5219\u548c\u5951\u7ea6\u5f0f\u7f16\u7a0b\u3002 SOLID\u539f\u5247 [&hellip;]<\/p>\n","protected":false},"author":5,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-50626","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v21.5 (Yoast SEO v21.5) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>\u5728\u601d\u8003SOLID\u539f\u5219\u7b49\u7684\u60c5\u51b5\u4e0b\uff0c\u6d4f\u89c8LangChain\u7684\u6e90\u4ee3\u7801 - Blog - Silicon Cloud<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.silicloud.com\/zh\/blog\/\u5728\u601d\u8003solid\u539f\u5219\u7b49\u7684\u60c5\u51b5\u4e0b\uff0c\u6d4f\u89c8langchain\u7684\u6e90\u4ee3\u7801\u3002\/\" \/>\n<meta property=\"og:locale\" content=\"zh_CN\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"\u5728\u601d\u8003SOLID\u539f\u5219\u7b49\u7684\u60c5\u51b5\u4e0b\uff0c\u6d4f\u89c8LangChain\u7684\u6e90\u4ee3\u7801\" \/>\n<meta property=\"og:description\" content=\"\u5728\u8fd9\u91cc\uff0c\u6211\u4eec\u8bd5\u56fe\u901a\u8fc7\u5728LangChain\u7684\u5b9e\u73b0\u4e2d\u627e\u51fa\u8fd9\u4e9b\u8981\u7d20\u6765\u89e3\u91caSOLID\u539f\u5219\u548c\u5951\u7ea6\u5f0f\u7f16\u7a0b\u3002 SOLID\u539f\u5247 [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.silicloud.com\/zh\/blog\/\u5728\u601d\u8003solid\u539f\u5219\u7b49\u7684\u60c5\u51b5\u4e0b\uff0c\u6d4f\u89c8langchain\u7684\u6e90\u4ee3\u7801\u3002\/\" \/>\n<meta property=\"og:site_name\" content=\"Blog - Silicon Cloud\" \/>\n<meta property=\"article:published_time\" content=\"2023-12-25T01:36:44+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-05-03T17:44:58+00:00\" \/>\n<meta name=\"author\" content=\"\u6e05, \u5b87\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"\u4f5c\u8005\" \/>\n\t<meta name=\"twitter:data1\" content=\"\u6e05, \u5b87\" \/>\n\t<meta name=\"twitter:label2\" content=\"\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 \u5206\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e5%9c%a8%e6%80%9d%e8%80%83solid%e5%8e%9f%e5%88%99%e7%ad%89%e7%9a%84%e6%83%85%e5%86%b5%e4%b8%8b%ef%bc%8c%e6%b5%8f%e8%a7%88langchain%e7%9a%84%e6%ba%90%e4%bb%a3%e7%a0%81%e3%80%82\/\",\"url\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e5%9c%a8%e6%80%9d%e8%80%83solid%e5%8e%9f%e5%88%99%e7%ad%89%e7%9a%84%e6%83%85%e5%86%b5%e4%b8%8b%ef%bc%8c%e6%b5%8f%e8%a7%88langchain%e7%9a%84%e6%ba%90%e4%bb%a3%e7%a0%81%e3%80%82\/\",\"name\":\"\u5728\u601d\u8003SOLID\u539f\u5219\u7b49\u7684\u60c5\u51b5\u4e0b\uff0c\u6d4f\u89c8LangChain\u7684\u6e90\u4ee3\u7801 - Blog - Silicon Cloud\",\"isPartOf\":{\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#website\"},\"datePublished\":\"2023-12-25T01:36:44+00:00\",\"dateModified\":\"2024-05-03T17:44:58+00:00\",\"author\":{\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/1a6ecd3d914d22a5ac32791ffc1fbd8e\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e5%9c%a8%e6%80%9d%e8%80%83solid%e5%8e%9f%e5%88%99%e7%ad%89%e7%9a%84%e6%83%85%e5%86%b5%e4%b8%8b%ef%bc%8c%e6%b5%8f%e8%a7%88langchain%e7%9a%84%e6%ba%90%e4%bb%a3%e7%a0%81%e3%80%82\/#breadcrumb\"},\"inLanguage\":\"zh-Hans\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.silicloud.com\/zh\/blog\/%e5%9c%a8%e6%80%9d%e8%80%83solid%e5%8e%9f%e5%88%99%e7%ad%89%e7%9a%84%e6%83%85%e5%86%b5%e4%b8%8b%ef%bc%8c%e6%b5%8f%e8%a7%88langchain%e7%9a%84%e6%ba%90%e4%bb%a3%e7%a0%81%e3%80%82\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e5%9c%a8%e6%80%9d%e8%80%83solid%e5%8e%9f%e5%88%99%e7%ad%89%e7%9a%84%e6%83%85%e5%86%b5%e4%b8%8b%ef%bc%8c%e6%b5%8f%e8%a7%88langchain%e7%9a%84%e6%ba%90%e4%bb%a3%e7%a0%81%e3%80%82\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"\u9996\u9875\",\"item\":\"https:\/\/www.silicloud.com\/zh\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"\u5728\u601d\u8003SOLID\u539f\u5219\u7b49\u7684\u60c5\u51b5\u4e0b\uff0c\u6d4f\u89c8LangChain\u7684\u6e90\u4ee3\u7801\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#website\",\"url\":\"https:\/\/www.silicloud.com\/zh\/blog\/\",\"name\":\"Blog - Silicon Cloud\",\"description\":\"\",\"inLanguage\":\"zh-Hans\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/1a6ecd3d914d22a5ac32791ffc1fbd8e\",\"name\":\"\u6e05, \u5b87\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-Hans\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/4b2016c18459a605fc469c7566608f5686491baa112d0871ee613f61b7210565?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/4b2016c18459a605fc469c7566608f5686491baa112d0871ee613f61b7210565?s=96&d=mm&r=g\",\"caption\":\"\u6e05, \u5b87\"},\"url\":\"https:\/\/www.silicloud.com\/zh\/blog\/author\/qingyu\/\"},{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-Hans\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e5%9c%a8%e6%80%9d%e8%80%83solid%e5%8e%9f%e5%88%99%e7%ad%89%e7%9a%84%e6%83%85%e5%86%b5%e4%b8%8b%ef%bc%8c%e6%b5%8f%e8%a7%88langchain%e7%9a%84%e6%ba%90%e4%bb%a3%e7%a0%81%e3%80%82\/#local-main-organization-logo\",\"url\":\"\",\"contentUrl\":\"\",\"caption\":\"Blog - Silicon Cloud\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"\u5728\u601d\u8003SOLID\u539f\u5219\u7b49\u7684\u60c5\u51b5\u4e0b\uff0c\u6d4f\u89c8LangChain\u7684\u6e90\u4ee3\u7801 - Blog - Silicon Cloud","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.silicloud.com\/zh\/blog\/\u5728\u601d\u8003solid\u539f\u5219\u7b49\u7684\u60c5\u51b5\u4e0b\uff0c\u6d4f\u89c8langchain\u7684\u6e90\u4ee3\u7801\u3002\/","og_locale":"zh_CN","og_type":"article","og_title":"\u5728\u601d\u8003SOLID\u539f\u5219\u7b49\u7684\u60c5\u51b5\u4e0b\uff0c\u6d4f\u89c8LangChain\u7684\u6e90\u4ee3\u7801","og_description":"\u5728\u8fd9\u91cc\uff0c\u6211\u4eec\u8bd5\u56fe\u901a\u8fc7\u5728LangChain\u7684\u5b9e\u73b0\u4e2d\u627e\u51fa\u8fd9\u4e9b\u8981\u7d20\u6765\u89e3\u91caSOLID\u539f\u5219\u548c\u5951\u7ea6\u5f0f\u7f16\u7a0b\u3002 SOLID\u539f\u5247 [&hellip;]","og_url":"https:\/\/www.silicloud.com\/zh\/blog\/\u5728\u601d\u8003solid\u539f\u5219\u7b49\u7684\u60c5\u51b5\u4e0b\uff0c\u6d4f\u89c8langchain\u7684\u6e90\u4ee3\u7801\u3002\/","og_site_name":"Blog - Silicon Cloud","article_published_time":"2023-12-25T01:36:44+00:00","article_modified_time":"2024-05-03T17:44:58+00:00","author":"\u6e05, \u5b87","twitter_card":"summary_large_image","twitter_misc":{"\u4f5c\u8005":"\u6e05, \u5b87","\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4":"7 \u5206"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%9c%a8%e6%80%9d%e8%80%83solid%e5%8e%9f%e5%88%99%e7%ad%89%e7%9a%84%e6%83%85%e5%86%b5%e4%b8%8b%ef%bc%8c%e6%b5%8f%e8%a7%88langchain%e7%9a%84%e6%ba%90%e4%bb%a3%e7%a0%81%e3%80%82\/","url":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%9c%a8%e6%80%9d%e8%80%83solid%e5%8e%9f%e5%88%99%e7%ad%89%e7%9a%84%e6%83%85%e5%86%b5%e4%b8%8b%ef%bc%8c%e6%b5%8f%e8%a7%88langchain%e7%9a%84%e6%ba%90%e4%bb%a3%e7%a0%81%e3%80%82\/","name":"\u5728\u601d\u8003SOLID\u539f\u5219\u7b49\u7684\u60c5\u51b5\u4e0b\uff0c\u6d4f\u89c8LangChain\u7684\u6e90\u4ee3\u7801 - Blog - Silicon Cloud","isPartOf":{"@id":"https:\/\/www.silicloud.com\/zh\/blog\/#website"},"datePublished":"2023-12-25T01:36:44+00:00","dateModified":"2024-05-03T17:44:58+00:00","author":{"@id":"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/1a6ecd3d914d22a5ac32791ffc1fbd8e"},"breadcrumb":{"@id":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%9c%a8%e6%80%9d%e8%80%83solid%e5%8e%9f%e5%88%99%e7%ad%89%e7%9a%84%e6%83%85%e5%86%b5%e4%b8%8b%ef%bc%8c%e6%b5%8f%e8%a7%88langchain%e7%9a%84%e6%ba%90%e4%bb%a3%e7%a0%81%e3%80%82\/#breadcrumb"},"inLanguage":"zh-Hans","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.silicloud.com\/zh\/blog\/%e5%9c%a8%e6%80%9d%e8%80%83solid%e5%8e%9f%e5%88%99%e7%ad%89%e7%9a%84%e6%83%85%e5%86%b5%e4%b8%8b%ef%bc%8c%e6%b5%8f%e8%a7%88langchain%e7%9a%84%e6%ba%90%e4%bb%a3%e7%a0%81%e3%80%82\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%9c%a8%e6%80%9d%e8%80%83solid%e5%8e%9f%e5%88%99%e7%ad%89%e7%9a%84%e6%83%85%e5%86%b5%e4%b8%8b%ef%bc%8c%e6%b5%8f%e8%a7%88langchain%e7%9a%84%e6%ba%90%e4%bb%a3%e7%a0%81%e3%80%82\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"\u9996\u9875","item":"https:\/\/www.silicloud.com\/zh\/blog\/"},{"@type":"ListItem","position":2,"name":"\u5728\u601d\u8003SOLID\u539f\u5219\u7b49\u7684\u60c5\u51b5\u4e0b\uff0c\u6d4f\u89c8LangChain\u7684\u6e90\u4ee3\u7801"}]},{"@type":"WebSite","@id":"https:\/\/www.silicloud.com\/zh\/blog\/#website","url":"https:\/\/www.silicloud.com\/zh\/blog\/","name":"Blog - Silicon Cloud","description":"","inLanguage":"zh-Hans"},{"@type":"Person","@id":"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/1a6ecd3d914d22a5ac32791ffc1fbd8e","name":"\u6e05, \u5b87","image":{"@type":"ImageObject","inLanguage":"zh-Hans","@id":"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/4b2016c18459a605fc469c7566608f5686491baa112d0871ee613f61b7210565?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/4b2016c18459a605fc469c7566608f5686491baa112d0871ee613f61b7210565?s=96&d=mm&r=g","caption":"\u6e05, \u5b87"},"url":"https:\/\/www.silicloud.com\/zh\/blog\/author\/qingyu\/"},{"@type":"ImageObject","inLanguage":"zh-Hans","@id":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%9c%a8%e6%80%9d%e8%80%83solid%e5%8e%9f%e5%88%99%e7%ad%89%e7%9a%84%e6%83%85%e5%86%b5%e4%b8%8b%ef%bc%8c%e6%b5%8f%e8%a7%88langchain%e7%9a%84%e6%ba%90%e4%bb%a3%e7%a0%81%e3%80%82\/#local-main-organization-logo","url":"","contentUrl":"","caption":"Blog - Silicon Cloud"}]}},"_links":{"self":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts\/50626","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/comments?post=50626"}],"version-history":[{"count":2,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts\/50626\/revisions"}],"predecessor-version":[{"id":95363,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts\/50626\/revisions\/95363"}],"wp:attachment":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/media?parent=50626"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/categories?post=50626"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/tags?post=50626"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}