Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

KB RAG v2 のオプション(フィルター)の UI 検討 #817

Merged
merged 11 commits into from
Jan 16, 2025
22 changes: 20 additions & 2 deletions packages/web/src/components/InputChatContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
PiArrowsCounterClockwise,
PiPaperclip,
PiSpinnerGap,
PiSlidersHorizontal,
} from 'react-icons/pi';
import useFiles from '../hooks/useFiles';
import FileCard from './FileCard';
Expand Down Expand Up @@ -39,7 +40,16 @@ type Props = {
| {
hideReset: true;
}
);
) &
(
| {
setting: true;
onSetting: () => void;
}
| {
setting?: false;
}
);

const InputChatContent: React.FC<Props> = (props) => {
const { pathname } = useLocation();
Expand Down Expand Up @@ -177,7 +187,7 @@ const InputChatContent: React.FC<Props> = (props) => {
</div>
)}
<Textarea
className={`scrollbar-thumb-gray-200 scrollbar-thin m-2 -mr-14 bg-transparent ${props.fileUpload ? 'pr-24' : 'pr-14'}`}
className={`scrollbar-thumb-gray-200 scrollbar-thin m-2 -mr-14 bg-transparent ${props.fileUpload || props.setting ? 'pr-24' : 'pr-14'}`}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fileUpload と setting が両方有効であることは現状想定されない実装

placeholder={props.placeholder ?? '入力してください'}
noBorder
notItem
Expand Down Expand Up @@ -209,6 +219,14 @@ const InputChatContent: React.FC<Props> = (props) => {
</label>
</div>
)}
{props.setting && (
<ButtonSend
className="absolute bottom-2 right-12"
disabled={loading}
onClick={props.onSetting}
icon={<PiSlidersHorizontal />}
/>
)}
<ButtonSend
className="absolute bottom-2 right-2"
disabled={disabledSend}
Expand Down
120 changes: 60 additions & 60 deletions packages/web/src/pages/RagKnowledgeBasePage.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import InputChatContent from '../components/InputChatContent';
import { create } from 'zustand';
import Alert from '../components/Alert';
import useChat from '../hooks/useChat';
import { useLocation } from 'react-router-dom';
import ChatMessage from '../components/ChatMessage';
Expand All @@ -20,7 +19,8 @@ import { RetrievalFilterLabel } from '../components/KbFilter';
import KbFilter from '../components/KbFilter';
import { ExplicitFilterConfiguration } from 'generative-ai-use-cases-jp';
import { Option, SelectValue } from '../components/FilterSelect';
import { PiSlidersHorizontal } from 'react-icons/pi';
import ModalDialog from '../components/ModalDialog';
import Button from '../components/Button';

