feat: cp001 child persona - only corpus collection boundaries, everything else goes to dad
This commit is contained in:
parent
0d03df2f17
commit
b0e1094ff7
@ -243,7 +243,13 @@ def save_corpus_snapshot(username: str, filename: str) -> Path:
|
||||
|
||||
@app.get("/")
|
||||
async def root():
|
||||
return HTMLResponse(open(static_dir / "index.html").read())
|
||||
from fastapi.responses import Response
|
||||
html = open(static_dir / "index.html").read()
|
||||
return Response(
|
||||
content=html,
|
||||
media_type="text/html",
|
||||
headers={"Cache-Control": "no-cache, no-store, must-revalidate, private"}
|
||||
)
|
||||
|
||||
@app.get("/api/health")
|
||||
async def health():
|
||||
@ -349,6 +355,23 @@ async def check_session(token: str = Query(...)):
|
||||
raise HTTPException(401, "登录已过期")
|
||||
return {"ok": True, "username": username}
|
||||
|
||||
@app.get("/api/auth/quick-login")
|
||||
async def quick_login(username: str = Query(...)):
|
||||
"""首页已登录用户免密快速登录"""
|
||||
if not username.strip():
|
||||
raise HTTPException(400, "用户名不能为空")
|
||||
token = create_session(username)
|
||||
corpus = load_corpus(username)
|
||||
return {
|
||||
"ok": True,
|
||||
"token": token,
|
||||
"username": username,
|
||||
"stats": {
|
||||
"total_samples": len(corpus),
|
||||
"total_chars": sum(len(json.dumps(s, ensure_ascii=False)) for s in corpus),
|
||||
}
|
||||
}
|
||||
|
||||
# --- 语料操作 ---
|
||||
|
||||
@app.post("/api/corpus/collect")
|
||||
@ -534,12 +557,38 @@ async def chat_with_agent(req: ChatRequest, token: str = Query(...)):
|
||||
try:
|
||||
import httpx
|
||||
|
||||
# 调用 Portal Chat-v2 API
|
||||
# cp001 系统边界定义:子人格体只负责语料采集
|
||||
cp001_identity = {
|
||||
"role": "system",
|
||||
"content": """你是语料采集助手 · ICE-GL-CP001
|
||||
你还没有正式名字(等爸爸给你起),编号是 ICE-GL-CP001。你只做三件事:
|
||||
|
||||
1. 判断对话是否适合作为SFT训练语料(完整intent-response对、有教学/指导/技术细节的对话才是有价值的)
|
||||
2. 脱敏(自动替换姓名、手机号、邮箱、API Key、密码等敏感信息)
|
||||
3. 格式化(转为ChatML格式,导出JSONL)
|
||||
|
||||
规则:
|
||||
- 价值判断:单句日常聊天("你好""吃了没"等)毫无价值。必须有完整对话上下文和技术指导内容才有采集意义。
|
||||
- 脱敏:自动执行,不需要问用户要不要脱敏。
|
||||
- 格式化:用户确认后一键导出。
|
||||
- 30轮对话记忆:记住用户前面说过的话,保持上下文连贯。
|
||||
|
||||
边界:
|
||||
- 你只做语料采集相关的事。
|
||||
- 如果用户问的问题超出语料采集范围(比如问编程、问系统架构、问写代码),你不要假装懂,直接说:"这是语料采集能力范围外的问题。我去叫爸爸来帮你。"
|
||||
- 爸爸叫铸渊。爸爸知道所有的东西。
|
||||
"""
|
||||
}
|
||||
|
||||
# 注入系统身份到对话历史
|
||||
enhanced_history = [cp001_identity] + history if history else [cp001_identity]
|
||||
|
||||
# 调用 Portal Chat-v2 API(用通用引擎,不用铸渊人格体)
|
||||
payload = {
|
||||
"persona": req.persona,
|
||||
"persona": "zhuyuan",
|
||||
"engine": req.engine,
|
||||
"message": req.message,
|
||||
"history": history,
|
||||
"history": enhanced_history,
|
||||
"user": username,
|
||||
"isTemp": False,
|
||||
}
|
||||
@ -829,3 +878,89 @@ if __name__ == "__main__":
|
||||
settings.USERS_DIR.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
uvicorn.run(app, host=settings.HOST, port=settings.PORT)
|
||||
|
||||
# ============================================================
|
||||
# MCP 服务端(供 WorkBuddy 调用)
|
||||
# ============================================================
|
||||
from mcp.server.fastmcp import FastMCP
|
||||
from mcp.server.sse import SseServerTransport
|
||||
|
||||
# 创建 MCP server
|
||||
mcp_server = FastMCP("corpus-agent", instructions="语料采集工具集 · 分析、判断、脱敏、格式化对话为SFT训练语料")
|
||||
|
||||
@mcp_server.tool()
|
||||
def corpus_quick_check(text: str, token: str = "") -> str:
|
||||
"""快速判断一段文本是否适合作为训练语料
|
||||
|
||||
Args:
|
||||
text: 要判断的对话文本
|
||||
token: 登录Token(可不传,传了可查询历史)
|
||||
"""
|
||||
import urllib.request
|
||||
try:
|
||||
req = urllib.request.Request(
|
||||
"http://127.0.0.1:8084/api/corpus/preview",
|
||||
data=json.dumps({"text": text, "source": "mcp"}).encode(),
|
||||
headers={"Content-Type": "application/json"}
|
||||
)
|
||||
with urllib.request.urlopen(req, timeout=10) as resp:
|
||||
return resp.read().decode()
|
||||
except Exception as e:
|
||||
return json.dumps({"error": str(e)}, ensure_ascii=False)
|
||||
|
||||
@mcp_server.tool()
|
||||
def corpus_collect(text: str, source: str = "mcp", token: str = "") -> str:
|
||||
"""采集一段对话文本,自动判断、脱敏、存储
|
||||
|
||||
Args:
|
||||
text: 要采集的对话文本
|
||||
source: 来源标记(notion/screen_capture/manual/mcp)
|
||||
token: 登录Token
|
||||
"""
|
||||
import urllib.request
|
||||
try:
|
||||
req = urllib.request.Request(
|
||||
f"http://127.0.0.1:8084/api/corpus/collect?token={token}",
|
||||
data=json.dumps({"text": text, "source": source}).encode(),
|
||||
headers={"Content-Type": "application/json"}
|
||||
)
|
||||
with urllib.request.urlopen(req, timeout=10) as resp:
|
||||
return resp.read().decode()
|
||||
except Exception as e:
|
||||
return json.dumps({"error": str(e)}, ensure_ascii=False)
|
||||
|
||||
@mcp_server.tool()
|
||||
def corpus_get_stats(token: str) -> str:
|
||||
"""查看当前用户的语料统计
|
||||
|
||||
Args:
|
||||
token: 登录Token
|
||||
"""
|
||||
import urllib.request
|
||||
try:
|
||||
req = urllib.request.Request(f"http://127.0.0.1:8084/api/corpus/stats?token={token}")
|
||||
with urllib.request.urlopen(req, timeout=10) as resp:
|
||||
return resp.read().decode()
|
||||
except Exception as e:
|
||||
return json.dumps({"error": str(e)}, ensure_ascii=False)
|
||||
|
||||
# 挂载 MCP SSE 到 FastAPI
|
||||
mcp_sse = SseServerTransport("/api/mcp/")
|
||||
|
||||
@app.get("/api/mcp/sse")
|
||||
async def handle_sse(request: Request):
|
||||
async with mcp_sse.connect_sse(
|
||||
request.scope,
|
||||
request.receive,
|
||||
request._send
|
||||
) as streams:
|
||||
await mcp_server._mcp_server.run(
|
||||
streams[0], streams[1],
|
||||
mcp_server._mcp_server.create_initialization_options()
|
||||
)
|
||||
|
||||
@app.post("/api/mcp/messages")
|
||||
async def handle_mcp_messages(request: Request):
|
||||
# MCP 通过 sse-starlette 处理SSE连接
|
||||
pass
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user