项ç®ä¿¡æ¯
- 项ç®å: MetaGPT (FoundationAgents/MetaGPT)
- GitHub: github.com/geekan/MetaâŠ
- Star: 67,502 â
- License: MIT
- è¯èš: Python
䞺ä»ä¹çè¿äžªé¡¹ç®ïŒ
æè¿åšç ç©¶å€ Agent ç³»ç»ç讟计ïŒåç° MetaGPT ç Slogan ç¹å«æææââ"Enable GPT to work in a software company"ïŒè®© GPT åçå®èœ¯ä»¶å ¬åžäžæ ·åäœïŒ
æ žå¿ç念 "Code = SOP(Team)" ä¹åŸæå¯åæ§ïŒæçå®èœ¯ä»¶å ¬åžçæ åäœäžçšåºïŒSOPïŒåºåäžæ¥ïŒåºçšå° LLM Agent å¢éäžã
æ žå¿ç念ïŒCode = SOP(Team)
ç°å®èœ¯ä»¶å
¬åž MetaGPT
âââââââââââââââââââââââââââââââââââââââââ
èæ¿ïŒäžå¥è¯éæ±ïŒ â çšæ·èŸå
¥
产åç»ç â ProductManager
æ¶æåž â Architect
å·¥çšåž â Engineer
æµè¯å·¥çšåž â QaEngineer
SOP æµçš â SOP 驱åš
MetaGPT ææŽäžªèœ¯ä»¶åŒåæµçšåäºäžäžªæœè±¡ïŒèŸå ¥æ¯äžå¥è¯éæ±ïŒèŸåºæ¯å®æŽç代ç ãè§èææ¡£ãæµè¯çšäŸçãèå éšè¿äœåæš¡æäºäžå®¶èœ¯ä»¶å ¬åžç SOPã
æŽäœæ¶æ
ââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â Team (å
¬åž) â
â â
â âââââââââââââââ âââââââââââââââ âââââââââââââââ â
â â 产åç»ç â â æ¶æåž â â å·¥çšåž â â
â â ProductMgr â â Architect â â Engineer â â
â â Alice â â Brian â â Cathy â â
â ââââââââ¬âââââââ ââââââââ¬âââââââ ââââââââ¬âââââââ â
â â â â â
â ââââââââââââââââââŽâŽââââââââââââââââââ â
â ⌠â
â âââââââââââââââââââââââââ â
â â Environment â â
â â âââââââââââââââââââ â â
â â â¢ æ¶æ¯æ»çº¿ïŒå¹¿æïŒ â â
â â ⢠è§è²æ³šå衚 â â
â â ⢠åå²è®°åœ â â
â âââââââââââââââââââââââââ â
â â â
â âââââââââââââŽââââââââââââ â
â â CostManager â â
â â é¢ç®æ§å¶ & 计莹 â â
â âââââââââââââââââââââââââ â
ââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
æ žå¿æä»¶ç»æ
| æä»¶ | äœçš |
|---|---|
software_company.py | å
¬åžå
¥å£ïŒhire() æèè§è²ãinvest() 讟眮é¢ç®ãrun() è¿è¡ |
team.py | Team ç±»ïŒç®¡çå€äžª Role åå ±äº«ç Environment |
environment/base_env.py | ç¯å¢ç±»ïŒæ¿èœœè§è²ãæ¶æ¯å¹¿æãåŒæ¥æ§è¡ |
roles/role.py | Role åºç±»ïŒæ žå¿ç think/act/observe åŸªç¯ |
roles/product_manager.py | 产åç»çïŒå PRDãç«ååæ |
roles/architect.py | æ¶æåžïŒç³»ç»è®Ÿè®¡ |
roles/engineer.py | å·¥çšåžïŒå代ç |
actions/ | åç§å¯æ§è¡çåšäœ |
utils/cost_manager.py | é¢ç®æ§å¶å莹çšè®¡ç® |
Think / Act / Observe 埪ç¯è¯Šè§£
è¿æ¯ MetaGPT ææ žå¿çè¿è¡æºå¶ïŒæ¯äžª Role éœæ¯æç §è¿äžªåŸªç¯è¿äœçïŒ
âââââââââââââââââââââââââââââââââââââââââââ
â Role è¿è¡åŸªç¯ â
â â
â ââââââââ observe âââââââââ â
â â â â
â â 1. 仿¶æ¯çŒå²åº â â
â â è¯»åæ°æ¶æ¯ â â
â â â â
â â 2. æ ¹æ® watch è¿æ»€ â â
â â åªä¿çå
³å¿çæ¶æ¯ â â
â â â â
â â 3. åå
¥èªèº«è®°å¿ â â
â âââââ¬ââââââââââââââââââââ â
â â ææ°æ¶æ¯ â
â ⌠â
â ââââââââ think ââââââââââ â
â â â â
â â 1. æ ¹æ® react_mode â â
â â å³å®äžäžæ¥ç¶æ â â
â â â â
â â 2. éæ©èŠæ§è¡ç â â
â â Action â â
â â â â
â â 3. 讟眮 state â â
â âââââ¬ââââââââââââââââââââ â
â â ç¡®å®èŠæ§è¡ â
â ⌠â
â ââââââââ act âââââââââââ â
â â â â
â â 1. è°çš Action.run() â â
â â æ§è¡å
·äœåšäœ â â
â â â â
â â 2. çæå倿¶æ¯ â â
â â â â
â â 3. ååžå°ç¯å¢ â â
â â 4. åå
¥è®°å¿ â â
â âââââ¬ââââââââââââââââââââ â
â â â
â ââââââââââââ â
â â â
â 埪ç¯çŽå° state=-1 â
âââââââââââââââââââââââââââââââââââââââââââ
1. Observe â è§å¯ïŒæç¥ç¯å¢ïŒ
async def _observe(self) -> int:
"""仿¶æ¯çŒå²åºè¯»åæ°æ¶æ¯å¹¶è¿æ»€"""
# 1. 仿¶æ¯çŒå²åº pop æææ¶æ¯
news = self.rc.msg_buffer.pop_all()
# 2. æ ¹æ® watch åè¡šè¿æ»€
# watch è®°åœäºè¿äžª Role å
³å¿åªäº Action 产ççæ¶æ¯
self.rc.news = [
n for n in news
if (n.cause_by in self.rc.watch or self.name in n.send_to)
and n not in old_messages
]
# 3. åå
¥èªèº«è®°å¿
self.rc.memory.add_batch(self.rc.news)
return len(self.rc.news) # è¿åæ°æ¶æ¯æ°é
å
³é®æŠå¿µ watchïŒæ¯äžª Role æäžäžª watch éåïŒé颿¯èŠçå¬çæ¶æ¯ç±»åãæ¯åŠäº§åç»çäŒçå¬ UserRequirementïŒçšæ·éæ±ïŒå PrepareDocumentsïŒåå€ææ¡£ïŒè¿äž€äžª Action 产ççæ¶æ¯ã
2. Think â æèïŒå³å®è¡åšïŒ
async def _think(self) -> bool:
"""å³å®äžäžæ¥æ§è¡åªäžª Action"""
# æ
åµ1: åªæäžäžª ActionïŒçŽæ¥æ§è¡
if len(self.actions) == 1:
self._set_state(0)
return True
# æ
åµ2: BY_ORDER æš¡åŒïŒæé¡ºåºæ§è¡
if self.rc.react_mode == RoleReactMode.BY_ORDER:
self._set_state(self.rc.state + 1)
return self.rc.state < len(self.actions)
# æ
åµ3: REACT æš¡åŒïŒçš LLM å³å®
prompt = self._get_prefix() # è·åè§è²è®Ÿå®
prompt += STATE_TEMPLATE.format(
history=self.rc.history, # åå²è®°å¿
states="\n".join(self.states), # å¯éç¶æå衚
previous_state=self.rc.state, # äžäžäžªç¶æ
)
# LLM è¿åäžäžäžªç¶æçŒå·
next_state = await self.llm.aask(prompt)
next_state = extract_state_value_from_output(next_state)
# -1 è¡šç€ºç»æ
if next_state == -1:
logger.info("ç»æåšäœ")
self._set_state(next_state)
return True
äžç§ react_modeïŒ
| æš¡åŒ | è¡äžº | éçšåºæ¯ |
|---|---|---|
REACT | LLM åšæå³å®äžäžæ¥ | çµæŽ»ãéèŠæšççä»»å¡ |
BY_ORDER | æ actions åè¡šé¡ºåºæ§è¡ | åºå®æµçšãSOP 驱åšçä»»å¡ |
PLAN_AND_ACT | å 计åïŒåæè®¡åæ§è¡ | 倿任å¡ãéèŠè§å |
3. Act â è¡åšïŒæ§è¡åšäœïŒ
async def _act(self) -> Message:
"""æ§è¡åœå state 对åºç Action"""
# 1. è®°åœæ¥å¿
logger.info(f"{self._setting}: to do {self.rc.todo}")
# 2. è°çš Action.run() æ§è¡
response = await self.rc.todo.run(self.rc.history)
# 3. å°è£
æ AIMessage
msg = AIMessage(
content=response.content,
cause_by=self.rc.todo, # æ è®°ç±åªäžª Action 产ç
sent_from=self, # æ è®°åéè
)
# 4. åå
¥è®°å¿
self.rc.memory.add(msg)
return msg
è§è²éŽéä¿¡æºå¶
MetaGPT çè§è²éŽéä¿¡éçšååž-è®¢é æš¡åŒïŒæ žå¿æ¯æ¶æ¯è·¯ç±ïŒ
æ¶æ¯ååžæµçš
Role A Environment Role B
â â â
â publish_message(msg) â â
â âââââââââââââââââââââââââââââââââââââºâ â
â â â
â âââââââââââââââââââââââââââââââââââââââââââ â
â â éåææè§è²çå°å衚 (member_addrs) â â
â â æ£æ¥ msg.send_to æ¯åŠå¹é
â â
â âââââââââââââââââââââââââââââââââââââââââââ â
â â â
â â put_message(msg) â
â âââââââââââââââââââââââââââââââââââºâ
â â â
å ·äœä»£ç
# Role ååžæ¶æ¯
def publish_message(self, msg):
# åŠææ²¡ææå®ç¯å¢ïŒæ¶æ¯æ æ³åé
if not self.rc.env:
return
# åŠææå®äºç¯å¢ïŒå§æç»ç¯å¢ååž
self.rc.env.publish_message(msg)
# Environment å¹¿ææ¶æ¯
def publish_message(self, message: Message, peekable: bool = True):
for role, addrs in self.member_addrs.items():
# æ£æ¥æ¶æ¯ç send_to æ¯åŠå
å«è¿äžªè§è²
if is_send_to(message, addrs):
role.put_message(message) # æŸå
¥è§è²çç§ææ¶æ¯çŒå²åº
æ¶æ¯çç»æ
class Message(BaseModel):
content: str # æ¶æ¯å
容
send_to: set[str] # åéç»è°ïŒè§è²åæ "all"ïŒ
cause_by: str # ç±åªäžª Action 产ç
sent_from: str # åéè
æ¯è°
é信瀺äŸ
å讟产åç»çïŒAliceïŒåå®äº PRDïŒèŠåè¯æ¶æåžïŒBrianïŒïŒ
Alice:
msg = Message(
content="PRD 已宿ïŒå
嫿žžæéæ±ææ¡£",
send_to={"Brian"}, # æå®åéç»æ¶æåž
cause_by="WritePRD",
sent_from="Alice"
)
self.publish_message(msg)
Brian (åšäžäžæ¬¡åŸªç¯äž):
news = self._observe() # åç°ææ°æ¶æ¯æ¥èª Alice
self._think() # å³å®èŠå€çè¿äžªæ¶æ¯
self._act() # åŒå§åæ¶æè®Ÿè®¡
é¢ç®æ§å¶æºå¶
MetaGPT çš CostManager æ¥æ§å¶ææ¬ïŒé²æ¢ LLM è°çšå€±æ§ã
å·¥äœæµçš
çšæ·è°çš
â
â invest(3.0) 讟眮é¢ç® $3
âŒ
Team.invest()
â
â cost_manager.max_budget = 3.0
âŒ
ââââââââââââââââââââ
â CostManager â
â max_budget=$3 â
â total_cost=$0 â
ââââââââââ¬ââââââââââ
â
â æ¯æ¬¡ LLM è°çš
âŒ
ââââââââââââââââââââ
â LLM API è¿å â
â usage ä¿¡æ¯ â
ââââââââââ¬ââââââââââ
â
âŒ
ââââââââââââââââââââ
â cost_manager. â
â update_cost() â
â â
â total_cost += â
â æ°å¢èŽ¹çš â
ââââââââââ¬ââââââââââ
â
âŒ
ââââââââââââââââââââ
â Team._check_ â
â balance() â
â â
â if total_cost >= â
â max_budget: â
â raise NoMoneyException â
ââââââââââââââââââââ
莹çšè®¡ç®ä»£ç
class CostManager(BaseModel):
max_budget: float = 10.0 # æå€§é¢ç®
total_cost: float = 0 # åœå环计莹çš
def update_cost(self, prompt_tokens, completion_tokens, model):
"""æ¯æ¬¡ LLM è°çšåæŽæ°è޹çš"""
# ä»é¢å®ä¹ç TOKEN_COSTS 衚æ¥è޹ç
cost = (
prompt_tokens * self.token_costs[model]["prompt"]
+ completion_tokens * self.token_costs[model]["completion"]
) / 1000 # é€ä»¥ 1000 æ¯å äžºèŽ¹çæ¯ per 1K tokens
self.total_cost += cost
logger.info(f"Total: ${self.total_cost:.3f} / Max: ${self.max_budget:.3f}")
é¢ç®æ£æ¥
class Team:
def _check_balance(self):
"""æ¯æ¬¡è¿è¡åŸªç¯åæ£æ¥"""
if self.cost_manager.total_cost >= self.cost_manager.max_budget:
raise NoMoneyException(...)
async def run(self, n_round=3, idea=""):
while n_round > 0:
if self.env.is_idle:
break
n_round -= 1
self._check_balance() # â æ¯æ¬¡åŸªç¯æ£æ¥é¢ç®
await self.env.run()
Role ç¶ææºè¯Šè§£
æ¯äžª Role æ states å衚å state 屿§ïŒè¡šç€ºåœååšæ§è¡æµçšäžçåªäžªé¶æ®µã
ç¶æçå®ä¹
class Role:
states: list[str] = [] # å¯éç¶æå衚
rc.state: int = -1 # åœåç¶æçŽ¢åŒïŒ-1 衚瀺空é²/ç»æ
讟眮 Action æ¶äŒèªåšçæç¶æïŒ
def set_actions(self, actions: list[Action]):
for action in actions:
self.actions.append(action)
self.states.append(f"{len(self.actions) - 1}. {action}")
# äŸåŠïŒstates = ["0. WritePRD", "1. WriteSpec", "2. Review"]
ç¶æçäœçš
1. 远螪è¿åºŠ â ç¥éæ§è¡å°åªäžæ¥äº
2. å³å®äžäžæ¥ â æ ¹æ®åœåç¶æéæ©äžäžäžª Action
# ç¶æèœ¬æ¢ç€ºäŸ
State 0: WritePRD (åéæ±ææ¡£)
â 产åç»ç宿
State 1: DesignAPI (讟计 API)
â æ¶æåžå®æ
State 2: WriteCode (å代ç )
â å·¥çšåžå®æ
State -1: ç»æ
3. æ¢å€æ§è¡ â åŠæäžéŽåºéïŒå¯ä»¥ä»æäžªç¶ææ¢å€
# æ¢å€æ¶ä»ä¹åçç¶æç»§ç»
if self.recovered and self.rc.state >= 0:
self._set_state(self.rc.state) # 仿¢å€çç¶æç»§ç»
äžå react_mode çç¶æè¡äžº
| react_mode | ç¶æè¡äžº |
|---|---|
REACT | LLM æ ¹æ® history ååœå state åšæå³å®äžäžäžª state |
BY_ORDER | æ¯æ¬¡ act å state +1ïŒæé¡ºåºæ§è¡ |
PLAN_AND_ACT | å çš Planner çæè®¡åïŒè®¡åäžçæ¯äžª task 对åºäžäžª state |
ææ°åšæå项ç®çå ³ç³»
MetaGPT å¢éåš 2025 幎ååžäºäžå°æ°äžè¥¿ïŒ
1. MGX â AI Agent åŒåå¢é产å
æ¶éŽ: 2025 幎 2 ææ£åŒååž
éŸæ¥: mgx.dev/
MGX æ¯åºäº MetaGPT æ¡æ¶çåäžå产åïŒå®äœäžº"äžçéŠäžª AI Agent åŒåå¢é"ãçšæ·èŸå ¥äžäžªæ³æ³ïŒMGX äŒèªåšç»å»ºäžäžªèæ AI å ¬åžæ¥å®ææŽäžªé¡¹ç®ã
2. AFlow â ICLR 2025 Oral 论æ
æ¶éŽ: 2025 幎 1 æïŒICLR 2025 OralïŒTop 1.8%ïŒ
论æ: openreview.net/forum?id=z5âŠ
AFlow æ¯äžäžªèªåšåçæ Agent å·¥äœæµçæ¡æ¶ãå¯ä»¥ç解䞺 MetaGPT çäžäžä»£ææ¯ââäžåªæ¯çš SOP é©±åš AgentïŒèæ¯èªåšçææåéç SOPã
3. SPO å AOT 论æ
æ¶éŽ: 2025 幎 2 æ
代ç : å·²åš examples ç®åœ
SPO å AOT æ¯äž€ç¯å ³äº Agent äŒååæšççæ°è®ºæïŒè¿äžæ¥å®åäº MetaGPT çç论åºç¡ã
æ»ç»
MetaGPT å±ç€ºäºäžç§åŸæææçå€ Agent åäœèåŒïŒæçå®å ¬åžç SOP æµçšè¿ç§»å° AI Agent å¢éäžã
æ žå¿è®Ÿè®¡æš¡åŒ
| æš¡åŒ | 诎æ |
|---|---|
| Think-Act-Observe åŸªç¯ | Agent çåºæ¬è¿äœæºå¶ |
| ååž-è®¢é æ¶æ¯ | è§£èŠçåŒæ¥éä¿¡ |
| ç¶ææºé©±åš | éè¿ state æ§å¶æµçš |
| é¢ç®ä¿æ€ | 鲿¢ LLM 莹çšå€±æ§ |
| è§è²åå·¥ | äžåè§è²æäžåç®æ ã纊æãAction |
æ¶æäº®ç¹
- Environment äœäžºæ¶æ¯æ»çº¿ â ææè§è²éè¿ç¯å¢å¹¿ææ¶æ¯
- Role ç§ææ¶æ¯çŒå²åº â
msg_bufferå®ç°åŒæ¥æ¶æ¯æ¥æ¶ - å€å±è®°å¿ â
memoryïŒé¿æïŒãworking_memoryïŒå·¥äœïŒãmsg_bufferïŒçŒå²ïŒ - 坿æç react_mode â æ¯æå€ç§æè-è¡åšçç¥
å¯¹å€ Agent åŒåçå¯ç€º
åŠææ³åŒå类䌌"AI å ¬åž"çå€ Agent ç³»ç»ïŒMetaGPT ç讟计åŒåŸåèïŒ
- çš SOP åºåæµçšæ¯å®å šåšæåäœæŽå¯æ§
- æ¶æ¯è·¯ç±åç¶æè¿œèžªæ¯åäœçå ³é®
- äžå®èŠæé¢ç®æ§å¶é²æ¢å€±æ§
项ç®éŸæ¥: github.com/geekan/MetaâŠ
åèéŸæ¥:
- AFlow 论æ: openreview.net/forum?id=z5âŠ
- MGX 产å: mgx.dev/
ç³»ååŸæ:
- #002: mem0 â è®°å¿å¢åŒºç AI Agent
- #001: browser-use â 让 AI Agent æäœæµè§åš
ãCode = SOP(Team)ãâ MetaGPT 让 LLM Agent åäœæäºäžç§æ°çå¯èœæ§ã