按照要求修改

This commit is contained in:
zhouzinimg 2023-10-16 22:53:28 +08:00
parent e2af76fb08
commit f3c7da32a0
41 changed files with 342 additions and 944 deletions

View file

@ -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"

View file

@ -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

View file

@ -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)

View file

@ -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 .
```
## 配置

View file

@ -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"

View file

@ -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'))

View file

@ -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 = ""

View file

@ -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

View file

@ -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")

View file

@ -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

View file

@ -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] = {}

View file

@ -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",

View file

@ -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:]

View file

@ -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:

View file

@ -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 []

View file

@ -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

View file

@ -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})

View file

@ -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, # 取值为[16],默认为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

View file

@ -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}

View file

@ -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):

File diff suppressed because one or more lines are too long

View file

@ -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

View file

@ -1,3 +0,0 @@
import pycodestyle as pcs
checker = pcs.StyleGuide()
checker.input_dir('./')

View file

@ -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]]]
'''

View file

@ -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

View file

@ -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))

View file

@ -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)

View file

@ -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)])

View 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"]))

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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()

View file

@ -0,0 +1,4 @@
from metagpt.provider.spark_api import SparkAPI
def test_message():
llm=SparkAPI()
llm.ask('只回答"收到了"这三个字。')

View file

@ -16,7 +16,7 @@ DETAIL_REQUIREMENT = """需求开发一个基于LLM大语言模型
3. 私有知识库支持pdfwordtxt等各种文件格式上传上传后可以在服务端解析为文本存储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/)代码可以直接使用这个部署"""

View file

@ -8,7 +8,7 @@
import pytest
import metagpt.llm as LLM
from metagpt.llm import LLM
@pytest.fixture()

View 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)

View file