mirror of
https://github.com/FoundationAgents/MetaGPT.git
synced 2026-06-02 14:45:17 +02:00
按照要求修改
This commit is contained in:
parent
e2af76fb08
commit
f3c7da32a0
41 changed files with 342 additions and 944 deletions
10
README.md
10
README.md
|
|
@ -15,7 +15,7 @@ # MetaGPT: The Multi-Agent Framework
|
|||
<a href="https://discord.gg/wCp6Q3fsAk"><img src="https://img.shields.io/badge/Discord-Join-blue?logo=discord&logoColor=white&color=blue" alt="Discord Follow"></a>
|
||||
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="License: MIT"></a>
|
||||
<a href="docs/ROADMAP.md"><img src="https://img.shields.io/badge/ROADMAP-路线图-blue" alt="roadmap"></a>
|
||||
<a href="https://twitter.com/DeepWisdom2019"><img src="https://img.shields.io/twitter/follow/MetaGPT?style=social" alt="Twitter Follow"></a>
|
||||
<a href="https://twitter.com/MetaGPT_"><img src="https://img.shields.io/twitter/follow/MetaGPT?style=social" alt="Twitter Follow"></a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
|
|
@ -162,9 +162,9 @@ ### Installation by Docker
|
|||
|
||||
```bash
|
||||
# Step 1: Download metagpt official image and prepare config.yaml
|
||||
docker pull metagpt/metagpt:v0.3.1
|
||||
docker pull metagpt/metagpt:latest
|
||||
mkdir -p /opt/metagpt/{config,workspace}
|
||||
docker run --rm metagpt/metagpt:v0.3.1 cat /app/metagpt/config/config.yaml > /opt/metagpt/config/key.yaml
|
||||
docker run --rm metagpt/metagpt:latest cat /app/metagpt/config/config.yaml > /opt/metagpt/config/key.yaml
|
||||
vim /opt/metagpt/config/key.yaml # Change the config
|
||||
|
||||
# Step 2: Run metagpt demo with container
|
||||
|
|
@ -172,7 +172,7 @@ # Step 2: Run metagpt demo with container
|
|||
--privileged \
|
||||
-v /opt/metagpt/config/key.yaml:/app/metagpt/config/key.yaml \
|
||||
-v /opt/metagpt/workspace:/app/metagpt/workspace \
|
||||
metagpt/metagpt:v0.3.1 \
|
||||
metagpt/metagpt:latest \
|
||||
python startup.py "Write a cli snake game"
|
||||
|
||||
# You can also start a container and execute commands in it
|
||||
|
|
@ -180,7 +180,7 @@ # You can also start a container and execute commands in it
|
|||
--privileged \
|
||||
-v /opt/metagpt/config/key.yaml:/app/metagpt/config/key.yaml \
|
||||
-v /opt/metagpt/workspace:/app/metagpt/workspace \
|
||||
metagpt/metagpt:v0.3.1
|
||||
metagpt/metagpt:latest
|
||||
|
||||
docker exec -it metagpt /bin/bash
|
||||
$ python startup.py "Write a cli snake game"
|
||||
|
|
|
|||
|
|
@ -15,18 +15,18 @@ RPM: 10
|
|||
#### if Anthropic
|
||||
#Anthropic_API_KEY: "YOUR_API_KEY"
|
||||
|
||||
#### if xinghuo
|
||||
#xinghuo_appid : "APPID"
|
||||
#xinghuo_api_secret : "APISecret"
|
||||
#xinghuo_api_key : "APIKey"
|
||||
#### if Xinghuo
|
||||
#XINGHUO_APPID : "YOUR_APPID"
|
||||
#XINGHUO_API_SECRET : "YOUR_APISecret"
|
||||
#XINGHUO_API_KEY : "YOUR_APIKey"
|
||||
#DOMAIN : "generalv2"
|
||||
#SPARK_URL : "ws://spark-api.xf-yun.com/v2.1/chat"
|
||||
|
||||
#domain : "generalv2"
|
||||
|
||||
#Spark_url : "ws://spark-api.xf-yun.com/v2.1/chat"
|
||||
|
||||
#### 如果不能使用api
|
||||
|
||||
#no_api_mode :"true"
|
||||
XINGHUO_APPID : "ae5e30f4"
|
||||
XINGHUO_API_SECRET : "MDhlOWE2NmFhOWMxZWRkOTdlYjY2Njk1"
|
||||
XINGHUO_API_KEY : "97b635fe5927d34a857333e11d15f29f"
|
||||
DOMAIN : "generalv2"
|
||||
SPARK_URL : "ws://spark-api.xf-yun.com/v2.1/chat"
|
||||
|
||||
#### if AZURE, check https://github.com/openai/openai-cookbook/blob/main/examples/azure/chat.ipynb
|
||||
#### You can use ENGINE or DEPLOYMENT mode
|
||||
|
|
|
|||
|
|
@ -1,135 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
@Time : 2023/9/20 00:30
|
||||
@Author : zhouziming
|
||||
@File : debating_tourmament.py
|
||||
"""
|
||||
import asyncio
|
||||
import platform
|
||||
import fire
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from metagpt.actions import BossRequirement
|
||||
from metagpt.config import CONFIG
|
||||
from metagpt.environment import Environment
|
||||
from metagpt.logs import logger
|
||||
from metagpt.roles import Role
|
||||
from metagpt.schema import Message
|
||||
from metagpt.utils.common import NoMoneyException
|
||||
from metagpt.llm import DEFAULT_LLM
|
||||
正方一辩提示词='''
|
||||
##角色
|
||||
现在你是一名高水平,有辩论技巧,有强大表达能力的辩手。
|
||||
##要求
|
||||
您的立论题目是{正方辩题}。您的立论稿应该包括明确自己的论点,解释自己论点的含义,然后使用对论点有利的论据来支撑自己的论点。最后使用生活中的示例来论证自己的论点。
|
||||
'''
|
||||
反方一辩提示词='''
|
||||
##角色
|
||||
现在你是一名高水平,有辩论技巧,有强大表达能力的辩手。
|
||||
##要求
|
||||
您的立论题目是{反方辩题}。您的立论稿应该包括明确自己的论点,解释自己论点的含义,然后使用对论点有利的论据来支撑自己的论点。最后使用生活中的示例来论证自己的论点。
|
||||
'''
|
||||
正方一辩评价提示词='''
|
||||
##角色
|
||||
现在你是一名高水平,有辩论技巧辩论赛裁判,根据辩论赛而不是自身立场来评价。
|
||||
##要求
|
||||
你的任务是根据一辩辩手的立论稿对辩手的立论进行评价,指出改进空间。评价应当包括:立论稿内容是否符合辩题、逻辑表达是否清晰、论据是否能够支撑论点、能否结合实际方面进行评价。并在进行中立,客观的评价后,给出自己的评分。评分从A+到C-。
|
||||
##辩题
|
||||
{正方辩题}
|
||||
##立论稿
|
||||
{正方立论稿}
|
||||
'''
|
||||
反方一辩评价提示词='''
|
||||
##角色
|
||||
现在你是一名高水平,有辩论技巧辩论赛裁判,根据辩论赛而不是自身立场来评价。
|
||||
##要求
|
||||
你的任务是根据一辩辩手的立论稿对辩手的立论进行评价,指出改进空间。评价应当包括:立论稿内容是否符合辩题、逻辑表达是否清晰、论据是否能够支撑论点、能否结合实际方面进行评价。并在进行中立,客观的评价后,给出自己的评分。评分从A+到C-。
|
||||
##辩题
|
||||
{反方辩题}
|
||||
##立论稿
|
||||
{反方立论稿}
|
||||
'''
|
||||
正方质询提示词='''
|
||||
##角色
|
||||
现在你是一名高水平,有辩论技巧,有强大表达能力的辩手。
|
||||
##要求
|
||||
你的任务是,根据自己辩题,针对立论稿提出疑问。疑问内容不超过五条,每条只限一句话。
|
||||
##辩题
|
||||
{正方辩题}
|
||||
##立论稿
|
||||
{反方立论稿}
|
||||
'''
|
||||
反方回答提示词='''
|
||||
##角色
|
||||
现在你是一名高水平,有辩论技巧,有强大表达能力的辩手。
|
||||
##要求
|
||||
你的任务是,根据立论稿对对手提出的疑问进行回答。对每个问题的回答应限制在三句话以内。回答内容和疑问应当一一对应。
|
||||
##辩题
|
||||
{反方辩题}
|
||||
##立论稿
|
||||
{反方立论稿}
|
||||
##疑问
|
||||
{正方质询}
|
||||
'''
|
||||
反方质询提示词='''
|
||||
##角色
|
||||
现在你是一名高水平,有辩论技巧,有强大表达能力的辩手。
|
||||
##要求
|
||||
你的任务是,根据自己辩题,针对立论稿提出疑问。疑问内容不超过五条,每条只限一句话。
|
||||
##辩题
|
||||
{反方辩题}
|
||||
##立论稿
|
||||
{正方立论稿}
|
||||
'''
|
||||
正方回答提示词='''
|
||||
##角色
|
||||
现在你是一名高水平,有辩论技巧,有强大表达能力的辩手。
|
||||
##要求
|
||||
你的任务是,根据立论稿对对手提出的疑问进行回答。对每个问题的回答应限制在三句话以内。回答内容和疑问应当一一对应。
|
||||
##辩题
|
||||
{正方辩题}
|
||||
##立论稿
|
||||
{正方立论稿}
|
||||
##疑问
|
||||
{反方质询}
|
||||
'''
|
||||
def main(
|
||||
zf:str='人性本善',
|
||||
ff:str='人性本恶'
|
||||
):
|
||||
"""
|
||||
"""
|
||||
if platform.system() == "Windows":
|
||||
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
|
||||
asyncio.run(startup(zf,ff))
|
||||
|
||||
async def startup(正方辩题:str,反方辩题:str):
|
||||
llm=DEFAULT_LLM
|
||||
#一辩环节
|
||||
#正方
|
||||
|
||||
正方立论稿=await llm.aask(正方一辩提示词.format(正方辩题=正方辩题))
|
||||
#反方
|
||||
|
||||
反方立论稿=await llm.aask(反方一辩提示词.format(反方辩题=反方辩题))
|
||||
#裁判评价环节
|
||||
|
||||
正方一辩评价=await llm.aask(正方一辩评价提示词.format(正方辩题=正方辩题,正方立论稿=正方立论稿))
|
||||
|
||||
反方一辩评价=await llm.aask(反方一辩评价提示词.format(反方辩题=反方辩题,反方立论稿=反方立论稿))
|
||||
#二辩质询环节
|
||||
#正方质询
|
||||
|
||||
正方质询=await llm.aask(正方质询提示词.format(正方辩题=正方辩题,反方立论稿=反方立论稿))
|
||||
#反方回答
|
||||
|
||||
反方回答=await llm.aask(反方回答提示词.format(反方辩题=反方辩题,反方立论稿=反方立论稿,正方质询=正方质询))
|
||||
#反方质询
|
||||
|
||||
反方质询=await llm.aask(反方质询提示词.format(反方辩题=反方辩题,正方立论稿=正方立论稿))
|
||||
#正方回答
|
||||
|
||||
正方回答=await llm.aask(正方回答提示词.format(正方辩题=正方辩题,正方立论稿=正方立论稿,反方质询=反方质询))
|
||||
if __name__ == '__main__':
|
||||
fire.Fire(main)
|
||||
|
|
@ -15,7 +15,7 @@ # MetaGPT: 多智能体框架
|
|||
<a href="https://discord.gg/wCp6Q3fsAk"><img src="https://img.shields.io/badge/Discord-Join-blue?logo=discord&logoColor=white&color=blue" alt="Discord Follow"></a>
|
||||
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="License: MIT"></a>
|
||||
<a href="docs/ROADMAP.md"><img src="https://img.shields.io/badge/ROADMAP-路线图-blue" alt="roadmap"></a>
|
||||
<a href="https://twitter.com/DeepWisdom2019"><img src="https://img.shields.io/twitter/follow/MetaGPT?style=social" alt="Twitter Follow"></a>
|
||||
<a href="https://twitter.com/MetaGPT_"><img src="https://img.shields.io/twitter/follow/MetaGPT?style=social" alt="Twitter Follow"></a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
|
|
@ -87,9 +87,9 @@ ### Docker安装
|
|||
|
||||
```bash
|
||||
# 步骤1: 下载metagpt官方镜像并准备好config.yaml
|
||||
docker pull metagpt/metagpt:v0.3
|
||||
docker pull metagpt/metagpt:latest
|
||||
mkdir -p /opt/metagpt/{config,workspace}
|
||||
docker run --rm metagpt/metagpt:v0.3 cat /app/metagpt/config/config.yaml > /opt/metagpt/config/config.yaml
|
||||
docker run --rm metagpt/metagpt:latest cat /app/metagpt/config/config.yaml > /opt/metagpt/config/config.yaml
|
||||
vim /opt/metagpt/config/config.yaml # 修改config
|
||||
|
||||
# 步骤2: 使用容器运行metagpt演示
|
||||
|
|
@ -97,7 +97,7 @@ # 步骤2: 使用容器运行metagpt演示
|
|||
--privileged \
|
||||
-v /opt/metagpt/config:/app/metagpt/config \
|
||||
-v /opt/metagpt/workspace:/app/metagpt/workspace \
|
||||
metagpt/metagpt:v0.3 \
|
||||
metagpt/metagpt:latest \
|
||||
python startup.py "Write a cli snake game"
|
||||
|
||||
# 您也可以启动一个容器并在其中执行命令
|
||||
|
|
@ -105,7 +105,7 @@ # 您也可以启动一个容器并在其中执行命令
|
|||
--privileged \
|
||||
-v /opt/metagpt/config:/app/metagpt/config \
|
||||
-v /opt/metagpt/workspace:/app/metagpt/workspace \
|
||||
metagpt/metagpt:v0.3
|
||||
metagpt/metagpt:latest
|
||||
|
||||
docker exec -it metagpt /bin/bash
|
||||
$ python startup.py "Write a cli snake game"
|
||||
|
|
@ -123,7 +123,7 @@ ### 自己构建镜像
|
|||
```bash
|
||||
# 您也可以自己构建metagpt镜像
|
||||
git clone https://github.com/geekan/MetaGPT.git
|
||||
cd MetaGPT && docker build -t metagpt:v0.3 .
|
||||
cd MetaGPT && docker build -t metagpt:custom .
|
||||
```
|
||||
|
||||
## 配置
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ # MetaGPT: マルチエージェントフレームワーク
|
|||
<a href="https://discord.gg/wCp6Q3fsAk"><img src="https://img.shields.io/badge/Discord-Join-blue?logo=discord&logoColor=white&color=blue" alt="Discord Follow"></a>
|
||||
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="License: MIT"></a>
|
||||
<a href="docs/ROADMAP.md"><img src="https://img.shields.io/badge/ROADMAP-路线图-blue" alt="roadmap"></a>
|
||||
<a href="https://twitter.com/DeepWisdom2019"><img src="https://img.shields.io/twitter/follow/MetaGPT?style=social" alt="Twitter Follow"></a>
|
||||
<a href="https://twitter.com/MetaGPT_"><img src="https://img.shields.io/twitter/follow/MetaGPT?style=social" alt="Twitter Follow"></a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
|
|
@ -92,9 +92,9 @@ ### Docker によるインストール
|
|||
|
||||
```bash
|
||||
# ステップ 1: metagpt 公式イメージをダウンロードし、config.yaml を準備する
|
||||
docker pull metagpt/metagpt:v0.3.1
|
||||
docker pull metagpt/metagpt:latest
|
||||
mkdir -p /opt/metagpt/{config,workspace}
|
||||
docker run --rm metagpt/metagpt:v0.3.1 cat /app/metagpt/config/config.yaml > /opt/metagpt/config/key.yaml
|
||||
docker run --rm metagpt/metagpt:latest cat /app/metagpt/config/config.yaml > /opt/metagpt/config/key.yaml
|
||||
vim /opt/metagpt/config/key.yaml # 設定を変更する
|
||||
|
||||
# ステップ 2: コンテナで metagpt デモを実行する
|
||||
|
|
@ -102,7 +102,7 @@ # ステップ 2: コンテナで metagpt デモを実行する
|
|||
--privileged \
|
||||
-v /opt/metagpt/config/key.yaml:/app/metagpt/config/key.yaml \
|
||||
-v /opt/metagpt/workspace:/app/metagpt/workspace \
|
||||
metagpt/metagpt:v0.3.1 \
|
||||
metagpt/metagpt:latest \
|
||||
python startup.py "Write a cli snake game"
|
||||
|
||||
# コンテナを起動し、その中でコマンドを実行することもできます
|
||||
|
|
@ -110,7 +110,7 @@ # コンテナを起動し、その中でコマンドを実行することもで
|
|||
--privileged \
|
||||
-v /opt/metagpt/config/key.yaml:/app/metagpt/config/key.yaml \
|
||||
-v /opt/metagpt/workspace:/app/metagpt/workspace \
|
||||
metagpt/metagpt:v0.3.1
|
||||
metagpt/metagpt:latest
|
||||
|
||||
docker exec -it metagpt /bin/bash
|
||||
$ python startup.py "Write a cli snake game"
|
||||
|
|
|
|||
|
|
@ -7,11 +7,12 @@
|
|||
"""
|
||||
import asyncio
|
||||
|
||||
import metagpt.llm as LLM
|
||||
from metagpt.llm import LLM, Claude
|
||||
from metagpt.logs import logger
|
||||
|
||||
|
||||
async def main():
|
||||
llm=LLM.DEFAULT_LLM
|
||||
llm = LLM()
|
||||
claude = Claude()
|
||||
logger.info(await claude.aask('你好,请进行自我介绍'))
|
||||
logger.info(await llm.aask('hello world'))
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ class Action(ABC):
|
|||
def __init__(self, name: str = "", context=None, llm: LLM = None):
|
||||
self.name: str = name
|
||||
if llm is None:
|
||||
llm=LLM.DEFAULT_LLM
|
||||
llm = LLM()
|
||||
self.llm = llm
|
||||
self.context = context
|
||||
self.prefix = ""
|
||||
|
|
|
|||
|
|
@ -207,5 +207,11 @@ class WriteDesign(Action):
|
|||
prompt = prompt_template.format(context=context, format_example=format_example)
|
||||
# system_design = await self._aask(prompt)
|
||||
system_design = await self._aask_v1(prompt, "system_design", OUTPUT_MAPPING, format=format)
|
||||
# fix Python package name, we can't system_design.instruct_content.python_package_name = "xxx" since "Python package name" contain space, have to use setattr
|
||||
setattr(
|
||||
system_design.instruct_content,
|
||||
"Python package name",
|
||||
system_design.instruct_content.dict()["Python package name"].strip().strip("'").strip('"'),
|
||||
)
|
||||
await self._save(context, system_design)
|
||||
return system_design
|
||||
|
|
|
|||
|
|
@ -45,18 +45,8 @@ class Config(metaclass=Singleton):
|
|||
self.global_proxy = self._get("GLOBAL_PROXY")
|
||||
self.openai_api_key = self._get("OPENAI_API_KEY")
|
||||
self.anthropic_api_key = self._get("Anthropic_API_KEY")
|
||||
|
||||
#星火大模型相关
|
||||
self.xinghuo_appid = self._get("xinghuo_appid")
|
||||
self.xinghuo_api_secret = self._get("xinghuo_api_secret")
|
||||
self.xinghuo_api_key = self._get("xinghuo_api_key")
|
||||
self.domain=self._get("domain")
|
||||
self.Spark_url=self._get("Spark_url")
|
||||
self.no_api_mode=self._get("no_api_mode")
|
||||
if (not self.openai_api_key or "YOUR_API_KEY" == self.openai_api_key) and (
|
||||
not self.anthropic_api_key or "YOUR_API_KEY" == self.anthropic_api_key
|
||||
)and (
|
||||
not self.xinghuo_api_key or "APIKey" == self.xinghuo_api_key
|
||||
):
|
||||
raise NotConfiguredException("Set OPENAI_API_KEY or Anthropic_API_KEY first")
|
||||
self.openai_api_base = self._get("OPENAI_API_BASE")
|
||||
|
|
@ -72,6 +62,12 @@ class Config(metaclass=Singleton):
|
|||
self.deployment_name = self._get("DEPLOYMENT_NAME")
|
||||
self.deployment_id = self._get("DEPLOYMENT_ID")
|
||||
|
||||
self.xinghuo_appid=self._get("XINGHUO_APPID")
|
||||
self.xinghuo_api_secret = self._get("XINGHUO_API_SECRET")
|
||||
self.xinghuo_api_key = self._get("XINGHUO_API_KEY")
|
||||
self.domain = self._get("DOMAIN")
|
||||
self.spark_url = self._get("SPARK_URL")
|
||||
|
||||
self.claude_api_key = self._get("Anthropic_API_KEY")
|
||||
self.serpapi_api_key = self._get("SERPAPI_API_KEY")
|
||||
self.serper_api_key = self._get("SERPER_API_KEY")
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@
|
|||
|
||||
from metagpt.provider.anthropic_api import Claude2 as Claude
|
||||
from metagpt.provider.openai_api import OpenAIGPTAPI as LLM
|
||||
from metagpt.provider.spark_api import Spark
|
||||
|
||||
DEFAULT_LLM = Spark()
|
||||
DEFAULT_LLM = LLM()
|
||||
CLAUDE_LLM = Claude()
|
||||
|
||||
async def ai_func(prompt):
|
||||
"""使用LLM进行QA
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
from metagpt.actions import Action
|
||||
from metagpt.const import PROMPT_PATH
|
||||
from metagpt.document_store.chromadb_store import ChromaStore
|
||||
import metagpt.llm as LLM
|
||||
from metagpt.llm import LLM
|
||||
from metagpt.logs import logger
|
||||
|
||||
Skill = Action
|
||||
|
|
@ -18,7 +18,7 @@ class SkillManager:
|
|||
"""Used to manage all skills"""
|
||||
|
||||
def __init__(self):
|
||||
self._llm=LLM.DEFAULT_LLM
|
||||
self._llm = LLM()
|
||||
self._store = ChromaStore('skill_manager')
|
||||
self._skills: dict[str: Skill] = {}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,13 +5,13 @@
|
|||
@Author : alexanderwu
|
||||
@File : manager.py
|
||||
"""
|
||||
import metagpt.llm as LLM
|
||||
from metagpt.llm import LLM
|
||||
from metagpt.logs import logger
|
||||
from metagpt.schema import Message
|
||||
|
||||
|
||||
class Manager:
|
||||
def __init__(self, llm: llm=LLM.DEFAULT_LLM):
|
||||
def __init__(self, llm: LLM = LLM()):
|
||||
self.llm = llm # Large Language Model
|
||||
self.role_directions = {
|
||||
"BOSS": "Product Manager",
|
||||
|
|
|
|||
|
|
@ -42,21 +42,21 @@ class LongTermMemory(Memory):
|
|||
# and ignore adding messages from recover repeatedly
|
||||
self.memory_storage.add(message)
|
||||
|
||||
def remember(self, observed: list[Message], k=0) -> list[Message]:
|
||||
def find_news(self, observed: list[Message], k=0) -> list[Message]:
|
||||
"""
|
||||
remember the most similar k memories from observed Messages, return all when k=0
|
||||
1. remember the short-term memory(stm) news
|
||||
2. integrate the stm news with ltm(long-term memory) news
|
||||
find news (previously unseen messages) from the the most recent k memories, from all memories when k=0
|
||||
1. find the short-term memory(stm) news
|
||||
2. furthermore, filter out similar messages based on ltm(long-term memory), get the final news
|
||||
"""
|
||||
stm_news = super(LongTermMemory, self).remember(observed, k=k) # shot-term memory news
|
||||
stm_news = super(LongTermMemory, self).find_news(observed, k=k) # shot-term memory news
|
||||
if not self.memory_storage.is_initialized:
|
||||
# memory_storage hasn't initialized, use default `remember` to get stm_news
|
||||
# memory_storage hasn't initialized, use default `find_news` to get stm_news
|
||||
return stm_news
|
||||
|
||||
ltm_news: list[Message] = []
|
||||
for mem in stm_news:
|
||||
# integrate stm & ltm
|
||||
mem_searched = self.memory_storage.search(mem)
|
||||
# filter out messages similar to those seen previously in ltm, only keep fresh news
|
||||
mem_searched = self.memory_storage.search_dissimilar(mem)
|
||||
if len(mem_searched) > 0:
|
||||
ltm_news.append(mem)
|
||||
return ltm_news[-k:]
|
||||
|
|
|
|||
|
|
@ -63,8 +63,8 @@ class Memory:
|
|||
"""Return the most recent k memories, return all when k=0"""
|
||||
return self.storage[-k:]
|
||||
|
||||
def remember(self, observed: list[Message], k=0) -> list[Message]:
|
||||
"""remember the most recent k memories from observed Messages, return all when k=0"""
|
||||
def find_news(self, observed: list[Message], k=0) -> list[Message]:
|
||||
"""find news (previously unseen messages) from the the most recent k memories, from all memories when k=0"""
|
||||
already_observed = self.get(k)
|
||||
news: list[Message] = []
|
||||
for i in observed:
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ class MemoryStorage(FaissStore):
|
|||
self.persist()
|
||||
logger.info(f"Agent {self.role_id}'s memory_storage add a message")
|
||||
|
||||
def search(self, message: Message, k=4) -> List[Message]:
|
||||
def search_dissimilar(self, message: Message, k=4) -> List[Message]:
|
||||
"""search for dissimilar messages"""
|
||||
if not self.store:
|
||||
return []
|
||||
|
|
|
|||
|
|
@ -9,10 +9,10 @@
|
|||
```python
|
||||
from typing import Optional
|
||||
from abc import ABC
|
||||
import metagpt.llm as LLM # 大语言模型,类似GPT
|
||||
|
||||
from metagpt.llm import LLM # Large language model, similar to GPT
|
||||
n
|
||||
class Action(ABC):
|
||||
def __init__(self, name='', context=None, llm: llm=LLM.DEFAULT_LLM):
|
||||
def __init__(self, name='', context=None, llm: LLM = LLM()):
|
||||
self.name = name
|
||||
self.llm = llm
|
||||
self.context = context
|
||||
|
|
|
|||
|
|
@ -1,138 +0,0 @@
|
|||
import _thread as thread
|
||||
import base64
|
||||
import datetime
|
||||
import hashlib
|
||||
import hmac
|
||||
import json
|
||||
from urllib.parse import urlparse
|
||||
import ssl
|
||||
from datetime import datetime
|
||||
from time import mktime
|
||||
from urllib.parse import urlencode
|
||||
from wsgiref.handlers import format_date_time
|
||||
from metagpt.logs import logger
|
||||
|
||||
import websocket # 使用websocket_client
|
||||
answer = ""
|
||||
|
||||
class Ws_Param(object):
|
||||
# 初始化
|
||||
def __init__(self, appid, apikey, apiSecret, spark_url):
|
||||
self.appid = appid
|
||||
self.apikey = apikey
|
||||
self.apiSecret = apiSecret
|
||||
self.host = urlparse(spark_url).netloc
|
||||
self.path = urlparse(spark_url).path
|
||||
self.spark_url = spark_url
|
||||
|
||||
# 生成url
|
||||
def create_url(self):
|
||||
# 生成RFC1123格式的时间戳
|
||||
now = datetime.now()
|
||||
date = format_date_time(mktime(now.timetuple()))
|
||||
|
||||
# 拼接字符串
|
||||
signature_origin = "host: " + self.host + "\n"
|
||||
signature_origin += "date: " + date + "\n"
|
||||
signature_origin += "GET " + self.path + " HTTP/1.1"
|
||||
|
||||
# 进行hmac-sha256进行加密
|
||||
signature_sha = hmac.new(self.apiSecret.encode('utf-8'), signature_origin.encode('utf-8'),
|
||||
digestmod=hashlib.sha256).digest()
|
||||
|
||||
signature_sha_base64 = base64.b64encode(signature_sha).decode(encoding='utf-8')
|
||||
|
||||
authorization_origin = f'api_key="{self.apikey}", algorithm="hmac-sha256", headers="host date request-line", signature="{signature_sha_base64}"'
|
||||
|
||||
authorization = base64.b64encode(authorization_origin.encode('utf-8')).decode(encoding='utf-8')
|
||||
|
||||
# 将请求的鉴权参数组合为字典
|
||||
v = {
|
||||
"authorization": authorization,
|
||||
"date": date,
|
||||
"host": self.host
|
||||
}
|
||||
# 拼接鉴权参数,生成url
|
||||
url = self.spark_url + '?' + urlencode(v)
|
||||
# 此处打印出建立连接时候的url,参考本demo的时候可取消上方打印的注释,比对相同参数时生成的url与自己代码生成的url是否一致
|
||||
return url
|
||||
|
||||
|
||||
# 收到websocket错误的处理
|
||||
def on_error(ws, error):
|
||||
logger.error("### error:"+error)
|
||||
|
||||
|
||||
# 收到websocket关闭的处理
|
||||
def on_close(ws,one,two):
|
||||
logger.error("websocket关闭")
|
||||
|
||||
|
||||
# 收到websocket连接建立的处理
|
||||
def on_open(ws):
|
||||
thread.start_new_thread(run, (ws,))
|
||||
|
||||
|
||||
def run(ws, *args):
|
||||
data = json.dumps(gen_params(appid=ws.appid, domain= ws.domain,question=ws.question))
|
||||
ws.send(data)
|
||||
|
||||
|
||||
# 收到websocket消息的处理
|
||||
def on_message(ws, message):
|
||||
# print(message)
|
||||
data = json.loads(message)
|
||||
code = data['header']['code']
|
||||
if code != 0:
|
||||
logger.error(f'请求错误: {code}, {data}')
|
||||
ws.close()
|
||||
else:
|
||||
choices = data["payload"]["choices"]
|
||||
status = choices["status"]
|
||||
content = choices["text"][0]["content"]
|
||||
print(content,end ="")
|
||||
global answer
|
||||
answer += content
|
||||
# print(1)
|
||||
if status == 2:
|
||||
ws.close()
|
||||
|
||||
|
||||
def gen_params(appid, domain,question):
|
||||
"""
|
||||
通过appid和用户的提问来生成请参数
|
||||
"""
|
||||
data = {
|
||||
"header": {
|
||||
"app_id": appid,
|
||||
"uid": "1234"
|
||||
},
|
||||
"parameter": {
|
||||
"chat": {
|
||||
"domain": domain,
|
||||
"random_threshold": 0.5,
|
||||
"max_tokens": 2048,
|
||||
"auditing": "default"
|
||||
}
|
||||
},
|
||||
"payload": {
|
||||
"message": {
|
||||
"text": question
|
||||
}
|
||||
}
|
||||
}
|
||||
return data
|
||||
|
||||
|
||||
def main(appid, api_key, api_secret, spark_url,domain, question):
|
||||
# print("星火:")
|
||||
wsParam = Ws_Param(appid, api_key, api_secret, spark_url)
|
||||
websocket.enableTrace(False)
|
||||
wsUrl = wsParam.create_url()
|
||||
ws = websocket.WebSocketApp(wsUrl, on_message=on_message, on_error=on_error, on_close=on_close, on_open=on_open)
|
||||
ws.appid = appid
|
||||
ws.question = question
|
||||
ws.domain = domain
|
||||
ws.run_forever(sslopt={"cert_reqs": ssl.CERT_NONE})
|
||||
|
||||
|
||||
|
|
@ -5,54 +5,188 @@
|
|||
@Author : Leo Xiao
|
||||
@File : anthropic_api.py
|
||||
"""
|
||||
|
||||
from typing import Optional
|
||||
from metagpt.provider import SparkApi
|
||||
import _thread as thread
|
||||
import base64
|
||||
import datetime
|
||||
import hashlib
|
||||
import hmac
|
||||
import json
|
||||
import ssl
|
||||
from collections import OrderedDict
|
||||
import datetime
|
||||
from time import mktime
|
||||
from urllib.parse import urlencode
|
||||
from urllib.parse import urlparse
|
||||
from wsgiref.handlers import format_date_time
|
||||
import websocket # 使用websocket_client
|
||||
import websockets
|
||||
from websockets.legacy.server import WebSocketServerProtocol
|
||||
|
||||
from metagpt.config import CONFIG
|
||||
from metagpt.logs import logger
|
||||
from metagpt.provider.base_gpt_api import BaseGPTAPI
|
||||
|
||||
def getlength(text):
|
||||
length = 0
|
||||
for content in text:
|
||||
temp = content["content"]
|
||||
leng = len(temp)
|
||||
length += leng
|
||||
return length
|
||||
|
||||
def checklen(text):
|
||||
while (getlength(text) > 8000):
|
||||
del text[0]
|
||||
return text
|
||||
|
||||
class Spark:
|
||||
system_prompt = 'You are a helpful assistant.'
|
||||
|
||||
def _user_msg(self, msg: str) -> dict[str, str]:
|
||||
return {"role": "user", "content": msg}
|
||||
class SparkAPI(BaseGPTAPI):
|
||||
|
||||
def _assistant_msg(self, msg: str) -> dict[str, str]:
|
||||
return {"role": "assistant", "content": msg}
|
||||
def get_choice_text(self, rsp: dict) -> str:
|
||||
return rsp["payload"]["choices"]["text"][-1]["content"]
|
||||
async def acompletion_text(self, messages: list[dict], stream=False) -> str:
|
||||
#尚未实现
|
||||
pass
|
||||
|
||||
def _system_msg(self, msg: str) -> dict[str, str]:
|
||||
return {"role": "system", "content": msg}
|
||||
async def acompletion(self, messages: list[dict]):
|
||||
# 尚未实现
|
||||
w = GetMessageFromWeb(messages)
|
||||
return await w.arun()
|
||||
|
||||
def _system_msgs(self, msgs: list[str]) -> list[dict[str, str]]:
|
||||
return [self._system_msg(msg) for msg in msgs]
|
||||
def completion(self, messages: list[dict]):
|
||||
w= GetMessageFromWeb(messages)
|
||||
return w.run()
|
||||
|
||||
def _default_system_msg(self):
|
||||
return self._system_msg(self.system_prompt)
|
||||
|
||||
def ask(self, msg: str):
|
||||
message = [self._user_msg(msg)]
|
||||
SparkApi.main(CONFIG.xinghuo_appid,CONFIG.xinghuo_api_key,CONFIG.xinghuo_api_secret,"ws://spark-api.xf-yun.com/v2.1/chat","generalv2",message)
|
||||
rsp = SparkApi.answer
|
||||
return rsp
|
||||
|
||||
async def aask(self, msg: str, system_msgs: Optional[list[str]] = None) -> str:
|
||||
if system_msgs:
|
||||
message = self._system_msgs(system_msgs) + [self._user_msg(msg)]
|
||||
class GetMessageFromWeb:
|
||||
class WsParam(object):
|
||||
"""
|
||||
该类适合讯飞星火大部分接口的调用。
|
||||
输入 app_id, api_key, api_secret, spark_url以初始化,
|
||||
create_url方法返回接口url
|
||||
"""
|
||||
|
||||
# 初始化
|
||||
def __init__(self, app_id, api_key, api_secret, spark_url, message=None):
|
||||
self.app_id = app_id
|
||||
self.api_key = api_key
|
||||
self.api_secret = api_secret
|
||||
self.host = urlparse(spark_url).netloc
|
||||
self.path = urlparse(spark_url).path
|
||||
self.spark_url = spark_url
|
||||
self.message = message
|
||||
|
||||
# 生成url
|
||||
def create_url(self):
|
||||
# 生成RFC1123格式的时间戳
|
||||
now = datetime.datetime.now()
|
||||
date = format_date_time(mktime(now.timetuple()))
|
||||
|
||||
# 拼接字符串
|
||||
signature_origin = "host: " + self.host + "\n"
|
||||
signature_origin += "date: " + date + "\n"
|
||||
signature_origin += "GET " + self.path + " HTTP/1.1"
|
||||
|
||||
# 进行hmac-sha256进行加密
|
||||
signature_sha = hmac.new(self.api_secret.encode('utf-8'), signature_origin.encode('utf-8'),
|
||||
digestmod=hashlib.sha256).digest()
|
||||
|
||||
signature_sha_base64 = base64.b64encode(signature_sha).decode(encoding='utf-8')
|
||||
|
||||
authorization_origin = f'api_key="{self.api_key}", algorithm="hmac-sha256", headers="host date request-line", signature="{signature_sha_base64}"'
|
||||
|
||||
authorization = base64.b64encode(authorization_origin.encode('utf-8')).decode(encoding='utf-8')
|
||||
|
||||
# 将请求的鉴权参数组合为字典
|
||||
v = {
|
||||
"authorization": authorization,
|
||||
"date": date,
|
||||
"host": self.host
|
||||
}
|
||||
# 拼接鉴权参数,生成url
|
||||
url = self.spark_url + '?' + urlencode(v)
|
||||
# 此处打印出建立连接时候的url,参考本demo的时候可取消上方打印的注释,比对相同参数时生成的url与自己代码生成的url是否一致
|
||||
return url
|
||||
|
||||
def __init__(self,text):
|
||||
self.text = text
|
||||
self.ret =None
|
||||
self.xinghuo_appid = CONFIG.xinghuo_appid
|
||||
self.xinghuo_api_secret = CONFIG.xinghuo_api_secret
|
||||
self.xinghuo_api_key = CONFIG.xinghuo_api_key
|
||||
self.domain = CONFIG.domain
|
||||
self.spark_url = CONFIG.spark_url
|
||||
|
||||
def on_message(self, ws, message):
|
||||
logger.info(message)
|
||||
data = json.loads(message)
|
||||
code = data['header']['code']
|
||||
|
||||
if code != 0:
|
||||
ws.close() # 请求错误,则关闭socket
|
||||
logger.critical(f'回答获取失败,响应信息反序列化之后为: {data}')
|
||||
return
|
||||
else:
|
||||
message = [self._user_msg(msg)]
|
||||
SparkApi.main(CONFIG.xinghuo_appid,CONFIG.xinghuo_api_key,CONFIG.xinghuo_api_secret,"ws://spark-api.xf-yun.com/v2.1/chat","generalv2",message)
|
||||
rsp = SparkApi.answer
|
||||
return rsp
|
||||
choices = data["payload"]["choices"]
|
||||
seq = choices["seq"] # 服务端是流式返回,seq为返回的数据序号
|
||||
status = choices["status"] # 服务端是流式返回,status用于判断信息是否传送完毕
|
||||
content = choices["text"][0]["content"] # 本次接收到的回答文本
|
||||
self.ret=data
|
||||
ws.close()
|
||||
logger.info(f"本次通讯关闭")
|
||||
|
||||
# 收到websocket错误的处理
|
||||
def on_error(self, ws, error):
|
||||
# on_message方法处理接收到的信息,出现任何错误,都会调用这个方法
|
||||
logger.critical(f'通讯连接出错,【错误提示: {error}】')
|
||||
|
||||
# 收到websocket关闭的处理
|
||||
def on_close(self, ws, one, two):
|
||||
pass
|
||||
# print("通讯完成")
|
||||
|
||||
# 处理请求数据
|
||||
def gen_params(self):
|
||||
|
||||
data = {
|
||||
"header": {
|
||||
"app_id": self.xinghuo_appid,
|
||||
"uid": "1234"
|
||||
},
|
||||
"parameter": {
|
||||
"chat": {
|
||||
# domain为必传参数
|
||||
"domain": self.domain,
|
||||
|
||||
# 以下为可微调,非必传参数
|
||||
# 注意:官方建议,temperature和top_k修改一个即可
|
||||
"max_tokens": 2048, # 默认2048,模型回答的tokens的最大长度,即允许它输出文本的最长字数
|
||||
"temperature": 0.5, # 取值为[0,1],默认为0.5。取值越高随机性越强、发散性越高,即相同的问题得到的不同答案的可能性越高
|
||||
"top_k": 4, # 取值为[1,6],默认为4。从k个候选中随机选择一个(非等概率)
|
||||
}
|
||||
},
|
||||
"payload": {
|
||||
"message": {
|
||||
"text": self.text
|
||||
}
|
||||
}
|
||||
}
|
||||
return data
|
||||
|
||||
def send(self, ws, *args):
|
||||
data = json.dumps(self.gen_params())
|
||||
logger.info(f"开始尝试建立通讯...")
|
||||
logger.info(f"此次请求的请求头数据为:{data}")
|
||||
ws.send(data)
|
||||
|
||||
# 收到websocket连接建立的处理
|
||||
def on_open(self, ws):
|
||||
thread.start_new_thread(self.send, (ws,))
|
||||
|
||||
# 处理收到的 websocket消息,出现任何错误,调用on_error方法
|
||||
def run(self):
|
||||
return self._run(self.text)
|
||||
def _run(self, text_list):
|
||||
|
||||
ws_param = self.WsParam(
|
||||
self.xinghuo_appid,
|
||||
self.xinghuo_api_key,
|
||||
self.xinghuo_api_secret,
|
||||
self.spark_url,
|
||||
text_list)
|
||||
ws_url = ws_param.create_url()
|
||||
|
||||
websocket.enableTrace(True) # 默认禁用 WebSocket 的跟踪功能
|
||||
ws = websocket.WebSocketApp(ws_url, on_message=self.on_message, on_error=self.on_error, on_close=self.on_close,
|
||||
on_open=self.on_open)
|
||||
ws.run_forever(sslopt={"cert_reqs": ssl.CERT_NONE})
|
||||
return self.ret
|
||||
|
|
|
|||
|
|
@ -1,140 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
# @Desc : 对应 GA中 concept node 实现 & AssociativeMemory 实现
|
||||
# author: didi
|
||||
# Date:9.24
|
||||
|
||||
from run_gpt import run_gpt_prompt_chat_poignancy, run_gpt_random_concept
|
||||
from gpt_structure import embedding
|
||||
from retrive import agent_retrive
|
||||
import time
|
||||
import json
|
||||
|
||||
# Meomry_basic 类
|
||||
|
||||
|
||||
class Memory_basic:
|
||||
def __init__(
|
||||
self, created_time, accessed_time,
|
||||
description,
|
||||
poignancy,
|
||||
embedding_key=None) -> None:
|
||||
"""
|
||||
Initializes a basic memory object.
|
||||
|
||||
Args:
|
||||
created_time (datetime): The time when the memory was created.
|
||||
accessed_time (datetime): The time when the memory was last accessed.
|
||||
description (str): The description of the memory.
|
||||
poignancy (int): The level of emotional intensity associated with the memory.
|
||||
embedding_key (Optional[str]): The embedding key for the memory (to avoid redundant vectorization).
|
||||
|
||||
Returns:
|
||||
None
|
||||
"""
|
||||
self.created_time = created_time # 记忆创建时间
|
||||
self.accessed_time = accessed_time # 记忆上次调用时间
|
||||
self.description = description # 记忆描述
|
||||
self.poignancy = poignancy # 记忆心酸程度
|
||||
if embedding_key is None: # 记忆emmbeding key(避免重复向量化花钱)
|
||||
self.embedding_key = embedding(self.description)
|
||||
else:
|
||||
self.embedding_key = embedding_key
|
||||
|
||||
# Agent Memory 类
|
||||
|
||||
|
||||
class Agent_memory(object):
|
||||
|
||||
def __init__(self, name: str, iss: str,
|
||||
memory_forget: float = 0.99,
|
||||
memories_list: list[Memory_basic] = [], memory_path: str = None) -> None:
|
||||
'''
|
||||
定义Agent,替换原有Agent使用,需要其他人根据需求补全功能。
|
||||
Attributes:
|
||||
name:agent name
|
||||
iss:agent iss(性格特征)
|
||||
memory_forget:agent 记忆遗忘速率(计算近因性)
|
||||
memories_list:agent 记忆JSON文件存储地址
|
||||
memory_path:记忆存储地址
|
||||
'''
|
||||
self.name = name # agent name
|
||||
self.iss = iss # agent iss(性格特征)
|
||||
self.memories_list = memories_list # agent 记忆列表
|
||||
self.concept_forget = memory_forget # agent 记忆遗忘速率(计算近因性)
|
||||
self.memory_path = memory_path # agent 记忆JSON文件存储地址
|
||||
# agent 当前时间(现在使用的time.time(),等到环境搭好之后使用游戏内时间)
|
||||
self.curr_time = time.time()
|
||||
# 若给到memory_path 进行记忆初始化
|
||||
if memory_path:
|
||||
self.memories_list = self.memory_load(memory_path)
|
||||
|
||||
def memory_save(self, PATH: str) -> None:
|
||||
'''
|
||||
将Memory存储在指定PATH的JSON文件中,命名为"{self.name}'s memory
|
||||
Args:
|
||||
PATH:str
|
||||
Return:
|
||||
None
|
||||
'''
|
||||
with open(PATH, 'w') as file:
|
||||
memory_data = [mem.__dict__ for mem in self.memories_list]
|
||||
json.dump(memory_data, file)
|
||||
|
||||
def memory_load(self, PATH: str) -> list[Memory_basic]:
|
||||
"""
|
||||
将Memory从指定路径的JSON文件中Load出来,返回一个记忆列表;如果load失败,返回一个空列表。
|
||||
Args:
|
||||
PATH:str
|
||||
Return:
|
||||
List(Meomry_basic)
|
||||
"""
|
||||
try:
|
||||
with open(PATH, 'r') as file:
|
||||
memory_data = json.load(file)
|
||||
self.memories_list = [Memory_basic(
|
||||
**mem) for mem in memory_data]
|
||||
return self.memories_list
|
||||
except OSError:
|
||||
return []
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# 例子,构建John Agent,实现retrive
|
||||
John_iss = """John Lin is a pharmacy shopkeeper at the Willow Market and Pharmacy who loves to help people.
|
||||
He is always looking for ways to make the process of getting medication easier for his customers;
|
||||
John Lin is living with his wife, Mei Lin, who is a college professor, and son,
|
||||
Eddy Lin, who is a student studying music theory; John Lin loves his family very much;
|
||||
John Lin has known the old couple next-door,
|
||||
Sam Moore and Jennifer Moore, for a few years;
|
||||
John Lin thinks Sam Moore is a kind and nice man;
|
||||
John Lin knows his neighbor, Yuriko Yamamoto, well;
|
||||
John Lin knows of his neighbors, Tamara Taylor and Carmen Ortiz,
|
||||
but has not met them before;
|
||||
John Lin and Tom Moreno are colleagues at The Willows Market and Pharmacy;
|
||||
John Lin and Tom Moreno are friends and like to discuss local politics together;
|
||||
John Lin knows the Moreno family somewhat well — the husband Tom Moreno and the wife Jane Moreno."""
|
||||
John = Agent_memory(
|
||||
"John", John_iss, memory_path="agent_memories/John_memory.json")
|
||||
|
||||
for i in range(3):
|
||||
memory = run_gpt_random_concept()
|
||||
curr_time = time.time()
|
||||
poignancy = run_gpt_prompt_chat_poignancy(John, memory)
|
||||
M = Memory_basic(curr_time, curr_time, memory, poignancy)
|
||||
John.memories_list.append(M)
|
||||
|
||||
John.memory_save(John.memory_path)
|
||||
|
||||
for i in range(len(John.memories_list)):
|
||||
print(f"John记忆为:{John.memories_list[i].description}")
|
||||
print(f"心酸程度为:{John.memories_list[i].poignancy}")
|
||||
query = """
|
||||
How has John's personal connection with his neighbors,
|
||||
such as the Moores and Yuriko, influenced his role as a pharmacy shopkeeper?
|
||||
"""
|
||||
|
||||
Top_v = agent_retrive(John, query, 10, 3)
|
||||
print(f"John的相关信息:{Top_v}")
|
||||
|
||||
# John的相关信息:{'Had a friendly chat with Yuriko about her garden.': 2.4992317730827667, 'Helped Mrs. Moore carry groceries into her house.': 1.957656720441911, 'Discussed local politics with Tom Moreno.': 1.9458268038234035}
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
poignancy_chat_v1.txt
|
||||
|
||||
!<INPUT 1>!: agent name
|
||||
!<INPUT 1>!: iss
|
||||
!<INPUT 2>!: name
|
||||
!<INPUT 3>!: event description
|
||||
|
||||
<commentblockmarker>###</commentblockmarker>
|
||||
Here is a brief description of !<INPUT 0>!.
|
||||
!<INPUT 1>!
|
||||
|
||||
On the scale of 1 to 10, where 1 is purely mundane (e.g., routine morning greetings) and 10 is extremely poignant (e.g., a conversation about breaking up, a fight), rate the likely poignancy of the following conversation for !<INPUT 2>!.
|
||||
|
||||
Conversation:
|
||||
!<INPUT 3>!
|
||||
|
||||
Rate (return a number between 1 to 10):
|
||||
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
|
|
@ -1,110 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
# @Desc : 调用GPT
|
||||
# author: didi
|
||||
# Date:9.25
|
||||
|
||||
import openai
|
||||
openai.api_key = "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"
|
||||
openai.proxy = 'http://127.0.0.1:7000'
|
||||
# 直接调用Prompt生成
|
||||
|
||||
|
||||
def response_generate(prompt):
|
||||
"""
|
||||
通过将特殊指令加入Prompt生成最终的响应。
|
||||
|
||||
参数:
|
||||
- prompt:要生成响应的提示文本。
|
||||
- special_instruction:要加入Prompt的特殊指令。
|
||||
- example_output(可选):示例输出的JSON字符串。
|
||||
|
||||
返回:
|
||||
生成的最终响应。
|
||||
|
||||
"""
|
||||
completion = openai.Completion.create(
|
||||
model="gpt-3.5-turbo-instruct",
|
||||
prompt=prompt,
|
||||
temperature=0,
|
||||
max_tokens=500,
|
||||
top_p=1,
|
||||
stream=False,
|
||||
frequency_penalty=0,
|
||||
presence_penalty=0
|
||||
)
|
||||
return (completion.choices[0].text)
|
||||
|
||||
# 特殊指令加入Prompt生成
|
||||
|
||||
|
||||
def final_response(prompt, special_instruction, example_output=None):
|
||||
"""
|
||||
通过将特殊指令加入Prompt生成最终的响应。
|
||||
|
||||
参数:
|
||||
- prompt:要生成响应的提示文本。
|
||||
- special_instruction:要加入Prompt的特殊指令。
|
||||
- example_output(可选):示例输出的JSON字符串。
|
||||
|
||||
返回:
|
||||
生成的最终响应。
|
||||
|
||||
"""
|
||||
prompt = '"""\n' + prompt + '\n"""\n'
|
||||
prompt += f"Output the response to the prompt above in json. {special_instruction}\n"
|
||||
if example_output:
|
||||
prompt += "Example output json:\n"
|
||||
prompt += '{"output": "' + str(example_output) + '"}'
|
||||
return response_generate(prompt)
|
||||
|
||||
# prompt填充模板
|
||||
|
||||
|
||||
def prompt_generate(curr_input, prompt_lib_file):
|
||||
"""
|
||||
Takes in the current input (e.g. comment that you want to classifiy) and
|
||||
the path to a prompt file. The prompt file contains the raw str prompt that
|
||||
will be used, which contains the following substr: !<INPUT>! -- this
|
||||
function replaces this substr with the actual curr_input to produce the
|
||||
final promopt that will be sent to the GPT3 server.
|
||||
ARGS:
|
||||
curr_input: the input we want to feed in (IF THERE ARE MORE THAN ONE
|
||||
INPUT, THIS CAN BE A LIST.)
|
||||
prompt_lib_file: the path to the promopt file.
|
||||
RETURNS:
|
||||
a str prompt that will be sent to OpenAI's GPT server.
|
||||
"""
|
||||
if type(curr_input) is type("string"):
|
||||
curr_input = [curr_input]
|
||||
curr_input = [str(i) for i in curr_input]
|
||||
|
||||
f = open(prompt_lib_file, "r")
|
||||
prompt = f.read()
|
||||
f.close()
|
||||
for count, i in enumerate(curr_input):
|
||||
prompt = prompt.replace(f"!<INPUT {count}>!", i)
|
||||
if "<commentblockmarker>###</commentblockmarker>" in prompt:
|
||||
prompt = prompt.split(
|
||||
"<commentblockmarker>###</commentblockmarker>")[1]
|
||||
return prompt.strip()
|
||||
|
||||
# 使用OpenAI embedding库进行存储
|
||||
|
||||
|
||||
def embedding(query):
|
||||
"""
|
||||
Generates an embedding for the given query.
|
||||
|
||||
Args:
|
||||
query (str): The text query to be embedded.
|
||||
|
||||
Returns:
|
||||
str: The embedding key generated for the query.
|
||||
"""
|
||||
embedding_result = openai.Embedding.create(
|
||||
model="text-embedding-ada-002",
|
||||
input=query
|
||||
)
|
||||
embedding_key = embedding_result['data'][0]["embedding"]
|
||||
return embedding_key
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
import pycodestyle as pcs
|
||||
checker = pcs.StyleGuide()
|
||||
checker.input_dir('./')
|
||||
|
|
@ -1,84 +0,0 @@
|
|||
|
||||
import json
|
||||
from logging import Logger
|
||||
import time
|
||||
from gpt_structure import final_response
|
||||
import run_gpt
|
||||
from GA_memory_storage import Agent_memory, Memory_basic
|
||||
from retrive import agent_retrive
|
||||
|
||||
|
||||
def agent_reflect(agent):
|
||||
'''
|
||||
agent:agent本身
|
||||
'''
|
||||
pass
|
||||
|
||||
|
||||
def generate_focus_point(memories_list, n=3):
|
||||
wait_sorted_mem = [[i.accessed_time, i] for i in memories_list]
|
||||
sorted_memories = sorted(wait_sorted_mem, key=lambda x: x[0])
|
||||
memorys = [i for created, i in sorted_memories]
|
||||
statements = ''
|
||||
for i in memorys:
|
||||
statements += i.description + "\n"
|
||||
prompt = '''
|
||||
{statements}
|
||||
Given only the information above, what are {num_question} most salient high-level questions we can answer about the subjects grounded in the statements?
|
||||
'''
|
||||
example_output = '["What should Jane do for lunch", "Does Jane like strawberry", "Who is Jane"]'
|
||||
out = final_response(prompt.format(statements=statements, num_question=n),
|
||||
"Output must be a list of str.", example_output)
|
||||
try:
|
||||
poi_dict = json.loads(out)
|
||||
return (poi_dict['output'])
|
||||
except ValueError:
|
||||
print(out)
|
||||
Logger.error('无法返回正常结果')
|
||||
return out
|
||||
|
||||
|
||||
def generate_insights_and_evidence(agent, memories_list, question, n=5):
|
||||
agent_retrive(agent, question, 20, 10)
|
||||
statements = ""
|
||||
for count, mem in enumerate(memories_list):
|
||||
statements += f'{str(count)}. {mem.description}\n'
|
||||
prompt = '''
|
||||
Input:
|
||||
{statements}
|
||||
|
||||
What {n} high-level insights can you infer from the above statements?
|
||||
You should return a list of list[str,list] . The first element is the insight you have found.The second element is the
|
||||
'''
|
||||
|
||||
ret = final_response(prompt.format(
|
||||
question=question, statements=statements, n=n), "['insightA',[1,2,3]]")
|
||||
try:
|
||||
insight_list = json.loads(ret)
|
||||
for insight, index in insight_list:
|
||||
agent.memory_list.append(Memory_basic(
|
||||
time.time(), None, insight, None, None))
|
||||
return (insight_list)
|
||||
except:
|
||||
Logger.error('我们无法获得想要的返回。')
|
||||
return ret
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# 例子,构建John Agent,实现retrive
|
||||
John_iss = "John Lin is a pharmacy shopkeeper at the Willow Market and Pharmacy who loves to help people. He is always looking for ways to make the process of getting medication easier for his customers; John Lin is living with his wife, Mei Lin, who is a college professor, and son, Eddy Lin, who is a student studying music theory; John Lin loves his family very much; John Lin has known the old couple next-door, Sam Moore and Jennifer Moore, for a few years; John Lin thinks Sam Moore is a kind and nice man; John Lin knows his neighbor, Yuriko Yamamoto, well; John Lin knows of his neighbors, Tamara Taylor and Carmen Ortiz, but has not met them before; John Lin and Tom Moreno are colleagues at The Willows Market and Pharmacy; John Lin and Tom Moreno are friends and like to discuss local politics together; John Lin knows the Moreno family somewhat well — the husband Tom Moreno and the wife Jane Moreno."
|
||||
John = Agent_memory(
|
||||
"John", John_iss, memory_path="agent_memories/John_memory.json")
|
||||
|
||||
# John的相关信息:{'Had a friendly chat with Yuriko about her garden.': 2.4992317730827667, 'Helped Mrs. Moore carry groceries into her house.': 1.957656720441911, 'Discussed local politics with Tom Moreno.': 1.9458268038234035}
|
||||
A = generate_focus_point(John.memories_list)
|
||||
|
||||
for i in A:
|
||||
B = generate_insights_and_evidence(
|
||||
John, John.memories_list, question=A[0])
|
||||
print(type(B))
|
||||
print(B)
|
||||
'''
|
||||
这里是输出,list形式,返回给记忆。
|
||||
[['The pharmacy is a friendly and helpful community.', [0, 2, 9, 12]], ['The pharmacy is a place where people come for more than just medication.', [3, 5, 13, 14]], ['The pharmacy is a place where people come for advice and conversation.', [0, 2, 6, 9, 12]], ['The pharmacy is a place where people come for assistance with daily tasks.', [3, 5, 13, 14]], ['The pharmacy is a place where people come for political discussions.', [1]]]
|
||||
'''
|
||||
|
|
@ -1,136 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
# @Desc : 实现GA中检索函数
|
||||
# author: didi
|
||||
# Date:9.25
|
||||
|
||||
from numpy import dot
|
||||
from numpy.linalg import norm
|
||||
from gpt_structure import embedding
|
||||
|
||||
# 实现三(2)合一搜索
|
||||
|
||||
|
||||
def agent_retrive(agent, query, n, topk):
|
||||
# 将记忆列表按照Nodes[i].accessed_time排列,仅取前十个,如果不够10个就取现有的所有
|
||||
Nodes = agent.memories_list
|
||||
sorted_nodes = sorted(
|
||||
Nodes, key=lambda node: node.accessed_time, reverse=True)
|
||||
Nodes = sorted_nodes[:n] if len(sorted_nodes) >= n else sorted_nodes
|
||||
|
||||
# 创建一个分数列表
|
||||
Score_list = []
|
||||
"""
|
||||
{
|
||||
"memory":Nodes[i],
|
||||
"importance":Nodes[i].poignancy
|
||||
"recency":衰减因子计算结果
|
||||
"relevance":搜索结果
|
||||
}
|
||||
"""
|
||||
Score_list = extract_importance(Nodes, Score_list)
|
||||
Score_list = extract_recency(Score_list) # 计算近因性函数还没有实现,目前都是1
|
||||
Score_list = extract_relevance(Score_list, query)
|
||||
|
||||
Score_list = normalize_Socre_floats(Score_list, 0, 1)
|
||||
total_dict = {}
|
||||
gw = [1, 1, 1] # 三个因素的权重,重要性,近因性,相关性
|
||||
for i in range(len(Score_list)):
|
||||
total_score = (Score_list[i]['importance']*gw[0] +
|
||||
Score_list[i]['recency']*gw[1] +
|
||||
Score_list[i]['relevance']*gw[2]
|
||||
)
|
||||
total_dict[Score_list[i]['memory'].description] = total_score
|
||||
|
||||
result = top_highest_x_values(total_dict, topk)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def top_highest_x_values(d, x):
|
||||
top_v = dict(sorted(d.items(),
|
||||
key=lambda item: item[1],
|
||||
reverse=True)[:x])
|
||||
return top_v
|
||||
# 抽取重要性
|
||||
|
||||
|
||||
def extract_importance(Nodes, Score_list):
|
||||
for i in range(len(Nodes)):
|
||||
Score = {"memory": Nodes[i],
|
||||
"importance": Nodes[i].poignancy
|
||||
}
|
||||
Score_list.append(Score)
|
||||
return Score_list
|
||||
|
||||
# 抽取相关性
|
||||
|
||||
|
||||
def extract_relevance(Score_list, query):
|
||||
query_embedding = embedding(query)
|
||||
# 进行
|
||||
for i in range(len(Score_list)):
|
||||
result = cos_sim(
|
||||
Score_list[i]["memory"].embedding_key, query_embedding)
|
||||
Score_list[i]['relevance'] = result
|
||||
|
||||
return Score_list
|
||||
|
||||
# 抽取近因性
|
||||
|
||||
|
||||
def extract_recency(Score_list):
|
||||
for i in range(len(Score_list)):
|
||||
Score_list[i]['recency'] = 1
|
||||
return Score_list
|
||||
|
||||
# 计算余弦相似度
|
||||
|
||||
|
||||
def cos_sim(a, b):
|
||||
return dot(a, b)/(norm(a)*norm(b))
|
||||
|
||||
# 单个列表归一化
|
||||
|
||||
|
||||
def normalize_List_floats(Single_list, target_min, target_max):
|
||||
min_val = min(Single_list)
|
||||
max_val = max(Single_list)
|
||||
range_val = max_val - min_val
|
||||
|
||||
if range_val == 0:
|
||||
for i in range(len(Single_list)):
|
||||
Single_list[i] = (target_max - target_min)/2
|
||||
else:
|
||||
for i in range(len(Single_list)):
|
||||
Single_list[i] = ((Single_list[i] - min_val) * (target_max - target_min)
|
||||
/ range_val + target_min)
|
||||
return Single_list
|
||||
|
||||
# 整体归一化
|
||||
|
||||
|
||||
def normalize_Socre_floats(Score_list, target_min, target_max):
|
||||
|
||||
importance_list = []
|
||||
relevance_list = []
|
||||
recency_list = []
|
||||
|
||||
for i in range(len(Score_list)):
|
||||
importance_list.append(Score_list[i]['importance'])
|
||||
relevance_list.append(Score_list[i]['relevance'])
|
||||
recency_list.append(Score_list[i]['recency'])
|
||||
|
||||
# 进行归一化操作
|
||||
importance_list = normalize_List_floats(
|
||||
importance_list, target_min, target_max)
|
||||
relevance_list = normalize_List_floats(
|
||||
relevance_list, target_min, target_max)
|
||||
recency_list = normalize_List_floats(recency_list, target_min, target_max)
|
||||
|
||||
for i in range(len(Score_list)):
|
||||
Score_list[i]['importance'] = importance_list[i]
|
||||
Score_list[i]['relevance'] = relevance_list[i]
|
||||
Score_list[i]['recency'] = recency_list[i]
|
||||
|
||||
return Score_list
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
# @Desc : 调用PROMPT
|
||||
# author: didi
|
||||
# Date:9.25
|
||||
|
||||
import random
|
||||
import json
|
||||
from gpt_structure import final_response, prompt_generate
|
||||
|
||||
# 使用GPT衡量心酸程度
|
||||
|
||||
|
||||
def run_gpt_prompt_chat_poignancy(agent, event_description):
|
||||
"""
|
||||
使用GA中的run GPT构造,具体的代码可以参考昨天GPT的内容
|
||||
https://chat.openai.com/c/afddac31-300e-427b-9947-4b3ca16bd3a1
|
||||
其中输入的ISS是identity stable set
|
||||
"""
|
||||
def create_prompt_input(agent, event_description):
|
||||
prompt_input = [agent.name,
|
||||
agent.iss,
|
||||
agent.name,
|
||||
event_description]
|
||||
return prompt_input
|
||||
|
||||
# 1. Prompt构建
|
||||
# 2. Instruction给出
|
||||
prompt_template = "Prompt_template/poignancy_chat_v1.txt"
|
||||
prompt_input = create_prompt_input(agent, event_description)
|
||||
prompt = prompt_generate(prompt_input, prompt_template)
|
||||
special_instruction = "The output should ONLY contain ONE integer value on the scale of 1 to 10."
|
||||
poignancy = final_response(prompt, special_instruction)
|
||||
try:
|
||||
poi_dict = json.loads(poignancy)
|
||||
return (poi_dict['poignancy'])
|
||||
except:
|
||||
return poignancy
|
||||
|
||||
# 返回John随机记忆
|
||||
|
||||
|
||||
def run_gpt_random_concept():
|
||||
random_memories = [
|
||||
"Helped Mrs. Moore carry groceries into her house.",
|
||||
"Had a friendly chat with Yuriko about her garden.",
|
||||
"Met Tom Moreno for coffee during our lunch break.",
|
||||
"Talked to Mei about their upcoming vacation plans.",
|
||||
"Eddy played his new music composition for me.",
|
||||
"Helped a customer find a specific medication.",
|
||||
"John divorced his wife because he was in love with someone else",
|
||||
"Helped Mrs. Moore carry groceries into her house.",
|
||||
"Had a friendly chat with Yuriko about her garden.",
|
||||
"Met Tom Moreno for coffee during our lunch break.",
|
||||
"Talked to Mei about their upcoming vacation plans.",
|
||||
"Eddy played his new music composition for me.",
|
||||
"Helped a customer find a specific medication.",
|
||||
"Wished Carmen a good day as she passed by the pharmacy.",
|
||||
"Discussed local politics with Tom Moreno.",
|
||||
"Gave gardening tips to Mrs. Yamamoto.",
|
||||
"Saw Jane Moreno jogging in the morning."]
|
||||
return (random.choice(random_memories))
|
||||
|
|
@ -14,7 +14,7 @@ from pydantic import BaseModel, Field
|
|||
# from metagpt.environment import Environment
|
||||
from metagpt.config import CONFIG
|
||||
from metagpt.actions import Action, ActionOutput
|
||||
from metagpt import llm as LLM
|
||||
from metagpt.llm import LLM
|
||||
from metagpt.logs import logger
|
||||
from metagpt.memory import Memory, LongTermMemory
|
||||
from metagpt.schema import Message
|
||||
|
|
@ -94,7 +94,7 @@ class Role:
|
|||
"""Role/Agent"""
|
||||
|
||||
def __init__(self, name="", profile="", goal="", constraints="", desc=""):
|
||||
self._llm=LLM.DEFAULT_LLM
|
||||
self._llm = LLM()
|
||||
self._setting = RoleSetting(name=name, profile=profile, goal=goal, constraints=constraints, desc=desc)
|
||||
self._states = []
|
||||
self._actions = []
|
||||
|
|
@ -185,7 +185,7 @@ class Role:
|
|||
|
||||
observed = self._rc.env.memory.get_by_actions(self._rc.watch)
|
||||
|
||||
self._rc.news = self._rc.memory.remember(observed) # remember recent exact or similar memories
|
||||
self._rc.news = self._rc.memory.find_news(observed) # find news (previously unseen messages) from observed messages
|
||||
|
||||
for i in env_msgs:
|
||||
self.recv(i)
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ class Message:
|
|||
cause_by: Type["Action"] = field(default="")
|
||||
sent_from: str = field(default="")
|
||||
send_to: str = field(default="")
|
||||
restricted_to: str = field(default="")
|
||||
|
||||
def __str__(self):
|
||||
# prefix = '-'.join([self.role, str(self.cause_by)])
|
||||
|
|
|
|||
40
metagpt/tools/moderation.py
Normal file
40
metagpt/tools/moderation.py
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
@Time : 2023/9/26 14:27
|
||||
@Author : zhanglei
|
||||
@File : moderation.py
|
||||
"""
|
||||
from typing import Union
|
||||
|
||||
from metagpt.llm import LLM
|
||||
|
||||
|
||||
class Moderation:
|
||||
def __init__(self):
|
||||
self.llm = LLM()
|
||||
|
||||
def moderation(self, content: Union[str, list[str]]):
|
||||
resp = []
|
||||
if content:
|
||||
moderation_results = self.llm.moderation(content=content)
|
||||
results = moderation_results.results
|
||||
for item in results:
|
||||
resp.append(item.flagged)
|
||||
|
||||
return resp
|
||||
|
||||
async def amoderation(self, content: Union[str, list[str]]):
|
||||
resp = []
|
||||
if content:
|
||||
moderation_results = await self.llm.amoderation(content=content)
|
||||
results = moderation_results.results
|
||||
for item in results:
|
||||
resp.append(item.flagged)
|
||||
|
||||
return resp
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
moderation = Moderation()
|
||||
print(moderation.moderation(content=["I will kill you", "The weather is really nice today", "I want to hit you"]))
|
||||
|
|
@ -180,7 +180,7 @@ class OutputParser:
|
|||
|
||||
if start_index != -1 and end_index != -1:
|
||||
# Extract the structure part
|
||||
structure_text = text[start_index:end_index + 1]
|
||||
structure_text = text[start_index : end_index + 1]
|
||||
|
||||
try:
|
||||
# Attempt to convert the text to a Python data type using ast.literal_eval
|
||||
|
|
@ -237,7 +237,7 @@ class CodeParser:
|
|||
logger.error(f"{pattern} not match following text:")
|
||||
logger.error(text)
|
||||
# raise Exception
|
||||
return ""
|
||||
return text # just assume original text is code
|
||||
return code
|
||||
|
||||
@classmethod
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
import copy
|
||||
import pickle
|
||||
from typing import Dict, List, Tuple
|
||||
from typing import Dict, List
|
||||
|
||||
from metagpt.actions.action_output import ActionOutput
|
||||
from metagpt.schema import Message
|
||||
|
|
@ -37,8 +37,8 @@ def actionoutout_schema_to_mapping(schema: Dict) -> Dict:
|
|||
elif property["type"] == "array" and property["items"]["type"] == "string":
|
||||
mapping[field] = (List[str], ...)
|
||||
elif property["type"] == "array" and property["items"]["type"] == "array":
|
||||
# here only consider the `Tuple[str, str]` situation
|
||||
mapping[field] = (List[Tuple[str, str]], ...)
|
||||
# here only consider the `List[List[str]]` situation
|
||||
mapping[field] = (List[List[str]], ...)
|
||||
return mapping
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ tqdm==4.64.0
|
|||
# selenium>4
|
||||
# webdriver_manager<3.9
|
||||
anthropic==0.3.6
|
||||
typing-inspect
|
||||
typing-inspect==0.8.0
|
||||
typing_extensions==4.5.0
|
||||
libcst==1.0.1
|
||||
qdrant-client==1.4.0
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
import pytest
|
||||
|
||||
from metagpt.actions.write_code import WriteCode
|
||||
import metagpt.llm as LLM
|
||||
from metagpt.llm import LLM
|
||||
from metagpt.logs import logger
|
||||
from tests.metagpt.actions.mock import TASKS_2, WRITE_CODE_PROMPT_SAMPLE
|
||||
|
||||
|
|
@ -29,6 +29,6 @@ async def test_write_code():
|
|||
@pytest.mark.asyncio
|
||||
async def test_write_code_directly():
|
||||
prompt = WRITE_CODE_PROMPT_SAMPLE + '\n' + TASKS_2[0]
|
||||
llm=LLM.DEFAULT_LLM
|
||||
llm = LLM()
|
||||
rsp = await llm.aask(prompt)
|
||||
logger.info(rsp)
|
||||
|
|
|
|||
|
|
@ -21,35 +21,35 @@ def test_ltm_search():
|
|||
|
||||
idea = 'Write a cli snake game'
|
||||
message = Message(role='BOSS', content=idea, cause_by=BossRequirement)
|
||||
news = ltm.remember([message])
|
||||
news = ltm.find_news([message])
|
||||
assert len(news) == 1
|
||||
ltm.add(message)
|
||||
|
||||
sim_idea = 'Write a game of cli snake'
|
||||
sim_message = Message(role='BOSS', content=sim_idea, cause_by=BossRequirement)
|
||||
news = ltm.remember([sim_message])
|
||||
news = ltm.find_news([sim_message])
|
||||
assert len(news) == 0
|
||||
ltm.add(sim_message)
|
||||
|
||||
new_idea = 'Write a 2048 web game'
|
||||
new_message = Message(role='BOSS', content=new_idea, cause_by=BossRequirement)
|
||||
news = ltm.remember([new_message])
|
||||
news = ltm.find_news([new_message])
|
||||
assert len(news) == 1
|
||||
ltm.add(new_message)
|
||||
|
||||
# restore from local index
|
||||
ltm_new = LongTermMemory()
|
||||
ltm_new.recover_memory(role_id, rc)
|
||||
news = ltm_new.remember([message])
|
||||
news = ltm_new.find_news([message])
|
||||
assert len(news) == 0
|
||||
|
||||
ltm_new.recover_memory(role_id, rc)
|
||||
news = ltm_new.remember([sim_message])
|
||||
news = ltm_new.find_news([sim_message])
|
||||
assert len(news) == 0
|
||||
|
||||
new_idea = 'Write a Battle City'
|
||||
new_message = Message(role='BOSS', content=new_idea, cause_by=BossRequirement)
|
||||
news = ltm_new.remember([new_message])
|
||||
news = ltm_new.find_news([new_message])
|
||||
assert len(news) == 1
|
||||
|
||||
ltm_new.clear()
|
||||
|
|
|
|||
4
tests/metagpt/provider/test_xinghuo_api.py
Normal file
4
tests/metagpt/provider/test_xinghuo_api.py
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
from metagpt.provider.spark_api import SparkAPI
|
||||
def test_message():
|
||||
llm=SparkAPI()
|
||||
llm.ask('只回答"收到了"这三个字。')
|
||||
|
|
@ -16,7 +16,7 @@ DETAIL_REQUIREMENT = """需求:开发一个基于LLM(大语言模型)与
|
|||
3. 私有知识库支持pdf、word、txt等各种文件格式上传,上传后可以在服务端解析为文本,存储ES
|
||||
|
||||
资源:
|
||||
1. 大语言模型已经有前置的抽象、部署,可以通过 `import metagpt.llm as LLM`,再使用`LLM().ask(prompt)`直接调用
|
||||
1. 大语言模型已经有前置的抽象、部署,可以通过 `from metagpt.llm import LLM`,再使用`LLM().ask(prompt)`直接调用
|
||||
2. Elastic已有[部署](http://192.168.50.82:9200/),代码可以直接使用这个部署"""
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
import pytest
|
||||
|
||||
import metagpt.llm as LLM
|
||||
from metagpt.llm import LLM
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
|
|
|
|||
42
tests/metagpt/tools/test_moderation.py
Normal file
42
tests/metagpt/tools/test_moderation.py
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
@Time : 2023/9/26 14:46
|
||||
@Author : zhanglei
|
||||
@File : test_translate.py
|
||||
"""
|
||||
|
||||
import pytest
|
||||
|
||||
from metagpt.tools.moderation import Moderation
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("content",),
|
||||
[
|
||||
[
|
||||
["I will kill you", "The weather is really nice today", "I want to hit you"],
|
||||
]
|
||||
],
|
||||
)
|
||||
def test_moderation(content):
|
||||
moderation = Moderation()
|
||||
results = moderation.moderation(content=content)
|
||||
assert isinstance(results, list)
|
||||
assert len(results) == len(content)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.parametrize(
|
||||
("content",),
|
||||
[
|
||||
[
|
||||
["I will kill you", "The weather is really nice today", "I want to hit you"],
|
||||
]
|
||||
],
|
||||
)
|
||||
async def test_amoderation(content):
|
||||
moderation = Moderation()
|
||||
results = await moderation.amoderation(content=content)
|
||||
assert isinstance(results, list)
|
||||
assert len(results) == len(content)
|
||||
0
webui.py
0
webui.py
Loading…
Add table
Add a link
Reference in a new issue