【AI大模型应用开发】【综合实战】AI+搜索,手把手带你实现属于你的AI搜索引擎(附完整代码)

news2024/11/15 17:50:12

现在市面上有很多的AI+搜索的应用或插件,一直想学习其背后的实现原理。今天咱们就学习一下,并且亲自动手实践,从0开始,搭建一个自己的AI搜索引擎。最终实现效果如下:

在这里插入图片描述

话不多说,开干。

本文代码参考:mp.weixin.qq.com/s/6F22Mls7z… 的API。

0. 框架

先来搞定框架。

代码中,服务端使用了Python + Flask框架,前端使用HTML。通过 Flask的render_template函数渲染HTML页面。render_template 函数是 Flask 提供的一个工具,用于渲染 Jinja2 模板。Jinja2 是一个 Python 的模板引擎,它允许你在 HTML 文件中使用 Python 变量和表达式。

代码如下:

python代码解读复制代码from flask import Flask, render_template, request, jsonify
@app.route('/', methods=['GET'])
def index():
    chat_history = history
    return render_template('ai_search.html', history=chat_history)

代码中,HTML页面的名称为 “ai_search.html”。

注意,在使用此种方法渲染HTML页面时,需要将HTML文件放到templates文件夹下,否则找不到文件,报错。
在这里插入图片描述

也就是说,工程目录结构应该如下:

在这里插入图片描述

1. 服务端(Python + Flask)

服务端就是利用Flask封装一个个地接口,然后进行相应处理。

1.1 Search接口

python代码解读复制代码@app.route('/search', methods=['GET', 'POST'])
def search():
    if request.method == 'POST':
        keyword = request.form['keyword']
    elif request.method == 'GET':
        keyword = request.args.get('keyword', '')
    else:
        keyword = ''
    
    results = crawl_pages(keyword)
    output = ""
    for result in results:
     output += f"<li><a id='myID' href='javascript:void(0);' οnclick='handleLinkClick(\"{result['url']}\")'>{result['title']}</a></li><br>"
    return output

Search接口接收用户输入的关键字,然后调用 crawl_pages 接口去获取检索结果。

1.1.1 crawl_pages接口

python代码解读复制代码def crawl_pages(query_text, page_num=2):
    browser = mechanicalsoup.Browser()
    query_text_encoded = quote(query_text) # 关键字编码,例如关键字中的中文要转码才能作为URL的参数
    results = []
    for page_index in range(1, page_num+1):
        url = f"https://search.cctv.com/search.php?qtext={query_text_encoded}&type=web&page={page_index}"
        page = browser.get(url)
        soup = BeautifulSoup(page.text, 'html.parser')
        web_content_links = soup.find_all('a', id=lambda x: x and x.startswith('web_content_'))
        for i, link in enumerate(web_content_links):
            target_page = parse_qs(urlparse(link['href']).query).get('targetpage', [None])[0]
            results.append({'title': link.text, 'url': target_page})
    return results

该接口通过关键字来去固定网页去检索该关键字,获取前两页的检索结果,通过前两页的检索结果,通过爬虫,将结果的标题和URL提取出来。

(1)url = f"https://search.cctv.com/search.php?qtext={query_text_encoded}&type=web&page={page_index}",这是表明去哪个网页搜索这个关键字。这个链接相当于以下操作,去CCTV网搜关键字:

在这里插入图片描述

(2)通过简单的爬虫,将以上获取到的检索结果界面中的所有结果的URL和标题提取出来:target_page = parse_qs(urlparse(link['href']).query).get('targetpage', [None])[0],例如这一句,提取URL。

(3)然后你就会获得一堆的URL,返回给Search接口后,通过 output += f"<li><a id='myID' href='javascript:void(0);' onclick='handleLinkClick(\"{result['url']}\")'>{result['title']}</a></li><br>" 组装结果,插入到HTML中去显示。也就是侧边栏的效果:

在这里插入图片描述

1.2 generate-text接口

python代码解读复制代码@app.route('/generate-text', methods=['POST'])
def generate_text_api():
    prompt = request.json['prompt']
    result = generate_text(prompt)
    return jsonify(result)

在这里插入图片描述

该接口是将用户输入的关键字当作Prompt,给大模型,让大模型根据这个信息回复点什么东西。中间没有什么特别的处理。要说值得注意的,就是 history.append({"user": prompt, "bot": generated_text}) 来将对话信息添加到历史记录里面。

