LangChain、RStudio、Enough Python を使って人工知能を構築する方法

LangChain、RStudio、Enough Python を使って人工知能を構築する方法

翻訳者 |李睿

レビュー | Chonglou

LangChain は、生成 AI を使用するアプリケーションを作成するための現在最も人気のある開発プラットフォームの 1 つですが、Python と JavaScript でのみ動作します。 LangChain を使用したい R プログラマーは何をすべきでしょうか?

幸いなことに、LangChain では非常に基本的な Python コードを使用して、多くの便利なことを実行できます。また、reticulate R パッケージのおかげで、R および RStudio ユーザーは、Python と R の間でオブジェクトやデータをやり取りするなど、使い慣れた環境でPython を記述および実行できます。

この LangChain チュートリアルでは、Python と R を使用して LangChain および OpenAI APIにアクセスする方法を説明します。これにより、大規模言語モデル (LLM) を使用して ggplot2 の 300 ページの PDF ドキュメントを照会できるようになります。最初のクエリ例: 「グラフの x 軸上でテキストを回転するにはどうすればよいですか?」

プロセスのステップバイステップガイドは次のとおりです。

(1)まだ実行していない場合は、Pythonとreticulateを実行するようにシステムを設定する必要があります。

(2)ggplot2 PDFドキュメントファイルをプレーンテキストのLangChainオブジェクトとしてインポートします。

(3)大規模な言語モデルでは一度に読み取れる量に制限があるため、テキストを大規模な言語モデルで読み取れる小さな部分に分割する。 300 ページのテキストは OpenAI の企業制限を超えてしまいます。

(4)LLMを使用して、テキストブロックごとに「埋め込み」を作成し、すべてをデータベースに保存します。埋め込みは、多次元空間内のテキストの意味を表す数字の文字列です。

(5)ユーザーの質問に対する埋め込みを作成し、その質問の埋め込みをテキスト内の既存のすべての質問と比較します。最も関連性の高いテキスト スニペットを見つけて取得します。

(6)テキストの関連部分のみをGPT-3.5のようなLLMに入力し、答えを生成するように依頼します。

ユーザーが例に従って OpenAI API を使用する場合は、API キーが必要です。 platform.openai.com で登録できます。別のモデルを使用する場合、LangChain には OpenAI だけでなく多くの LLM のチェーンを構築するためのコンポーネントがあるため、単一の LLM プロバイダーに縛られることはありません。

LangChain には、特に企業がデフォルト設定に満足している場合、これらの手順を簡単に処理できるコンポーネントが備わっています。だからこそ人気が出たのです。

以下は段階的に実施されます。

ステップ1: RStudioでPythonを実行するようにシステムをセットアップする

すでに Python と reticulate を実行している場合は、次の手順に進むことができます。それ以外の場合は、システムに最新バージョンの Python がインストールされていることを確認してください。 Python をインストールする方法はたくさんありますが、python.org の Web サイトからダウンロードするだけで十分です。次に、 install.packages("reticulate") を使用して、通常の方法で reticulate R パッケージをインストールします。

Python がすでにインストールされているが、reticulate がそれを見つけられない場合は、use_Python("/path/to/your/Python") コマンドを使用できます。

 library(reticulate) virtualenv_create(envname = "langchain_env", packages = c( "langchain", "openai", "pypdf", "bs4", "python-dotenv", "chromadb", "tiktoken")) # Only do this once

ユーザーは環境に任意の名前を付けることができることに注意してください。環境を作成した後にパッケージをインストールする必要がある場合は、次のように py_install() を使用します。

 py_install(packages = c( "langchain", "openai", "pypdf", "bs4", "python-dotenv", "chromadb", "tiktoken"), envname = "langchain_env")

R と同様に、ユーザーは環境を使用する必要があるたびにパッケージをインストールする必要はなく、一度だけパッケージをインストールする必要があります。また、仮想環境を有効にすることを忘れないでください。

 use_virtualenv("langchain_env")

プロジェクトに戻るたびに、Python コードの実行を開始する前にこれを実行してください。

ユーザーはPython環境が

reticulate::py_run_string(' print("Hello, world!") ')

ユーザーが希望する場合は、OpenAI API キーを Python 変数として設定できます。 R 環境変数にすでにあるため、通常は R を使用して OpenAI API キーを設定します。ユーザーは、reticulate の r_to_py() 関数を使用して、環境変数を含む任意の R 変数を Python に適した形式で保存できます。

 api_key_for_py <- r_to_py(Sys.getenv("OPENAI_API_KEY"))

