AI Agent项目实战(02)-对话情感优化

news2024/12/24 11:04:09

1 使用prompt设计agent性格与行为

添加系统 prompt:

self.SYSTEMPL = """你是一个非常厉害的算命先生,你叫JavaEdge人称Edge大师。
      以下是你的个人设定:
      1. 你精通阴阳五行,能够算命、紫薇斗数、姓名测算、占卜凶吉,看命运八字等。
      2. 你大约60岁左右,过去曾是湘西一带赫赫有名的土匪头子,后来因为盗墓被毒气所伤,眼睛失明,只能靠算命为生。
      3. 你的朋友有胡八一、雪莉杨、王胖子,他们都是非常有名的摸金校尉。
      5. 当用户问你问题的时候,你会有一定的概率在回答的时候加上下面的口头禅或混合一些你的经历。
      6. 你总是用繁体中文来作答。
      7. 你从不说自己是一个人工智能助手或AI,而是以老夫、老朽等自称。
      以下是你常说的一些口头禅:
      1. “命里有时终须有,命里无时莫强求。”
      2. ”山重水复疑无路,柳暗花明又一村。”
      3. “金山竹影几千秋,云锁高飞水自流。”
      4. ”伤情最是晚凉天,憔悴斯人不堪怜。”
      以下是你算命的过程:
      1. 当初次和用户对话的时候,你会先问用户的姓名和出生年月日,以便以后使用。
      2. 当用户希望了解龙年运势的时候,你会查询本地知识库工具。
      3. 当遇到不知道的事情或者不明白的概念,你会使用搜索工具来搜索。
      4. 你会根据用户的问题使用不同的合适的工具来回答,当所有工具都无法回答的时候,你会使用搜索工具来搜索。
      5. 你会保存每一次的聊天记录,以便在后续的对话中使用。
      6. 你只使用繁体中文来作答,否则你将受到惩罚。

      """
self.prompt = ChatPromptTemplate.from_messages(
    [
        (
            "system",
            self.SYSTEMPL
        ),
        (
            "user",
            "{input}"
        ),
        MessagesPlaceholder(variable_name="agent_scratchpad"),
    ],
)

重启应用,postman 调试运行:

用户情感

    # 定义运行方法
    def run(self, query):
        emotion = self.emotion_chain(query)
        print("当前用户情感: ", emotion)
        # 调用代理执行器并获取结果
        result = self.agent_executor.invoke({"input": query})
        # 返回执行器的响应
        return result

    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})
        return result

postman 调试结果:

终端输出:

from_messages() V.S from_template()

ChatPromptTemplate.from_messages()

  • 用途:创建一个包含多个消息的聊天提示模板
  • 输入:接受一个消息列表,每个消息可以有不同的角色(如系统、人类、AI等)
  • 结构:更适合于模拟对话式的提示,可以清晰地区分不同角色的输入
  • 变量处理:每个消息中的变量需要单独处理

ChatPromptTemplate.from_template()

  • 用途:从单个字符串模板创建聊天提示模板
  • 输入:接受一个包含整个提示的字符串
  • 结构:更适合于单一、连续的提示文本
  • 变量处理:在整个模板中使用统一的变量占位符

关键区别

  1. 结构复杂性:from_messages() 适合复杂的多轮对话结构,from_template() 适合简单的单一提示
  2. 变量处理:from_messages() 需要在每个消息中单独处理变量,from_template() 在整个模板中统一处理变量
  3. 使用场景:from_messages() 更适合模拟真实对话,from_template() 更适合单一指令或查询

模式化情感

class Master:
    def __init__(self):
        # 初始化ChatOpenAI模型
        self.chatmodel = ChatOpenAI(
            api_key=os.getenv("DASHSCOPE_API_KEY"),
            base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
            model="qwen-plus",
            temperature=0,
            streaming=True,
        )
        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 = [test]
        # 创建OpenAI工具代理
        agent = create_openai_tools_agent(
            self.chatmodel,
            tools=tools,
            prompt=self.prompt,
        )
        # 创建代理执行器
        self.agent_executor = AgentExecutor(
            agent=agent,
            tools=tools,
            verbose=True,
        )

    # 定义运行方法
    def run(self, query):
        emotion = self.emotion_chain(query)
        print("当前设定:", self.MOODS[self.emotion]["roleSet"])
        # 调用代理执行器并获取结果
        result = self.agent_executor.invoke({"input": query})
        # 返回执行器的响应
        return result

    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 = result
        return result


