Skip to content

Commit

Permalink
minion
Browse files Browse the repository at this point in the history
  • Loading branch information
femto committed Aug 7, 2024
1 parent f6cbf06 commit 0ef45e1
Show file tree
Hide file tree
Showing 5 changed files with 855 additions and 3 deletions.
50 changes: 50 additions & 0 deletions examples/smart_minion/brain.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
@Time : 2023/9/13 12:29
@Author : femto Zheng
@File : brain.py
"""
import asyncio

from metagpt.minion.brain import Brain


async def smart_brain():
brain = Brain()

obs, score, *_ = await brain.step(query="what's the solution 234*568")
# obs, score,*_ = await brain.step(query="what's the solution for game of 24 for 4 3 9 8")
# obs, score,*_ = await brain.step(query="what's the solution for game of 24 for 2 5 11 8")
# obs, score,*_ = await brain.step(query="solve x=1/(1-beta^2*x) where beta=0.85")

# obs, score, *_ = await brain.step(
# query="Write a 500000 characters novel named 'Reborn in Skyrim'. "
# "Fill the empty nodes with your own ideas. Be creative! Use your own words!"
# "I will tip you $100,000 if you write a good novel."
# "since the novel is very long, you may need to divide into subtasks"
# )
# obs, score, *_ = await brain.step(query=
# """
# 2024阿里巴巴全球数学竞赛
#
# 问题1
#
# 几位同学假期组成一个小组去某市旅游.该市有6座塔,它们的位置分别为A,B,C,D,B,F。
#
# 同学们自由行动一段时间后,每位同学都发现,自己在所在的位置只能看到位于A,B,C,D 处的四座塔,而看不到位于E 和F的塔。已知
#
# (1)同学们的位置和塔的位置均视为同一平面上的点,且这些点彼此不重合:
#
# (2) A,B,C,D,E,F中任意3点不共线:
#
# (3) 看不到塔的唯一可能就是视线被其它的塔所阻挡,例如,如果某位同学所在的位置P 和A,B 共线,且A 在线段PB上,那么该同学就看不到位于B 处的塔。
#
# 请问,这个旅游小组最多可能有多少名同学?
#
# (A)3 (B) 4 (C)6 (D) 12
# """)
print(obs)


asyncio.run(smart_brain())
167 changes: 167 additions & 0 deletions metagpt/minion/brain.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
@Time : 2023/9/13 12:29
@Author : femto Zheng
@File : brain.py
"""

import uuid
from datetime import datetime
from typing import Any

from jinja2 import Template
from mem0 import Memory
from pydantic import BaseModel, Field

from metagpt.actions.action_node import ActionNode
from metagpt.llm import LLM
from metagpt.minion.minion import SmartMinion


class Input(BaseModel):
long_context: str = Field(default="")
short_context: str = "" # abstract/summarized version
query: str = ""
query_type: str = "question" # question or requirement
guidance: str = ""
constraint: str = "" # question or requirement
instruction: str = "" # instruction for each step, different step can have different instruction
complexity: str = "" # low,medium,high
query_range: str = "" # short range query, or multiple step range like writing a very long novel
# plan:str = "" # current plan
score_func: Any = None

answer: str = ""

# metadata
query_time: Any = None
processed_minions: int = 0 # how many minions processed this
metadata: dict = {}
info: dict = {}

run_id: str = Field(default_factory=uuid.uuid4)

@property
def context(self):
return self.long_context

@context.setter
def context(self, context):
self.long_context = context


class Mind(BaseModel):
id: str = "UnnamedMind"
description: str = ""
brain: Any = None # Brain

async def step(self, input, run_id=None):
input.run_id = run_id or uuid.uuid4()
input.short_context = input.context # first set digested context same as context

smart = SmartMinion(input, brain=self.brain)
answer, score = await smart.execute()
return answer, score, False, False, {} # terminated: false, truncated:false, info:{}


class Brain:
def __init__(self, id=None, memory=None, llm=LLM()):
self.id = id or uuid.uuid4()
self.minds = {}
self.add_mind(
Mind(
id="left_mind",
description="""
I'm the left mind, adept at logical reasoning and analytical thinking. I excel in tasks involving mathematics, language, and detailed analysis. My capabilities include:
Solving complex mathematical problems
Understanding and processing language with precision
Performing logical reasoning and critical thinking
Analyzing and synthesizing information systematically
Engaging in tasks that require attention to detail and structure""",
)
)
self.add_mind(
Mind(
id="right_mind",
description="""
I'm the right mind, flourishing in creative and artistic tasks. I thrive in activities that involve imagination, intuition, and holistic thinking. My capabilities include:
Creating and appreciating art and music
Engaging in creative problem-solving and innovation
Understanding and interpreting emotions and expressions
Recognizing patterns and spatial relationships
Thinking in a non-linear and abstract manner""",
)
)

self.add_mind(
Mind(
id="hippocampus_mind",
description="""I'm the hippocampus mind, specializing in memory formation, organization, and retrieval. I play a crucial role in both the storage of new memories and the recall of past experiences. My capabilities include:
Forming and consolidating new memories
Organizing and structuring information for easy retrieval
Facilitating the recall of past experiences and learned information
Connecting new information with existing knowledge
Supporting navigation and spatial memory""",
)
)

# self.add_mind(Mind(id="hypothalamus", description="..."))
if not memory:
config = {"collection_name": f"brain-mem-{self.id}"}

memory = Memory.from_config(config)
self.mem = memory
self.llm = llm

def add_mind(self, mind):
self.minds[mind.id] = mind
mind.brain = self

async def step(self, input=None, query="", query_type="", **kwargs):
run_id = uuid.uuid4()

input = input or Input(query=query, query_type=query_type, query_time=datetime.utcnow(), **kwargs)

mind_id = await self.choose_mind(input)
mind = self.minds[mind_id]
return await mind.step(input, run_id)

async def choose_mind(self, input):
mind_template = Template(
"""
I have minds:
{% for mind in minds %}
1. **ID:** {{ mind.id }}
**Description:**
"{{ mind.description }}"
{% endfor %}
According to the current user's query,
which is of query type: {{ input.query_type }},
and user's query: {{ input.query }}
help me choose the right mind to process the query.
return the id of the mind, please note you *MUST* return exactly case same as I provided here, do not uppercase or downcase yourself.
"""
)

# Create the filled template
filled_template = mind_template.render(minds=self.minds.values(), input=input)

node = ActionNode(
key="mind",
expected_type=str,
instruction="mind id",
example="",
)
node = await node.fill(
context=filled_template,
llm=self.llm,
)

return node.instruct_content.mind


Mind.update_forward_refs()
Loading

0 comments on commit 0ef45e1

Please sign in to comment.