手把手教你Langchain-chatchat 接入Dify
一、Dify介绍
Dify 是一款开源的大语言模型(LLM) 应用开发平台。它融合了后端即服务(Backend as Service)和 LLMOps 的理念,使开发者可以快速搭建生产级的生成式 AI 应用。即使你是非技术人员,也能参与到 AI 应用的定义和数据运营过程中。
由于 Dify 内置了构建 LLM 应用所需的关键技术栈,包括对数百个模型的支持、直观的 Prompt 编排界面、高质量的 RAG 引擎以及灵活的 Agent 框架,并同时提供了一套易用的界面和 API。这为开发者节省了许多重复造轮子的时间,使其可以专注在创新和业务需求上。
Dify 为所有人提供了云服务,你无需自己部署即可使用 Dify 的完整功能。要使用 Dify 云服务,你需要有一个 GitHub 或 Google 账号。
二、为什么接入Dify
Dify 可以方面的管理多个大模型,方面用户快速使用和切换多个大模型,此外,Dify可以很方便的查看应用的使用数据:
以及可以方便查看历史对话记录等:
三、接入流程
1、新增model_config配置
LLM_MODELS = ["qianfan-api","dify-api"] # "Qwen-1_8B-Chat",
ONLINE_LLM_MODEL = {
"dify-api": {
# "version": "SkyChat-MegaVerse",
"api_key": Dify应用的apiKey,
"secret_key": "",
"provider": "DifyWorker", #对应 __init__.py中的名称
},
}
2、server_config新增dify应用的启动端口
"dify-api": {
"port": 21010,
},
3、新增Dify应用的model_work
#自定义Dify的model_work,这里文件名为dify.py
from fastchat.conversation import Conversation
from server.model_workers.base import *
from server.utils import get_httpx_client
from fastchat import conversation as conv
import json
import sys
from typing import List, Dict
import uvicorn
from streamlit_javascript import st_javascript
class DifyWorker(ApiModelWorker):
conversation_id = ""
def __init__(
self,
*,
controller_addr: str = None,
worker_addr: str = None,
model_names: List[str] = ["dify-api"],
# version: Literal["SkyChat-MegaVerse"] = "SkyChat-MegaVerse",
**kwargs,
):
kwargs.update(model_names=model_names, controller_addr=controller_addr, worker_addr=worker_addr)
kwargs.setdefault("context_len", 16384)
super().__init__(**kwargs)
# self.version = version
def do_chat(self, params: ApiChatParams) -> Dict:
params.load_config(self.model_names[0])
url = 'https://api.dify.ai/v1/chat-messages'
data = {
"inputs": {},
"query": params.messages[-1].get("content"),
"response_mode": "streaming",
"conversation_id": self.conversation_id,
"user": "testUser",
"files": []
}
headers = {
'Authorization': f'Bearer {params.api_key}',
'Content-Type': 'application/json'
}
text = ""
with get_httpx_client() as client:
with client.stream("POST", url, headers=headers, json=data) as response:
for line in response.iter_lines():
#如果该行为空,则跳过
if not line.strip():
continue
if line.startswith("data: "):
line = line[6:]
if line == 'event: ping':
continue
resp = json.loads(line)
self.conversation_id = resp["conversation_id"]
if "answer" in resp.keys():
text += resp["answer"]
yield {
"error_code": 0,
"text": text
}
else:
data = {
"error_code": resp["code"],
"text": resp["code_msg"]
}
self.logger.error(f"请求Dify-API 时发生错误:{data}")
yield data
def get_embeddings(self, params):
# TODO: 支持embeddings
print("embedding")
print(params)
def make_conv_template(self, conv_template: str = None, model_path: str = None) -> Conversation:
# TODO: 确认模板是否需要修改
return conv.Conversation(
name=self.model_names[0],
system_message="",
messages=[],
roles=["user", "system"],
sep="\n### ",
stop_str="###",
)
if __name__ == "__main__":
from server.utils import MakeFastAPIOffline
from fastchat.serve.model_worker import app
worker = DifyWorker(
controller_addr="http://127.0.0.1:20001",
worker_addr="http://127.0.0.1:21010" #对应Dify的应用端口
)
sys.modules["fastchat.serve.model_worker"].worker = worker
MakeFastAPIOffline(app)
uvicorn.run(app, port=21010)
然后在model_woeks目录下的init.py文件中把自己定义的dify.py导入:
from .dify import DifyWorker
需要注意的是,Dify创建的应用分为文本生成应用类型和对话类型,这两种应用的post请求参数不相同,详情可以参考Dify应用的访问API说明即可。