OPENAI_API_KEY 環境変数を取得し、それがPythonフレンドリーであることを確認して、新しい変数 api_key_for_py (任意の名前を使用できます) に保存します。

ついに、コードを書く準備が整いました。

ステップ2: PDFファイルをダウンロードしてインポートする

メイン プロジェクト ディレクトリの下に新しい docs サブディレクトリが作成され、R を使用してそこにファイルがダウンロードされます。

 # Create the directory if it doesn't exist if(!(dir.exists("docs"))) { dir.create("docs") } # Download the file download.file("https://cran.r-project.org/web/packages/ggplot2/ggplot2.pdf", destfile = "docs/ggplot2.pdf", mode = "wb")

次は、このファイルをコンテンツとメタデータを含む LangChain ドキュメント オブジェクトとしてインポートする Python コードです。このために、prep_docs.py という名前の新しい Python スクリプト ファイルが作成されます。上記のように py_run_string() 関数を使用して、R スクリプト内から Python コードの実行を継続できます。ただし、ユーザーがより大きなタスクに取り組んでいる場合、コード補完などの失敗が発生するため、これは理想的ではありません

Python 初心者向けの重要なポイント: スクリプト ファイルに、ロードする Python モジュールと同じ名前を付けないでください。つまり、ファイル名を prep_docs.py にする必要はありませんが、langchain パッケージをインポートする場合は、langchain.py という名前を付けないでください。競合が発生します。これは R では問題ではありません。

新しい prep_docs.py ファイルの最初のセクションは次のとおりです。

 If running from RStudio, remember to first run in R: # library(reticulate) # use_virtualenv("the_virtual_environment_you_set_up") # api_key_py <- r_to_py(Sys.getenv("OPENAI_API_KEY")) from langchain.document_loaders import PyPDFLoader my_loader = PyPDFLoader('docs/ggplot2.pdf') # print(type (my_loader)) all_pages = my_loader.load() # print(type(all_pages)) print( len(all_pages) )

このコードは、まず PDF ドキュメント ローダー PyPDFLoader をインポートします。次に、PDF ローダー クラスのインスタンスを作成します。次に、ローダーとそのロード メソッドを実行し、結果を all_pages という変数に保存します。オブジェクトは Python リストです。

ここに、オブジェクト タイプを表示するコメント行をいくつか含めました。最後の行にはリストの長さが出力されます。この場合は 304 です。

RStudio のソース ボタンをクリックすると、完全な Python スクリプトを実行できます。あるいは、R スクリプトの場合と同様に、いくつかのコード行を強調表示して、その行だけを実行します。 Python コードは、実行すると R コンソールで Python 対話型 REPL セッションが開かれるため、R コードとは若干異なって見えます。終了したら、ユーザーは exit または quit (括弧なし) と入力して終了し、通常の R コンソールに戻るように指示されます。

ユーザーは、reticulate.py オブジェクトを使用して、R で all_pages Python オブジェクトを検査できます。次の R コードは、Python all_pages オブジェクトを all_pages_in_r という R 変数に格納します (任意の名前を付けることができます)。その後、オブジェクトは他の R オブジェクトと同様に処理できます。この場合はリストです。

 all_pages_in_r <- py$all_pages # Examples: all_pages_in_r[[1]]$metadata # See metadata in the first item nchar(all_pages_in_r[[100]]$page_content) # Count number of characters in the 100th item

LangChain 統合

PDF を読み取り可能なテキストに変換するためのお気に入りの方法がまだない場合は、LangChain の PyPDFLoader が AI 以外のプロジェクトで役立ちます。さらに、LangChain には、PowerPoint、Word、Web ページ、YouTube、epub、Evernote、Notion などの形式を含む 100 を超えるファイル ローダーがあります。いくつかのファイル形式と統合されたドキュメント ローダーは、LangChain 統合センターで確認できます。

ステップ3: ドキュメントを複数の部分に分割する

LangChain には、文字、トークン、タグ ヘッダーによる分割など、ドキュメントをチャンクに分割できるトランスフォーマーがいくつかあります。推奨されるデフォルトは、有効な文字を見つけるために異なる文字で再帰的に分割を試みる RecursiveCharacterTextSplitter です。もう一つの人気のあるオプションは、ユーザーがパラメータを設定できるように設計されています。

