接着第四篇文章、何も書くことがわからなかったので、ちょうどグループで誰かが他の場所で anythingllm の API を呼び出す方法について言及しているのを見たので、このブログ記事が生まれました。これは技術学習のためのものです。より多くの応用方法については、anythingllm の API ドキュメントを参照してください。
現在、cloud studio を利用してプライベートな知識ベースを構築しましたが、他の場所でどのように呼び出すことができるのでしょうか?または、私たちが使用できる API を提供してもらえますか?
anythingllm は実際に API を提供していますが、少しプログラミングの知識が必要です。API があれば、任意のプロジェクトで使用できることを意味します。投げ込んだデータは使うためのものであり、どこで使いたいかに応じて使用することができ、anythingllm の下だけで使用することはできません。
さて、無駄話はここまで、チュートリアルを始めましょう。
現在、第四篇の記事を通じて deepseek にデータを投げ込んだので、API を通じてどのように使用するかを見てみましょう。
- anythingllm の設定画面を開きます【小さなスパナのアイコン】。
- 左側のメニューをスライドして、ツール ---> API キーを選択します。
- 新しい API キーを生成するボタンをクリックすると、新しいポップアップが表示されます。私たちは API キーを作成します。
- 次に、copy key と read the api doc を順にクリックします。
- 開いた AnythingLLM Developer API ページで、
Authorize
をクリックし、先ほどコピーした API キーを貼り付けます。
- ポップアップを閉じます。
- 下にスクロールして Workspaces グループの /v1/workspace/{slug}/stream-chat を見つけてクリックします。
- try out ボタンをクリックし、slug の値を変更します。slug の値は、私たちが最初に作成したワークスペースの名前です。
画像を見てください:ワークスペース
ここでの値は demo です。
Request body の内容を次のように変更します:
{
"message": "こんにちは、あなたは何の大モデルですか",
"mode": "chat"
}
最後に実行をクリックします。
以下のようになります:
少し待つと、回答内容が見られます。
ここでは、この API が正常に使用できるかどうかをテストしています。
では、他の場所でどのように呼び出すことができるのでしょうか?
仮に、私たちがあるウェブページで呼び出すとしましょう。
これには node+html が必要です。
テストなので、私のデモコードを直接示します。
main.js
document.addEventListener('DOMContentLoaded', () => {
const messageInput = document.getElementById('message-input');
const sendButton = document.getElementById('send-button');
const stopButton = document.getElementById('stop-button');
const chatMessages = document.getElementById('chat-messages');
const authInput = document.getElementById('auth-input');
const saveAuthButton = document.getElementById('save-auth-button');
let currentController = null;
function addMessage(message, isUser = false) {
const messageElement = document.createElement('div');
messageElement.classList.add('message');
messageElement.classList.add(isUser ? 'user-message' : 'bot-message');
messageElement.textContent = message;
chatMessages.appendChild(messageElement);
chatMessages.scrollTop = chatMessages.scrollHeight;
}
function setLoading(isLoading) {
sendButton.disabled = isLoading;
messageInput.disabled = isLoading;
stopButton.disabled = !isLoading;
sendButton.textContent = isLoading ? '送信中...' : '送信';
}
async function typeText(element, text) {
const delay = 20; // 各文字の遅延時間(ミリ秒)
for (let i = 0; i < text.length; i++) {
const char = text[i];
const span = document.createElement('span');
span.textContent = char;
span.classList.add('typing');
element.appendChild(span);
await new Promise(resolve => setTimeout(resolve, delay));
}
}
async function sendMessage(message) {
try {
setLoading(true);
currentController = new AbortController();
const response = await fetch('https://ottzkl-pkzulq-3001.app.cloudstudio.work/api/v1/workspace/demo/stream-chat', {
method: 'POST',
headers: {
'accept': 'text/event-stream',
'Authorization': `Bearer ${authInput.value}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
message: message,
mode: 'chat'
}),
signal: currentController.signal
});
if (!response.ok) {
throw new Error(`HTTPエラー!ステータス:${response.status}`);
}
const reader = response.body.getReader();
const decoder = new TextDecoder();
let currentMessageElement = null;
let buffer = '';
while (true) {
const {value, done} = await reader.read();
if (done) break;
const chunk = decoder.decode(value, {stream: true});
buffer += chunk;
let startIndex = 0;
while (true) {
const endIndex = buffer.indexOf('\n', startIndex);
if (endIndex === -1) break;
const line = buffer.slice(startIndex, endIndex).trim();
startIndex = endIndex + 1;
if (line.startsWith('data:')) {
try {
const jsonStr = line.substring(5).trim();
if (!jsonStr) continue;
const data = JSON.parse(jsonStr);
if (data.textResponse !== undefined) {
if (!currentMessageElement) {
currentMessageElement = document.createElement('div');
currentMessageElement.classList.add('message', 'bot-message');
chatMessages.appendChild(currentMessageElement);
}
await typeText(currentMessageElement, data.textResponse);
chatMessages.scrollTop = chatMessages.scrollHeight;
} else if (data.error) {
throw new Error(data.error);
}
} catch (e) {
console.error('レスポンスデータの解析中にエラーが発生しました:', e);
}
}
}
buffer = buffer.slice(startIndex);
}
} catch (error) {
if (error.name === 'AbortError') {
addMessage('会話が停止しました', false);
} else {
console.error('エラー:', error);
let errorMessage = '申し訳ありません、エラーが発生しました';
if (error.response) {
errorMessage += `(HTTP ${error.response.status})`;
} else if (error.request) {
errorMessage += '(ネットワーク接続に失敗しました)';
} else {
errorMessage += `(${error.message})`;
}
addMessage(errorMessage, false);
}
} finally {
currentController = null;
setLoading(false);
}
}
stopButton.addEventListener('click', () => {
if (currentController) {
currentController.abort();
}
});
saveAuthButton.addEventListener('click', () => {
const authValue = authInput.value.trim();
if (authValue) {
addMessage('認証コードが更新されました', false);
} else {
addMessage('有効な認証コードを入力してください', false);
}
});
sendButton.addEventListener('click', () => {
const message = messageInput.value.trim();
if (message) {
addMessage(message, true);
messageInput.value = '';
sendMessage(message);
}
});
messageInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
sendButton.click();
}
});
// ウェルカムメッセージを追加
addMessage('こんにちは!私はAIアシスタントです。何かお手伝いできることはありますか?', false);
});
index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AnythingLLM チャット</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 20px;
background-color: #f5f5f5;
}
.chat-container {
max-width: 800px;
margin: 0 auto;
background-color: white;
border-radius: 10px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
display: flex;
flex-direction: column;
height: 90vh;
}
.settings-container {
padding: 10px 20px;
border-bottom: 1px solid #dee2e6;
display: flex;
gap: 10px;
align-items: center;
}
.auth-input {
flex-grow: 1;
padding: 8px;
border: 1px solid #dee2e6;
border-radius: 5px;
font-size: 14px;
}
.save-auth-button {
padding: 8px 15px;
background-color: #28a745;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 14px;
}
.save-auth-button:hover {
background-color: #218838;
}
.chat-messages {
flex-grow: 1;
overflow-y: auto;
padding: 20px;
}
.message {
margin-bottom: 15px;
padding: 10px 15px;
border-radius: 15px;
max-width: 70%;
animation: fadeIn 0.3s ease-in-out;
word-wrap: break-word;
}
.user-message {
background-color: #007bff;
color: white;
margin-left: auto;
}
.bot-message {
background-color: #e9ecef;
color: black;
margin-right: auto;
}
.typing {
display: inline-block;
overflow: hidden;
white-space: pre-wrap;
animation: typing 0.05s steps(1, end);
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
@keyframes typing {
from { width: 0; }
to { width: 100%; }
}
.input-container {
padding: 20px;
border-top: 1px solid #dee2e6;
display: flex;
gap: 10px;
}
#message-input {
flex-grow: 1;
padding: 10px;
border: 1px solid #dee2e6;
border-radius: 5px;
font-size: 16px;
}
.action-button {
padding: 10px 20px;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 16px;
}
#send-button {
background-color: #007bff;
}
#stop-button {
background-color: #dc3545;
}
#send-button:hover {
background-color: #0056b3;
}
#stop-button:hover {
background-color: #c82333;
}
#stop-button:disabled {
background-color: #6c757d;
cursor: not-allowed;
}
</style>
</head>
<body>
<div class="chat-container">
<div class="settings-container">
<input type="text" id="auth-input" class="auth-input" placeholder="認証コードを入力..." value="E8HX1PF-BWT4ZZM-KW8VGRH-9W0QS1B" />
<button id="save-auth-button" class="save-auth-button">認証コードを保存</button>
</div>
<div class="chat-messages" id="chat-messages"></div>
<div class="input-container">
<input type="text" id="message-input" placeholder="メッセージを入力..." />
<button id="send-button" class="action-button">送信</button>
<button id="stop-button" class="action-button" disabled>停止</button>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script src="main.js"></script>
</body>
</html>
これらの 2 つのファイルは、cs で直接書き込むことができます。
ディレクトリ構造は次のとおりです:
その後、ターミナルで、私は簡単に python を使ってウェブサービスを提供し、ポートは 8089 です。Enter を押すと、nginx や nodejs でも可能です。
python3 -m http.server 8089
ブラウザを開くとクリックします。
以前に作成したキーを貼り付けて、保存をクリックします。
ダイアログボックスに私たちの質問を入力します。
回答がどうなるか見てみましょう。
ここまでで、私たちは以前に demo ワークスペースで構築したプライベートな知識ベースのデータを呼び出しました。