Appearance
第2章:核心引擎实现
2.1 Agent主循环
Agent是Nanobot2的核心引擎,负责处理用户请求、生成响应、管理上下文等核心功能。Agent采用思考-行动-观察循环(Thought-Action-Observation Loop)模式,模拟人类的决策过程。
2.1.1 核心实现
python
class Agent:
def __init__(self, provider_manager, session_manager, message_bus):
self.provider_manager = provider_manager
self.session_manager = session_manager
self.message_bus = message_bus
async def process_message(self, user_id: str, channel: str, content: str) -> str:
# 获取或创建会话
session = self.session_manager.get_or_create_session(user_id, channel)
# 添加用户消息到会话
session.add_message("user", content)
# 构建上下文
context = self._build_context(session)
# 调用LLM生成响应
response = await self._call_llm(context)
# 添加助手响应到会话
session.add_message("assistant", response)
# 发布助手响应事件
await self.message_bus.publish("assistant.response", {
"user_id": user_id,
"channel": channel,
"content": response
})
return response2.1.2 工作流程
- 接收消息:从渠道接收用户消息
- 会话管理:获取或创建用户会话
- 上下文构建:基于会话历史构建上下文
- LLM调用:使用上下文调用LLM生成响应
- 响应处理:处理LLM响应并存储到会话
- 事件发布:发布助手响应事件
- 响应返回:将响应返回给渠道
2.2 上下文构建
上下文是LLM生成响应的重要依据,包含用户历史消息、系统提示和其他相关信息。Agent需要构建一个包含足够信息但又不过长的上下文。
2.2.1 上下文构建实现
python
def _build_context(self, session: Session) -> str:
"""
构建上下文
Args:
session: 会话对象
Returns:
构建好的上下文
"""
# 系统提示
system_prompt = """
你是Nanobot2,一个智能AI助手。
你的任务是帮助用户解决问题,回答用户的问题,执行用户的命令。
你需要保持友好、专业的态度,提供准确、有用的信息。
可用技能:
- search: 搜索网络信息
- weather: 查询天气
- calculator: 计算数学表达式
- time: 获取当前时间
如果你不确定如何回答,或者需要更多信息,请直接询问用户。
"""
# 获取历史消息
messages = session.get_messages(limit=20) # 限制消息数量
# 构建上下文
context = system_prompt + "\n\n"
for message in messages:
role = message["role"]
content = message["content"]
context += f"{role}: {content}\n"
return context2.2.2 上下文优化
- 消息限制:限制历史消息数量,避免上下文过长
- 重要信息优先:优先保留最近的消息
- 系统提示优化:清晰定义助手的角色和能力
- 格式规范:使用统一的格式,便于LLM理解
2.3 LLM集成
LLM(大型语言模型)是Agent的核心能力来源,Nanobot2支持多种LLM提供商,包括OpenAI、Anthropic和本地模型。
2.3.1 LLM提供商抽象
python
class LLMProvider(ABC):
@abstractmethod
async def generate(self, prompt: str, **kwargs) -> str:
pass
class OpenAIProvider(LLMProvider):
def __init__(self, api_key: str, model: str = "gpt-3.5-turbo"):
self.api_key = api_key
self.model = model
async def generate(self, prompt: str, **kwargs) -> str:
import openai
openai.api_key = self.api_key
response = await openai.ChatCompletion.acreate(
model=self.model,
messages=[{"role": "user", "content": prompt}],
**kwargs
)
return response.choices[0].message.content
class AnthropicProvider(LLMProvider):
def __init__(self, api_key: str, model: str = "claude-2"):
self.api_key = api_key
self.model = model
async def generate(self, prompt: str, **kwargs) -> str:
import anthropic
client = anthropic.Anthropic(api_key=self.api_key)
response = client.completions.create(
model=self.model,
prompt=prompt,
max_tokens=1024,
**kwargs
)
return response.completion2.3.2 提供商管理
python
class ProviderManager:
def __init__(self):
self.providers = {}
self.default_provider = None
def register_provider(self, name: str, provider: LLMProvider):
self.providers[name] = provider
def set_default_provider(self, name: str):
if name in self.providers:
self.default_provider = name
def get_provider(self, name: str = None) -> LLMProvider:
if name and name in self.providers:
return self.providers[name]
elif self.default_provider and self.default_provider in self.providers:
return self.providers[self.default_provider]
else:
raise ValueError("No provider available")2.4 响应生成
Agent调用LLM生成响应后,需要对响应进行处理,确保其符合预期格式和内容要求。
2.4.1 响应处理
python
async def _call_llm(self, context: str) -> str:
"""
调用LLM生成响应
Args:
context: 上下文
Returns:
LLM生成的响应
"""
try:
# 获取默认提供商
provider = self.provider_manager.get_provider()
# 调用LLM生成响应
response = await provider.generate(context)
# 处理响应
response = self._process_response(response)
return response
except Exception as e:
print(f"调用LLM失败: {e}")
return f"抱歉,我现在无法处理您的请求,请稍后再试。错误信息: {str(e)}"
def _process_response(self, response: str) -> str:
"""
处理LLM响应
Args:
response: LLM生成的响应
Returns:
处理后的响应
"""
# 去除首尾空白
response = response.strip()
# 处理空响应
if not response:
return "抱歉,我没有理解您的问题,请再详细说明一下。"
# 返回处理后的响应
return response2.4.2 响应质量控制
- 错误处理:捕获并处理LLM调用错误
- 响应验证:确保响应非空且有意义
- 格式标准化:统一响应格式
- 安全检查:过滤不安全内容
2.5 核心引擎测试
2.5.1 单元测试
为核心引擎编写单元测试,确保各功能正常工作:
python
import unittest
from unittest.mock import Mock, AsyncMock
from nanobot.agent import Agent
from nanobot.session import Session
class TestAgent(unittest.TestCase):
def setUp(self):
# 创建模拟对象
self.provider_manager = Mock()
self.session_manager = Mock()
self.message_bus = Mock()
self.message_bus.publish = AsyncMock()
# 创建模拟提供商
self.mock_provider = Mock()
self.mock_provider.generate = AsyncMock(return_value="测试响应")
self.provider_manager.get_provider = Mock(return_value=self.mock_provider)
# 创建模拟会话
self.mock_session = Mock(spec=Session)
self.mock_session.get_messages = Mock(return_value=[])
self.session_manager.get_or_create_session = Mock(return_value=self.mock_session)
# 创建Agent实例
self.agent = Agent(self.provider_manager, self.session_manager, self.message_bus)
async def test_process_message(self):
# 测试处理消息
response = await self.agent.process_message("user1", "cli", "你好")
# 验证结果
self.assertEqual(response, "测试响应")
self.mock_session.add_message.assert_any_call("user", "你好")
self.mock_session.add_message.assert_any_call("assistant", "测试响应")
self.message_bus.publish.assert_called_once()
if __name__ == "__main__":
unittest.main()2.5.2 集成测试
运行完整的集成测试,确保核心引擎与其他模块正常协作:
bash
python -m pytest tests/test_agent.py -v2.6 性能优化
2.6.1 异步处理
使用Python的asyncio库实现异步处理,提高并发性能:
python
async def process_messages(self, messages: list):
"""
批量处理消息
Args:
messages: 消息列表
Returns:
响应列表
"""
tasks = []
for message in messages:
user_id = message["user_id"]
channel = message["channel"]
content = message["content"]
task = self.process_message(user_id, channel, content)
tasks.append(task)
return await asyncio.gather(*tasks)2.6.2 缓存优化
使用缓存减少重复计算和API调用:
python
class ResponseCache:
def __init__(self, max_size=1000):
self.cache = {}
self.max_size = max_size
def get(self, key):
return self.cache.get(key)
def set(self, key, value):
if len(self.cache) >= self.max_size:
# 删除最旧的项
oldest_key = next(iter(self.cache))
del self.cache[oldest_key]
self.cache[key] = value
def clear(self):
self.cache.clear()2.7 小结
本章介绍了Nanobot2核心引擎的实现,包括:
- Agent主循环:处理用户请求的核心逻辑
- 上下文构建:为LLM提供必要的信息
- LLM集成:支持多种LLM提供商
- 响应生成:处理和优化LLM响应
- 测试与优化:确保核心引擎的可靠性和性能
核心引擎是Nanobot2的大脑,负责理解用户意图、生成响应和协调各模块工作。在接下来的章节中,我们将学习技能系统和多渠道集成,进一步增强Nanobot2的能力。