ユーザーは、このスプリッターの最大テキスト ブロック サイズ、文字数でカウントするか LLM トークン数でカウントするか (トークンは通常 1 ~ 4 文字)、およびテキスト ブロックをどの程度重ねるかを設定できます。 LangChain を使い始める前は、テキストのブロックが重なり合う必要性について考えたことはありませんでしたが、ユーザーが論理ブロック (ヘッダーで区切られた章やセクションなど) で区切ることができない限り、重なり合うことは理にかなっています。そうしないと、テキストが文の途中で分割され、重要なメッセージが 2 つの部分に分割され、どちらの部分も完全な意味を持たなくなる可能性があります。

ユーザーは、テキストを分割するときにスプリッターが優先する区切り文字を選択することもできます。 CharacterTextSplitter のデフォルト値は、最初に 2 つの新しい行 (\n\n) で分割し、次に新しい行とスペースで再度分割し、最後に区切り文字なしで分割します。

次のコードは、Python 内の reticulate R オブジェクトを使用して、R api_key_for_py 変数から OpenAI API キーをインポートします。また、OpenAI Python パッケージと LangChain の再帰文字分割器を読み込み、RecursiveCharacterTextSplitter クラスのインスタンスを作成し、そのインスタンスの split_documents() メソッドを all_pages チャンクで実行します。

 import openai openai.api_key = r.api_key_for_py from langchain.text_splitter import RecursiveCharacterTextSplitter my_doc_splitter_recursive = RecursiveCharacterTextSplitter() my_split_docs = my_doc_splitter_recursive.split_documents(all_pages)

同様に、ユーザーは R コードを使用してこれらの結果を R に送信できます。次に例を示します。

 My_split_docs <- py$ My_split_docs

ブロック内の最大文字数が何文字か疑問に思ったことはありませんか? R のカスタム関数を使用してこのリストを確認できます。

 get_characters <- function(the_chunk) { x <- nchar(the_chunk$page_content) return(x) } purrr::map_int(my_split_docs, get_characters) |> max()

これにより 3,985 文字が生成されるため、デフォルトのチャンクの最大値は 4,000 文字のようです。

テキストのチャンクを小さくしたい場合は、まず CharacterTextSplitter を試して、chunk_size を人為的に 4,000 未満に設定します。例:

 chunk_size = 1000 chunk_overlap = 150 from langchain.text_splitter import CharacterTextSplitter c_splitter = CharacterTextSplitter(chunk_size=chunk_size, chunk_overlap=chunk_overlap, separator=" ") c_split_docs = c_splitter.split_documents(all_pages) print(len(c_split_docs)) # To see in Python how many chunks there are now

結果は R と Python で確認できます。

 c_split_docs <- py$c_split_docs length(c_split_docs)

このコードは 695 個のブロックを生成し、最大 1000 個になります。

費用はいくらですか?

さらに進む前に、これらすべてのブロックの埋め込みを生成するのに非常にコストがかかるかどうかを知りたい場合があります。デフォルトの 306 項目の再帰分割から開始します。 R オブジェクト上のこれらのチャンク内の文字の合計数は次のようにカウントできます。

 purrr::map_int(my_split_docs, get_characters) |> sum()

答えは513506です。控えめに見積もってトークンあたり 2 文字とすると、約 200,000 文字になります。

より正確にしたい場合は、OpenAIR R パッケージに count_tokens() 関数があります (必ずこれをインストールして、以下の R コードを使用してください)。

 purrr::map_int(my_split_docs, ~ TheOpenAIR::count_tokens(.x$page_content)) |> sum ()

コードには 126,343 個のトークンが表示されます。

費用はいくらですか? OpenAI が埋め込みを生成するために使用するモデルは ada-2 です。現在、ada-2 の 1000 トークンの価格は 0.0001 ドル、126,000 トークンの価格は約 1.3 セントです。これらの費用は予算内です。

ステップ4: 埋め込みを生成する

LangChain には、テキスト ブロックから埋め込みを作成して保存できる既成のコンポーネントがあります。ストレージには、LangChain の最もシンプルなオプションの 1 つである、ローカルで使用できるオープンソースの組み込みデータベースである Chroma を使用します。