python代码解读复制代码def get_openai_chat_completion(messages, temperature, model = "gpt-3.5-turbo-1106"):
    response = client.chat.completions.create(
        model = model,
        messages = messages,
        temperature = temperature,
    )
    return response

def generate_text(prompt, temperature=0.5):
    messages = [
        {
            "role": "user",
            "content": prompt,
        }   
    ]
    response = get_openai_chat_completion(messages = messages, temperature=temperature)
    generated_text = response.choices[0].message.content
    history.append({"user": prompt, "bot": generated_text})  # 将用户输入和模型输出添加到历史记录中
    return {"status": "success", "response": generated_text}

这一步的效果如下,与检索毫无关系:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

1.3 page_content接口

该接口是通过URL来获取网页内容。就是一个简单的爬虫程序,将网页中的文字和图片提取出来。

python代码解读复制代码@app.route('/page_content')
def page_content():
    url = request.args.get('url', '')
    if not url:
        return '缺少 url 参数'
    browser = mechanicalsoup.Browser()
    page = browser.get(url)
    page.encoding = 'utf-8'  # 指定页面的编码为 utf-8
    soup = BeautifulSoup(page.text, 'html.parser')
    all_text = ''
    all_images = []

    # 获取页面中所有文本内容
    for element in soup.find_all(['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'span']):
        all_text += element.get_text() + ' '

    # 获取页面中所有图片链接
    for img in soup.find_all('img'):
        img_src = img.get('src')
        if img_src:
            all_images.append("https:"+img_src)

    return f"文本内容: {all_text}<br>图片链接: {', '.join(all_images)}"

2. 前端(HTML)

2.1 用户输入关键字后的动作

先来看下前端HTML代码中,当用户点击提交按钮后的动作,重点是下面几行。

python代码解读复制代码inputForm.addEventListener('submit', async (event) => {
    ......

    const aa = document.getElementById('listView');
    aa.innerHTML = await getA(userInput);
    const response = await generateText(userInput);
    hideTypingAnimation(userMessage);
    
    ......
});

可以看到,当用户点击提交按钮后,首先调用了 getA 函数:

python代码解读复制代码async function getA(prompt) {
    const response = await fetch(SERVER_URL + `/search?keyword=${prompt}`, {
        method: 'GET',
        headers: {
            'Content-Type': 'application/json'
        }
    });
    return await response.text();
}

getA函数,调用了服务端的 Search接口,去固定网页检索关键字,获取URL和标题列表。

然后,紧接着调用了 generateText 函数:

python代码解读复制代码async function generateText(prompt) {
    const response = await fetch(SERVER_URL + '/generate-text', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({
            prompt
        })
    });
    return await response.json();
}

generateText 函数,调用了服务端的 generate-text 函数,利用大模型进行回复。

2.2 用户点击侧边栏标题后的动作

当用户点击侧边栏的某个标题后,执行的动作如下:

python代码解读复制代码async function handleLinkClick(link) {
    const content = await getPageContent(link);
    
    ......
    
    const response = await generateText("总结内容:" + content);
    
    ......
}

首先,调用了 getPageContent 接口,通过服务端的 page_content 接口,爬取了该URL中的所有文字内容和图片内容。

然后,通过 generateText 接口,调用服务端的 generate-text 接口,使用大模型对这些文字内容进行总结,从而形成下面的效果:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

3. 完整代码

3.1 ai_search.html

python代码解读复制代码<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Chat with AI</title>
    <style>
        body {
            display: flex;
            flex-direction: column;
            height: 100vh;
            margin: 0;
            font-family: Arial, sans-serif;
        }

        .website-container {
            position: fixed;
            top: 0;
            right: 0;
            width: 350px;
            height: 100%;
            border: 1px solid #ccc;
            overflow-y: auto;
            background-color: #f9f9f9;
            padding: 10px;
        }

        .chat-container {
            height: 100%;
            width: 85%;
            overflow: hidden;
            overflow-y: auto;
            padding: 10px;
            margin-right: 220px;
            /* 腾出右侧栏的宽度 */
        }

        .chat-container::-webkit-scrollbar {
            display: none;
        }

        .avatar-user {
            width: 40px;
            height: 40px;
            background-color: #7fb8e7;
            /* 设置用户头像颜色 */
            border-radius: 50%;
            /* 将头像设置为圆形 */
            margin-left: 10px;
            /* 调整头像与消息之间的间距 */
        }

        .avatar-bot {
            width: 40px;
            height: 40px;
            right: 0;
            background-color: #28a745;
            /* 设置机器人头像颜色 */
            border-radius: 50%;
            /* 将头像设置为圆形 */
            margin-right: 10px;
            /* 调整头像与消息之间的间距 */
            object-fit: cover;
            /* 防止头像变形 */
        }

        .message {
            display: flex;
            align-items: center;
            /* 垂直居中消息和头像 */
            margin-bottom: 1rem;
        }


        .message-text {
            padding: 10px;
            word-wrap: break-word;
            border-radius: 6px;
            max-width: 70%;
            margin:100px;
        }

        .message-text-user {
            padding: 10px;
            border-radius: 6px;
            max-width: 70%;
            margin:100px;
            word-wrap: break-word;
            background-color: #ececec;
        }

        .user-message {
            display: flex;
            justify-content: flex-end;

        }

        .bot-message .message-text {
            background-color: #2ea44f;
            color: white;
        }

        .input-container {
            position: fixed;
            bottom: 0;
            left: 0;
            width: calc(100% - 220px);
            /* 考虑右侧栏的宽度 */
            display: flex;
            align-items: center;
            background-color: #f9f9f9;
            padding: 10px;
        }

        .input-field {
            flex-grow: 1;
            padding: 0.75rem;
            border: 1px solid #d1d5da;
            border-radius: 6px;
            margin-right: 1rem;
        }

        .send-button {
            padding: 0.75rem 1rem;
            background-color: #2ea44f;
            color: white;
            border: none;
            border-radius: 6px;
            cursor: pointer;
        }

        .del-button {
            padding: 0.75rem 1rem;
            background-color: #aeaeae;
            color: white;
            border: none;
            margin-right: 10px;
            border-radius: 6px;
            cursor: pointer;
        }

        .send-button:disabled {
            opacity: 0.5;
            cursor: not-allowed;
        }

        .typing-indicator {
            position: absolute;
            margin-bottom: 50px font-size: 0.8rem;
            color: #586069;
        }

        .typing:before,
        .typing:after {
            content: '';
            display: inline-block;
            width: 0.75rem;
            height: 0.75rem;
            border-radius: 50%;
            margin-right: 0.25rem;
            animation: typing 1s infinite;
        }

        @keyframes typing {
            0% {
                transform: scale(0);
            }

            50% {
                transform: scale(1);
            }

            100% {
                transform: scale(0);
            }
        }

        /* 样式定义 */
        .listView {
            list-style-type: none;
            margin: 0;
            padding: 0;
        }

        .listView li {
            background-color: #f4f4f4;
            padding: 10px;
            margin-bottom: 5px;
            box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.1);
            transition: box-shadow 0.3s ease;
        }

        .listView li:hover {
            box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.2);
        }

        .listView li a {
            text-decoration: none;
            color: #333;
            display: block;
            transition: color 0.3s ease;
        }

        .listView li a:hover {
            color: #ff6600;
        }
    </style>
