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 工作空间里的私有知识库的数据调用。

加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。