KoiAgent MCP Server
README.md
# 🐟 KoiAgent - 智能客服值守机器人
KoiAgent 是一套面向电商平台客服场景的 **AI 值守解决方案**,实现 7×24 小时自动化值守,支持多专家协同决策、智能议价与上下文感知对话。
## 🌟 核心特性
### 智能对话引擎
| 功能模块 | 技术实现 | 关键特性 |
| ---------- | ---------------------------- | ------------------------------------------------------------ |
| 上下文感知 | LangGraph Checkpointer 记忆 | 以会话 ID 作为 thread_id 持久化多轮对话与工具调用轨迹 |
| 专家路由 | LangGraph 状态图 + 混合路由 | 规则优先、LLM 结构化输出兜底;专家 Agent 以状态图节点编排 |
| 工具调用 | Function Calling | 议价策略 / 知识库检索 / 时间查询由模型自主调度 |
| 推理循环 | ReAct(思考→行动→观察) | Agent 与 ToolNode 循环,超出最大步数自动收敛 |
| 知识检索 | RAG(Embedding + 向量索引) | 向量检索优先,未配置 Embedding 时自动降级关键词检索 |
### 业务功能矩阵
| 模块 | 已实现 | 规划中 |
| -------- | ------------------------------- | ------------------------------ |
| 核心引擎 | ✅ LLM 自动回复<br>✅ 上下文管理 | 🔄 情感分析增强 |
| 协作机制 | ✅ 专家路由<br>✅ 审核 Agent 反思重写 | 🔄 多专家辩论仲裁 |
| 生态集成 | ✅ MCP Server(4 个能力) | 🔄 更多 MCP 客户端适配 |
| 安全防护 | ✅ Prompt 注入防护<br>✅ 站外联系拦截 | 🔄 敏感词库热更新 |
| 议价系统 | ✅ 阶梯降价策略 | 🔄 市场比价功能 |
| 技术支持 | ✅ RAG 知识库检索(向量/关键词) | 🔄 多模态问答 |
| 运维监控 | ✅ 全链路追踪<br>✅ 指标与成本统计<br>✅ 健康检查 | 🔄 钉钉告警<br>🔄 Web 管理台 |
| 稳定性 | ✅ 幂等去重<br>✅ 熔断降级<br>✅ 并发限流 | 🔄 多实例部署<br>🔄 持久化记忆 |
## 🧠 Agent 架构
编排层基于 **LangGraph** 构建,将客服流程建模为一张有状态图:
```mermaid
flowchart LR
START([START]) --> G["guard<br/>注入防护"]
G -->|"命中注入"| F["finalize<br/>收敛"]
G -->|"放行"| C["classify<br/>意图识别"]
C -->|"no_reply"| F
C -->|"price / tech / default"| A["agent<br/>专家推理"]
A -->|"需要工具"| T["tools<br/>工具执行"]
T --> A
A -->|"生成草稿"| K["critic<br/>审核 Agent"]
K -->|"驳回→重写"| A
K -->|"通过"| F
F --> E([END])
```
**技术栈**
| 能力 | 实现 |
| ---- | ---- |
| 状态图编排 | `langgraph` `StateGraph` + 条件边 |
| 意图路由 | 关键词/正则规则优先 → LLM 结构化输出(Pydantic `IntentDecision`)兜底 |
| 工具调用 | `bind_tools` + `ToolNode`,由模型自主调度 |
| 知识检索 | RAG:Embedding(OpenAI 兼容)+ numpy 余弦检索;向量缓存落盘,未配置时降级关键词检索 |
| ReAct 循环 | `agent ⇄ tools` 循环,`AGENT_MAX_STEPS` 上限保护 |
| 多 Agent 协作 | 生产者-审核者(Producer-Critic):独立审核 Agent 复核草稿,「驳回→带反馈重写」构成 **Reflexion 反思循环**,`AGENT_MAX_REFLECTIONS` 限制返工轮数 |
| MCP 协议 | 以 `MCPServer` 暴露 4 个能力(3 个纯工具 + 完整 Agent 委派),支持 stdio / streamable-http |
| 并发模型 | 全异步:节点 `ainvoke` + `graph.ainvoke`,LLM 请求不阻塞事件循环 |
| 可靠性 | 幂等去重 / 熔断降级(失败返回兜底话术)/ 并发限流 / 会话记忆 TTL+LRU 淘汰 |
| 对话记忆 | `MemorySaver` Checkpointer,`thread_id = chat_id` |
| 提示词 | 按意图动态装载 `prompts/*_example.txt` 专家角色提示词 |
| 安全护栏 | **输入侧** Prompt 注入防护(归一化 + 加权规则 + 风险分级,命中直达拦截);**输出侧**关键词过滤拦截站外联系方式 |
| 可观测性 | 全链路 Trace + 指标聚合 + Token/成本统计,Callback 零侵入采集,可选 Langfuse |
**内置工具**
| 工具 | 作用 |
| ---- | ---- |
| `get_bargain_policy(bargain_count)` | 按议价轮次返回阶梯让步策略 |
| `search_knowledge_base(query)` | 检索 `knowledge/` 本地知识库 |
| `get_current_time()` | 获取当前时间,回答发货时效 |
**可靠性设计**
| 机制 | 说明 |
| ---- | ---- |
| 幂等去重 | LRU + TTL 去重窗口,重连 / 重复推送不会重复回复 |
| 熔断降级 | 连续失败达阈值即熔断,直接返回**兜底话术**而非静默无响应 |
| 并发限流 | `asyncio.Semaphore` 限制同时推理数,平抑瞬时并发 |
| 记忆治理 | Checkpointer 会话按 TTL + LRU 淘汰,防止长跑进程内存无限增长 |
## 🎨 效果图
<div align="center">
<img src="./images/demo1.png" width="600" alt="客服">
<br>
<em>图1: 客服随叫随到</em>
</div>
<div align="center">
<img src="./images/demo2.png" width="600" alt="议价专家">
<br>
<em>图2: 阶梯式议价</em>
</div>
<div align="center">
<img src="./images/demo3.png" width="600" alt="技术专家">
<br>
<em>图3: 技术专家上场</em>
</div>
### 运行日志与指标(真实输出)
```text
2026-09-11 21:14:34.352 | INFO | koiagent.agent.graph:__init__:180 - KoiAgent 图已编译完成,工具: ['get_bargain_policy', 'search_knowledge_base', 'get_current_time'], 最大推理步数: 4
2026-09-11 21:14:34.353 | INFO | koiagent.rag.knowledge:reload:202 - RAG 运行于【关键词检索】模式,已加载 2 个知识片段
2026-09-11 21:14:34.364 | INFO | koiagent.agent.graph:_classify:282 - [classify] 意图=price(路由: rule)
2026-09-11 21:14:34.367 | INFO | koiagent.agent.graph:_agent:322 - [agent] step=1, tool_calls=无
2026-09-11 21:14:34.371 | INFO | koiagent.agent.graph:_critic:366 - [critic] 草稿审核通过
2026-09-11 21:14:34.388 | WARNING | koiagent.agent.graph:_guard:227 - [guard] 拦截疑似 Prompt 注入 (score=10, 命中=['指令覆盖', '提示词探测'])
──────── KoiAgent 运行指标 ────────
总运行次数 : 3
错误次数 : 0 (错误率 0.00%)
平均耗时 : 10.63 ms
P95 耗时 : 20.16 ms
意图分布 : {'price': 1, 'tech': 2}
拦截注入 : 1
────────────────────────────────────
```
## 🚴 快速开始
### 环境要求
- Python 3.10+(依赖 langgraph / langchain 的最新版本要求)
### 安装步骤
```bash
1. 克隆仓库
git clone https://github.com/Xiao-Snake123/KoiAgent.git
cd KoiAgent
2. 安装依赖
pip install -r requirements.txt
3. 配置环境变量
复制 .env.example 为 .env,并填写以下内容:
```
```dotenv
# 必配配置
API_KEY=apikey通过模型平台获取
COOKIES_STR=填写网页端获取的cookie
MODEL_BASE_URL=模型地址
MODEL_NAME=模型名称
# 可选配置
TOGGLE_KEYWORDS=接管模式切换关键词,默认为句号(输入句号切换为人工接管,再次输入则切换AI接管)
SIMULATE_HUMAN_TYPING=False # 模拟人工回复延迟
# Agent 编排(可选)
AGENT_MAX_STEPS=4 # ReAct 最大推理步数
AGENT_MAX_MESSAGES=20 # 单次送入模型的最大历史消息数
AGENT_MAX_REFLECTIONS=1 # 审核驳回后的最大返工轮数
CRITIC_ENABLED=true # 是否启用审核 Agent
KNOWLEDGE_DIR=knowledge # 本地知识库目录
# RAG 向量检索(可选,留空 EMBEDDING_MODEL 则自动使用关键词检索)
EMBEDDING_MODEL= # 如 text-embedding-v3
EMBEDDING_BASE_URL= # 留空回退 MODEL_BASE_URL
EMBEDDING_API_KEY= # 留空回退 API_KEY
RAG_TOP_K=3 # 返回片段数
RAG_CHUNK_SIZE=300 # 切片长度
RAG_CHUNK_OVERLAP=60 # 切片重叠
# 输入侧 Prompt 注入防护(可选)
GUARD_ENABLED=true # 关闭注入防护
GUARD_BLOCK_SCORE=5 # 拦截阈值(命中权重累加)
GUARD_MAX_INPUT=1000 # 最大输入长度,超出截断
# 可靠性(可选)
LLM_MAX_CONCURRENCY=4 # LLM 并发上限
CIRCUIT_FAILURE_THRESHOLD=5 # 连续失败几次后熔断
CIRCUIT_RESET_TIMEOUT=60 # 熔断冷却秒数
FALLBACK_REPLY=稍等,我确认下再回复您 # 降级兜底话术
DEDUP_TTL=300 # 消息去重窗口(秒)
MEMORY_MAX_THREADS=500 # 会话记忆最大 thread 数
MEMORY_TTL=7200 # 会话记忆空闲淘汰(秒)
# 可观测性与稳定性(可选)
TRACE_ENABLED=true # 关闭追踪
TRACE_DIR=logs # Trace 与指标输出目录
LLM_TIMEOUT=30 # 单次 LLM 请求超时(秒)
LLM_MAX_RETRIES=2 # LLM 请求失败重试次数
HEALTH_FILE=data/health.json # 健康检查心跳文件
```
> 📘 **完整配置项(含逐项中文备注、模型选择建议、各厂商接入示例)见 [`.env.example`](./.env.example)。**
> 最小可用配置只需两项:`API_KEY`(模型密钥)与 `COOKIES_STR`(闲鱼网页端 Cookie)。
> - 默认使用**通义千问**,如需使用其他 API,请自行修改 `.env` 文件中的模型地址和模型名称;
> - `COOKIES_STR` 请在闲鱼网页端获取(网页端 F12 打开控制台,选择 Network,点击 Fetch/XHR,点击一个请求,查看 cookies)。
```bash
4. 准备提示词文件
prompts/*_prompt.txt 可直接删除模板名称中的 _example 得到,否则默认读取四个提示词模板中的内容
```
### 使用方法
运行主程序:
```bash
python -m koiagent # 推荐
# 或(等价)
python main.py
```
### 自定义提示词
可以通过编辑 `prompts` 目录下的文件来自定义各个专家的提示词:
- `classify_prompt.txt`: 意图分类提示词
- `price_prompt.txt`: 价格专家提示词
- `tech_prompt.txt`: 技术专家提示词
- `default_prompt.txt`: 默认回复提示词
- `critic_prompt.txt`: 审核 Agent 提示词(质检维度与判定规则)
## 📁 目录结构
```
KoiAgent/
├── koiagent/ # 主包
│ ├── __init__.py # 包元信息(__version__ / 分层说明)
│ ├── __main__.py # 入口:python -m koiagent
│ ├── app.py # 应用装配:WebSocket 长连 / 心跳 / Token 刷新 / 人工接管
│ ├── config.py # 配置加载 / 日志初始化 / 缺失配置交互式补全
│ ├── agent/ # Agent 编排层
│ │ ├── graph.py # LangGraph 状态图 guard→classify→agent⇄tools→critic
│ │ ├── tools.py # Function Calling 工具集
│ │ └── guard.py # 输入侧 Prompt 注入防护
│ ├── rag/
│ │ └── knowledge.py # RAG 检索层(向量 / 关键词双模式 + 向量缓存)
│ ├── platform/
│ │ ├── api.py # 平台 HTTP 接口(登录 / Token / 商品)
│ │ └── protocol.py # 协议工具(Cookie / 签名 / MessagePack 解码)
│ ├── infra/
│ │ ├── observability.py # 全链路 Trace / 指标聚合 / Token 与成本
│ │ └── resilience.py # 幂等去重 / 熔断 / 并发限流 / 记忆治理
│ ├── storage/
│ │ └── context.py # SQLite 业务数据(议价次数 / 商品缓存)
│ ├── mcp/
│ │ └── server.py # MCP Server
│ └── ops/
│ └── healthcheck.py # 容器健康检查
├── main.py # 兼容入口(等价于 python -m koiagent)
├── knowledge/ # 本地知识库(供 search_knowledge_base 检索)
├── prompts/ # 专家提示词模板
├── eval/ # 评估 Harness(评估集 + runner + 报告)
├── tests/ # pytest 单元测试
├── .github/workflows/ # CI 流水线(编译 + 测试 + 评估门禁)
├── images/ # 演示图片
├── pyproject.toml # 工具配置(pytest)
├── requirements.txt # 运行时依赖
├── requirements-dev.txt # 开发/测试依赖
├── Dockerfile
└── docker-compose.yml
```
## 🐳 Docker 部署
```bash
# 先准备 .env 与 prompts/*.txt
docker compose up -d
```
## 🔌 MCP 集成
项目内置 **MCP Server**,可把能力暴露给 Claude Desktop / Cursor 等任意 MCP 客户端。
```bash
python -m koiagent.mcp.server # stdio(桌面客户端默认)
python -m koiagent.mcp.server --transport streamable-http # HTTP 传输
```
**暴露的能力**
| 工具 | 作用 | 需要 LLM |
| ---- | ---- | ---- |
| `get_bargain_policy` | 按议价轮次返回阶梯让步策略 | 否 |
| `search_knowledge_base` | RAG 检索本地知识库 | 否 |
| `get_current_time` | 当前服务器时间 | 否 |
| `ask_koi_agent` | 委派完整 Agent 图处理并返回可直接发送的回复 | 是 |
**客户端配置**(`claude_desktop_config.json`)
```json
{
"mcpServers": {
"koi-agent": {
"command": "python",
"args": ["-m", "koiagent.mcp.server"],
"cwd": "/path/to/KoiAgent"
}
}
}
```
> 💡 三个纯工具**无需 API Key** 即可离线使用;只有 `ask_koi_agent` 需要配置模型 API,
> 未配置时返回明确提示而非报错。stdio 传输下日志被强制重定向到 stderr,保证协议帧独占 stdout。
## 🧪 质量保障
### 单元测试
```bash
pip install -r requirements-dev.txt
pytest
```
覆盖:Prompt 注入防护、意图路由、Function Calling 工具、RAG 双模式与缓存、可观测性、LangGraph 图结构与异步执行。
### 评估 Harness
```bash
python eval/run_eval.py # 离线:规则路由 + RAG 检索
python eval/run_eval.py --with-llm # 追加 LLM 路由兜底评估(需 API_KEY)
```
产出 `eval/report.md` 评估报告;未达 `--min-intent-acc` / `--min-retrieval-hit` 阈值时返回非 0 退出码,可**直接作为 CI 质量门禁**。
### 可观测性
| 产物 | 内容 |
| ---- | ---- |
| `logs/traces.jsonl` | 每次运行的意图 / 路由方式 / 工具调用序列 / 推理步数 / 耗时 / Token / 成本 / 异常 |
| `logs/metrics.json` | 累计运行数、错误率、平均与 P95 耗时、意图分布、工具分布、Token 与成本 |
程序退出时自动打印指标报告;配置 `LANGFUSE_*` 且安装 `langfuse` 后可自动上报。
### 持续集成
`.github/workflows/ci.yml` 在每次 push / PR 时执行:
**字节编译校验 → 单元测试 → 评估门禁**(未达阈值直接失败),并上传评估报告为构建产物。
### 容器健康检查
worker 类容器没有 HTTP 端口,因此采用**心跳文件探活**:主程序在连接建立与每次心跳响应成功时
刷新 `data/health.json`;`HEALTHCHECK` 每分钟调用 `python -m koiagent.ops.healthcheck` 校验其新鲜度
(默认 180s 内视为健康,可用 `HEALTH_MAX_AGE` 调整)。
## 🛡 免责声明
⚠️ 本项目仅供**学习与交流**使用,请遵守平台相关服务条款。使用本项目所产生的一切后果由使用者自行承担。
## 📄 开源协议
本项目基于 [GNU General Public License v3.0](./LICENSE) 发布。
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues