feat: v2.0 配置驱动版 - 新增工具/技能/MCP无需改源码
重构内容: - agent.py 替代 agent_v3.py,所有配置从 config.yaml 加载 - tools/ 目录自动扫描,丢.py文件即注册新工具 - skills/ 目录自动扫描,丢.yaml文件即注册新技能 - config.yaml 统一管理模型参数、MCP服务器、路由关键词 - MCP支持多服务器配置 + 确定性路由关键词 - 删除旧版 step1_basic_fc.py 和 agent_v3.py
This commit is contained in:
155
README.md
155
README.md
@@ -1,6 +1,8 @@
|
||||
# 黄庄三号四能力 Agent
|
||||
|
||||
基于 LangGraph 的多能力 AI Agent,集成 FC/MCP/思考模式/Skill 四种核心能力。
|
||||
基于 LangGraph 的多能力 AI Agent,集成 FC / MCP / 思考模式 / Skill 四种核心能力。
|
||||
|
||||
**v2.0 配置驱动版** — 新增工具/技能/MCP服务器无需改源码,丢文件或改配置即可。
|
||||
|
||||
## 四项能力
|
||||
|
||||
@@ -11,46 +13,107 @@
|
||||
| 思考模式 | 自建 think_node + CoT 推理链 | ★★★★ |
|
||||
| Skill | 自建 SkillRegistry 注册机制 | ★★★★ |
|
||||
|
||||
## 模型
|
||||
## 目录结构
|
||||
|
||||
GLM-4.5-air(智谱,OpenAI 兼容接口)
|
||||
```
|
||||
hz3-agent/
|
||||
├── config.yaml ← 一个文件管所有配置(模型、MCP、路由关键词)
|
||||
├── agent.py ← Agent 主程序,从配置加载
|
||||
├── mcp_server.py ← MCP 服务器(示例:时间/字符统计/UUID)
|
||||
├── tools/ ← 工具目录,丢 .py 文件即注册
|
||||
│ ├── weather.py
|
||||
│ ├── calculator.py
|
||||
│ └── knowledge.py
|
||||
├── skills/ ← 技能目录,丢 .yaml 文件即注册
|
||||
│ ├── weather_analyst.yaml
|
||||
│ ├── math_tutor.yaml
|
||||
│ └── knowledge_explorer.yaml
|
||||
└── README.md
|
||||
```
|
||||
|
||||
## 快速开始
|
||||
|
||||
```bash
|
||||
cd /path/to/hz3-agent
|
||||
cd hz3-agent
|
||||
|
||||
# 自动测试(不带MCP)
|
||||
python3 agent_v3.py --test
|
||||
python3 agent.py --test
|
||||
|
||||
# 自动测试(带MCP)
|
||||
python3 agent_v3.py --mcp --test
|
||||
python3 agent.py --mcp --test
|
||||
|
||||
# 交互模式
|
||||
python3 agent_v3.py --mcp
|
||||
# 交互模式(带MCP)
|
||||
python3 agent.py --mcp
|
||||
|
||||
# 交互模式(不带MCP)
|
||||
python3 agent.py
|
||||
```
|
||||
|
||||
## 文件说明
|
||||
## 新增工具
|
||||
|
||||
| 文件 | 说明 |
|
||||
|------|------|
|
||||
| `agent_v3.py` | Agent 主程序(四能力完整版) |
|
||||
| `mcp_server.py` | MCP 服务器(示例工具:时间/字符统计/UUID) |
|
||||
| `step1_basic_fc.py` | Step1 基础 FC 验证 |
|
||||
|
||||
## 代码调用
|
||||
在 `tools/` 目录下创建 .py 文件,暴露 `TOOLS` 列表即可:
|
||||
|
||||
```python
|
||||
from agent_v3 import run_agent, build_graph
|
||||
# tools/stock.py
|
||||
from langchain_core.tools import tool
|
||||
|
||||
graph = build_graph()
|
||||
result = await run_agent("黄庄天气怎么样?", graph)
|
||||
@tool
|
||||
def get_stock_price(symbol: str) -> str:
|
||||
"""查询股票价格"""
|
||||
return f"{symbol}: 当前价格 123.45"
|
||||
|
||||
print(result["reply"]) # 回复
|
||||
print(result["thinking"]) # 思考过程
|
||||
print(result["skill"]) # 使用的技能
|
||||
TOOLS = [get_stock_price] # 必须!供自动扫描
|
||||
```
|
||||
|
||||
重启 Agent 即自动加载,无需改任何其他文件。
|
||||
|
||||
## 新增技能
|
||||
|
||||
在 `skills/` 目录下创建 .yaml 文件:
|
||||
|
||||
```yaml
|
||||
# skills/stock_analyst.yaml
|
||||
name: stock_analyst
|
||||
description: "股票分析师 - 查询股价并给出分析"
|
||||
prompt: |
|
||||
你是股票分析师。根据以下行情给出分析建议:
|
||||
行情数据:{input}
|
||||
tools:
|
||||
- get_stock_price
|
||||
```
|
||||
|
||||
然后在 `config.yaml` 的 `skill_keywords` 中添加路由关键词:
|
||||
|
||||
```yaml
|
||||
skill_keywords:
|
||||
stock_analyst: ["股价", "股票", "行情"]
|
||||
```
|
||||
|
||||
## 新增 MCP 服务器
|
||||
|
||||
在 `config.yaml` 的 `mcp_servers` 列表中添加一项:
|
||||
|
||||
```yaml
|
||||
mcp_servers:
|
||||
- name: "hz3-tools" # 已有的
|
||||
command: "python3"
|
||||
args: ["mcp_server.py"]
|
||||
transport: "stdio"
|
||||
route_keywords:
|
||||
get_current_time: ["几点", "时间"]
|
||||
count_chars: ["统计字符", "字符数"]
|
||||
generate_uuid: ["UUID"]
|
||||
|
||||
- name: "my-new-server" # 新增的
|
||||
command: "python3"
|
||||
args: ["path/to/my_server.py"]
|
||||
transport: "stdio"
|
||||
route_keywords:
|
||||
my_tool: ["关键词1", "关键词2"]
|
||||
```
|
||||
|
||||
启动时加 `--mcp` 参数即可连接所有配置的 MCP 服务器。
|
||||
|
||||
## 架构流程
|
||||
|
||||
```
|
||||
@@ -73,30 +136,36 @@ print(result["skill"]) # 使用的技能
|
||||
回到agent
|
||||
```
|
||||
|
||||
## MCP 服务器
|
||||
|
||||
`mcp_server.py` 基于 FastMCP 提供 3 个示例工具:
|
||||
|
||||
- `get_current_time` - 获取当前时间
|
||||
- `count_chars` - 统计文本字符数
|
||||
- `generate_uuid` - 生成随机 UUID
|
||||
|
||||
## Skill 系统
|
||||
|
||||
已注册 3 个示例技能,扩展只需一行:
|
||||
## 代码调用
|
||||
|
||||
```python
|
||||
skills.register(SkillDef(
|
||||
name="新技能",
|
||||
description="技能描述",
|
||||
prompt="提示词模板,{input}为占位符",
|
||||
tools=["依赖的工具名"]
|
||||
))
|
||||
from agent import run_agent, build_graph, load_config, scan_tools, scan_skills
|
||||
|
||||
config = load_config()
|
||||
tools = scan_tools()
|
||||
skills = scan_skills()
|
||||
graph = await build_graph(config, skills, None, tools)
|
||||
|
||||
result = await run_agent("黄庄天气怎么样?", graph)
|
||||
print(result["reply"]) # 回复
|
||||
print(result["thinking"]) # 思考过程
|
||||
print(result["skill"]) # 使用的技能
|
||||
```
|
||||
|
||||
## 关键设计决策
|
||||
|
||||
1. **MCP 确定性路由**:关键词匹配后直接 session.call_tool(),绕过模型不调工具的问题
|
||||
2. **思考结果合并**:与 system prompt 合并为单条 SystemMessage,避免干扰工具调用
|
||||
3. **AsyncExitStack 长连接**:MCP session 在 Agent 生命周期内保持,退出时统一关闭
|
||||
4. **迭代保护**:agent 节点迭代超过 5 次强制结束,防止无限循环
|
||||
1. **MCP 确定性路由** — 关键词匹配后直接 session.call_tool(),绕过模型不调工具的问题
|
||||
2. **思考结果合并** — 与 system prompt 合并为单条 SystemMessage,避免干扰工具调用
|
||||
3. **AsyncExitStack 长连接** — MCP session 在 Agent 生命周期内保持
|
||||
4. **迭代保护** — agent 节点迭代超过阈值强制结束,防死循环
|
||||
5. **配置驱动** — 所有新增/调整通过 config.yaml + 丢文件完成,不改源码
|
||||
|
||||
## 依赖
|
||||
|
||||
```
|
||||
langgraph>=1.1
|
||||
langchain-openai>=1.2
|
||||
langchain-mcp-adapters>=0.2
|
||||
mcp>=1.0
|
||||
pyyaml>=6.0
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user