likes
comments
collection
share

用极快的速度开发一个AI心理咨询机器人

作者站长头像
站长
· 阅读数 4

项目开发整体流程

数据准备 → 数据向量化 → 机器人实现 → 界面部署 → 主流程

  1. 数据准备:生成心理咨询问题和答案的数据,并将这些数据保存到文件data.txt中。
  2. 数据向量化:利用langchain_text_splitters库的CharacterTextSplitter模块对数据进行预处理,然后使用智谱AI的向量模型进行向量化,并将向量数据存储在FAISS向量数据库中。
  3. 机器人实现:定义一个聊天机器人,通过加载FAISS向量数据库,利用检索器获取相关问题,并结合上下文和对话历史生成回复。这里使用ChatZhipuAI作为聊天模型。
  4. 界面部署:使用Gradio库创建用户界面,用户可以通过该界面与聊天机器人进行交流。
  5. 主流程:在程序入口处,首先调用函数初始化聊天机器人,然后调用Gradio界面,完成整个心理咨询机器人的搭建。

数据向量化

数据准备

首先我们需要一些通用的数据,因为我不是心理咨询师,作为开发者我需要一些资料——关于心理咨询会遇到的问题和对应的答案。

可以直接让智谱清言为我们生成一些心理咨询相关的问题和答案,先生成50条吧。

用极快的速度开发一个AI心理咨询机器人

虽然智谱清言说“很抱歉”,但还是为我们生成了10条问答。那就让他继续吧,直到输出50条为止。

用极快的速度开发一个AI心理咨询机器人

把这些数据复制到文件data.txt中。

在做向量化之前,需要先对数据进行预处理。可以用langchain_text_splitters库的CharacterTextSplitter,langchain提供了多种工具用于处理文档,CharacterTextSplitter模块主要用于拆分文本字符。

from langchain_text_splitters import CharacterTextSplitter

with open("data.txt") as f:
    data = f.read()

text_splitter = CharacterTextSplitter(
    separator="\n",
    chunk_size=200,
    length_function=len,
    is_separator_regex=True,
)
docs = text_splitter.create_documents([data])
  • separator被设置为\n,这表示文本将会以换行符作为分隔符进行分割。
  • chunk_size 被设置为200,这表示每个文本块的大小为200个字符。
  • length_function 被设置为len,这表示用于计算文本长度的函数为Python内置的len函数。
  • is_separator_regex 被设置为True,这表示分隔符会被视为一个正则表达式进行处理。

向量数据库的创建

接下来将处理好的数据向量化,可以用FAISS(FaceBook开源的向量数据库)进行管理:

from langchain_community.vectorstores.faiss import FAISS
from langchain_zhipu.embeddings import ZhipuAIEmbeddings
from utils import get_ak

db = FAISS.from_documents(docs, ZhipuAIEmbeddings(
    api_key=get_ak(),
))

首先,引入这个ZhipuAIEmbeddings模块代表我们使用了智谱的向量模型进行向量化。langchain_zhipu这个库不是官方的,因为智谱AI的官方SDK使用了 pydantic v2,这与 langchain(尤其是langserve)不兼容,所以有人写了这个库langchain_zhipu对智谱和langchain的库进行适配。

get_ak()是我写的一个方法,只是return我的api_key。没有api_key的话可以去智谱AI开发平台注册获取。

langchain_community.vectorstores.faiss库引入了向量数据库FAISS,langchain_community是LangChain社区包含的第三方集成。from_documents方法用于通过文档和嵌入来初始化VectorStore(VectorStore是一个抽象基类,用于表示向量存储)。

查询与检索

docs = db.similarity_search("物业管理怎么样?",k=3)

async def asimilarity():
    results = await db.asimilarity_search("我的同事批评我怎么办?", k=3)

asyncio.run(asimilarity())

db.save_local("faiss_index")

db.similarity_search("物业管理怎么样?", k=3) - 这一行代码是在数据库db中进行相似性搜索,使用输入的查询字符串"物业管理怎么样?"来查找相似的文档,k=3表示向量数据库将查找前3相似的文本。db.asimilarity_search是相同的功能,不过是异步的实现。

最后,使用db对象的save_local方法将Faiss索引保存在本地文件“faiss_index”中。

需要注意的是向量化的过程会消耗大量时间,这个例子中的data.txt向量化完成需要90秒左右。

机器人实现

机器人初始化

def initialize_chatbot(vector_store_dir: str="faiss_index"):
    db = FAISS.load_local(vector_store_dir, ZhipuAIEmbeddings(api_key=get_ak()), allow_dangerous_deserialization=True)
    llm = ChatZhipuAI(model_name="glm-4", temperature=0.8, api_key=get_ak())
    
    template = """
        Use the following context (delimited by <ctx></ctx>) and the chat history (delimited by <hs></hs>) to answer the question:
        ------
        <ctx>
        {context}
        </ctx>
        ------
        <hs>
        {history}
        </hs>
        ------
        {question}
    """
    prompt = PromptTemplate(
        input_variables=["history", "context", "question"],
        template=template,
    )

    global BOT    
    BOT = RetrievalQA.from_chain_type(
        llm, 
        retriever=db.as_retriever(search_kwargs={"k": 1}),
        chain_type='stuff',
        chain_type_kwargs={
            "verbose": True,
            "prompt": prompt,
            "memory": ConversationBufferMemory(
                memory_key="history",
                input_key="question"
            ),
        }
    )
    # 返回向量数据库的检索结果
    BOT.return_source_documents = True

    return BOT

这段代码通过initialize_chatbot函数初始化一个聊天机器人。

首先,它加载了本地的向量存储vector_store_dir,并使用ZhipuAI嵌入的API密钥来获取数据库db。然后,实例化了一个ChatZhipuAI模型llm,使用指定的模型名称和API密钥。其中的参数temperature用于指定语言模型生成文本时的多样性或不确定性的程度,较高的temperature值会导致更加多样化和不确定的输出,而较低的值则倾向于生成更加确定性和保守的输出。

接下来,定义了一个模板template,用于指定如何使用上下文、对话历史和问题来回答问题。langchain_core.prompts库的PromptTemplate模块用于存储模版。

随后,在全局命名空间中创建了一个名为BOT的RetrievalQA实例。这里使用RetrievalQA.from_chain_type方法,传入llm作为聊天模型,db作为检索器,并传入各种其他参数和设置来配置聊天过程。最后,代码设置了BOT.return_source_documents为True,以便返回向量数据库的检索结果。

Gradio界面部署

def chat(message, history):
    ans = BOT({"query": message})
    print(ans)
    return ans["result"]

def launch_gradio():
    demo = gr.ChatInterface(
        fn=chat,
        title="心理咨询",
        chatbot=gr.Chatbot(height=600),
    )
    demo.launch(share=True, server_name="0.0.0.0")

if __name__ == "__main__":
    initialize_chatbot()
    launch_gradio()

launch_gradio函数创建了一个基于Gradio库的用户界面,用于展示心理咨询的聊天机器人。

最后,在程序的主入口点处,initialize_chatbot函数用于初始化聊天机器人,然后调用launch_gradio函数,启动了Gradio用户界面,从而允许用户与聊天机器人进行交互。

最终展示

用极快的速度开发一个AI心理咨询机器人

用极快的速度开发一个AI心理咨询机器人

代码地址:github.com/jiangjiax/p…