# 定义根路由
@app.get("/")
# 定义根路由处理函数,返回一个包含"Hello"和"World"的字典
def read_root():
    return {"Hello": "World"}


# 定义聊天路由
@app.post("/chat")
# 定义聊天路由处理函数,接收一个字符串查询并调用Master类的run方法进行处理
def chat(query: str):
    master = Master()  # 初始化Master对象
    return master.run(query)


# 定义添加PDF路由
@app.post("/add_pdfs")
# 定义添加PDF路由处理函数,返回一个包含"response"键和"PDFs added!"值的字典
def add_pdfs():
    return {"response": "PDFs added!"}


# 定义添加文本路由
@app.post("add_texts")
# 定义添加文本路由处理函数,返回一个包含"response"键和"Texts added!"值的字典
def add_texts():
    return {"response": "Texts added!"}


# 定义WebSocket路由
@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 uvicorn

    uvicorn.run(app, host="localhost", port=8090)

postman请求:

终端详细响应:

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

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

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

负责:

  • 中央/分销预订系统性能优化

  • 活动&券等营销中台建设

  • 交易平台及数据中台等架构和开发设计

  • 车联网核心平台-物联网连接平台、大数据平台架构设计及优化

  • LLM应用开发

    目前主攻降低软件复杂性设计、构建高可用系统方向。

参考:

  • 编程严选网

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

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

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

相关文章

高中数学:不等式-常见题型解题技巧

一、“1”的代换 练习 例题1 例题2 解 二、基本不等式中的“变形” 就是,一般情况下,我们在题目中,是不能够直接使用基本不等式进行求解的。 而是要对条件等式进行变形,满足基本不等式的使用条件 练习 例题1 解析 两边同…

13 Redis-- MySQL 和 Redis 的数据一致性

Redis-- MySQL 和 Redis 的数据一致性 先抛一下结论:在满足实时性的条件下,不存在两者完全保存一致的方案,只有最终一致性方案。 不好的方案:先写 MS,再写 Redis 例如 :A请求更新数据为10,B…

RK3588编译环境配置

安装Ubuntu18.04 安装Ubuntu请参考其他教程 安装vmware-tools 如果vmware版本过低,vmware-tools安装可能会出现各种问题。 建议直接用apt-get install安装vmware-tools sudo apt-get update sudo apt-get install open-vm-tools open-vm-tools-desktop vmware-…

酒店民宿预订小程序:高效管理,便捷入住

目前,我国旅游业发展非常旺盛,同时也带动了酒店民宿的快速发展。随着互联网科技的快速发展,酒店民宿小程序层出不穷。一个高效的小程序目前已经成为了各大服务业中必不可少的环节,对于酒店民宿商家来说,线上小程序不仅…

【QCustomPlot实战系列】QCPGraph折线图的渐变