</head>

<body style="display: flex; flex-direction: column; height: 100vh;">

    <div id="website-container" class="website-container">
        <ul class="listView" id="listView"></ul>
    </div>
    <div style="height: 90%; width:80%; overflow-y: auto; display: flex; flex-direction: column;">
        <ul class="chat-container" id="chat-container">
            {% for item in history %}
                {% if loop.index == 1 %}
                    <!-- 对于第一条消息,可能想要做一些特殊处理 -->
                    <li class="message user-message">
                        <div class="message-text-user">{{ item.user }}</div> <!-- 这里应该插入用户消息 -->
                        <div class="avatar-user"></div>
                    </li>
                    <li class="message bot-message">
                        <div class="avatar-bot"></div>
                        <div class="message-text">{{ item.bot }}</div> <!-- 这里应该插入机器人消息 -->
                    </li>
                {% else %}
                    <!-- 对于其他消息,正常处理 -->
                    <li class="message user-message">
                        <div class="message-text-user">{{ item.user }}</div>
                        <div class="avatar-user"></div>
                    </li>
                    <li class="message bot-message">
                        <div class="avatar-bot"></div>
                        <div class="message-text">{{ item.bot }}</div>
                    </li>
                {% endif %}
            {% endfor %}
        </ul>
    </div>

    <form class="input-container" id="input-form" method="POST"
        style="position: fixed; bottom: 0; left: 0; width: 65%;">
        <button type="button" class="del-button" id="del-button" style="width: 100px;" onclick='del()'>清除</button>
        <input type="text" placeholder="你负责搜,我负责找" class="input-field" id="input-field" name="prompt" autocomplete="off"
            style="width: calc(100% - 100px);">
        <button type="submit" class="send-button" id="send-button" disabled style="width: 100px;">搜索</button>
    </form>

    <script>
        const SERVER_URL = '';
        const inputForm = document.getElementById('input-form');
        const inputField = document.getElementById('input-field');
        const chatContainer = document.getElementById('chat-container');

        inputField.addEventListener('input', () => {
            const userInput = inputField.value.trim();
            document.getElementById('send-button').disabled = !userInput;
        });

        inputForm.addEventListener('submit', async (event) => {
            event.preventDefault();
            const userInput = inputField.value.trim();
            const chatContainer = document.getElementById('chat-container');
            if (!userInput) {
                return;
            }
            const userMessage = createMessageElement(userInput, 'user-message', "message-text-user", "avatar-user");
            chatContainer.appendChild(userMessage);
            inputField.value = '';
            chatContainer.scrollTop = chatContainer.scrollHeight;
            inputField.disabled = true;
            document.getElementById('send-button').disabled = true;
            showTypingAnimation(userMessage);

            const aa = document.getElementById('listView');
            aa.innerHTML = await getA(userInput);
            const response = await generateText(userInput);
            hideTypingAnimation(userMessage);
            if (response.status === 'success') {
                const botResponse = createMessageElement(response.response, 'bot-message', "message-text", "avatar-bot");
                chatContainer.appendChild(botResponse);
                printMessageText(botResponse);

            } else {
                alert(response.message);
            }
            inputField.disabled = false;
            inputField.focus();
        });

        async function generateText(prompt) {
            const response = await fetch(SERVER_URL + '/generate-text', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    prompt
                })
            });
            return await response.json();
        }
        async function getA(prompt) {
            const response = await fetch(SERVER_URL + `/search?keyword=${prompt}`, {
                method: 'GET',
                headers: {
                    'Content-Type': 'application/json'
                }
            });
            return await response.text();
        }
        function createMessageElement(text, className, name, bot) {
            const message = document.createElement('li');
            message.classList.add('message', className, 'typing');
            if (bot == "avatar-bot") {
                message.innerHTML = `
                <div class=${bot}></div>
                <div class=${name}>${text}</div>
                `;
            } else {
                message.innerHTML = `
                <div class=${name}>${text}</div>
                <div class=${bot}></div>
                
                `;
            }
            return message;
        }

        function showTypingAnimation(element) {
            const chatContainer = document.getElementById('chat-container');
            chatContainer.scrollTop = chatContainer.scrollHeight + 10;
            const rect = element.getBoundingClientRect();
            const topPosition = rect.top + window.scrollY + rect.height;
            const leftPosition = rect.left + window.scrollX;
            const typingIndicator = document.createElement('div');
            typingIndicator.classList.add('typing-indicator');
            typingIndicator.style.top = `${topPosition}px`;
            typingIndicator.style.left = `${leftPosition}px`;
            typingIndicator.innerHTML = '思考中...';

            document.body.appendChild(typingIndicator);
        }

        function hideTypingAnimation(element) {
            const typingIndicator = document.querySelector('.typing-indicator');
            if (typingIndicator) {
                typingIndicator.remove();
            }
            element.classList.remove('typing');
        }

        // 添加逐字打印效果
        function printMessageText(message) {
            const chatContainer = document.getElementById('chat-container');
            const text = message.querySelector('.message-text');
            const textContent = text.textContent;
            text.textContent = '';
            for (let i = 0; i < textContent.length; i++) {
                setTimeout(() => {
                    text.textContent += textContent.charAt(i);
                    chatContainer.scrollTop = chatContainer.scrollHeight;
                }, i * 10); // 控制打印速度
            }
        }
        async function handleLinkClick(link) {
            const content = await getPageContent(link);
            console.log(link);
            console.log(content);
            const userMessage = createMessageElement("总结中:" + link, 'user-message', "message-text-user", "avatar-user");
            showTypingAnimation(userMessage);

            const chatContainer = document.getElementById('chat-container');
            chatContainer.appendChild(userMessage);
            const response = await generateText("总结内容:" + content);
            hideTypingAnimation(userMessage);
            if (response.status === 'success') {
                const botResponse = createMessageElement(response.response, 'bot-message', "message-text", "avatar-bot");
                chatContainer.appendChild(botResponse);
                printMessageText(botResponse);

            } else {
                alert(response.message);
            }
        }
        function del(url) {
            const response = fetch(SERVER_URL + `/clear`, {
                method: 'POST'
            });
            location.replace("/");

            return 0;
        }
        // 获取页面内容
        async function getPageContent(url) {
            const response = await fetch(SERVER_URL + `/page_content?url=${url}`, {
                method: 'GET'
            });
            return await response.text();
        }
    </script>
