This commit is contained in:
bridge
2025-11-22 18:49:15 +08:00
parent 0c0d4f8240
commit 9634ace682
5 changed files with 107 additions and 19 deletions

View File

@@ -5,6 +5,7 @@ NPC AI 的类。
from __future__ import annotations
from abc import ABC, abstractmethod
from typing import TYPE_CHECKING
import asyncio
from src.classes.world import World
from src.classes.event import Event, NULL_EVENT
@@ -35,8 +36,16 @@ class AI(ABC):
"""
results = {}
max_decide_num = CONFIG.ai.max_decide_num
# 使用 asyncio.gather 并行执行多个批次的决策
tasks = []
for i in range(0, len(avatars_to_decide), max_decide_num):
results.update(await self._decide(world, avatars_to_decide[i:i+max_decide_num]))
tasks.append(self._decide(world, avatars_to_decide[i:i+max_decide_num]))
if tasks:
batch_results_list = await asyncio.gather(*tasks)
for batch_result in batch_results_list:
results.update(batch_result)
for avatar, result in list(results.items()):
action_name_params_pairs, avatar_thinking, short_term_objective = result # type: ignore

View File

@@ -1,4 +1,5 @@
import random
import asyncio
from src.classes.calendar import Month, Year, MonthStamp
from src.classes.avatar import Avatar, Gender
@@ -118,9 +119,14 @@ class Simulator:
events = []
for avatar in self.world.avatar_manager.avatars.values():
avatar.update_time_effect()
for avatar in list(self.world.avatar_manager.avatars.values()):
fortune_events = await try_trigger_fortune(avatar)
events.extend(fortune_events)
# 使用 gather 并行触发奇遇
tasks = [try_trigger_fortune(avatar) for avatar in self.world.avatar_manager.avatars.values()]
results = await asyncio.gather(*tasks)
for res in results:
if res:
events.extend(res)
return events
async def _phase_nickname_generation(self):
@@ -129,11 +135,11 @@ class Simulator:
"""
from src.classes.nickname import process_avatar_nickname
events = []
for avatar in list(self.world.avatar_manager.avatars.values()):
event = await process_avatar_nickname(avatar)
if event:
events.append(event)
# 并发执行
tasks = [process_avatar_nickname(avatar) for avatar in self.world.avatar_manager.avatars.values()]
results = await asyncio.gather(*tasks)
events = [e for e in results if e]
return events
async def _phase_long_term_objective_thinking(self):
@@ -141,11 +147,11 @@ class Simulator:
长期目标思考阶段
检查角色是否需要生成/更新长期目标
"""
events = []
for avatar in list(self.world.avatar_manager.avatars.values()):
event = await process_avatar_long_term_objective(avatar)
if event:
events.append(event)
# 并发执行
tasks = [process_avatar_long_term_objective(avatar) for avatar in self.world.avatar_manager.avatars.values()]
results = await asyncio.gather(*tasks)
events = [e for e in results if e]
return events
def _phase_update_celestial_phenomenon(self):

53
src/utils/ai_batch.py Normal file
View File

@@ -0,0 +1,53 @@
"""
通用 AI 任务批处理器。
用于将串行的异步任务收集起来并行执行,优化 LLM 密集型场景的性能。
"""
import asyncio
from typing import Coroutine, Any, List
class AITaskBatch:
"""
AI 任务批处理器。
使用示例:
```python
async with AITaskBatch() as batch:
for item in items:
batch.add(process_item(item))
# with 块结束时,所有任务已并发执行完毕
```
"""
def __init__(self):
self.tasks: List[Coroutine[Any, Any, Any]] = []
def add(self, coro: Coroutine[Any, Any, Any]) -> None:
"""
添加一个协程任务到池中(不立即执行)。
注意:传入的协程应该自行处理结果(如修改对象状态),或者通过外部变量收集结果。
"""
self.tasks.append(coro)
async def run(self) -> List[Any]:
"""
并行执行池中所有任务,并等待全部完成。
返回所有任务的结果列表(顺序与添加顺序一致)。
"""
if not self.tasks:
return []
# 使用 gather 并发执行
results = await asyncio.gather(*self.tasks)
# 清空任务队列
self.tasks = []
return list(results)
async def __aenter__(self) -> "AITaskBatch":
return self
async def __aexit__(self, exc_type, exc_val, exc_tb) -> None:
# 如果 with 块内部发生异常,不执行任务,直接抛出
if exc_type:
return
await self.run()