yagibrary

あだ名のやぎと図書館のlibraryを組み合わせてyagibraryです。本から学んだことをみなさんに紹介します。

【読書メモ】【LangChain完全入門】Chapter3 Retrieval - 未知のデータを扱えるようにする

02 与えたPDFをもとに回答するチャットボットを作る

pip install chromadb==0.5.3

0.5.4だと上手くいきませんでした。
参考記事
github.com

chat_3.py

import chainlit as cl
from langchain_groq import ChatGroq
from langchain_community.document_loaders import PyMuPDFLoader
from langchain_huggingface import HuggingFaceEmbeddings
from langchain.prompts import PromptTemplate
from langchain.schema import HumanMessage
from langchain.text_splitter import SpacyTextSplitter
from langchain_community.vectorstores import Chroma

embeddings = HuggingFaceEmbeddings(
  model_name="oshizo/sbert-jsnli-luke-japanese-base-lite"
)

chat = ChatGroq(model_name="llama3-70b-8192")

prompt = PromptTemplate(template="""文章を元に日本語で質問に答えてください。

文章:
{document}

質問: {query}
""", input_variables=["document", "query"])

text_splitter = SpacyTextSplitter(chunk_size=300, pipeline="ja_core_news_sm")

@cl.on_chat_start
async def on_chat_start():
  files = None

  while files == None:
      files = await cl.AskFileMessage(
          content="Please upload a pdf file to begin!", accept=["application/pdf"]
      ).send()

  file = files[0]

  await cl.Message(
      content=f"`{file.name}` uploaded"
  ).send()

  documents = PyMuPDFLoader(file.path).load()
  splitted_documents = text_splitter.split_documents(documents)

  database = Chroma(
    embedding_function=embeddings,
    # 今回はpersist_directoryを指定しないことでデータベースの永続化を行わない
  )

  database.add_documents(splitted_documents)

  cl.user_session.set(
    "database",
    database
  )

@cl.on_message
async def on_message(input_message):
  message_content = input_message.content
  print("入力されたメッセージ: " + message_content)
  database = cl.user_session.get("database")

  documents = database.similarity_search(message_content)

  documents_string = ""

  for document in documents:
    documents_string += f"""
  -------------------------
  {document.page_content}
  """

  result = chat([
    HumanMessage(content=prompt.format(document=documents_string, query=message_content))
  ])
  await cl.Message(content=result.content).send()


03 RetrievalQAを使ってQAシステムの構築を楽にする

query_3.py

from langchain.chains.retrieval_qa.base import RetrievalQA
from langchain_groq import ChatGroq
from langchain_huggingface import HuggingFaceEmbeddings
from langchain.prompts import PromptTemplate
from langchain.schema import HumanMessage
from langchain_community.vectorstores import Chroma

chat = ChatGroq(model_name="llama3-70b-8192")

embeddings = HuggingFaceEmbeddings(
  model_name="oshizo/sbert-jsnli-luke-japanese-base-lite"
)

database = Chroma(
  persist_directory="./.data",
  embedding_function=embeddings
)

retriever = database.as_retriever()

qa = RetrievalQA.from_llm(
  llm=chat,
  retriever=retriever,
  return_source_documents=True
)

result = qa.invoke("飛行車の最高速度を教えて")

print(result["result"])

print(result["source_documents"])

【読書メモ】【プロになるためのSpring入門】第14章 Spring Securityを用いた認証と認可 その2

14.6 リクエストの認可

リクエストの認可のコンフィグレーションじゃ、SecurityFilterChainのBean定義で行います。

▼ソース14.2 リクエストの認可のコンフィグレーション

@Configuration
@EnableWebSecurity
public class SecurityConfig {
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { ❶
        http
            .authorizeHttpRequests()
            .requestMatchers(HttpMethod.POST, "/admin/**").hasRole("ADMIN") ❷
            .requestMatchers("/admin/**").hasAnyRole("ADMIN", "STAFF") ❸
            .anyRequest().permitAll(); ❹
        return http.build();
    }
}

❶の行で@Beanメソッドを追加しています。戻り値の型は、Bean定義したいSecurityFilterChainです。引数で受け取っているのは、SecurityFilterChainオブジェクトを生成してくれるHttpSecurityオブジェクトです。HttpSecurityオブジェクトは、自動的にDIコンテナに登録されるため、@Beanメソッドの引数で受け取ることができます。

