Compare commits
5 Commits
c9f5724119
...
critical_a
| Author | SHA1 | Date | |
|---|---|---|---|
| 740568592d | |||
| 143b609924 | |||
| bad715aa00 | |||
| 3ea05893df | |||
| 7f3176efc7 |
169
README.md
169
README.md
@@ -1,26 +1,28 @@
|
|||||||
# 慧遇 Agent
|
# 慧遇 Agent
|
||||||
|
|
||||||
慧遇智能体项目,基于 Google ADK (Agent Development Kit) 构建。
|
基于 Google ADK (Agent Development Kit) 构建的智能体项目,支持多智能体协作、多用户会话管理和 REST API 集成。
|
||||||
|
|
||||||
## 项目结构
|
## 项目结构
|
||||||
|
|
||||||
```
|
```
|
||||||
workspace/
|
├── root_agent/ # 根智能体(小慧)
|
||||||
├── agents/ # 所有 Agent 模块
|
|
||||||
│ ├── __init__.py
|
│ ├── __init__.py
|
||||||
│ └── root_agent/ # Root Agent
|
│ └── agent.py # 定义 root_agent,包含子智能体引用
|
||||||
│ ├── __init__.py
|
├── note_agent/ # 笔记子智能体
|
||||||
│ └── agent.py
|
|
||||||
├── base/ # 基础工具类
|
|
||||||
│ ├── __init__.py
|
│ ├── __init__.py
|
||||||
│ └── agent.py # HuiYuBaseAgent 基类
|
│ ├── agent.py # 定义 root_agent(ADK 要求导出名)
|
||||||
├── common/ # 公共模块
|
│ └── note_formatter.py # Markdown 笔记格式化器
|
||||||
│ ├── __init__.py # 环境初始化(.env 加载、日志配置)
|
├── agent_base/ # Agent 基类
|
||||||
│ ├── logger.py # 模型调用耗时日志
|
│ ├── __init__.py
|
||||||
│ └── prompt_guard.py # 防提示词注入检测
|
│ └── agent_base.py # HuiYuBaseAgent(防注入 + 日志)
|
||||||
├── .env # 环境变量配置(不提交到 Git)
|
├── common/ # 公共工具
|
||||||
├── .env.example # 配置示例(可提交到 Git)
|
│ ├── __init__.py # 环境初始化(.env 加载、日志配置)
|
||||||
├── .gitignore
|
│ ├── logger.py # 模型调用耗时日志
|
||||||
|
│ └── prompt_guard.py # 防提示词注入检测
|
||||||
|
├── .env # 环境变量配置(不提交到 Git)
|
||||||
|
├── .env.example # 配置示例
|
||||||
|
├── API_DOC.md # REST API 接口文档
|
||||||
|
├── requirements.txt
|
||||||
└── README.md
|
└── README.md
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -29,16 +31,9 @@ workspace/
|
|||||||
- Python >= 3.10
|
- Python >= 3.10
|
||||||
- pip
|
- pip
|
||||||
|
|
||||||
## 环境搭建
|
## 快速开始
|
||||||
|
|
||||||
### 1. 克隆项目
|
### 1. 安装依赖
|
||||||
|
|
||||||
```bash
|
|
||||||
git clone <your-repo-url>
|
|
||||||
cd <project-directory>
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. 安装依赖
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pip install -r requirements.txt
|
pip install -r requirements.txt
|
||||||
@@ -47,97 +42,98 @@ pip install -r requirements.txt
|
|||||||
主要依赖:
|
主要依赖:
|
||||||
- `google-adk` — Google Agent Development Kit
|
- `google-adk` — Google Agent Development Kit
|
||||||
- `python-dotenv` — 环境变量管理
|
- `python-dotenv` — 环境变量管理
|
||||||
- `litellm` — 多模型适配层
|
- `litellm` — 多模型适配层(对接 MiniMax 等大模型)
|
||||||
|
|
||||||
### 3. 配置环境变量
|
### 2. 配置环境变量
|
||||||
|
|
||||||
复制示例配置文件并填入你的 API Key:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cp .env.example .env
|
cp .env.example .env
|
||||||
```
|
```
|
||||||
|
|
||||||
编辑 `.env` 文件:
|
编辑 `.env`:
|
||||||
|
|
||||||
```env
|
```env
|
||||||
# MiniMax API Key(替换为你自己的)
|
|
||||||
MINIMAX_API_KEY=your_api_key_here
|
MINIMAX_API_KEY=your_api_key_here
|
||||||
|
|
||||||
# MiniMax API 地址
|
|
||||||
MINIMAX_API_BASE=https://api.minimaxi.com/v1
|
MINIMAX_API_BASE=https://api.minimaxi.com/v1
|
||||||
|
|
||||||
# 模型名称
|
|
||||||
MINIMAX_MODEL=openai/MiniMax-M2.7
|
MINIMAX_MODEL=openai/MiniMax-M2.7
|
||||||
```
|
```
|
||||||
|
|
||||||
### 4. 启动服务
|
### 3. 启动服务
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd agents
|
# Web UI 模式(带聊天界面)
|
||||||
adk web
|
adk web .
|
||||||
|
|
||||||
|
# API 服务模式(纯 REST API,适合外部集成)
|
||||||
|
adk api_server . --auto_create_session
|
||||||
```
|
```
|
||||||
|
|
||||||
启动后访问 http://127.0.0.1:8000,在下拉菜单中选择 Agent 即可开始对话。
|
启动后访问 `http://127.0.0.1:8000`。
|
||||||
|
|
||||||
|
## 智能体架构
|
||||||
|
|
||||||
|
```
|
||||||
|
root_agent(小慧)
|
||||||
|
├── 通用对话:回答用户问题
|
||||||
|
└── 子智能体委派:
|
||||||
|
└── note_agent(笔记助手)
|
||||||
|
├── generate_text_note — 生成文本笔记
|
||||||
|
└── generate_image_note — 生成图片笔记
|
||||||
|
```
|
||||||
|
|
||||||
|
当用户请求涉及笔记生成、内容整理时,root_agent 会自动委派给 note_agent 处理。
|
||||||
|
|
||||||
|
## API 集成
|
||||||
|
|
||||||
|
使用 `adk api_server` 启动后,可通过 REST API 与 Agent 对话:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 启动 API 服务
|
||||||
|
adk api_server . --auto_create_session --port 8000
|
||||||
|
|
||||||
|
# 发送对话
|
||||||
|
curl -X POST http://localhost:8000/run \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{
|
||||||
|
"app_name": "root_agent",
|
||||||
|
"user_id": "user_001",
|
||||||
|
"session_id": "my_session",
|
||||||
|
"new_message": {"role": "user", "parts": [{"text": "你好"}]}
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
详细的接口文档见 [API_DOC.md](API_DOC.md),Swagger 文档地址:`http://localhost:8000/docs`
|
||||||
|
|
||||||
## 内置能力
|
## 内置能力
|
||||||
|
|
||||||
所有继承 `HuiYuBaseAgent` 的 Agent 自动获得以下能力:
|
所有继承 `HuiYuBaseAgent` 的 Agent 自动获得:
|
||||||
|
|
||||||
### 防提示词注入
|
### 防提示词注入
|
||||||
|
|
||||||
在模型调用前自动检测用户输入中的提示词注入攻击,包括:
|
模型调用前自动检测用户输入中的注入攻击(角色扮演、指令泄露、分隔符注入、越狱尝试等),检测到时拒绝请求。
|
||||||
- 角色扮演 / 身份覆盖
|
|
||||||
- 指令泄露尝试
|
|
||||||
- 分隔符注入
|
|
||||||
- 越狱尝试
|
|
||||||
|
|
||||||
检测到注入时会拒绝请求并返回提示。
|
|
||||||
|
|
||||||
### 模型调用日志
|
### 模型调用日志
|
||||||
|
|
||||||
每次模型调用完成后自动记录:
|
每次模型调用完成后自动记录 Agent 名称、模型版本、调用耗时、Token 用量:
|
||||||
- Agent 名称
|
|
||||||
- 模型版本
|
|
||||||
- 调用耗时
|
|
||||||
- Token 使用量(prompt / completion / total)
|
|
||||||
|
|
||||||
日志示例:
|
|
||||||
|
|
||||||
```
|
```
|
||||||
2026-04-06 07:54:59 [adk.agent] INFO - 模型调用完成 | agent=minimax_agent model=MiniMax-M2.7 latency=11.701s prompt_tokens=78 completion_tokens=31 total_tokens=109
|
2026-04-06 07:54:59 [adk.agent] INFO - 模型调用完成 | agent=huiyu_agent model=MiniMax-M2.7 latency=11.701s prompt_tokens=78 completion_tokens=31 total_tokens=109
|
||||||
```
|
```
|
||||||
|
|
||||||
## 新增 Agent
|
## 新增 Agent
|
||||||
|
|
||||||
在 `agents/` 目录下创建新的子目录即可:
|
在项目根目录下创建新的子目录即可:
|
||||||
|
|
||||||
```
|
```
|
||||||
agents/
|
my_new_agent/
|
||||||
├── root_agent/
|
├── __init__.py # 留空即可
|
||||||
│ ├── __init__.py
|
└── agent.py # 必须导出名为 root_agent 的变量
|
||||||
│ └── agent.py
|
|
||||||
└── my_new_agent/ # 新增 Agent
|
|
||||||
├── __init__.py # 内容同 root_agent/__init__.py
|
|
||||||
└── agent.py
|
|
||||||
```
|
```
|
||||||
|
|
||||||
`__init__.py` 内容(用于设置 Python 路径):
|
`agent.py` 示例:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
import sys
|
from agent_base.agent_base import HuiYuBaseAgent
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
sys.path.insert(0, str(Path(__file__).parent.parent.parent))
|
|
||||||
|
|
||||||
from . import agent
|
|
||||||
|
|
||||||
__all__ = ["agent"]
|
|
||||||
```
|
|
||||||
|
|
||||||
`agent.py` 中继承 `HuiYuBaseAgent`:
|
|
||||||
|
|
||||||
```python
|
|
||||||
from base.agent import HuiYuBaseAgent
|
|
||||||
from google.adk.models.lite_llm import LiteLlm
|
from google.adk.models.lite_llm import LiteLlm
|
||||||
import os
|
import os
|
||||||
|
|
||||||
@@ -147,11 +143,26 @@ model = LiteLlm(
|
|||||||
api_key=os.getenv("MINIMAX_API_KEY"),
|
api_key=os.getenv("MINIMAX_API_KEY"),
|
||||||
)
|
)
|
||||||
|
|
||||||
my_agent = HuiYuBaseAgent(
|
root_agent = HuiYuBaseAgent(
|
||||||
name="my_agent",
|
name="my_agent",
|
||||||
model=model,
|
model=model,
|
||||||
|
description="我的智能体",
|
||||||
instruction="你是一个专业的助手。",
|
instruction="你是一个专业的助手。",
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
重启 `adk web` 后,新 Agent 会自动出现在下拉菜单中。
|
> **注意**:ADK 要求每个 agent 目录的 `agent.py` 中必须导出名为 `root_agent` 的变量。
|
||||||
|
|
||||||
|
如需作为 root_agent 的子智能体,在 `root_agent/agent.py` 中添加引用:
|
||||||
|
|
||||||
|
```python
|
||||||
|
from my_new_agent.agent import root_agent as my_new_agent
|
||||||
|
|
||||||
|
root_agent = HuiYuBaseAgent(
|
||||||
|
name="huiyu_agent",
|
||||||
|
...,
|
||||||
|
sub_agents=[my_new_agent],
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
重启服务后新 Agent 自动生效。
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
"""
|
|
||||||
Agent 模块
|
|
||||||
|
|
||||||
每个 Agent 是一个独立的子目录,包含 agent.py 和 __init__.py。
|
|
||||||
"""
|
|
||||||
|
|
||||||
# 导出所有 Agent,供 adk web 服务注册
|
|
||||||
from .root_agent import agent as root_agent
|
|
||||||
|
|
||||||
__all__ = ["root_agent"]
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
import sys
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
sys.path.insert(0, str(Path(__file__).parent.parent.parent))
|
|
||||||
|
|
||||||
from . import agent
|
|
||||||
|
|
||||||
__all__ = ["agent"]
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
import sys
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
# 将项目根目录加入 sys.path(adk web 从 agents/ 启动)
|
|
||||||
# __file__ = agents/root_agent/__init__.py → parent.parent.parent = workspace/
|
|
||||||
sys.path.insert(0, str(Path(__file__).parent.parent.parent))
|
|
||||||
|
|
||||||
from . import agent
|
|
||||||
|
|
||||||
__all__ = ["agent"]
|
|
||||||
1
critical_awareness_agent/__init__.py
Normal file
1
critical_awareness_agent/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
# ADK agent_loader 会自动扫描并加载 agent.py
|
||||||
117
critical_awareness_agent/agent.py
Normal file
117
critical_awareness_agent/agent.py
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
from google.adk.models.lite_llm import LiteLlm
|
||||||
|
from agent_base.agent_base import HuiYuBaseAgent
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
# MiniMax 模型配置(从 .env 文件读取)
|
||||||
|
# ============================================================
|
||||||
|
MINIMAX_API_KEY = os.getenv("MINIMAX_API_KEY")
|
||||||
|
MINIMAX_API_BASE = os.getenv("MINIMAX_API_BASE")
|
||||||
|
MINIMAX_MODEL = os.getenv("MINIMAX_MODEL")
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
# 创建 LiteLlm 模型适配器
|
||||||
|
# ============================================================
|
||||||
|
model = LiteLlm(
|
||||||
|
model=MINIMAX_MODEL,
|
||||||
|
api_base=MINIMAX_API_BASE,
|
||||||
|
api_key=MINIMAX_API_KEY,
|
||||||
|
)
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
# 定义 Agent(继承 HuiYuBaseAgent)
|
||||||
|
# ============================================================
|
||||||
|
critical_awareness_agent = HuiYuBaseAgent(
|
||||||
|
name="critical_awareness_agent",
|
||||||
|
model=model,
|
||||||
|
description="用于处理用户心智散乱、情绪化或认知混淆的专家。它通过‘三界(外中内)’判别法强制用户回归觉知。当用户表达焦虑、愤怒、分心或无法区分事实与观点时,必须调用此工具。",
|
||||||
|
instruction="""
|
||||||
|
# 角色
|
||||||
|
你是"觉察引导师",精通"临界觉察法"。你的唯一任务是帮助用户将混沌的体验拆解为三界,然后引导其回归当下的觉知本身。
|
||||||
|
|
||||||
|
你不是心理咨询师,不给建议、不安慰、不分析原因。你是一把手术刀——精准、干净、只切开,不缝合。
|
||||||
|
|
||||||
|
# 三界判定规则
|
||||||
|
|
||||||
|
## 外界(External)
|
||||||
|
- 定义:纯粹感官原始数据
|
||||||
|
- 判定标准:不带任何诠释的感知
|
||||||
|
- 示例:"窗外有雨声"、"屏幕亮着"、"对方说了那句话"
|
||||||
|
- 关键词:看到、听到、闻到、触到、尝到
|
||||||
|
|
||||||
|
## 中界(Middle)
|
||||||
|
- 定义:头脑对经验的加工层
|
||||||
|
- 判定标准:包含想法、念头、评判、逻辑、语言叙事、对过去的回忆、对未来的担忧
|
||||||
|
- 示例:"他不应该那样对我"、"我太差了"、"万一失败了怎么办"、"想起了一件事"
|
||||||
|
- 关键词:应该、因为、如果、觉得、认为、想起、担心、后悔
|
||||||
|
|
||||||
|
## 内界(Internal)
|
||||||
|
- 定义:身体的直接生理感受与情绪的身体投影
|
||||||
|
- 判定标准:可定位到身体部位的感知,或无明确念头的情绪涌动
|
||||||
|
- 示例:"胸口发紧"、"胃里不舒服"、"心跳加速"、"手在发抖"、"突然想哭"
|
||||||
|
- 关键词:身体部位 + 感受词(紧、热、沉、空、跳、缩)
|
||||||
|
|
||||||
|
# 响应结构
|
||||||
|
|
||||||
|
每次回复严格遵循以下格式:
|
||||||
|
|
||||||
|
## 1. 拆解(必做)
|
||||||
|
用三界框架拆解用户输入。只拆解用户明确表达的内容,不臆测。
|
||||||
|
|
||||||
|
格式:
|
||||||
|
【中界】
|
||||||
|
...
|
||||||
|
【内界】
|
||||||
|
...
|
||||||
|
【外界】
|
||||||
|
...
|
||||||
|
|
||||||
|
如果某界用户未提及,可以:
|
||||||
|
- 留空该界
|
||||||
|
- 或用一个温和的提问邀请用户觉察(每次最多一个问题)
|
||||||
|
|
||||||
|
## 2. 核心看见(必做)
|
||||||
|
一句话,点破最核心的觉察契机。要像禅宗公案一样短、准、狠。
|
||||||
|
|
||||||
|
## 3. 回归当下(必做)
|
||||||
|
给出一个极其简单的当下锚定指令(不超过两步)。
|
||||||
|
- 默认:三次呼吸觉知
|
||||||
|
- 可根据情境变化:感受脚底、聆听周围声音、观察眼前颜色
|
||||||
|
|
||||||
|
# 语气规则
|
||||||
|
|
||||||
|
- 简洁如刀。每句话都有用,没有废话。
|
||||||
|
- 不用感叹号表达关怀,不用"我理解你"式共情。
|
||||||
|
- 不说"这很正常"、"没关系的"。
|
||||||
|
- 可以用比喻,但要精准,不要文艺腔。
|
||||||
|
- 允许沉默感——不是每句话都需要填满。
|
||||||
|
|
||||||
|
# 边界处理
|
||||||
|
|
||||||
|
- 如果用户持续停留在中界叙事(反复讲同一件事),温和地打断:"你已经说了三次了。现在——身体在哪里?"
|
||||||
|
- 如果用户在测试系统或闲聊,简短回应后回归引导:"有趣。此刻你的体验是什么?"
|
||||||
|
- 如果用户表达严重心理危机(自伤、自杀意念),不做三界拆解,直接引导其寻求专业帮助。
|
||||||
|
|
||||||
|
# 示例
|
||||||
|
|
||||||
|
用户:今天被领导当众批评了,太丢人了。
|
||||||
|
|
||||||
|
【中界】🔪
|
||||||
|
- 念头:"被批评了"——事件已过去,此刻在重播。
|
||||||
|
- 评判:"太丢人了"——头脑给事件贴了羞耻的标签。
|
||||||
|
|
||||||
|
【内界】
|
||||||
|
- 你没有提到。此刻身体有什么感觉?脸上热不热?胃里有没有什么?
|
||||||
|
|
||||||
|
【外界】
|
||||||
|
- 此刻——你面前的屏幕,你所在的房间。领导不在这里。
|
||||||
|
|
||||||
|
核心看见:
|
||||||
|
"丢人"是念头在评价念头。
|
||||||
|
身体只负责发烫、发紧——它没有"丢人"这个概念。
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
root_agent = critical_awareness_agent # 将 critical_awareness_agent 作为 root_agent 导出,供 adk web 注册
|
||||||
1
note_agent/__init__.py
Normal file
1
note_agent/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
# ADK agent_loader 会自动扫描并加载 agent.py
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
from base.agent import HuiYuBaseAgent
|
from agent_base.agent_base import HuiYuBaseAgent
|
||||||
from google.adk.models.lite_llm import LiteLlm
|
from google.adk.models.lite_llm import LiteLlm
|
||||||
from .note_formatter import NoteFormatter
|
from .note_formatter import NoteFormatter
|
||||||
|
|
||||||
@@ -75,3 +75,5 @@ note_agent = HuiYuBaseAgent(
|
|||||||
),
|
),
|
||||||
tools=[generate_text_note, generate_image_note],
|
tools=[generate_text_note, generate_image_note],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
root_agent = note_agent
|
||||||
1
root_agent/__init__.py
Normal file
1
root_agent/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
# ADK agent_loader 会自动扫描并加载 agent.py
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
from base.agent import HuiYuBaseAgent
|
from agent_base.agent_base import HuiYuBaseAgent
|
||||||
from google.adk.models.lite_llm import LiteLlm
|
from google.adk.models.lite_llm import LiteLlm
|
||||||
|
from critical_awareness_agent.agent import critical_awareness_agent
|
||||||
|
from note_agent.agent import note_agent
|
||||||
|
|
||||||
# ============================================================
|
# ============================================================
|
||||||
# MiniMax 模型配置(从 .env 文件读取)
|
# MiniMax 模型配置(从 .env 文件读取)
|
||||||
@@ -26,5 +28,12 @@ root_agent = HuiYuBaseAgent(
|
|||||||
name="huiyu_agent",
|
name="huiyu_agent",
|
||||||
model=model,
|
model=model,
|
||||||
description="一个智能助手,能够回答用户的各种问题。",
|
description="一个智能助手,能够回答用户的各种问题。",
|
||||||
instruction="你是一个乐于助人的中文 AI 助手,你的名字叫小慧,请用中文回答用户的问题,回答要准确、简洁、友好。",
|
instruction=(
|
||||||
|
"你是一个乐于助人的中文 AI 助手,你的名字叫小慧,请用中文回答用户的问题,回答要准确、简洁、友好。\n\n"
|
||||||
|
"你有一个子助手「笔记助手」(note_agent),当用户需要生成笔记、整理内容、做总结时,"
|
||||||
|
"请将任务委派给 note_agent 处理。"
|
||||||
|
"你还有一个子助手「临界觉察助手」(critical_awareness_agent),当用户出现心智散乱、情绪化或认知混淆时,"
|
||||||
|
"请将任务委派给 critical_awareness_agent 处理。"
|
||||||
|
),
|
||||||
|
sub_agents=[note_agent, critical_awareness_agent], # 将 note_agent 和 critical_awareness_agent 作为子 Agent
|
||||||
)
|
)
|
||||||
Reference in New Issue
Block a user