Datawhale AI夏令营 RAG入门 Task05~

import os
from dotenv import load_dotenv


# 加载环境变量
load_dotenv()
# 从环境变量中读取api_key
api_key = os.getenv('ZHIPU_API_KEY')
base_url = "https://open.bigmodel.cn/api/paas/v4/"
chat_model = "glm-4-air"
emb_model = "embedding-2"

# 配置对话模型
from llama_index.llms.zhipuai import ZhipuAI
llm = ZhipuAI(
    api_key = api_key,
    model = chat_model,
)

# 配置嵌入模型
from llama_index.embeddings.zhipuai import ZhipuAIEmbedding
embedding = ZhipuAIEmbedding(
    api_key = api_key,
    model = emb_model,
)
emb = embedding.get_text_embedding("测试测试测试")

from llama_index.core import SimpleDirectoryReader,Document
documents = SimpleDirectoryReader(input_files=['../docs/强化学习入门指南.txt']).load_data()

from llama_index.core import VectorStoreIndex
# 想要看到进度条的话,加一个参数 show_progress=True,但是在本课程中不建议这样做,因为在后面流式输出的时候,会和Jupyter Notebook的输出渲染机制之间存在冲突
index = VectorStoreIndex.from_documents(documents,embed_model=embedding)

本课的主要内容:将问答引擎部署成一个能够提供流式输出(Streaming Output)的Web服务

什么是流式输出

在之前的学习中,当调用 query_engine.query() 时,程序会:

  1. 向大模型发送请求。
  2. 等待大模型生成完整的答案。
  3. 一次性将完整的答案返回给你。

这个过程对于用户来说体验不佳,因为在等待期间,界面是静止的,用户不知道系统是否在正常工作。

流式输出则完全不同:

  1. 向大模型发送请求。
  2. 大模型每生成一小部分(可能是一个词或几个字),就立刻通过网络发送回来。
  3. 程序接收到一小部分,就立刻处理(比如在界面上显示出来)。

这个过程是连续不断的,直到大模型生成完所有内容。这就实现了我们熟悉的“打字机”效果,极大地提升了用户体验。

在 LlamaIndex 中启用流式响应

这是实现所有后续功能的基础。

query_engine = index.as_query_engine(
    streaming=True,
    similarity_top_k=3,
    llm=llm
)

streaming=True: 这是最关键的参数。这个参数为True的时候,我们构建的就是一个流式输出的引擎。

response_stream = query_engine.query("请写一篇1000字的文章,论述强化学习的应用前景")
for text in response_stream.response_gen:
    print(text, end="")
强化学习作为人工智能领域的一个重要分支,近年来取得了显著的进展。它通过不断尝试和交互,使智能体学会在复杂环境中做出最优决策。本文将从四个方面论述强化学习的应用前景,分别为游戏领域、机器人控制、智能交通和推荐系统。

首先,在游戏领域,强化学习展现了极高的应用价值。以AlphaGo为例,它是由DeepMind开发的一款基于强化学习算法的围棋人工智能程序。AlphaGo在2016年与世界围棋冠军李世石的比赛中取得了胜利,震惊了围棋界。此外,强化学习还可以应用于其他电子游戏,如Atari游戏、星际争霸等。通过强化学习,智能体可以学会在各种游戏环境中制定策略,提高游戏水平。

其次,在机器人控制领域,强化学习具有广泛的应用前景。机器人需要在复杂环境中完成各种任务,如行走、搬运等。强化学习可以使机器人学会在不确定情况下做出最优决策,提高其自主性和智能水平。例如,强化学习可以帮助机器人学会在复杂地形上行走,提高其在实际应用中的性能。

再者,智能交通是强化学习的另一个重要应用领域。随着城市化进程的加快,交通拥堵问题日益严重。强化学习可以应用于智能交通系统,帮助车辆在复杂路况中做出最优行驶策略。通过实时获取道路状况、车辆位置等信息,强化学习可以使车辆在保证安全的前提下,提高行驶效率,降低能耗。此外,强化学习还可以应用于自动驾驶技术,使车辆具备更高的智能水平。

最后,在推荐系统领域,强化学习同样具有巨大潜力。随着互联网的普及,用户在网络上产生的数据日益丰富。推荐系统可以根据用户的历史行为、兴趣等信息,为用户推荐合适的商品、服务或内容。强化学习可以使推荐系统具备更高的智能水平,实时调整推荐策略,提高用户满意度。例如,强化学习可以应用于电商平台的商品推荐,帮助商家提高销售额。

