๐ค ๅบไบ MCP ๅ่ฎฎ็ๆบ่ฝ Agent ็ณป็ป | ๆฏๆๅคๆ่ฝ่ฐๅบฆใๅทฅๅ ท่ฐ็จไธ RAG ๅขๅผบ | Ollama + Vue 3 + FastAPI
SkillMCP-Agent
๐ค ๅบไบ MCP ๅ่ฎฎ็ๆบ่ฝ Agent ็ณป็ป
ๆฏๆๅคๆ่ฝ่ฐๅบฆใๅทฅๅ ท่ฐ็จไธ RAG ๅขๅผบ | 100% ็ๅฎๆฐๆฎ | ้ถ่ๆ
๐ ๅฟซ้ๅผๅง | ๐ ่ฏฆ็ปๆๆกฃ | ๐ฏ ๅ่ฝ็นๆง | ๐บ๏ธ ่ทฏ็บฟๅพ | ๐ค ่ดก็ฎๆๅ
๐ฏ ้กน็ฎๆฆ่ฟฐ
SkillMCP-Agent ๆฏไธไธช็ไบง็บง็ AI Agent ็ณป็ป๏ผ้็จๆจกๅๅๆถๆ่ฎพ่ฎก๏ผๅฎ็ฐไบ๏ผ
- ๐ง ๆบ่ฝ่งๅ๏ผๅค่ฝฎๅฏน่ฏ็่งฃ + ๆๅพ่ฏๅซ + ไปปๅกๅ่งฃ
- โก ๆ่ฝ่ฐๅบฆ๏ผๅบไบ่ฏญไนๅน้ ็ๆ่ฝ้ๆฉไธๆง่ก
- ๐ง MCP ๅทฅๅ ท๏ผ้ตๅพช Model Context Protocol ่ง่็ๅทฅๅ ท่ฐ็จ
- ๐ RAG ๅขๅผบ๏ผๅ้ๆฃ็ดขๅขๅผบ็ๆ๏ผๆฏๆ็ฅ่ฏๅบ้ฎ็ญ
- ๐จ ๅฏ่งๅๆงๅถๅฐ๏ผVue 3 + Element Plus ๆๅปบ็ Agent Console
ๆๆฏไบฎ็น
| ็นๆง | ่ฏดๆ | |------|------| | MCP ๅ่ฎฎ | ๅฎ็ฐๆ ๅ MCP Server/Client๏ผๆฏๆๅทฅๅ ทๅ็ฐไธ่ฐ็จ | | ๅคๆจกๅๆฏๆ | ๆฏๆ OpenAIใOllama ๆฌๅฐๆจกๅใ่ชๅฎไน LLM | | ๆตๅผๅๅบ | SSE ๅฎๆถๆจ้ Agent ๆ่่ฟ็จไธๆง่ก็ถๆ | | ๆง่ก่ฟฝ่ธช | ๅฎๆด็ๆง่ก้พ่ทฏ่ฟฝ่ธชไธๅทฅๅ ท่ฐ็จ่ฎฐๅฝ | | ็ญๆๆๆ่ฝ | ้่ฟ่ฃ ้ฅฐๅจๅฟซ้ๆณจๅๆฐๆ่ฝ๏ผๆ ้ไฟฎๆนๆ ธๅฟไปฃ็ |
๐ ๆถๆ่ฎพ่ฎก
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Frontend (Vue 3) โ
โ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ ChatInput โ โ MessageView โ โ DebugPanel / AgentTrace โ โ
โ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ HTTP/SSE
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ FastAPI Backend โ
โ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ /chat โ โ /stream โ โ /health /sessions โ โ
โ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Agent Orchestrator โ
โ โโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโ โโโโโโโโโโโโโ โ
โ โ Planner โโ โ SkillSelectorโโ โ Executor โโ โ Reasoner โ โ
โ โโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโ โโโโโโโโโโโโโ โ
โ โ โ โ โ
โ โโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโ โ
โ โ Memory โ โ Tracer โ โ ToolRecord โ โ
โ โโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโ
โผ โผ โผ
โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ
โ Skills Layer โ โ MCP Client โ โ RAG Pipeline โ
โ โโโโโโโโโโโโโ โ โ โ โ โโโโโโโโโโ โ
โ โ travel โ โ โ โโโโโโโโ โ โ โEmbedderโ โ
โ โ weather โ โ โ โTools โ โ โ โChunker โ โ
โ โ knowledge โ โ โ โโโโโโโโ โ โ โRetriev โ โ
โ โ summarize โ โ โ โ โ โโโโโโโโโโ โ
โ โโโโโโโโโโโโโ โ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ
โโโโโโโโโโโโโโโโโโโ โ
โผ
โโโโโโโโโโโโโโโโโโโโ
โ MCP Server โ
โ โโโโโโโโโโโโโโ โ
โ โtrain_query โ โ
โ โweather_api โ โ
โ โsystem_time โ โ
โ โrag_retriev โ โ
โ โโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโ
ๆ ธๅฟๆจกๅ
| ๆจกๅ | ่่ดฃ | ๅ
ณ้ฎ็ฑป |
|------|------|--------|
| Core | ๅบ็ก่ฎพๆฝ๏ผ้
็ฝฎใๆฅๅฟใๅผๅธธ | Settings, get_logger |
| Agent | ไปปๅก่งๅไธๆง่ก่ฐๅบฆ | AgentOrchestrator, Planner, Executor |
| Skills | ไธๅกๆ่ฝๅฐ่ฃ
| BaseSkill, SkillRegistry |
| MCP | ๅทฅๅ
ทๅ่ฎฎๅฎ็ฐ | MCPServer, MCPClient, BaseTool |
| RAG | ๆฃ็ดขๅขๅผบ็ๆ | RAGPipeline, Embedder, VectorStore |
| API | HTTP ๆฅๅฃๅฑ | FastAPI, ChatService |
๐ ๅฟซ้ๅผๅง
็ฏๅข่ฆๆฑ
- Python 3.10+
- Node.js 18+ (ๅ็ซฏ)
- Ollama (ๆฌๅฐๆจกๅ) ๆ OpenAI API Key
ๅฎ่ฃ ๆญฅ้ชค
# 1. ๅ
้้กน็ฎ
git clone https://github.com/yourusername/SkillMCP-Agent.git
cd SkillMCP-Agent
# 2. ๅๅปบ่ๆ็ฏๅข
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
# 3. ๅฎ่ฃ
ไพ่ต
pip install -r requirements.txt
# 4. ้
็ฝฎ็ฏๅขๅ้
cp .env.example .env
# ็ผ่พ .env ้
็ฝฎ LLM ๅๆฐ
# 5. ๅฏๅจๅ็ซฏ
python -m uvicorn src.api.app:app --reload --port 8000
# 6. ๅฏๅจๅ็ซฏ (ๆฐ็ป็ซฏ)
cd frontend
npm install
npm run dev
้ ็ฝฎ่ฏดๆ
# .env ๆไปถ
# LLM ้
็ฝฎ
LLM_PROVIDER=ollama # ollama / openai
OLLAMA_MODEL=gemma3:latest # Ollama ๆจกๅๅ
OLLAMA_EMBEDDING_MODEL=nomic-embed-text:latest
# OpenAI ้
็ฝฎ (ๅฏ้)
OPENAI_API_KEY=sk-xxx
OPENAI_MODEL=gpt-4o-mini
# RAG ้
็ฝฎ
RAG_EMBEDDER_TYPE=ollama
EMBEDDING_DIMENSION=768
# ๆฅๅฟ
LOG_LEVEL=INFO
ๅฟซ้้ช่ฏ
# ๅฅๅบทๆฃๆฅ
curl http://localhost:8000/api/v1/health
# ๅ้ๆถๆฏ
curl -X POST http://localhost:8000/api/v1/chat \
-H "Content-Type: application/json" \
-d '{"message": "ๅไบฌไปๅคฉๅคฉๆฐๆไนๆ ท๏ผ"}'
๐ ๆฉๅฑๆๅ
ๆฐๅข Skill
ๆ่ฝๆฏไธๅก้ป่พ็ๅฐ่ฃ ๅๅ ๏ผ้่ฟ่ฃ ้ฅฐๅจๆณจๅ๏ผ
# src/skills/my_skill.py
from src.skills.base import BaseSkill, skill_registry
@skill_registry.register("my_skill")
class MySkill(BaseSkill):
"""ๆ็่ชๅฎไนๆ่ฝ"""
name = "my_skill"
description = "่ฟๆฏไธไธช่ชๅฎไนๆ่ฝ๏ผ็จไบๅค็็นๅฎไปปๅก"
# ๆ่ฝ่งฆๅๅ
ณ้ฎ่ฏ
keywords = ["ๅ
ณ้ฎ่ฏ1", "ๅ
ณ้ฎ่ฏ2", "็นๅฎๅบๆฏ"]
async def execute(self, query: str, context: dict = None) -> dict:
"""
ๆง่กๆ่ฝ้ป่พ
Args:
query: ็จๆท่พๅ
ฅ
context: ไธไธๆไฟกๆฏ๏ผๅ
ๅซๅๅฒๅฏน่ฏใ็จๆทไฟกๆฏ็ญ๏ผ
Returns:
dict: ๅ
ๅซ success, data, message ็็ปๆ
"""
# 1. ่งฃๆ็จๆทๆๅพ
intent = self._parse_intent(query)
# 2. ่ฐ็จ MCP ๅทฅๅ
ท (ๅฆ้่ฆ)
from src.mcp import get_mcp_client
mcp = get_mcp_client()
tool_result = await mcp.call_tool("my_tool", {"param": "value"})
# 3. ๅค็็ปๆ
return {
"success": True,
"data": {
"result": tool_result,
"processed": self._process(tool_result)
},
"message": "ๅค็ๅฎๆ"
}
def _parse_intent(self, query: str) -> str:
# ๆๅพ่งฃๆ้ป่พ
return "default"
def _process(self, data: dict) -> dict:
# ๆฐๆฎๅค็้ป่พ
return data
ๆฐๅข MCP Tool
MCP ๅทฅๅ ทๆฏๅฏ่ขซ Agent ่ฐ็จ็ๅๅญ่ฝๅ๏ผ
# src/mcp/tools/my_tool.py
from src.mcp.base import BaseTool, tool_registry
@tool_registry.register("my_tool")
class MyTool(BaseTool):
"""ๆ็ MCP ๅทฅๅ
ท"""
name = "my_tool"
description = "ๆง่ก็นๅฎๆไฝ็ๅทฅๅ
ท"
# ๅๆฐ Schema (JSON Schema ๆ ผๅผ)
parameters = {
"type": "object",
"properties": {
"param1": {
"type": "string",
"description": "ๅๆฐ1่ฏดๆ"
},
"param2": {
"type": "integer",
"description": "ๅๆฐ2่ฏดๆ",
"default": 10
}
},
"required": ["param1"]
}
async def execute(self, **kwargs) -> dict:
"""
ๆง่กๅทฅๅ
ท้ป่พ
Args:
**kwargs: ๆ นๆฎ parameters schema ไผ ๅ
ฅ็ๅๆฐ
Returns:
dict: ๅทฅๅ
ทๆง่ก็ปๆ
"""
param1 = kwargs.get("param1")
param2 = kwargs.get("param2", 10)
# ๆง่กๅ
ทไฝ้ป่พ
result = await self._do_something(param1, param2)
return {
"success": True,
"data": result
}
async def _do_something(self, p1: str, p2: int) -> dict:
# ๅฎ้
ไธๅก้ป่พ
return {"processed": f"{p1}-{p2}"}
ๆฐๅข RAG ๆฐๆฎๆบ
# ๆทปๅ ๆๆกฃๅฐ RAG ็ฅ่ฏๅบ
from src.rag import get_rag_pipeline
pipeline = get_rag_pipeline()
# ๆนๅผ1: ไปๆไปถๅ ่ฝฝ
await pipeline.load_documents("path/to/documents/")
# ๆนๅผ2: ็ดๆฅๆทปๅ ๆๆฌ
await pipeline.add_texts([
"่ฟๆฏ็ฌฌไธๆฎต็ฅ่ฏๅ
ๅฎน...",
"่ฟๆฏ็ฌฌไบๆฎต็ฅ่ฏๅ
ๅฎน...",
], metadata=[
{"source": "manual", "category": "FAQ"},
{"source": "manual", "category": "Guide"},
])
# ๆฃ็ดข้ช่ฏ
results = await pipeline.retrieve("็ธๅ
ณ้ฎ้ข", top_k=3)
๐ก API ๆๆกฃ
POST /api/v1/chat
ๅ้ๆถๆฏๅนถ่ทๅ Agent ๅๅบ
Request:
{
"message": "ๅไบฌๆๅคฉ็ๅคฉๆฐๆไนๆ ท๏ผ",
"session_id": "optional-session-id",
"stream": false
}
Response:
{
"success": true,
"data": {
"response": "ๅไบฌๆๅคฉๆด๏ผๆฐๆธฉ 15-25ยฐC๏ผ้ๅๅบ่กใ",
"structured": {
"intent": "weather",
"skill": "weather_skill",
"tools_called": ["weather_query"],
"execution_time_ms": 1234
}
},
"session_id": "sess_abc123",
"trace_id": "trace_xyz789"
}
GET /api/v1/chat/stream
SSE ๆตๅผๅๅบ
Event Types:
thinking: Agent ๆ่่ฟ็จtool_call: ๅทฅๅ ท่ฐ็จไบไปถcontent: ๅๅบๅ ๅฎน็ๆฎตdone: ๅฎๆไฟกๅท
GET /api/v1/health
ๅฅๅบทๆฃๆฅ
Response:
{
"status": "healthy",
"version": "1.0.0",
"components": {
"llm": "ok",
"mcp": "ok",
"rag": "ok"
}
}
๐ ๆง่ก่ฟฝ่ธช
็ณป็ปๅ ็ฝฎๅฎๆด็ๆง่ก่ฟฝ่ธช่ฝๅ๏ผ
from src.agent import create_tracer, TraceEventType
# ๅๅปบ่ฟฝ่ธชๅจ
tracer = create_tracer()
tracer.start(query="็จๆทๆฅ่ฏข")
# ่ฟฝ่ธช่งๅ้ถๆฎต
with tracer.trace(TraceEventType.PLANNER_START):
tracer.log_intent("weather")
tracer.log_plan(["่งฃๆๅๅธ", "ๆฅ่ฏขๅคฉๆฐ", "ๆ ผๅผๅ็ปๆ"])
# ่ฟฝ่ธชๅทฅๅ
ท่ฐ็จ
tracer.log_tool_call(
tool_name="weather_query",
arguments={"city": "ๅไบฌ"},
result={"temp": 25},
duration_ms=150
)
# ่ทๅ่ฟฝ่ธชๆฅๅ
report = tracer.get_report()
timeline = tracer.get_timeline()
ๆงๅถๅฐ่พๅบ็คบไพ:
๐ [agent_start] {"query": "ๅไบฌๅคฉๆฐ"}
๐ฏ [planner_start]
๐ก [planner_intent] {"intent": "weather"}
๐ [planner_plan] {"step_count": 3}
โ [planner_end] (15.2ms)
โก [skill_selected] {"skill": "weather_skill"}
๐ง [mcp_call_start] {"tool": "weather_query"}
โ [mcp_call_end] (150.3ms)
โ
[agent_end] (320.5ms) {"total_tool_calls": 1}
๐งช ๆต่ฏ
# ่ฟ่กๆๆๆต่ฏ
pytest tests/ -v
# ่ฟ่ก็นๅฎๆต่ฏ
pytest tests/test_ollama.py -v
# ๆต่ฏ่ฆ็็
pytest tests/ --cov=src --cov-report=html
๐ ้กน็ฎ็ปๆ
SkillMCP-Agent/
โโโ src/
โ โโโ core/ # ๆ ธๅฟๅบ็ก่ฎพๆฝ
โ โ โโโ config.py # ้
็ฝฎ็ฎก็
โ โ โโโ logging.py # ๆฅๅฟ็ณป็ป
โ โ โโโ exceptions.py # ๅผๅธธๅฎไน
โ โ โโโ ollama.py # Ollama ๅฎขๆท็ซฏ
โ โโโ agent/ # Agent ๆ ธๅฟ
โ โ โโโ orchestrator.py # ็ผๆๅจ
โ โ โโโ planner.py # ่งๅๅจ
โ โ โโโ executor.py # ๆง่กๅจ
โ โ โโโ reasoner.py # ๆจ็ๅจ
โ โ โโโ tracer.py # ๆง่ก่ฟฝ่ธช
โ โ โโโ tool_recorder.py # ๅทฅๅ
ท่ฎฐๅฝ
โ โโโ skills/ # ๆ่ฝๅฑ
โ โ โโโ base.py # ๆ่ฝๅบ็ฑป
โ โ โโโ registry.py # ๆ่ฝๆณจๅ่กจ
โ โ โโโ impl/ # ๆ่ฝๅฎ็ฐ
โ โโโ mcp/ # MCP ๅ่ฎฎๅฑ
โ โ โโโ server.py # MCP ๆๅก็ซฏ
โ โ โโโ client.py # MCP ๅฎขๆท็ซฏ
โ โ โโโ base.py # ๅทฅๅ
ทๅบ็ฑป
โ โ โโโ tools/ # ๅทฅๅ
ทๅฎ็ฐ
โ โโโ rag/ # RAG ๅญ็ณป็ป
โ โ โโโ pipeline.py # RAG ๆตๆฐด็บฟ
โ โ โโโ embedder.py # ๅ้ๅ
โ โ โโโ chunker.py # ๆๆกฃๅๅ
โ โ โโโ retriever.py # ๆฃ็ดขๅจ
โ โโโ api/ # API ๅฑ
โ โโโ app.py # FastAPI ๅบ็จ
โ โโโ routes/ # ่ทฏ็ฑ
โ โโโ schemas/ # ๆฐๆฎๆจกๅ
โโโ frontend/ # Vue 3 ๅ็ซฏ
โ โโโ src/
โ โ โโโ views/ # ้กต้ข
โ โ โโโ components/ # ็ปไปถ
โ โ โโโ api/ # API ่ฐ็จ
โ โโโ vite.config.js
โโโ tests/ # ๆต่ฏ
โโโ docs/ # ๆๆกฃ
โโโ requirements.txt
๐ ๆๆฏๆ
ๅ็ซฏ:
- Python 3.10+
- FastAPI - ้ซๆง่ฝ Web ๆกๆถ
- Pydantic - ๆฐๆฎ้ช่ฏ
- httpx - ๅผๆญฅ HTTP ๅฎขๆท็ซฏ
- FAISS - ๅ้ๅญๅจ
ๅ็ซฏ:
- Vue 3 - ๅๅบๅผๆกๆถ
- Vite - ๆๅปบๅทฅๅ ท
- Element Plus - UI ็ปไปถๅบ
- Pinia - ็ถๆ็ฎก็
LLM:
- Ollama - ๆฌๅฐๆจกๅ้จ็ฝฒ
- OpenAI API - ไบ็ซฏๆจกๅ
๐ License
MIT License
๐ค Contributing
ๆฌข่ฟๆไบค Issue ๅ Pull Request๏ผ
- Fork ๆฌไปๅบ
- ๅๅปบ็นๆงๅๆฏ (
git checkout -b feature/amazing-feature) - ๆไบคๆดๆน (
git commit -m 'Add amazing feature') - ๆจ้ๅฐๅๆฏ (
git push origin feature/amazing-feature) - ๆไบค Pull Request
ๅฆๆ่ฟไธช้กน็ฎๅฏนไฝ ๆๅธฎๅฉ๏ผ่ฏท็ปไธไธช โญ Star๏ผ