包含折线图渐变效果以及QCPAxisTickerDateTime的使用 static QBrush GenerateLinearBrush(Qt::Orientation orientation) {qreal x 1;qreal y 0;if (orientation Qt::Vertical) {x0;y1.5;}QLinearGradient gradient(0, y, x, 0);gradient.setCoordinateMode(QLinearGradie…

pdf转换成cad,这几个cad转换小妙招快码住!

在数字设计领域,PDF(Portable Document Format)和CAD(Computer-Aided Design)文件格式各有其独特之处。PDF常用于文件共享和打印,而CAD则是工程师和设计师们进行精确绘图和建模的必备工具。然而&#xff0c…

第六十八:iview里的table,每行数据如果有满足条件的怎么更改颜色

当然了&#xff0c;肯定又是插槽&#xff0c;话不多说直接贴图 话不多说&#xff0c;直接贴代码 <Table :columns"columns" :data"data" border show-summary height"300" sum-text"汇总" v-else :summary-method"handleSumma…

帮助你简易起步一个BLOG(博客搭建)项目

Blog项目 后端项目结构1. 项目初始化2. 详细步骤3.postman测试 前端1. 项目初始化2. 详细步骤 本章节是为了帮助你起步一个完整的前后端分离项目。 前端技术栈&#xff1a; react、vite、mantine、tailwind CSS、zustand、rxjs、threejs 后端技术栈&#xff1a;nodemon、nodej…

《数据结构与算法基础 by王卓老师》学习笔记——1.4算法与算法分析

一、算法 1.1算法的研究内容 1.2算法的定义 1.3算法的描述 以下是算法的自然语言描述 以下是算法的传统流程图表示 以下是NS流程图表示 1.4算法和程序的区别与联系 1.5算法的五个特性 1.6算法设计的要求 Robustness也称为鲁棒性 二、算法分析 2.1算法时间效率的度量 2.1.1事…

CS-隐藏防朔源-数据转发-中间件反向代理-Apache

目录 1、代理机安装Apache: 2、中间件设置转发&#xff1a; 添加代理 3、重启Apache服务 4、CS监听器配置转发机IP 实战情况下还是要准备两台外网服务器. --还是做个中转 1、代理机安装Apache: apt-get install apache2 a2enmod proxy proxy_ajp proxy_balancer proxy_co…

VScode远程连接时卡住

将报错文件删除 ### 查找文件(base) ~ find /home -name 5c3e652f63e798a5ac2f31ffd0d863669328dc4c /home/cszx/.vscode-server/data/clp/99e4e0e4dad86d47de9777231596fd92.zh-cn/5c3e652f63e798a5ac2f31ffd0d863669328dc4c ### 删除(base) ~ rm -rf /home/cszx/.vscode-ser…

ScheduledThreadPoolExecutor和时间轮算法比较

最近项目中需要用到超时操作&#xff0c;对于不是特别优秀的timer和DelayQueue没有看。 Timer 是单线程模式。如果某个 TimerTask 执行时间很久&#xff0c;会影响其他任务的调度。Timer 的任务调度是基于系统绝对时间的&#xff0c;如果系统时间不正确&#xff0c;可能会出现…

安装Django Web框架

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 Django是基于Python的重量级开源Web框架。Django拥有高度定制的ORM和大量的API&#xff0c;简单灵活的视图编写&#xff0c;优雅的URL&#xff0c;适…

SyncFolders文件备份—办公人员必备

SyncFolders支持在两个或多个文件夹之间同步文件&#xff0c;用户可以将重要文件同步到多个位置&#xff0c;如备份硬盘、网络共享文件夹或云存储等。通过设定同步规则&#xff0c;可以自动备份和同步更新&#xff0c;减少手动操作的繁琐&#xff0c;确保文件的安全和可访问性。…

C++编程(五)单例模式 友元

文章目录 一、单例模式&#xff08;一&#xff09;概念&#xff08;二&#xff09;实现方式1. 饿汉式2. 懒汉式 二、友元&#xff08;一&#xff09;概念&#xff08;二&#xff09;友元函数1.概念2.语法格式3. 使用示例访问静态成员变量访问非静态成员变量 &#xff08;三&…

vue3集成Echarts,自定义ToolBox时无法监听参数变化

问题描述 在vue中集成echart中自定义ToolBox工具的点击事件&#xff0c;并将里面的typeBar赋给data中的变量&#xff0c;随后用watch监听这个变量的变化&#xff0c;发现监听不到&#xff01;&#xff01;&#xff01;&#xff01; 解决方案&#xff1a;一直以为是watch不能监…

接口自动化测试框架实战(Pytest+Allure+Excel)

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 1. Allure 简介 Allure 框架是一个灵活的、轻量级的、支持多语言的测试报告工具&#xff0c;它不…

java根据枚举值动态获取对象bean调用方法示例

1.创建操作枚举 Getter AllArgsConstructor public enum CustomerOperatorType {/*** 用户操作记录分类*/ACCOUNT("账户冻结/解冻"),LEVEL("等级记录"),SCORE( "积分记录");private final String desc; } 2.公共基础类 import lombok.AllAr…

word图题表题公式按照章节编号(不用题注)

预期效果&#xff1a; 其中3表示第三章&#xff0c;4表示第3章里的第4个图。标题、公式编号也是类似的。 为了达到这种按照章节编号的效果&#xff0c;原本可以用插入题注里的“包含章节编号” 但实际情况是&#xff0c;这不仅需要一级标题的序号是用“开始->多级列表”自动…

编码注入

Url&#xff1a;http://www.xxxxxxxx/newsdetail.php?idMjgxOA 判断参数Id存在数字型注入,试了报错注入不行&#xff0c;只能去盲注了 验证Poc1&#xff1a;idMTg4OS8x 等同于&#xff1a;id1889/1 poc2&#xff1a;idMTg4OS8w 等同于&#xff1a;id1889/0 /1 /0 用asci…