总之,强化学习在游戏领域、机器人控制、智能交通和推荐系统等方面具有广泛的应用前景。随着技术的不断发展,强化学习将更加成熟,为各行各业带来更大的价值。同时,我们也应关注强化学习可能带来的风险和挑战,以确保其在实际应用中的安全性和可靠性。在未来,强化学习有望成为推动人工智能发展的重要动力。
  • response_stream: 当 streaming=True 时,.query() 返回的不再是一个包含最终答案的 Response 对象,而是一个 StreamingResponse 对象。
  • response_stream.response_gen: 这个对象内部包含一个生成器(Generator) ,名为 response_gen。可以把它想象成一个“管道”,大模型生成的文本块会源源不断地从这个管道里流出来。
  • for text in ... : 通过 for 循环遍历这个生成器,并用 print 函数显示出来,从而在Jupyter Notebook中模拟出流式输出的效果。

注意,如果在运行上面的单元格的时候,输出内容中出现了诸如重复输出、某一文字块重复出现等现象,请把代码最开头部分中的index = VectorStoreIndex.from_documents(documents,embed_model=embedding,show_progress=True)show_progress=True参数删去,他和Jupyter Notebook的输出渲染机制之间存在冲突

用 FastAPI 部署流式接口

FastAPI是一个强大的框架,让任何人都可以通过网络(HTTP)来访问你的流式问答引擎。

import uvicorn
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import StreamingResponse
import threading

app = FastAPI()
app.add_middleware(CORSMiddleware,allow_origins=["*"])

# 新增服务器控制相关代码
_server_thread = None

def run_server():
    config = uvicorn.Config(app, host='0.0.0.0', port=5001)
    server = uvicorn.Server(config)
    server.run()

def start_server():
    """启动后台服务"""
    global _server_thread
    if not _server_thread or not _server_thread.is_alive():
        _server_thread = threading.Thread(target=run_server, daemon=True)
        _server_thread.start()
        print("服务已启动:http://localhost:5001/stream_chat")

@app.get('/stream_chat')
async def stream_chat(param:str = "你好"):
    async def generate():
        response_stream = query_engine.query(param)
        for text in response_stream.response_gen:
            yield text
    return StreamingResponse(generate(), media_type='text/event-stream')

# 在Notebook中直接调用启动服务
start_server()
服务已启动:http://localhost:5001/stream_chat
  • @app.get('/stream_chat') : 这是一个装饰器,它定义了一个HTTP GET接口,路径是 /stream_chat。当有人访问 http://你的地址:5000/stream_chat 时,就会触发下面的 stream_chat 函数。

  • async def stream_chat(...) : 使用 async 关键字定义了一个异步函数,这对于处理网络I/O等耗时操作非常高效。

  • async def generate(): yield text: 这是实现流式响应的核心

    • generate 函数内部包含 yield 关键字,这使得它不再是一个普通函数,而是一个异步生成器
    • for 循环从 response_stream.response_gen 中取出一个文本块时,yield text 会立即将这个文本块作为HTTP响应的一部分发送出去,然后函数暂停,等待下一个文本块。这个过程会一直重复,直到 response_gen 耗尽。
  • StreamingResponse(generate(), ...) : FastAPI提供的专门用于处理流式响应的类。它接收一个生成器(这里的 generate()),并告诉浏览器这是一个事件流(media_type='text/event-stream'),需要持续接收数据。

如何从客户端(Python脚本或前端JS)调用和处理这个流式接口

# 调用服务
import requests

def test_stream_chat(question="你好"):
    url = "http://localhost:5001/stream_chat"
    params = {"param": question}

    with requests.get(url, params=params, stream=True) as response:
        for chunk in response.iter_content(decode_unicode=True):
            if chunk:
                print(chunk, end="", flush=True)

# 调用示例
test_stream_chat("强化学习的就业前景如何?")
强化学习作为人工智能领域的一个重要分支,其就业前景广阔。随着人工智能技术的不断发展和应用领域的扩大,掌握强化学习的人才需求也在增加。毕业生可以在诸如互联网公司、科技企业、自动驾驶、机器人技术、金融分析、游戏开发等多个行业找到就业机会。此外,强化学习在科学研究、技术顾问、项目管理和教育等领域也有广泛的应用。因此,具备强化学习技能的专业人才通常具有较好的就业前景。
  • stream=True: 在使用 requests 库时,这个参数是必须的。它告诉 requests 不要一次性下载所有内容,而是保持连接,允许你通过迭代器逐块读取响应体。
  • response.iter_content(...) : 这就是那个迭代器,可以用 for 循环来一块一块地接收从服务器流过来的数据。
posted @ 2025-07-23 22:04  语冰morni  阅读(25)  评论(0)    收藏  举报