wd666/agents/base_agent.py
2026-01-07 11:02:05 +08:00

132 lines
4.0 KiB
Python

"""
Agent 基类 - 定义 Agent 的基本行为
"""
from dataclasses import dataclass
from typing import Generator
from agents.agent_profiles import get_agent_profile
@dataclass
class AgentMessage:
"""Agent 发言消息"""
agent_id: str
agent_name: str
emoji: str
content: str
round_num: int
class BaseAgent:
"""Agent 基类"""
def __init__(self, agent_id: str, llm_client):
"""
初始化 Agent
Args:
agent_id: Agent 标识符 (如 'ceo', 'cto')
llm_client: LLM 客户端实例
"""
self.agent_id = agent_id
self.llm_client = llm_client
profile = get_agent_profile(agent_id)
if not profile:
raise ValueError(f"未知的 Agent ID: {agent_id}")
self.name = profile["name"]
self.emoji = profile["emoji"]
self.perspective = profile["perspective"]
self.focus_areas = profile["focus_areas"]
self.system_prompt = profile["system_prompt"]
# 存储对话历史
self.conversation_history = []
def generate_response(
self,
topic: str,
context: str = "",
previous_speeches: list = None,
round_num: int = 1
) -> Generator[str, None, None]:
"""
生成 Agent 的发言(流式输出)
Args:
topic: 讨论议题
context: 背景信息
previous_speeches: 之前其他 Agent 的发言列表
round_num: 当前轮次
Yields:
str: 流式输出的文本片段
"""
# 构建对话 prompt
user_prompt = self._build_user_prompt(topic, context, previous_speeches, round_num)
# 调用 LLM 生成回复
full_response = ""
for chunk in self.llm_client.chat_stream(
system_prompt=self.system_prompt,
user_prompt=user_prompt
):
full_response += chunk
yield chunk
# 保存到历史
self.conversation_history.append({
"round": round_num,
"content": full_response
})
def _build_user_prompt(
self,
topic: str,
context: str,
previous_speeches: list,
round_num: int
) -> str:
"""构建用户 prompt"""
prompt_parts = [f"## 讨论议题\n{topic}"]
if context:
prompt_parts.append(f"\n## 背景信息\n{context}")
if previous_speeches and len(previous_speeches) > 0:
prompt_parts.append("\n## 其他人的观点")
for speech in previous_speeches:
prompt_parts.append(
f"\n**{speech['emoji']} {speech['name']}**:\n{speech['content']}"
)
if round_num == 1:
prompt_parts.append(
f"\n## 你的任务\n"
f"作为 {self.name},请从你的专业视角({self.perspective})对这个议题发表看法。\n"
f"重点关注:{', '.join(self.focus_areas)}\n"
f"请给出 2-3 个核心观点,每个观点用 1-2 句话阐述。保持简洁有力。"
)
else:
prompt_parts.append(
f"\n## 你的任务\n"
f"这是第 {round_num} 轮讨论。请针对其他人的观点进行回应:\n"
f"- 你同意或反对哪些观点?为什么?\n"
f"- 有没有被忽略的重要问题?\n"
f"- 你的立场有没有调整?\n"
f"请保持简洁,聚焦于最重要的 1-2 个点。"
)
return "\n".join(prompt_parts)
def get_summary(self) -> str:
"""获取该 Agent 所有发言的摘要"""
if not self.conversation_history:
return "暂无发言"
return "\n---\n".join([
f"{h['round']} 轮: {h['content']}"
for h in self.conversation_history
])