mirror of
https://github.com/FoundationAgents/MetaGPT.git
synced 2026-06-08 15:05:17 +02:00
Merge branch 'main'
This commit is contained in:
commit
c18f384356
17 changed files with 373 additions and 20 deletions
|
|
@ -15,6 +15,19 @@ RPM: 10
|
|||
#### if Anthropic
|
||||
#Anthropic_API_KEY: "YOUR_API_KEY"
|
||||
|
||||
#### if xinghuo
|
||||
#xinghuo_appid : "APPID"
|
||||
#xinghuo_api_secret : "APISecret"
|
||||
#xinghuo_api_key : "APIKey"
|
||||
|
||||
#domain : "generalv2"
|
||||
|
||||
#Spark_url : "ws://spark-api.xf-yun.com/v2.1/chat"
|
||||
|
||||
#### 如果不能使用api
|
||||
|
||||
#no_api_mode :"true"
|
||||
|
||||
#### if AZURE, check https://github.com/openai/openai-cookbook/blob/main/examples/azure/chat.ipynb
|
||||
#### You can use ENGINE or DEPLOYMENT mode
|
||||
#OPENAI_API_TYPE: "azure"
|
||||
|
|
|
|||
135
debating_tournament.py
Normal file
135
debating_tournament.py
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
#!/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)
|
||||
|
|
@ -7,12 +7,11 @@
|
|||
"""
|
||||
import asyncio
|
||||
|
||||
from metagpt.llm import LLM, Claude
|
||||
from metagpt.logs import logger
|
||||
import metagpt.llm as LLM
|
||||
|
||||
|
||||
async def main():
|
||||
llm = LLM()
|
||||
llm=LLM.DEFAULT_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()
|
||||
llm=LLM.DEFAULT_LLM
|
||||
self.llm = llm
|
||||
self.context = context
|
||||
self.prefix = ""
|
||||
|
|
|
|||
|
|
@ -45,8 +45,18 @@ 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")
|
||||
|
|
|
|||
|
|
@ -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 = LLM()
|
||||
CLAUDE_LLM = Claude()
|
||||
DEFAULT_LLM = Spark()
|
||||
|
||||
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
|
||||
from metagpt.llm import LLM
|
||||
import metagpt.llm as 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()
|
||||
self._llm=LLM.DEFAULT_LLM
|
||||
self._store = ChromaStore('skill_manager')
|
||||
self._skills: dict[str: Skill] = {}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,13 +5,13 @@
|
|||
@Author : alexanderwu
|
||||
@File : manager.py
|
||||
"""
|
||||
from metagpt.llm import LLM
|
||||
import metagpt.llm as LLM
|
||||
from metagpt.logs import logger
|
||||
from metagpt.schema import Message
|
||||
|
||||
|
||||
class Manager:
|
||||
def __init__(self, llm: LLM = LLM()):
|
||||
def __init__(self, llm: llm=LLM.DEFAULT_LLM):
|
||||
self.llm = llm # Large Language Model
|
||||
self.role_directions = {
|
||||
"BOSS": "Product Manager",
|
||||
|
|
|
|||
|
|
@ -9,10 +9,10 @@
|
|||
```python
|
||||
from typing import Optional
|
||||
from abc import ABC
|
||||
from metagpt.llm import LLM # Large language model, similar to GPT
|
||||
n
|
||||
import metagpt.llm as LLM # 大语言模型,类似GPT
|
||||
|
||||
class Action(ABC):
|
||||
def __init__(self, name='', context=None, llm: LLM = LLM()):
|
||||
def __init__(self, name='', context=None, llm: llm=LLM.DEFAULT_LLM):
|
||||
self.name = name
|
||||
self.llm = llm
|
||||
self.context = context
|
||||
|
|
|
|||
138
metagpt/provider/SparkApi.py
Normal file
138
metagpt/provider/SparkApi.py
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
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})
|
||||
|
||||
|
||||
58
metagpt/provider/spark_api.py
Normal file
58
metagpt/provider/spark_api.py
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
@Time : 2023/7/21 11:15
|
||||
@Author : Leo Xiao
|
||||
@File : anthropic_api.py
|
||||
"""
|
||||
|
||||
from typing import Optional
|
||||
from metagpt.provider import SparkApi
|
||||
|
||||
from metagpt.config import CONFIG
|
||||
|
||||
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}
|
||||
|
||||
def _assistant_msg(self, msg: str) -> dict[str, str]:
|
||||
return {"role": "assistant", "content": msg}
|
||||
|
||||
def _system_msg(self, msg: str) -> dict[str, str]:
|
||||
return {"role": "system", "content": msg}
|
||||
|
||||
def _system_msgs(self, msgs: list[str]) -> list[dict[str, str]]:
|
||||
return [self._system_msg(msg) for msg in msgs]
|
||||
|
||||
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)]
|
||||
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
|
||||
|
|
@ -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.llm import LLM
|
||||
from metagpt import llm as 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()
|
||||
self._llm=LLM.DEFAULT_LLM
|
||||
self._setting = RoleSetting(name=name, profile=profile, goal=goal, constraints=constraints, desc=desc)
|
||||
self._states = []
|
||||
self._actions = []
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ tqdm==4.64.0
|
|||
# selenium>4
|
||||
# webdriver_manager<3.9
|
||||
anthropic==0.3.6
|
||||
typing-inspect==0.8.0
|
||||
typing-inspect
|
||||
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
|
||||
from metagpt.llm import LLM
|
||||
import metagpt.llm as 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()
|
||||
llm=LLM.DEFAULT_LLM
|
||||
rsp = await llm.aask(prompt)
|
||||
logger.info(rsp)
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ DETAIL_REQUIREMENT = """需求:开发一个基于LLM(大语言模型)与
|
|||
3. 私有知识库支持pdf、word、txt等各种文件格式上传,上传后可以在服务端解析为文本,存储ES
|
||||
|
||||
资源:
|
||||
1. 大语言模型已经有前置的抽象、部署,可以通过 `from metagpt.llm import LLM`,再使用`LLM().ask(prompt)`直接调用
|
||||
1. 大语言模型已经有前置的抽象、部署,可以通过 `import metagpt.llm as LLM`,再使用`LLM().ask(prompt)`直接调用
|
||||
2. Elastic已有[部署](http://192.168.50.82:9200/),代码可以直接使用这个部署"""
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
import pytest
|
||||
|
||||
from metagpt.llm import LLM
|
||||
import metagpt.llm as LLM
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
|
|
|
|||
0
webui.py
Normal file
0
webui.py
Normal file
Loading…
Add table
Add a link
Reference in a new issue