14.7 ログイン画面

14.8 認可に失敗したときのエラー画面

14.9 認証用のデータの取得

14.10 画面表示の認可

【読書メモ】【プロになるためのSpring入門】第14章 Spring Securityを用いた認証と認可 その1

Spring Securityは、認証と認可を主としたセキュリティまわりの機能です。本章では、Spring Securityの概要を説明した後、ログイン画面を使った認証と、3種類の認可(リクエストのアクセス、メソッドの呼び出し、画面表示)の方法について具体的に説明します。

14.1 認証と認可

14.1.1 認証(Authentication)

認証は、アプリケーションを使用する相手を特定する行為です。また、相手のことをPrincipalとも呼びます。

14.1.2 認可(Authorization)

認可は、認証した相手がアクセスするリソースに対して、アクセスの可否を制御する行為です。権限のことを、Authorityと呼びます。

14.2 Spring Securityの認証の概要

Spring Securityは、様々な認証の手段をサポートしています。ログイン画面で認証するForm認証、HTTP標準のBasic認証シングルサインオンが可能なOAuth2.0など、主要な認証の手段に対応しています。

また、認証時に必要なID・パスワードといったデータをサーバ側で格納する場所も、さまざまな場所をサポートしています。

14.3 Spring Securityの認可の概要

Spring Securityの使用する際の認可には、代表的なものとして3種類があります。

  1. 「リクエストの認可」
  2. 「メソッドの認可」
  3. 「画面表示の認可」

リクエストの認可では、ブラウザからのリクエストに対して、アクセスの可否を判断します。

メソッドの認可では、呼び出されるメソッドに対して、呼び出しの可否を判断します。

画面表示の認可では、画面の特定の個所を、ログイン中のユーザの権限に応じて、表示したり非表示にしたりする判断をします。

なお、Spring Securityは、認可の処理と認証の処理がうまく分離されていますので、仮に認証の仕組みを変えたとしても、認可の部分の設定に影響がありません。

14.4 Spring SecurityのFilter

Spring Securityは、Servlet Filterの仕組みを使ってさまざまな処理を挟み込んでいます。前述の章で説明したSpring MVCは、裏ではDispatcherServletと呼ばれるServletが動いているため、DispatcherServletオブジェクトに処理が行きつく前に、Servlet Filterを使って処理が挟み込まれることになります。

また、Spring SecurityのFilterは、役割ごとの複数のFilterから構成されています。このFilterのつながりのことをSecurity Filter Chainと呼びます。

Security Filter Chainの中のFilterは通常10個以上存在しますが、代表的なものとして、以下のような役割のFilterが存在します。

  • 認証を行うFilter

ID・パスワードが送信されてきたらサーバ側で保持している認証情報と比較する。

  • リクエストの認可を行うFilter

リクエストに対して、ユーザの権限が満たされているかをチェックする。権限が満たない場合は例外をスローする。

  • 例外をハンドリングするFilter

未認証や権限エラーを表す例外がスローされたら、ログイン画面や権限エラー画面に遷移させる。

14.5 Security Filter Chainのコンフィグレーション

Spring Securityを使用する際は、Security Filter Chainをコンフィグレーションする必要があります。Security Filter Chainのコンフィグレーションは、JavaConfigクラスで行うことができます。

▼ソース14.1 Security Filter Chainのコンフィグレーション

@Configuration
@EnableWebSecurity
public class SecurityConfig {

}

【読書メモ】【確率思考の戦略論 USJでも実証された数学マーケティングの力】第1章 市場構造の本質

1 「客引きの兄ちゃんはみんな同じ顔をしている!」

著者がビジネスをする上で常に心がけていることは、「目に見えているものに惑わされず本質を洞察すること」です。

なぜ? なぜ? と現象から原因を掘り起こし。さらになぜ? という自問を繰り返すことで辿りつく奥底に、様々な現象をつくりあげてきた「問題の本質」が見えてきます。

私の身体の特徴をつくりあげている本質が何かと突き詰めていくと、私の構造を形づくっている本質が私の遺伝子(DNA)であることに行きつきます。

