ele

ele

ele

來羊毛啦,騰訊雲Cloud Studio大羊毛!!!五

接著第四篇文章,由於不知道寫什麼,剛好群裡看到有人提到如何在其他地方進行 anythingllm 的 api 調用,故此才會出現本篇博文,只做為技術學習使用。更多的應用方式詳看 anythingllm 的 api 文檔。

image

現在我們用利用 cloud stduio 搭建的私人知識庫搭建了知識庫,我們該如何在其他地方進行調用呢,或者說能否提供一個 api 讓讓我們進行使用?
anythingllm 其實提供了 api,但是需要稍微懂一點編程能力,才能用到這個,畢竟如果有了 api,那就意味著我們可以在任意項目下進行使用,畢竟投餵的數據,是要用起來的,並且是想在哪裡用就在哪裡用,而不能僅僅是在 anythingllm 下使用。

好了,話不多,開始教程。

現在我們已經通過第四篇的文章已經給 deepseek 投餵了數據,那我們該如何通過 api 來使用呢?

  1. 打開 anythingllm 的設置界面【小扳手圖標】。

image

  1. 左側菜單滑動,選擇工具 --->api 密鑰
  2. 點擊生成新的 api 密鑰,會出現新的彈框,我們 create apikey

39E3E616-C7CF-4592-A8D6-9D39941FBBAE

  1. 之後依次點擊 copy key 和 read the api doc,

8DDE62BF-6DA0-4684-B191-E90C835F5FE0

  1. 在打開的 AnythingLLM Developer API 頁面,我們點擊Authorize, 粘貼我們剛剛 copy 的 apikey

6574D458-8F8F-4C30-8C79-7DA2B6301E5F

image

  1. 關閉彈窗

image

  1. 下滑找到 Workspaces 分組下的 /v1/workspace/{slug}/stream-chat,並點擊

image

  1. 點擊 try out 按鈕,並修改 slug 的值,slug 的值就是我們當初新建的工作區的名稱,

image

看圖:工作區

image

我這裡的值是 demo

並修改 Request body 的內容為:

{
  "message": "你好,你是什麼大模型",
  "mode": "chat"
}

最後點擊執行
如圖所示:

image

稍等片刻我們就能看到了回答內容

image

這裡,我們都是在做測試這個 api 能否正常使用。
那麼如何我們在別的地方進行調用呢?
假設,我們在某個網頁裡進行調用。

這個就需要用到了 node+html 了
由於是測試,所以我就直接給出我的 demo 代碼
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 error! status: ${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:', 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="zh-CN">
<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>

這兩個文件可以在 cs 下直接可以寫入
目錄結構如下:

image

之後在終端,運行,我簡單的用 python 來提供 web 服務端口是 8089,回車,nginx nodejs 都可以。

python3 -m http.server 8089

點擊打開瀏覽器

image

粘貼我們之前新建的 key 密鑰,點擊保存

image

在對話框輸入我們的問題
看看回答如何

image

到這裡,我們就已經調用了我們之前在 demo 工作空間裡的私有知識庫的數據調用。

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。