Skip to content

Commit 8a7b02d

Browse files
committed
docs:新增 LLM 项目实战专栏
1 parent 666d49b commit 8a7b02d

4 files changed

+524
-0
lines changed

docs/.vuepress/config.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,10 @@ module.exports = {
654654
text: 'Agent',
655655
link: '/md/AI/01-what-are-agents'
656656
},
657+
{
658+
text: 'Agent项目实战',
659+
link: '/md/AI/01-从0到1搭建一个基于FastAPI的智能聊天机器人应用'
660+
},
657661
{
658662
text: '区块链',
659663
link: '/md/chain/00-区块链专栏概述.md'
@@ -997,6 +1001,8 @@ module.exports = {
9971001
"01-JVM虚拟机-上篇",
9981002
"02-JVM虚拟机-下篇",
9991003
"高并发BI系统避免频繁Y-GC",
1004+
"线上频繁Full GC,原来是外包同学不合理设置JVM参数!",
1005+
"Java NIO为何导致堆外内存OOM了?",
10001006
]
10011007
},
10021008
{
@@ -1440,6 +1446,15 @@ module.exports = {
14401446
"13-best-development-practices",
14411447
]
14421448
},
1449+
1450+
{
1451+
title: "Agent项目实战",
1452+
collapsable: false,
1453+
sidebarDepth: 0,
1454+
children: [
1455+
"01-从0到1搭建一个基于FastAPI的智能聊天机器人应用",
1456+
]
1457+
},
14431458
],
14441459