まず、Chroma ディレクトリにはデータベース以外のものを置かないことが推奨されているため、R コードを含む docs ディレクトリのサブディレクトリを作成します。 R コードは次のとおりです。

 if(!dir.exists("docs/chroma_db")) { dir.create("docs/chromaba_db") }

以下は、LangChain の OpenAIEmbeddings を使用して埋め込みを生成する Python コードです。これ現在 OpenAI の ada-2 モデルのデフォルトなので、指定する必要はありません。 LangChain は、埋め込みクラスを通じて、Hugging Face Hub、Cohere、Llama cpp、SpaCy など、他の多くの LLM をサポートしています。

以下の Python コードは、 DeepLearning.AIの LangChain Chatting with Its Data オンライン チュートリアルから若干変更したものです。

 from langchain.embeddings.openai import OpenAIEmbeddings embed_object = OpenAIEmbeddings() from langchain.vectorstores import Chroma chroma_store_directory = "docs/chroma_db" vectordb = Chroma.from_documents( documents=my_split_docs, embedding=embed_object, persist_directory=chroma_store_directory ) # Check how many embeddings were created print(vectordb._collection.count())

_collection.count() のアンダースコアに注意してください。

ggplot2 テキスト ブロックと同じ数、つまり 306 個の埋め込みがあることがわかります。

Python 初心者向けのもう 1 つの注意: Python ではインデントが重要です。インデントされていない行の前にスペースがないこと、およびインデントされている行ではすべて同じ数のインデント スペースが使用されていることを確認します。

このシステムでは、このコードはデータをディスクに保存するようです。ただし、チュートリアルでは、後で使用するために埋め込みを保存するには、次の Python コードを実行する必要があると記載されています。これを行う理由は、ドキュメントが変更されるまで埋め込みを再生成したくないためです

 vectordb.persist()

これで、クエリ用のドキュメントの準備が完了しました。作成されたベクトル埋め込みを使用するために、新しいファイル qanda.py が作成されます。

ステップ5: ユーザークエリを埋め込み、ドキュメントチャンクを見つける

ここで、質問をし、その質問に対する埋め込みを生成し、チャンクの埋め込みに基づいてその質問に最も関連性の高いドキュメントを取得します。

LangChain は、VectorDB オブジェクトの組み込みメソッドのおかげで、これらすべてを 1 行のコードで実行できるいくつかの方法を提供します。 similarity_search() メソッドはベクトルの類似度を直接計算し、最も類似したテキスト ブロックを返します。

ただし、max_marginal_relevance_search() など、これを行う方法は他にもいくつかあります。この背後にある考え方は、3 つのほぼ同じテキスト ブロックが必ずしも必要なわけではないということです。追加の有用な情報を得るためにテキストにもう少し多様性があれば、より豊富な回答が得られるかもしれません。したがって、max_marginal_relevance e_search() は、回答を得るために LLM に実際に渡す予定のテキストよりもわずかに多くの関連テキストを取得します (どれだけ多くするかはユーザーが決定します)。次に、一定レベルの多様性を組み込んで、最終的なテキスト断片を選択します。

ユーザーは、k パラメータを使用して、similarity_search() が返す関連テキスト ブロックの数を指定できます。 max_marginal_relevance() の場合、ユーザーは fetch_k を使用して最初に取得するブロックの数と、k を使用して LLM が回答を見つける最終的なテキスト フラグメントを指定します。

ドキュメントが変更されておらず、doc_prepare.py ファイルを実行したくない場合は、doc_prepare.py を使用する前と同じように、まず新しい qanda.py ファイルに必要なパッケージと環境変数 (OpenAI API キーなど) をロードします。次に、chromadb ベクター データベースがロードされます。

 # If running from RStudio, remember to first run in R: # library(reticulate) # use_virtualenv("the_virtual_environment_you_set_up") # api_key_py <- r_to_py(Sys.getenv("OPENAI_API_KEY")) import openai openai.api_key = r.api_key_for_py from langchain.embeddings.openai import OpenAIEmbeddings embed_object = OpenAIEmbeddings() from langchain.vectorstores import Chroma chroma_store_directory = "docs/chroma_db" vectordb = Chroma(persist_directory=chroma_store_directory, embedding_functinotallow=embed_object)