type StateType = {
sessionId: string | undefined;
Expand Down Expand Up @@ -74,7 +74,8 @@ const RagKnowledgeBasePage: React.FC = () => {
const prompter = useMemo(() => {
return getPrompter(modelId);
}, [modelId]);
const [expanded, setExpanded] = useState(window.innerWidth > 1024);

const [showSetting, setShowSetting] = useState(false);

const RetrievalFilterLabelToRetrievalFilter = (
f: RetrievalFilterLabel | null,
Expand Down Expand Up @@ -188,10 +189,7 @@ const RagKnowledgeBasePage: React.FC = () => {

return (
<>
<div
className={`${!isEmpty ? 'screen:pb-36' : ''} relative ${
expanded ? 'lg:mr-64' : ''
}`}>
<div className={`${!isEmpty ? 'screen:pb-36' : ''} relative`}>
<div className="invisible my-0 flex h-0 items-center justify-center text-xl font-semibold lg:visible lg:my-5 lg:h-min print:visible print:my-5 print:h-min">
RAG チャット
</div>
Expand All @@ -212,23 +210,6 @@ const RagKnowledgeBasePage: React.FC = () => {
</div>
)}

{isEmpty && (
<div
className={`absolute inset-x-0 top-28 m-auto flex justify-center`}>
<Alert severity="info">
<div>
RAG (Retrieval Augmented Generation)
手法のチャットを行うことができます。
</div>
<div>
メッセージが入力されると Knowledge Base
でドキュメントを検索し、検索したドキュメントをもとに LLM
が回答を生成します。
</div>
</Alert>
</div>
)}

<div ref={scrollableContainer}>
{messages.map((chat, idx) => (
<div key={idx}>
Expand All @@ -242,17 +223,12 @@ const RagKnowledgeBasePage: React.FC = () => {
))}
</div>

<div
className={`fixed right-4 top-[calc(50vh-2rem)] z-0 ${
expanded ? 'lg:pr-64' : ''
}`}>
<div className={`fixed right-4 top-[calc(50vh-2rem)] z-0 lg:right-8`}>
<ScrollTopBottom />
</div>

<div
className={`fixed bottom-0 z-0 flex w-full flex-col items-center justify-center print:hidden ${
expanded ? 'lg:pr-128' : 'lg:pr-64'
}`}>
className={`fixed bottom-0 z-0 flex w-full flex-col items-center justify-center lg:pr-64 print:hidden`}>
<InputChatContent
content={content}
disabled={loading}
Expand All @@ -261,40 +237,64 @@ const RagKnowledgeBasePage: React.FC = () => {
onSend();
}}
onReset={onReset}
setting={true}
onSetting={() => {
setShowSetting(true);
}}
/>
</div>
</div>

<div
className={`fixed top-0 transition-all ${
expanded ? 'right-0 z-50' : '-right-64 z-30'
} pointer-events-none flex h-full justify-center`}>
<div
className="bg-aws-smile pointer-events-auto mt-16 flex size-12 cursor-pointer items-center justify-center rounded-l-full"
onClick={() => {
setExpanded(!expanded);
}}>
<PiSlidersHorizontal className="text-aws-squid-ink size-6" />
</div>
<div className="bg-aws-squid-ink scrollbar-thin scrollbar-thumb-white pointer-events-auto h-full w-64 overflow-y-scroll break-words p-3 text-sm text-white">
<div className="my-2 flex items-center text-sm font-semibold">
<PiSlidersHorizontal className="mr-1.5 text-lg" />
高度なオプション
</div>
{userDefinedExplicitFilters.length > 0 && (
<ExpandableField
label="フィルタ"
className="relative w-full"
defaultOpened={true}>
<KbFilter
filterConfigs={userDefinedExplicitFilters}
filters={filters}
setFilters={setFilters}
/>
</ExpandableField>
)}
<ModalDialog
isOpen={showSetting}
onClose={() => {
setShowSetting(false);
}}
title="高度なオプション">
{userDefinedExplicitFilters.length > 0 && (
<ExpandableField
label="フィルタ"
className="relative w-full"
defaultOpened={true}>
<div className="flex justify-end">
フィルター設定については{' '}
<a
className="text-aws-smile underline"
href="https://github.com/aws-samples/generative-ai-use-cases-jp/blob/main/packages/common/src/custom/rag-knowledge-base.ts"
target="_blank">
こちら
</a>{' '}
をご参照ください。
</div>

<KbFilter
filterConfigs={userDefinedExplicitFilters}
filters={filters}
setFilters={setFilters}
/>
</ExpandableField>
)}
{userDefinedExplicitFilters.length === 0 && (
<p>
設定が見つかりませんでした。
<a
className="text-aws-smile underline"
href="https://github.com/aws-samples/generative-ai-use-cases-jp/blob/main/packages/common/src/custom/rag-knowledge-base.ts"
target="_blank">
packages/common/src/custom/rag-knowledge-base.ts
</a>{' '}
をカスタマイズすることでフィルターを追加できます。
</p>
)}
<div className="mt-4 flex justify-end">
<Button
onClick={() => {
setShowSetting(false);
}}>
設定
</Button>
</div>
</div>
</ModalDialog>
</>
);
};
Expand Down
27 changes: 1 addition & 26 deletions packages/web/src/pages/RagPage.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import React, { useCallback, useEffect } from 'react';
import InputChatContent from '../components/InputChatContent';
import { create } from 'zustand';
import Alert from '../components/Alert';
import useChat from '../hooks/useChat';
import useRag from '../hooks/useRag';
import { useLocation, Link } from 'react-router-dom';
import { useLocation } from 'react-router-dom';
import ChatMessage from '../components/ChatMessage';
import Select from '../components/Select';
import ScrollTopBottom from '../components/ScrollTopBottom';
Expand Down Expand Up @@ -95,30 +94,6 @@ const RagPage: React.FC = () => {
</div>
)}

{isEmpty && (
<div
className={`absolute inset-x-0 top-28 m-auto flex justify-center`}>
<Alert severity="info">
<div>
RAG (Retrieval Augmented Generation)
手法のチャットを行うことができます。
</div>
<div>
メッセージが入力されると Amazon Kendra
でドキュメントを検索し、検索したドキュメントをもとに LLM
が回答を生成します。
</div>
<div className="font-bold">
Amazon Kendra の検索のみを実行する場合は
<Link className="text-aws-smile" to="/kendra">
こちら
</Link>
のページに遷移してください。
</div>
</Alert>
</div>
)}

<div ref={scrollableContainer}>
{messages.map((chat, idx) => (
<div key={idx}>
Expand Down