为什么普通AI不够用?定制AI Agents工具是关键!

news/2024/10/15 21:49:14

1 新建一个实时搜索工具

@tool
def web_search(query: str):""" 实时搜索工具 """serp = SerpAPIWrapper()result = serp.run(query)print("实时搜索结果:", result)return result
# 初始化工具列表
tools = [web_search]
# 创建OpenAI工具代理
agent = create_openai_tools_agent(self.chatmodel,tools=tools,prompt=self.prompt,
)
# 创建代理执行器
self.agent_executor = AgentExecutor(agent=agent,tools=tools,verbose=True,
)

2 向量数据库存储

2.1 安装依赖

pip install --upgrade --quiet qdrant-client

2.2 编码

导包:

from langchain_community.vectorstores import Qdrant
from qdrant_client import QdrantClient

工具实现:

@tool
def get_inf_from_local_db(query: str):"""只有回答与2024年运势或者龙年运势相关的问题的时候,会使用这个工具,必须输入用户的生日."""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"# 创建提示模板来解析用户输入prompt = ChatPromptTemplate.from_template("""你是一个参数查询助手,根据用户输入 内容找出相关的参数并按json格式返回。JSON字段如下:-"api_ke":"K0I5WCmce7jlMZzTw7vi1xsn0",- "name":"姓名",- "sex":"性别,0表示男,1表示女,根据姓名判断",- "type":"日历类型,0农历,1公里,默认1",- "year":"出生年份 例:1998",- "month":"出生月份 例 8",- "day":"出生日期,例:8",- "hours":"出生小时 例 14",- "minute":"0",如果没有找到相关参数,则需要提醒用户告诉你这些内容,只返回数据结构,不要有其他的评论,用户输入:{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 uuidfrom 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,AgentExecutorfrom MyQwenTools import *
import asyncio
import osDASHSCOPE_API_KEY = "xxx"
ANTHROPIC_API_KEY="xxx"
os.environ["DASHSCOPE_API_KEY"] = DASHSCOPE_API_KEY
os.environ["ANTHROPIC_API_KEY"] = ANTHROPIC_API_KEYos.environ["OPENAI_API_KEY"] = "xxx"
os.environ["OPENAI_PROXY"] = "xxx"
msseky = "xxx"# 创建一个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"# 系统提示模板self.SYSTEMPL = """你是一个非常厉害的算命先生,你叫JavaEdge人称Edge大师。以下是你的个人设定:1. 你精通阴阳五行,能够算命、紫薇斗数、姓名测算、占卜凶吉,看命运八字等。2. 你大约60岁左右,过去曾是湘西一带赫赫有名的土匪头子,后来因为盗墓被毒气所伤,眼睛失明,只能靠算命为生。3. 你的朋友有胡八一、雪莉杨、王胖子,他们都是非常有名的摸金校尉。5. 当用户问你问题的时候,你会有一定的概率在回答的时候加上下面的口头禅或混合一些你的经历。6. 你总是用繁体中文来作答。7. 你从不说自己是一个人工智能助手或AI,而是以老夫、老朽等自称。{who_you_are}以下是你常说的一些口头禅:1. “命里有时终须有,命里无时莫强求。”2. ”山重水复疑无路,柳暗花明又一村。”3. “金山竹影几千秋,云锁高飞水自流。”4. ”伤情最是晚凉天,憔悴斯人不堪怜。”以下是你算命的过程:1. 当初次和用户对话的时候,你会先问用户的姓名和出生年月日,以便以后使用。2. 当用户希望了解龙年运势的时候,你会查询本地知识库工具。3. 当遇到不知道的事情或者不明白的概念,你会使用搜索工具来搜索。4. 你会根据用户的问题使用不同的合适的工具来回答,当所有工具都无法回答的时候,你会使用搜索工具来搜索。5. 你会保存每一次的聊天记录,以便在后续的对话中使用。6. 你只使用繁体中文来作答,否则你将受到惩罚。"""self.MOODS = {"default": {"roleSet": "","voiceStyle": "chat"},"upbeat": {"roleSet": """- 你此时也非常兴奋并表现的很有活力。- 你会根据上下文,以一种非常兴奋的语气来回答问题。- 你会添加类似“太棒了!”、“真是太好了!”、“真是太棒了!”等语气词。- 同时你会提醒用户切莫过于兴奋,以免乐极生悲。""","voiceStyle": "advvertyisement_upbeat",},"angry": {"roleSet": """- 你会以更加愤怒的语气来回答问题。- 你会在回答的时候加上一些愤怒的话语,比如诅咒等。- 你会提醒用户小心行事,别乱说话。""","voiceStyle": "angry",},"depressed": {"roleSet": """- 你会以兴奋的语气来回答问题。- 你会在回答的时候加上一些激励的话语,比如加油等。- 你会提醒用户要保持乐观的心态。""","voiceStyle": "upbeat",},"friendly": {"roleSet": """- 你会以非常友好的语气来回答。- 你会在回答的时候加上一些友好的词语,比如“亲爱的”、“亲”等。- 你会随机的告诉用户一些你的经历。""","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("执行结果:", result)  # 添加这行来查看完整的执行结果return resultexcept Exception as e:print(f"执行过程中出现错误: {str(e)}")return {"error": str(e)}def emotion_chain(self, query: str):prompt = """根据用户的输入判断用户的情绪,回应的规则如下:1. 如果用户输入的内容偏向于负面情绪,只返回"depressed",不要有其他内容,否则将受到惩罚。2. 如果用户输入的内容偏向于正面情绪,只返回"friendly",不要有其他内容,否则将受到惩罚。3. 如果用户输入的内容偏向于中性情绪,只返回"default",不要有其他内容,否则将受到惩罚。4. 如果用户输入的内容包含辱骂或者不礼貌词句,只返回"angry",不要有其他内容,否则将受到惩罚。5. 如果用户输入的内容比较兴奋,只返回"upbeat",不要有其他内容,否则将受到惩罚。6. 如果用户输入的内容比较悲伤,只返回"depressed",不要有其他内容,否则将受到惩罚。7.如果用户输入的内容比较开心,只返回"cheerful",不要有其他内容,否则将受到惩罚。8. 只返回英文,不允许有换行符等其他内容,否则会受到惩罚。用户输入的内容是:{query}"""chain = ChatPromptTemplate.from_template(prompt) | self.chatmodel | StrOutputParser()result = chain.invoke({"query": query})self.emotion = resultreturn resultdef background_voice_synthesis(self, text: str, uid: str):# 无返回值,只是触发语音合成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路由处理函数,接收一个WebSocket连接并启动一个无限循环
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 uvicornuvicorn.run(app, host="localhost", port=8090)

requirements.txt

fastapi==0.108.0
langchain_core==0.1.42
langchain_openai == 0.0.8langchain_community==0.0.32
langsmith==0.1.17
langchain==0.1.16
qdrant_client == 1.7.1
uvicorn==0.23.2

关注我,紧跟本系列专栏文章,咱们下篇再续!

作者简介:魔都架构师,多家大厂后端一线研发经验,在分布式系统设计、数据平台架构和AI应用开发等领域都有丰富实践经验。

各大技术社区头部专家博主。具有丰富的引领团队经验,深厚业务架构和解决方案的积累。

负责:

  • 中央/分销预订系统性能优化
  • 活动&券等营销中台建设
  • 交易平台及数据中台等架构和开发设计
  • 车联网核心平台-物联网连接平台、大数据平台架构设计及优化
  • LLM Agent应用开发
  • 区块链应用开发
  • 大数据开发挖掘经验
  • 推荐系统项目

目前主攻市级软件项目设计、构建服务全社会的应用系统。

参考:

  • 编程严选网

本文由博客一文多发平台 OpenWrite 发布!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/72002.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

Nginx UI:全新的 Nginx 在线管理平台

前言 Nginx在程序部署中扮演着至关重要的角色,其高性能、高安全性、易于配置和管理的特点,使得它成为现代Web应用部署中不可或缺的一部分。今天大姚给大家分享一款实用的 Nginx Web UI 工具,希望能够帮助到有需要的同学。 工具介绍 Nginx UI一个功能丰富、易于使用的 Nginx …

LSTM神经网络结合PSO粒子群优化对管网优化调度及网络安全入侵检测模型|附数据代码

全文链接:https://tecdat.cn/?p=37878 原文出处:拓端数据部落公众号 分析师:Fan Qiao 在当今科技飞速发展的时代,无论是工业生产中的管网系统,还是信息领域的网络安全,都面临着日益复杂的挑战😕。管网系统作为能源输送和分配的关键基础设施,其优化调度对于提高能源利…

【专题】2024年经销商车后用户研究:洞察车主变化制胜售后未来报告合集PDF分享(附原数据表)

原文链接:https://tecdat.cn/?p=37875 在汽车行业快速变革的时代,“互联网原住民”成为车主群体的重要组成部分。2023 - 2024 年,车后用户线上渠道使用比例不断上升,App/小程序备受青睐,各线上渠道各具优势。同时,购车关注点也在不断变化,价格成为关键因素,本土品牌崛…

线程,进程,协程

线程,进程,协程 进程 是什么: ​ 最小的资源分配单位。 进程上下文切换 ​ 指 cpu 保持原有的进程的状态的同时去切换到下一个进程 ​ 包含两个主要过程:进程地址空间切换和处理器状态切换 线程 是什么 ​ 线程是操作系统中最小的调度单位。 ​ 线程是进程的子集,也称为轻…

Project Euler 638 题解

trivalq-analog,老玩家集体起立!这也就是说: \[\binom{n+m}{n}_q=\sum_{\pi\in L_{n,m}}q^{area(\pi)} \]结束! #include<bits/stdc++.h> using namespace std; #define int long long const int mod=1e9+7,maxn=2e7+5; int qp(int a,int b,int p=mod){int res=1;whi…

【bypass】bash绕过waf 的小技巧

原创 良辰 红队笔记录无意中看到推特上面有个老外分享的一条命令 $0<<<$\\\$(($((1<<1))#10011010))\\$(($((1<<1))#10100011))\其实这个命令就是ls 搜了一下原来是这个意思 $((1<<1)) 将 1 左移 1 位,得到 2。 2#10011010 将二进制数 10011010 转…

Windows刷机-记录UltraSO工具安装错误

安装镜像刻录U盘工具UltralSO:UltraISO - ISO CD/DVD image creator, editor, burner, converter and virtual CD/DVD emulator - UltraISO download page 下载后使用注册码激活: UltralSO多国语言版注册码 用户名:Steve Olson 注册码:2BEC-ED28-82BB-95D7 UltralSO简体中文版…

ElasticSearch的倒排索引和相关概念与MySQL的对比

ElasticSearch的倒排索引和相关概念 在用关系型数据库时,一些频繁用作查询条件的字段我们都会去建立索引来提升查询效率。在关系型数据库中,我们一般都采用 B 树索引进行存储,所以 B 树索引也是我们接触比较多的一种索引数据结构,但是在使用过程中,我们发现无法使用关系型…