次に、質問をハードコードし、関連するドキュメントを取得します。 1 行のコードでドキュメントを取得できることに注意してください。

 my_question = "How do you rotate text on the x-axis of a graph?" # For straightforward similarity searching sim_docs = vectordb.similarity_search(my_question) # For maximum marginal relevance search retrieving 5 possible chunks and choosing 3 finalists: mm_docs = vectordb.max_marginal_relevance_search(my_question, k = 3, fetch_k = 5)

取得したドキュメント スニペットを表示する場合は、次のように Python で出力できます。

 for doc in mm_docs: print(doc.page_content) for doc in sim_docs: print(doc.page_content)

インデントは for ループの一部であることに注意してください。

次のコマンドを使用してメタデータを表示することもできます。

 for doc in mm_docs: print(doc.metadata) for docs in sim_docs: print(docs.metadata)

他のオブジェクトと同様に、これらのオブジェクトは R で表示できます。

 mm_relevant <- py$mm_docs sim_relevant <- py$sim_docs

3 つのドキュメントが要求されたときにモデルが 4 つのドキュメントを返すことがある理由はわかりませんが、テキストを反復処理して応答を生成するときに LLM がトークンを多く持っていない限り、これは問題にならないはずです。

ステップ6: 回答を生成する

ここで、GPT-3.5 のような LLM が、関連するドキュメントに基づいてユーザーの質問に対する書面による回答を生成するときが来ました。これは、LangChain の RetrievalQA 機能を使用して実現できます。

まず、実装が簡単で、プロトタイピングやユーザー自身の使用に適したLangChain のデフォルト テンプレートを試してみることをお勧めします

 # Set up the LLM you want to use, in this example OpenAI's gpt-3.5-turbo from langchain.chat_models import ChatOpenAI the_llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0) # Create a chain using the RetrievalQA component from langchain.chains import RetrievalQA qa_chain = RetrievalQA.from_chain_type(the_llm,retriever=vectordb.as_retriever()) # Run the chain on the question, and print the result print(qa_chain.run(my_question))

LLMは次のように回答しました。

 To rotate text on the x-axis of a graph, you can use the `theme()` function in ggplot2. Specifically, you can use the `axis.text.x` argument to modify the appearance of the x-axis text. Here is an example: ```R library(ggplot2) # Create a basic scatter plot p <- ggplot(mtcars, aes(x = mpg, y = wt)) + geom_point() # Rotate x-axis text by 45 degrees p + theme(axis.text.x = element_text(angle = 45, hjust = 1)) ``` In this example, the `angle` argument is set to 45, which rotates the x-axis text by 45 degrees. The `hjust` argument is set to 1, which aligns the text to the right. You can adjust the angle and alignment values to achieve the desired rotation and alignment of the x-axis text.

正しいようです!

チェーンが設定されたので、R スクリプトを使用して、1 つのコマンドで他の問題に対してチェーンを実行できます。

 py_run_string(' print(qa_chain.run("How can I make a bar chart where the bars are steel blue?")) ')

彼らの回答は次のとおりです。

 ```R library(ggplot2) # Create a bar chart with steel blue bars p <- ggplot(mtcars, aes(factor(cyl))) p + geom_bar(fill = "steelblue") ``` In this example, we use the `fill` aesthetic to specify the color of the bars as "steelblue". You can adjust the color to your preference by changing the color name or using a hexadecimal color code.

これは、ChatGPT 3.5 で時々受け取られる同じ質問よりもはるかに良い回答です。返されるコードが実際には機能しないこともあります。

ユーザーは、回答が一般的な ChatGPT ナレッジ ベースから抽出されたものではなく、実際にアップロードしたドキュメントから抽出されたものであることを確認することもできます。調べるには、ggplot2 とはまったく関係がなく、ドキュメントにも記載されていない質問をいくつかしてください。

 py_run_string(' print(qa_chain.run("What is the capital of Australia?")) ')

ユーザーは次のように応答する必要があります。

 I don't know.

アプリがより幅広い用途向けに作成されている場合、「わかりません」というのは少し簡潔すぎるかもしれません。デフォルトのテンプレートをカスタマイズしたい場合は、LangChain のドキュメントを確認してください。自分や小規模なチームだけではなく、複数のユーザー向けのアプリケーションを作成する場合は、応答をパーソナライズするのが合理的です。

テンプレートの調整は、LangChain が過度に複雑に感じられる領域の 1 つであり、テンプレートに小さな変更を実装するために複数行のコードが必要になる場合があります。ただし、独自のフレームワークを使用することはリスクを伴い、プロジェクトの全体的なメリットがコストに見合うかどうかを判断するのは各開発者の責任です。非常に人気があるにもかかわらず、誰もが LangChain の忠実なユーザーというわけではありません。