</body>

</html>

3.2 ai_search.py

python代码解读复制代码from flask import Flask, render_template, request, jsonify
from http import HTTPStatus
from openai import OpenAI
import mechanicalsoup
from bs4 import BeautifulSoup
from flask_cors import CORS
from urllib.parse import urlparse, parse_qs, quote
app = Flask(__name__)
client = OpenAI()

CORS(app)

history = []
def crawl_pages(query_text, page_num=2):
    browser = mechanicalsoup.Browser()
    query_text_encoded = quote(query_text)
    results = []
    for page_index in range(1, page_num+1):
        url = f"https://search.cctv.com/search.php?qtext={query_text_encoded}&type=web&page={page_index}"
        page = browser.get(url)
        soup = BeautifulSoup(page.text, 'html.parser')
        web_content_links = soup.find_all('a', id=lambda x: x and x.startswith('web_content_'))
        for i, link in enumerate(web_content_links):
            target_page = parse_qs(urlparse(link['href']).query).get('targetpage', [None])[0]
            results.append({'title': link.text, 'url': target_page})
    return results

def get_openai_chat_completion(messages, temperature, model = "gpt-3.5-turbo-1106"):
    response = client.chat.completions.create(
        model = model,
        messages = messages,
        temperature = temperature,
    )
    return response

