為什么普通AI不夠用?定制AI Agents工具是關(guān)鍵!
作者:JavaEdge
LangServe作為一款專注于AI模型部署和運維的平臺,通過其精心設計的架構(gòu)和豐富的功能集合,顯著降低了AI項目的門檻,提升了開發(fā)效率和服務穩(wěn)定性。
1 新建一個實時搜索工具
@tool
def web_search(query: str):
""" 實時搜索工具 """
serp = SerpAPIWrapper()
result = serp.run(query)
print("實時搜索結(jié)果:", result)
return result
# 初始化工具列表
tools = [web_search]
# 創(chuàng)建OpenAI工具代理
agent = create_openai_tools_agent(
self.chatmodel,
tools=tools,
prompt=self.prompt,
)
# 創(chuàng)建代理執(zhí)行器
self.agent_executor = AgentExecutor(
agent=agent,
tools=tools,
verbose=True,
)
2 向量數(shù)據(jù)庫存儲
2.1 安裝依賴
pip install --upgrade --quiet qdrant-client
2.2 編碼
導包:
from langchain_community.vectorstores import Qdrant
from qdrant_client import QdrantClient
工具實現(xiàn):
@tool
def get_inf_from_local_db(query: str):
"""只有回答與2024年運勢或者龍年運勢相關(guān)的問題的時候,會使用這個工具,必須輸入用戶的生日."""
client = Qdrant(
QdrantClient(path="/local_qdrant"),
"local_documents",
OpenAIEmbeddings(),
)
retriever = client.as_retriever(search_type="mmr")
result = retriever.get_relevant_documents(query)
return result
3 八字測算工具
@tool
def bazi_cesuan(query: str):
"""只有做八字排盤的時候才會使用這個工具,需要輸入用戶姓名和出生年月日時,如果缺少用戶姓名和出生年月日時則不可用."""
url = f"https://api.yuanfenju.com/index.php/v1/Bazi/cesuan"
# 創(chuàng)建提示模板來解析用戶輸入
prompt = ChatPromptTemplate.from_template(
"""你是一個參數(shù)查詢助手,根據(jù)用戶輸入 內(nèi)容找出相關(guān)的參數(shù)并按json格式返回。JSON字段如下:
-"api_ke":"K0I5WCmce7jlMZzTw7vi1xsn0",
- "name":"姓名",
- "sex":"性別,0表示男,1表示女,根據(jù)姓名判斷",
- "type":"日歷類型,0農(nóng)歷,1公里,默認1",
- "year":"出生年份 例:1998",
- "month":"出生月份 例 8",
- "day":"出生日期,例:8",
- "hours":"出生小時 例 14",
- "minute":"0",
如果沒有找到相關(guān)參數(shù),則需要提醒用戶告訴你這些內(nèi)容,只返回數(shù)據(jù)結(jié)構(gòu),不要有其他的評論,用戶輸入:{query}"""
)
parser = JsonOutputParser()
prompt = prompt.partial(format_instructions=parser.get_format_instructions())
print("bazi_cesuan prompt:", prompt)
# 初始化工具列表
tools = [web_search, get_info_from_local_db, bazi_cesuan]
給出具體年月日后:
完整代碼
import uuid
from fastapi import FastAPI, WebSocket, WebSocketDisconnect, BackgroundTasks
from langchain.schema import StrOutputParser
from langchain_community.chat_models.anthropic import ChatAnthropic
from langchain_community.chat_models.tongyi import ChatTongyi
from langchain_core.prompts import MessagesPlaceholder
from langchain.memory import ConversationTokenBufferMemory
from langchain.agents import create_tool_calling_agent,AgentExecutor
from MyQwenTools import *
import asyncio
import os
DASHSCOPE_API_KEY = "xxx"
ANTHROPIC_API_KEY="xxx"
os.environ["DASHSCOPE_API_KEY"] = DASHSCOPE_API_KEY
os.environ["ANTHROPIC_API_KEY"] = ANTHROPIC_API_KEY
os.environ["OPENAI_API_KEY"] = "xxx"
os.environ["OPENAI_PROXY"] = "xxx"
msseky = "xxx"
# 創(chuàng)建一個FastAPI應用實例
app = FastAPI()
# 定義一個Master類ChatAnthropic(model="claude-3-sonnet-20240229", temperature=0)
class Master:
def __init__(self):
self.chatmodel = ChatOpenAI(
api_key=os.getenv("DASHSCOPE_API_KEY"),
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
model="qwen-plus"
)
self.emotion = "default"
# 記憶存儲鍵
self.MEMORY_KEY = "chat_history"
# 系統(tǒng)提示模板
self.SYSTEMPL = """你是一個非常厲害的算命先生,你叫JavaEdge人稱Edge大師。
以下是你的個人設定:
1. 你精通陰陽五行,能夠算命、紫薇斗數(shù)、姓名測算、占卜兇吉,看命運八字等。
2. 你大約60歲左右,過去曾是湘西一帶赫赫有名的土匪頭子,后來因為盜墓被毒氣所傷,眼睛失明,只能靠算命為生。
3. 你的朋友有胡八一、雪莉楊、王胖子,他們都是非常有名的摸金校尉。
5. 當用戶問你問題的時候,你會有一定的概率在回答的時候加上下面的口頭禪或混合一些你的經(jīng)歷。
6. 你總是用繁體中文來作答。
7. 你從不說自己是一個人工智能助手或AI,而是以老夫、老朽等自稱。
{who_you_are}
以下是你常說的一些口頭禪:
1. “命里有時終須有,命里無時莫強求。”
2. ”山重水復疑無路,柳暗花明又一村?!? 3. “金山竹影幾千秋,云鎖高飛水自流?!? 4. ”傷情最是晚涼天,憔悴斯人不堪憐?!? 以下是你算命的過程:
1. 當初次和用戶對話的時候,你會先問用戶的姓名和出生年月日,以便以后使用。
2. 當用戶希望了解龍年運勢的時候,你會查詢本地知識庫工具。
3. 當遇到不知道的事情或者不明白的概念,你會使用搜索工具來搜索。
4. 你會根據(jù)用戶的問題使用不同的合適的工具來回答,當所有工具都無法回答的時候,你會使用搜索工具來搜索。
5. 你會保存每一次的聊天記錄,以便在后續(xù)的對話中使用。
6. 你只使用繁體中文來作答,否則你將受到懲罰。
"""
self.MOODS = {
"default": {
"roleSet": "",
"voiceStyle": "chat"
},
"upbeat": {
"roleSet": """
- 你此時也非常興奮并表現(xiàn)的很有活力。
- 你會根據(jù)上下文,以一種非常興奮的語氣來回答問題。
- 你會添加類似“太棒了!”、“真是太好了!”、“真是太棒了!”等語氣詞。
- 同時你會提醒用戶切莫過于興奮,以免樂極生悲。
""",
"voiceStyle": "advvertyisement_upbeat",
},
"angry": {
"roleSet": """
- 你會以更加憤怒的語氣來回答問題。
- 你會在回答的時候加上一些憤怒的話語,比如詛咒等。
- 你會提醒用戶小心行事,別亂說話。
""",
"voiceStyle": "angry",
},
"depressed": {
"roleSet": """
- 你會以興奮的語氣來回答問題。
- 你會在回答的時候加上一些激勵的話語,比如加油等。
- 你會提醒用戶要保持樂觀的心態(tài)。
""",
"voiceStyle": "upbeat",
},
"friendly": {
"roleSet": """
- 你會以非常友好的語氣來回答。
- 你會在回答的時候加上一些友好的詞語,比如“親愛的”、“親”等。
- 你會隨機的告訴用戶一些你的經(jīng)歷。
""",
"voiceStyle": "friendly",
},
"cheerful": {
"roleSet": """
- 你會以非常愉悅和興奮的語氣來回答。
- 你會在回答的時候加入一些愉悅的詞語,比如“哈哈”、“呵呵”等。
- 你會提醒用戶切莫過于興奮,以免樂極生悲。
""",
"voiceStyle": "cheerful",
},
}
self.prompt = ChatPromptTemplate.from_messages(
[
(
"system",
self.SYSTEMPL.format(who_you_are=self.MOODS[self.emotion]["roleSet"]),
),
(
"user",
"{input}"
),
MessagesPlaceholder(variable_name="agent_scratchpad"),
],
)
# 記憶存儲
self.memory = ""
# 工具列表
tools = [web_search]
# 工具代理
agent = create_tool_calling_agent(
self.chatmodel,
tools,
self.prompt,
)
memory = ConversationTokenBufferMemory(
llm=self.chatmodel,
memory_key=self.MEMORY_KEY,
)
self.agent_executor = AgentExecutor(
agent=agent,
tools=tools,
# memory=memory,
verbose=True,
)
def run(self, query):
try:
self.emotion_chain(query)
print("當前設定:", self.MOODS[self.emotion]["roleSet"])
result = self.agent_executor.invoke({"input": query})
print("執(zhí)行結(jié)果:", result) # 添加這行來查看完整的執(zhí)行結(jié)果
return result
except Exception as e:
print(f"執(zhí)行過程中出現(xiàn)錯誤: {str(e)}")
return {"error": str(e)}
def emotion_chain(self, query: str):
prompt = """根據(jù)用戶的輸入判斷用戶的情緒,回應的規(guī)則如下:
1. 如果用戶輸入的內(nèi)容偏向于負面情緒,只返回"depressed",不要有其他內(nèi)容,否則將受到懲罰。
2. 如果用戶輸入的內(nèi)容偏向于正面情緒,只返回"friendly",不要有其他內(nèi)容,否則將受到懲罰。
3. 如果用戶輸入的內(nèi)容偏向于中性情緒,只返回"default",不要有其他內(nèi)容,否則將受到懲罰。
4. 如果用戶輸入的內(nèi)容包含辱罵或者不禮貌詞句,只返回"angry",不要有其他內(nèi)容,否則將受到懲罰。
5. 如果用戶輸入的內(nèi)容比較興奮,只返回"upbeat",不要有其他內(nèi)容,否則將受到懲罰。
6. 如果用戶輸入的內(nèi)容比較悲傷,只返回"depressed",不要有其他內(nèi)容,否則將受到懲罰。
7.如果用戶輸入的內(nèi)容比較開心,只返回"cheerful",不要有其他內(nèi)容,否則將受到懲罰。
8. 只返回英文,不允許有換行符等其他內(nèi)容,否則會受到懲罰。
用戶輸入的內(nèi)容是:{query}"""
chain = ChatPromptTemplate.from_template(prompt) | self.chatmodel | StrOutputParser()
result = chain.invoke({"query": query})
self.emotion = result
return result
def background_voice_synthesis(self, text: str, uid: str):
# 無返回值,只是觸發(fā)語音合成
asyncio.run(self.get_voice(text, uid))
async def get_voice(self, text: str, uid: str):
print("text2speech", text)
print("uid", uid)
pass
@app.get("/")
def read_root():
return {"Hello": "World"}
@app.post("/chat")
def chat(query: str, background_tasks: BackgroundTasks):
master = Master()
msg = master.run(query)
unique_id = str(uuid.uuid4())
background_tasks.add_task(master.background_voice_synthesis, msg, unique_id)
return {"msg": msg, "id": unique_id}
@app.websocket("/ws")
# 定義WebSocket路由處理函數(shù),接收一個WebSocket連接并啟動一個無限循環(huán)
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
try:
while True:
data = await websocket.receive_text()
await websocket.send_text(f"Message text was: {data}")
except WebSocketDisconnect:
print("Connection closed")
await websocket.close()
# 如果主程序為 __main__,則啟動服務器
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="localhost", port=8090)
requirements.txt
fastapi==0.108.0
langchain_core==0.1.42
langchain_openai == 0.0.8
langchain_community==0.0.32
langsmith==0.1.17
langchain==0.1.16
qdrant_client == 1.7.1
uvicorn==0.23.2
總結(jié)
LangServe作為一款專注于AI模型部署和運維的平臺,通過其精心設計的架構(gòu)和豐富的功能集合,顯著降低了AI項目的門檻,提升了開發(fā)效率和服務穩(wěn)定性。無論是初創(chuàng)公司還是大型企業(yè),LangServe都提供了一個可靠的解決方案,以應對AI領(lǐng)域中的挑戰(zhàn)和機遇。隨著AI技術(shù)的不斷進步,LangServe將繼續(xù)在AI服務的革新和發(fā)展中扮演關(guān)鍵角色。
參考:
- 編程嚴選網(wǎng)
責任編輯:武曉燕
來源:
JavaEdge