「DNAという本質を核にして、その他の全ての構造が形成されている仕組み」そのものは、私以外の人も全て共通しています。他の動物でも、遺伝子を本質としてそれぞれの身体構造が形成されるという仕組みは全く同じなのです。
一見違うように見えるいくつかの現象の奥底を診てみると、人間社会の仕組みも実に興味深く「本質」によって形づくられていることに気がつきます。

アメリカの客引きの兄ちゃん達が、日本の客引きの兄ちゃんと同じ顔をしていると気づいた話。~

それぞれの職業に就く人間の「属性」に、国境を越えて共通している何かがあるのではないかと、著者はそう考えています。

それは「人は仕事を選ぶけれど、仕事も人を選んでいる」ということに他なりません。

ところで読者の皆さんは、資本主義の世界を形づくっている本質は一体何だと考えていますか? 著者はその答えをまだ探求している最中ではありますが、今のところ「人間の欲望」がその本質ではないかと考えているそうです。

「本質」によって構造が形づくられて、さまざまな「現象」が生まれてくる。本章では、自分が戦う市場構造(Market Structure)の本質が何なのか、つまり市場を形づくるDNAの正体に迫ります。

2 市場構造を理解する意味

市場構造を理解するメリットとは何でしょうか? 市場構造を理解することによって、私達は成功確率の高い企業戦略を選ぶことができるのです。

著者は市場構造を精緻に理解することに情熱を燃やし、「勝てる戦いを見つけること」と「市場構造を利用する方法を考えること」に思考を集中しているのです。

3 市場構造とは何か?

いきなり核心の答えを申し上げますが、それは消費者のPreference(プレファレンス)です。プレファレンスとは、消費者のブランドに対する相対的な好意度(簡単に言えば「好み」)のことで、主にブランド・エクイティー、価格、製品パフォーマンスの3つによって決定されています。市場構造を決定づけているDNAは、消費者のプレファレンスであることを頭の中に入れておいてください。

次に、カテゴリーとは何か? 同じ目的で使用され、同じような方法で便益をあたえる製品・サービスの集まりのことを「カテゴリー」と言います。

4 市場構造の本質はすべて同じ

5 ブランドも同じ法則に支配されている

6 経営資源を集中すべきは、プレファレンスである。

【読書メモ】【思考力の地図 論理とひらめきを使いこなせる頭のつくり方】第1章 WHY いまなぜ、思考力が重要なのか

なぜ思考力が重要なのか —— 知的能力を構成する要素

VUCA時代に求められる力

ビジネスにおける「心」「技」「体」とは何か。

まずはわかりやすい「体」からです。基本中の基本として、普段は意識していませんが「失ったときにその価値を痛感する」のが健康です。

次に「心」ですが、ベースとなっているのは健全な精神です。それに加えてモチベーション、誠実さ、さらには自ら積極的に動ける能動性なども「心」に入ることになるでしょう。

そして最後に残るのが「技」の部分です。「心」と「体」以外の、主に知的能力、いわゆる「頭を使って」発揮する能力がこの「技」の部分であると定義しておきます。

それでは人間の知的能力はどのような構成要素から成り立っているのでしょうか?
ここでは著者の定義する3つの要素を抽出しておきます。

それが「知識力」「対人感性力」そして本書のテーマである「思考力」です。

これらの3つの知的能力は、ビジネスにおけるさまざまな実務を行う上でいずれも必須のものとなります。中でも思考力の重要性が、現在のVUCAと呼ばれる変化が激しく先が読めない時代に相対的に上がってきています。

思考力は「自分なりのもの」を生み出す能力

VUCAの時代におけるこれら3つの能力を具体的に考えてみましょう。まず対人感性力ですが、これは人の気持ちを理解するスキルです。

続いて知識力ですが、ここでは個人が持つ知識の質と量、と定義します。ただ、知識というのは過去に(自分自身を含む)「誰かがやったこと」や誰かがまとめて形に残したものであり、いずれにしろ「過去の集大成」と言うことができます。

これに対して思考力は、新しいものや自分なりのもの、あるいはビジネスであれば他社との差別化を図るためのもの、つまり「違うもの」を生み出すための能力であり、それは変化が激しいときに特に重要な能力になるのです。

工夫に限界がないのと同じく、無限の可能性がある

イエスマンではもはや通用しない —— 思考力が足りないと?