14451460
"/md/design/": [{
Lines changed: 280 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,280 @@
1+
# 01-从0到1搭建一个基于FastAPI的智能聊天机器人应用
2+
3+
```txt
4+
fastapi==0.108.0
5+
langchain_core==0.1.28
6+
langchain_openai == 0.0.5
7+
langchain_community==0.0.25
8+
langchain==0.1.10
9+
redis==7.2.0
10+
qdrant_client == 1.7.1
11+
uvicorn==0.23.2
12+
```
13+
14+
15+
16+
```bash
17+
pip install -r requirements.txt
18+
```
19+
20+
21+
22+
![](https://my-img.javaedge.com.cn/javaedge-blog/2024/06/4a8934548721d36d454f028c2e4b6850.png)
23+
24+
想检查某依赖是否安装完毕:
25+
26+
```
27+
pip show fastapi
28+
```
29+
30+
![](https://my-img.javaedge.com.cn/javaedge-blog/2024/06/189744f9c41a8a33665841942b77dd2d.png)
31+
32+
那就先引入 fastapi。
33+
34+
```python
35+
# 这是一个使用 FastAPI 框架编写的简单应用程序的示例。
36+
# 导入FastAPI模块
37+
from fastapi import FastAPI
38+
39+
# 创建一个FastAPI应用实例
40+
app = FastAPI()
41+
42+
43+
# 定义一个路由,当访问'/'时会被触发
44+
@app.get("/")
45+
# 定义一个函数,返回一个字典,key为"Hello",value为"World"
46+
def read_root():
47+
return {"Hello": "World"}
48+
49+
50+
# 如果主程序为 __main__,则启动服务器
51+
if __name__ == "__main__":
52+
import uvicorn
53+
54+
uvicorn.run(app, host="localhost", port=8090)
55+
```
56+
57+
如何运行呢?
58+
59+
![](https://my-img.javaedge.com.cn/javaedge-blog/2024/06/c1ed3a8292d04a179a56379192a6d74e.png)
60+
61+
直接点击它:
62+
63+
![](https://my-img.javaedge.com.cn/javaedge-blog/2024/06/a38bd4d9a95da9889228bca1e4b92512.png)
64+
65+
[直达API文档](http://localhost:8090/docs)
66+
67+
![](https://my-img.javaedge.com.cn/javaedge-blog/2024/06/cbbfeed786d3bb3b07e005497e791bbb.png)
68+
69+
新增一个 chat 接口:
70+
71+
```python
72+
# 这是一个使用 FastAPI 框架编写的简单应用程序的示例。
73+
# 导入FastAPI模块
74+
from fastapi import FastAPI, BackgroundTasks
75+
76+
# 创建一个FastAPI应用实例
77+
app = FastAPI()
78+
79+
80+
# 定义一个路由,当访问'/'时会被触发
81+
@app.get("/")
82+
# 定义一个函数,返回一个字典,key为"Hello",value为"World"
83+
def read_root():
84+
return {"Hello": "World"}
85+
86+
87+
@app.post("/chat")
88+
def chat():
89+
return {"response": "I am a chat bot!"}
90+
91+
92+
# 如果主程序为 __main__,则启动服务器
93+
if __name__ == "__main__":
94+
import uvicorn
95+
96+
uvicorn.run(app, host="localhost", port=8090)
97+
```
98+
99+
API文档立即更新:
100+
101+
![](https://my-img.javaedge.com.cn/javaedge-blog/2024/06/75d1401e9ea4aa2c3fe5afac6f8b3136.png)
102+
103+
同理,我们编写ws函数:
104+
105+
```python
106+
@app.websocket("/ws")
107+
async def websocket_endpoint(websocket: WebSocket):
108+
await websocket.accept()
109+
try:
110+
while True:
111+
data = await websocket.receive_text()
112+
await websocket.send_text(f"Message text was: {data}")
113+
except WebSocketDisconnect:
114+
print("Connection closed")
115+
await websocket.close()
116+
```
117+
118+
使用 postman 构造 websocket 请求:
119+
120+
![](https://my-img.javaedge.com.cn/javaedge-blog/2024/06/2acb8156279b1639c140f8c5188803d3.png)
121+
122+
先点击 connect,再输入要发送的消息:你好。点击 send 即请求,响应了你好!
123+
124+
![](https://my-img.javaedge.com.cn/javaedge-blog/2024/06/b98ba1a6ff1cd5964e5398e44c011d13.png)
125+
126+
## 完整代码
127+
128+
```python
129+
# 这是一个使用 FastAPI 框架编写的简单应用程序的示例。
130+
# 导入FastAPI模块
131+
import os
132+
133+
from dotenv import load_dotenv, find_dotenv
134+
from fastapi import FastAPI, WebSocket, WebSocketDisconnect, BackgroundTasks
135+
from langchain_openai import ChatOpenAI
136+
from langchain.agents import create_openai_tools_agent, AgentExecutor, tool
137+
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
138+
from langchain.schema import StrOutputParser
139+
from langchain.memory import ConversationTokenBufferMemory
140+
from langchain_community.chat_message_histories import RedisChatMessageHistory
141+
from langchain_community.document_loaders import WebBaseLoader
142+
from langchain.text_splitter import RecursiveCharacterTextSplitter
143+
import os
144+
import asyncio
145+
import uuid
146+
from langchain_community.vectorstores import Qdrant
147+
from qdrant_client import QdrantClient
148+
from Mytools import *
149+
150+
# 设置 API 密钥
151+
DASHSCOPE_API_KEY = "xxx"
152+
load_dotenv(find_dotenv())
153+
os.environ["DASHSCOPE_API_KEY"] = DASHSCOPE_API_KEY
154+
os.environ["SERPAPI_API_KEY"] = "xxx"
155+
156+
# 创建一个FastAPI应用实例
157+
app = FastAPI()
158+
159+
160+
# 定义一个工具函数
161+
@tool
162+
def test():
163+
""" Test tool"""""
164+
return "test"
165+
166+
167+
# 定义一个Master类
168+
class Master:
169+
def __init__(self):
170+
# 初始化ChatOpenAI模型
171+
self.chatmodel = ChatOpenAI(
172+
api_key=os.getenv("DASHSCOPE_API_KEY"),
173+
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
174+
model="qwen-plus",
175+
temperature=0,
176+
streaming=True,
177+
)
178+
# 设置记忆存储键名
179+
self.MEMORY_KEY = "chat_history"
180+
# 初始化系统提示模板
181+
self.SYSTEMPL = ""
182+
self.prompt = ChatPromptTemplate.from_messages(
183+
[
184+
(
185+
"system",
186+
"你是一个助手"
187+
),
188+
(
189+
"user",
190+
"{input}"
191+
),
192+
MessagesPlaceholder(variable_name="agent_scratchpad"),
193+
],
194+
)
195+
# 初始化记忆存储
196+
self.memory = ""
197+
# 初始化工具列表
198+
tools = [test]
199+
# 创建OpenAI工具代理
200+
agent = create_openai_tools_agent(
201+
self.chatmodel,
202+
tools=tools,
203+
prompt=self.prompt,
204+
)
205+
# 创建代理执行器
206+
self.agent_executor = AgentExecutor(
207+
agent=agent,
208+
tools=tools,
209+
verbose=True,
210+
)
211+
212+
# 定义运行方法
213+
def run(self, query):
214+
# 调用代理执行器并获取结果
215+
result = self.agent_executor.invoke({"input": query})
216+
# 返回执行器的响应
217+
return result
218+
219+
220+
# 定义根路由
221+
@app.get("/")
222+
# 定义根路由处理函数,返回一个包含"Hello"和"World"的字典
223+
def read_root():
224+
return {"Hello": "World"}
225+
226+
227+
# 定义聊天路由
228+
@app.post("/chat")
229+
# 定义聊天路由处理函数,接收一个字符串查询并调用Master类的run方法进行处理
230+
def chat(query: str):
231+
master = Master() # 初始化Master对象
232+
return master.run(query)
233+
234+
235+
# 定义添加PDF路由
236+
@app.post("/add_pdfs")
237+
# 定义添加PDF路由处理函数,返回一个包含"response"键和"PDFs added!"值的字典
238+
def add_pdfs():
239+
return {"response": "PDFs added!"}
240+
241+
242+
# 定义添加文本路由
243+
@app.post("add_texts")
244+
# 定义添加文本路由处理函数,返回一个包含"response"键和"Texts added!"值的字典
245+
def add_texts():
246+
return {"response": "Texts added!"}
247+
248+
249+
# 定义WebSocket路由
250+
@app.websocket("/ws")
251+
# 定义WebSocket路由处理函数,接收一个WebSocket连接并启动一个无限循环
252+
async def websocket_endpoint(websocket: WebSocket):
253+
await websocket.accept()
254+
try:
255+
while True:
256+
data = await websocket.receive_text()
257+
await websocket.send_text(f"Message text was: {data}")
258+
except WebSocketDisconnect:
259+
print("Connection closed")
260+
await websocket.close()
261+
262+
263+
# 如果主程序为 __main__,则启动服务器
264+
if __name__ == "__main__":
265+
import uvicorn
266+
267+
uvicorn.run(app, host="localhost", port=8090)
268+
```
269+
270+
fastapi 请求:
271+
272+
![](https://my-img.javaedge.com.cn/javaedge-blog/2024/06/1b568a645fa825cc6a20be186ef2394d.png)
273+
274+
postman 请求:
275+
276+
![](https://my-img.javaedge.com.cn/javaedge-blog/2024/06/620a8421df406a18d9eece93f88c99c5.png)
277+
278+
PyCharm 命令行记录:
279+
280+
![](https://my-img.javaedge.com.cn/javaedge-blog/2024/06/7c0427a3680f3b285ef56aaa4f759666.png)

0 commit comments

Comments
 (0)