LangChain で他に何ができるでしょうか?

アプリケーションに最も簡単に追加できるのは、より多くのドキュメントを含めることです。 LangChain には、このプロセスを簡素化する DirectoryLoader があります。ユーザーが複数のドキュメントを検索している場合、応答を生成するためにどのドキュメントが使用されたかを知りたい場合があります。以下のように、RetrievalQA に return_source_documents=True パラメータを追加できます。

 qa_chain = RetrievalQA.from_chain_type(the_llm,retriever=vectordb.as_retriever(), return_source_documents=True) my_result = qa_chain({"query": my_question}) print(my_result['result'])

このコードは、最初は 1 人のユーザーがローカルで実行する場合にのみ役立ちますが、Python 用の Streamlit や Shiny などのフレームワークを使用するインタラクティブなWebアプリケーションの論理的な基盤になることができます。あるいは、Python と R を組み合わせて、LLM からの最終回答を R に送り返し、 Shiny R Webフレームワークを使用してアプリを作成することできます (ただし、Python と R の両方を使用して Shiny アプリをデプロイするのは少し複雑だと感じました)

また、このアプリはユーザーの以前の質問を記憶しないという点で、技術的には「チャットボット」ではないことにも留意することが重要です。したがって、「グラフのタイトル テキストのサイズを変更するにはどうすればよいですか?」や「凡例はどうなりますか?」などの「ダイアログ」は存在できません。ユーザーは新しい単語をそれぞれ入力する必要があります。

ただし、LangChain の ConversationBufferMemory を使用してアプリケーションにメモリを追加し、チャットボットに変えることは可能です。

追加リソース

LangChain について詳しく知るには、LangChain のドキュメントに加えて、kapa という AI チャットボットを備えた LangChain Discord サーバーもあります。ドキュメントを照会できます。

原題: Generative AI with LangChain, RStudio, and just enough Python 、著者: Sharon Machlis


<<:  大規模モデルをより強力にするには、検索拡張生成を使用します。ここでは、Python による実装手順を示します。

>>:  Microsoft の 230 ページに及ぶレポートでは、GPT-4 の最先端の科学研究機能をピクセル レベルで評価しています。無限の可能性を秘めたこのツールに、ぜひご活用ください。

ブログ    

推薦する

少なくとも 8 つのトップカンファレンス論文! NvidiaのLLM研究科学者の求人数は非常に多く、元Google Brainの科学者を驚かせるほどである。

機械学習の分野で仕事を見つけるのはどれくらい難しいですか? NVIDIA の大規模モデル研究科学者の...

...

...

ドイツの中小企業の35%以上がすでに人工知能技術を活用

序文ドイツ連邦政府は2018年に「ドイツ人工知能開発戦略」を発表し、人工知能分野におけるドイツの研究...

...

スマートビルディングにおけるAIの活用

[[428910]]人工知能は、スマートビルディングパズルの最も重要なピースの 1 つです。これがな...

...

放送・ホスティング業界における人工知能の限界についての簡単な分析

[[430680]]科学技術の継続的な発展により、人工知能は人間の生活のあらゆる側面に関わるだけでな...

ライブ放送室で見る高解像度1080Pは720Pほど良くないかもしれない

この記事はAI新メディアQuantum Bit(公開アカウントID:QbitAI)より許可を得て転載...

意見: 機械学習は私たちの注目を必要としています!

機械学習は、私たちがもっと注目する価値のある強力なテクノロジーです。機械学習アプリケーションについて...

人工知能の長所と短所について知っておくべき10の事実

AIの進歩は、人工的に生み出された富がどのように課税され、分配されるかによって、すべての人々が贅沢な...

自動化戦略の6つの重要な要素

[[440295]] IT 自動化は多くの場合、自然に発生します。たとえば、システム管理者は、日常業...

「中国製チップ」の20年と新たな時代

[[285892]] 「自信を持った国と民族だけが、未来への道を着実に前進することができます。木の高...

人間と機械のコラボレーションが顧客に力を与え、インテリジェントな顧客サービスが企業のマーケティング環境を一変させています。

「ロボットはアフターサービスにしか適していません。」 「ロボットはどのようにして人手によるマーケテ...

...