def generate_text(prompt, temperature=0.5):
    messages = [
        {
            "role": "user",
            "content": prompt,
        }   
    ]
    response = get_openai_chat_completion(messages = messages, temperature=temperature)
    generated_text = response.choices[0].message.content
    history.append({"user": prompt, "bot": generated_text})  # 将用户输入和模型输出添加到历史记录中
    return {"status": "success", "response": generated_text}

@app.route('/', methods=['GET'])
def index():
    chat_history = history
    return render_template('ai_search.html', history=chat_history)

@app.route('/generate-text', methods=['POST'])
def generate_text_api():
    prompt = request.json['prompt']
    result = generate_text(prompt)
    return jsonify(result)

@app.route('/clear', methods=['POST'])
def clear():
    global history
    history = []
    return '', HTTPStatus.NO_CONTENT

@app.route('/search', methods=['GET', 'POST'])
def search():
    if request.method == 'POST':
        keyword = request.form['keyword']
    elif request.method == 'GET':
        keyword = request.args.get('keyword', '')
    else:
        keyword = ''
    
    results = crawl_pages(keyword)
    output = ""
    for result in results:
     output += f"<li><a id='myID' href='javascript:void(0);' οnclick='handleLinkClick(\"{result['url']}\")'>{result['title']}</a></li><br>"
    return output

