add action chain

This commit is contained in:
bridge
2025-09-02 00:35:07 +08:00
parent 420a17d471
commit 3047de0367
18 changed files with 370 additions and 150 deletions

View File

@@ -3,25 +3,45 @@ NPC AI的类。
这里指的不是LLM或者Machine Learning而是NPC的决策机制
分为两类规则AI和LLM AI
"""
from __future__ import annotations
from abc import ABC, abstractmethod
from typing import TYPE_CHECKING
from src.classes.world import World
from src.classes.tile import Region
from src.classes.root import corres_essence_type
from src.classes.action import ACTION_SPACE_STR
from src.classes.event import Event, NULL_EVENT
from src.utils.llm import get_ai_prompt_and_call_llm
if TYPE_CHECKING:
from src.classes.avatar import Avatar
class AI(ABC):
"""
AI的基类
"""
def __init__(self, avatar: 'Avatar'):
def __init__(self, avatar: Avatar):
self.avatar = avatar
@abstractmethod
def decide(self, world: World) -> tuple[str, dict]:
def decide(self, world: World) -> tuple[str, dict, Event]:
"""
决定做什么
决定做什么,同时生成对应的事件
"""
# 先决定动作和参数
action_name, action_params = self._decide(world)
# 获取动作对象并生成事件
action = self.avatar.create_action(action_name)
event = action.get_event(**action_params)
return action_name, action_params, event
@abstractmethod
def _decide(self, world: World) -> tuple[str, dict]:
"""
决策逻辑:决定执行什么动作和参数
由子类实现具体的决策逻辑
"""
pass
@@ -29,9 +49,9 @@ class RuleAI(AI):
"""
规则AI
"""
def decide(self, world: World) -> tuple[str, dict]:
def _decide(self, world: World) -> tuple[str, dict]:
"""
定做什么
策逻辑:决定执行什么动作和参数
先做一个简单的:
1. 找到自己灵根对应的最好的区域
2. 检测自己是否在最好的区域
@@ -69,17 +89,19 @@ class LLMAI(AI):
不能每个单步step都调用一次LLM来决定下一步做什么。这样子一方面动作一直乱变另一方面也太费token了。
decide的作用是拉取既有的动作链如果没有了就call_llm再根据动作链决定动作以及动作之间的衔接。
"""
def decide(self, world: World) -> tuple[str, dict]:
def _decide(self, world: World) -> tuple[str, dict]:
"""
定做什么
策逻辑通过LLM决定执行什么动作和参数
"""
action_space_str = ACTION_SPACE_STR
avatar_infos_str = str(self.avatar)
regions_str = "\n".join([str(region) for region in world.map.regions.values()])
avatar_persona = self.avatar.persona.prompt
dict_info = {
"action_space": action_space_str,
"avatar_infos": avatar_infos_str,
"regions": regions_str
"regions": regions_str,
"avatar_persona": avatar_persona
}
res = get_ai_prompt_and_call_llm(dict_info)
action_name, action_params = res["action_name"], res["action_params"]