@app.route('/page_content')
def page_content():
    url = request.args.get('url', '')
    if not url:
        return '缺少 url 参数'
    browser = mechanicalsoup.Browser()
    page = browser.get(url)
    page.encoding = 'utf-8'  # 指定页面的编码为 utf-8
    soup = BeautifulSoup(page.text, 'html.parser')
    all_text = ''
    all_images = []

    # 获取页面中所有文本内容
    for element in soup.find_all(['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'span']):
        all_text += element.get_text() + ' '

    # 获取页面中所有图片链接
    for img in soup.find_all('img'):
        img_src = img.get('src')
        if img_src:
            all_images.append("https:"+img_src)

    return f"文本内容: {all_text}<br>图片链接: {', '.join(all_images)}"

if __name__ == '__main__':
    app.run(debug=True)

3.3 运行

运行 ai_search.py,打开提示中链接。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

3.4 可能需要安装的依赖

python代码解读复制代码pip install Flask -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install mechanicalsoup -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install Jinja2

3.5 一定是通过Jinja2加载HTML,而不是直接打开HTML

直接打开HTML文件会显示异常:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

4. 总结

本文我们从0开始写了一个AI+搜索的搜索引擎。整体原理还是比较简单的,搜索的原理就是固定URL+关键字,然后爬取网页内的标题和URL,就算是结果了。至于文本总结就更不用多说了,前面的文章详细介绍和实践过。

这个例子很简单,但应该算比较完整了,可以作为后续类似项目的快速开始,在此基础上快速搭建出自己的原型产品。

大家可以上手运行一下,然后运行过程中,你会对这个例子产生一些改进的想法。

有改进的想法,可以一起交流~

最后如果您也对AI大模型感兴趣想学习却苦于没有方向👀
小编给自己收藏整理好的学习资料分享出来给大家💖
👉获取方式:
😝有需要的小伙伴,可以保存图片到wx扫描二v码关注免费领取【保证100%免费】🆓

在这里插入图片描述

一、全套 AGI 大模型学习路线

AI 大模型时代的精彩学习之旅:从根基铸就到前沿探索,牢牢掌握人工智能核心技能!

在这里插入图片描述

二、640 套 AI 大模型报告合集

此套涵盖 640 份报告的精彩合集,全面涉及 AI 大模型的理论研究、技术实现以及行业应用等诸多方面。无论你是科研工作者、工程师,还是对 AI 大模型满怀热忱的爱好者,这套报告合集都将为你呈上宝贵的信息与深刻的启示。

在这里插入图片描述

三、AI 大模型经典 PDF 书籍

伴随人工智能技术的迅猛发展,AI 大模型已然成为当今科技领域的一大热点。这些大型预训练模型,诸如 GPT-3、BERT、XLNet 等,凭借其强大的语言理解与生成能力,正在重塑我们对人工智能的认知。而以下这些 PDF 书籍无疑是极为出色的学习资源。
在这里插入图片描述
在这里插入图片描述

阶段 1:AI 大模型时代的基础认知

  • 目标:深入洞悉 AI 大模型的基本概念、发展历程以及核心原理。

  • 内容

    • L1.1 人工智能概述与大模型起源探寻。
    • L1.2 大模型与通用人工智能的紧密关联。
    • L1.3 GPT 模型的辉煌发展历程。
    • L1.4 模型工程解析。
    • L1.4.1 知识大模型阐释。
    • L1.4.2 生产大模型剖析。
    • L1.4.3 模型工程方法论阐述。
    • L1.4.4 模型工程实践展示。
    • L1.5 GPT 应用案例分享。

阶段 2:AI 大模型 API 应用开发工程

  • 目标:熟练掌握 AI 大模型 API 的运用与开发,以及相关编程技能。

  • 内容

    • L2.1 API 接口详解。
    • L2.1.1 OpenAI API 接口解读。
    • L2.1.2 Python 接口接入指南。
    • L2.1.3 BOT 工具类框架介绍。
    • L2.1.4 代码示例呈现。
    • L2.2 Prompt 框架阐释。
    • L2.2.1 何为 Prompt。
    • L2.2.2 Prompt 框架应用现状分析。
    • L2.2.3 基于 GPTAS 的 Prompt 框架剖析。
    • L2.2.4 Prompt 框架与 Thought 的关联探讨。
    • L2.2.5 Prompt 框架与提示词的深入解读。
    • L2.3 流水线工程阐述。
    • L2.3.1 流水线工程的概念解析。
    • L2.3.2 流水线工程的优势展现。
    • L2.3.3 流水线工程的应用场景探索。
    • L2.4 总结与展望。

阶段 3:AI 大模型应用架构实践

  • 目标:深刻理解 AI 大模型的应用架构,并能够实现私有化部署。

  • 内容

    • L3.1 Agent 模型框架解读。
    • L3.1.1 Agent 模型框架的设计理念阐述。
    • L3.1.2 Agent 模型框架的核心组件剖析。
    • L3.1.3 Agent 模型框架的实现细节展示。
    • L3.2 MetaGPT 详解。
    • L3.2.1 MetaGPT 的基本概念阐释。
    • L3.2.2 MetaGPT 的工作原理剖析。
    • L3.2.3 MetaGPT 的应用场景探讨。
    • L3.3 ChatGLM 解析。
    • L3.3.1 ChatGLM 的特色呈现。
    • L3.3.2 ChatGLM 的开发环境介绍。
    • L3.3.3 ChatGLM 的使用示例展示。
    • L3.4 LLAMA 阐释。
    • L3.4.1 LLAMA 的特点剖析。
    • L3.4.2 LLAMA 的开发环境说明。
    • L3.4.3 LLAMA 的使用示例呈现。
    • L3.5 其他大模型介绍。

阶段 4:AI 大模型私有化部署

  • 目标:熟练掌握多种 AI 大模型的私有化部署,包括多模态和特定领域模型。

  • 内容

    • L4.1 模型私有化部署概述。
    • L4.2 模型私有化部署的关键技术解析。
    • L4.3 模型私有化部署的实施步骤详解。
    • L4.4 模型私有化部署的应用场景探讨。

学习计划:

  • 阶段 1:历时 1 至 2 个月,构建起 AI 大模型的基础知识体系。
  • 阶段 2:花费 2 至 3 个月,专注于提升 API 应用开发能力。
  • 阶段 3:用 3 至 4 个月,深入实践 AI 大模型的应用架构与私有化部署。
  • 阶段 4:历经 4 至 5 个月,专注于高级模型的应用与部署。
    在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2163357.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

累加求和-C语言

1.问题&#xff1a; 计算123……100的和&#xff0c;要求分别用while、do while、for循环实现。 2.解答&#xff1a; 累加问题&#xff0c;先后将100个数相加。要重复进行100次加法运算&#xff0c;可以用循环结构来实现。重复执行循环体100次&#xff0c;每次加一个数。 3.代…

02DSP学习-了解syscfg

不是哥们儿&#xff0c;学习DSP为什么不是上来就写代码啊&#xff0c;说了一堆&#xff0c;写小说呢啊&#xff1f; 你别着急&#xff0c;学习DSP本身&#xff0c;真不需要写多少代码&#xff0c;我们需要的写的是自己的算法。开车知道方向盘、油门、刹车、后视镜之后也能开&a…

【SpringBoot详细教程】-03-整合Junit【持续更新】

JUnit是一个用于Java编程语言的测试框架。它支持自动化单元测试&#xff0c;可以帮助开发人员测试代码的正确性和健壮性。JUnit提供了一组注解、断言和测试运行器&#xff0c;可以方便地编写和运行单元测试。 SpringBoot 整合 junit 特别简单&#xff0c;分为以下三步完成 在…

cmake--file

教程 参数 需要指定文件后缀 GLOB 只搜索当前目录 GLOB_RECURSE &#xff1a;搜索当前目录和其子目录&#xff08;递归搜索&#xff09; RELATIVE 相对于哪个路径进行搜索&#xff0c;获取文件的相对路径。 使用RELATIVE和不使用RELATIVE的区别&#xff1a; 1&#xff…

《让手机秒变超级电脑!ToDesk云电脑、易腾云、青椒云移动端深度体验》

前言 科技发展到如今2024年&#xff0c;可以说每一年都在发生翻天覆地的变化。云电脑这个市场近年来迅速发展&#xff0c;无需购买和维护额外的硬件就可以体验到电脑端顶配的性能和体验&#xff0c;并且移动端也可以带来非凡体验。我们在外出办公随身没有携带电脑情况下&#x…

MudBlazor:一个UI简洁美观漂亮的Blazor开源组件!

Blazor&#xff0c;作为.NET生态系统中的一个革命性框架&#xff0c;使得可以使用C#来全栈开发Web应用。下面推荐一个Blazor开源UI组件MudBlazor&#xff0c;方便我们快速开发。 01 项目简介 MudBlazor 是一个开源的 .NET 库&#xff0c;它为 Blazor 应用程序提供了一套丰富的…

Java JUC(二) Synchronized 基本使用与核心原理

Java JUC&#xff08;二&#xff09; Synchronized 基本使用与核心原理 随着 Java 多线程开发的引入&#xff0c;程序的执行效率和速度都取得了极大的提升。但此时&#xff0c;多条线程如果同时对一个共享资源进行了非原子性操作则可能会诱发线程安全问题&#xff0c;而线程安全…

前端报错401 【已解决】

前端报错401 【已解决】 在前端开发中&#xff0c;HTTP状态码401&#xff08;Unauthorized&#xff09;是一个常见的错误&#xff0c;它表明用户试图访问受保护的资源&#xff0c;但未能提供有效的身份验证信息。这个错误不仅关乎用户体验&#xff0c;也直接关系到应用的安全性…

JAVA开源项目 学科竞赛管理系统 计算机毕业设计

本文项目编号 T 047 &#xff0c;文末自助获取源码 \color{red}{T047&#xff0c;文末自助获取源码} T047&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 查…

修牛蹄视频哪里找?修牛蹄的解压视频素材网站分享

在现代农业和畜牧业中&#xff0c;牛蹄修剪技术的重要性不言而喻&#xff0c;不仅直接关联到牲畜的健康&#xff0c;也对农场的整体经济收益产生巨大影响。对于新手畜牧工作者而言&#xff0c;挑选出优秀的学习资源尤为关键。今天&#xff0c;我将为大家推荐几个提供优质牛蹄修…

烤羊肉串引来的思考——命令模式

文章目录 烤羊肉串引来的思考——命令模式吃烤羊肉串&#xff01;烧烤摊vs.烧烤店紧耦合设计命令模式松耦合设计进一步改进命令模式命令模式的作用 烤羊肉串引来的思考——命令模式 吃烤羊肉串&#xff01; 时间&#xff1a;6月23日17点  地点&#xff1a;小区门口  人物…

企业EMS -能源管理系统-能源在线监测平台

一、介绍 基于SpringCloud的能管管理系统-能源管理平台源码-能源在线监测平台-双碳平台源码-SpringCloud全家桶-能管管理系统源码 二、软件架构 二、功能介绍 三、数字大屏展示 四、数据采集原理 五、软件截图

在不受支持的 Mac 上安装 macOS Sequoia (OpenCore Legacy Patcher v2.0.1)

在不受支持的 Mac 上安装 macOS Sequoia (OpenCore Legacy Patcher v2.0.1) Install macOS on unsupported Macs 请访问原文链接&#xff1a;https://sysin.org/blog/install-macos-on-unsupported-mac/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主…

吉客云与金蝶云星空对接集成分页查询货品信息连通[标准]

吉客云与金蝶云星空对接集成分页查询货品信息连通[标准][付款单新增]-v1(付款单) 对接系统&#xff1a;吉客云 “吉客云”是一站式企业数字化解决方案系统&#xff0c;可实现业务、财务、办公、人事等一体化管理。相对于传统多套软件系统的集成方案&#xff0c;“吉客云”具有业…

剖析:基于 RDMA 的多机数据分发和接收场景

在基于 RDMA 的多机数据分发和接收场景中&#xff0c;数据的传输主要依赖于以下几个步骤和角色&#xff1a; 机器 A&#xff08;发送方&#xff09;&#xff1a;通过 RDMA 将数据直接写入远程机器的内存中。机器 B&#xff08;接收方&#xff09;&#xff1a;接收数据&#xf…

关于 NLP 应用方向与深度训练的核心流程

文章目录 主流应用方向核心流程&#xff08;5步&#xff09;1.选定语言模型结构2.收集标注数据3.forward 正向传播4.backward 反向传播5.使用模型预测真实场景 主流应用方向 文本分类文本匹配序列标注生成式任务 核心流程&#xff08;5步&#xff09; 基本流程实现的先后顺序…

ShardingSphere 分库分表

中间件 常用中间件 MyCat 是基于 Proxy&#xff0c;它复写了 MySQL 协议&#xff0c;将 Mycat Server 伪装成⼀个 MySQL 数据库客户端所有的jdbc请求都必须要先交给MyCat&#xff0c;再有 MyCat转发到具体的真实服务器缺点是效率偏低&#xff0c;中间包装了⼀层代码⽆侵⼊性…

解决Android Studio 右上角Gradle不显示task

解决Android Studio 右上角Gradle不显示task_gradle中没有build task-CSDN博客 不正常的情况下 正常的情况下 解决方案 依次点击&#xff1a;File -> Settings -> Experimental -> 取消勾选 “Do not build Gradle task list during Gradle sync” 同步项目即可

[数据集][目标检测]基于yolov5增强数据集算法mosaic来扩充自己的数据集自动生成增强图片和对应标注无需重新标注

【算法介绍】 YOLOv5最引人注目的增强技术之一是马赛克增强&#xff0c;它将四张不同的图像拼接成一张图像。 思路&#xff1a;首先&#xff0c;从数据集中随机选择四张图像&#xff0c;然后将它们缩放、随机裁剪&#xff0c;并按马赛克模式拼接在一起。这种方式允许模型看到…

【逐行注释】MATLAB的程序,对比EKF(扩展卡尔曼滤波)和PF(粒子滤波)的滤波效果,附下载链接

文章目录 总述部分源代码运行结果扩展性 总述 本代码使用 M A T L A B MATLAB MATLAB实现了扩展卡尔曼滤波&#xff08; E K F EKF EKF&#xff09;和粒子滤波&#xff08; P F PF PF&#xff09;在状态估计中的对比分析。 主要功能包括&#xff1a; 参数设置&#xff1a;初始…