Files
group_fqcd_jr/start.ps1
T

168 lines
7.8 KiB
PowerShell
Raw Normal View History

<#
.SYNOPSIS
启动金融 Agent 平台:依赖检查 → API → Agent Worker。
.NOTES
⚠️ 本文件必须保存为 **UTF-8 with BOM**。
Windows PowerShell 5.1 在缺少 BOM 时按系统 ANSI 解析脚本(简体中文下是 GBK),
中文注释与输出会变成乱码并直接抛语法错误(实测报 `Unexpected token '[璀﹀憡]'`)。
用编辑器改完本文件后,务必另存为「UTF-8 带 BOM」。
.DESCRIPTION
平台需要**两个进程**才能完整工作,本脚本把它们一起起在独立窗口里:
· API —— 所有 HTTP 接口与前端页面(/portal/)
· Worker —— 消费队列:Agent 对话、知识向量同步、记忆抽取、风控扫描
**没有 Worker 的后果**(这也是最容易踩的坑):
· 客服对话会一直停在 queued,前端显示"客服繁忙/超时";
· 新灌的知识写不进 Milvus,客服照旧答不上,且**没有任何报错**。
.PARAMETER Port
API 监听端口,默认 8000。
.PARAMETER SkipChecks
跳过依赖端口检查(MySQL / Redis / Milvus)。
.PARAMETER ApiOnly
只起 API,不起 Worker(仅在明确不需要 Agent 能力时使用)。
.PARAMETER SkipPriceSync
跳过启动时的行情刷新。仅在外部数据源不可用、或不想联网时使用。
.EXAMPLE
powershell -ExecutionPolicy Bypass -File start.ps1
powershell -ExecutionPolicy Bypass -File start.ps1 -Port 8100
#>
param(
[int]$Port = 8000,
[switch]$SkipChecks,
[switch]$ApiOnly,
[switch]$SkipPriceSync
)
$ErrorActionPreference = "Stop"
$Root = $PSScriptRoot
Set-Location $Root
Write-Host "=== 金融 Agent 平台 · 启动 ===" -ForegroundColor Cyan
Write-Host "工作目录:$Root"
# ---------------------------------------------------------------- 解释器
# 逐个尝试:项目虚拟环境 → 常见 conda 环境 → PATH 上的 python。
# 不写死任何一个,因为各人机器的环境不同(.venv 被 gitignore,不进仓库)。
$candidates = @(
(Join-Path $Root ".venv\Scripts\python.exe"),
"D:\conda\envs\jr_py313\python.exe",
"python"
)
$Python = $null
foreach ($candidate in $candidates) {
try {
if ($candidate -eq "python") {
$version = & python --version 2>&1
} else {
if (-not (Test-Path $candidate)) { continue }
$version = & $candidate --version 2>&1
}
if ($LASTEXITCODE -eq 0) {
$Python = $candidate
Write-Host "解释器:$candidate($version)" -ForegroundColor Green
break
}
} catch { continue }
}
if (-not $Python) {
Write-Host "[失败] 找不到可用的 Python。请先建虚拟环境,或把解释器路径加进本脚本的候选列表。" -ForegroundColor Red
exit 1
}
# ---------------------------------------------------------------- 依赖检查
if (-not $SkipChecks) {
Write-Host "`n--- 依赖服务检查 ---" -ForegroundColor Cyan
$services = @(
@{ Name = "MySQL"; HostName = "127.0.0.1"; Port = 3306; Required = $true },
@{ Name = "Redis"; HostName = "127.0.0.1"; Port = 6379; Required = $false },
@{ Name = "Milvus"; HostName = "127.0.0.1"; Port = 19530; Required = $false }
)
foreach ($service in $services) {
$reachable = $false
try {
$reachable = (Test-NetConnection -ComputerName $service.HostName -Port $service.Port `
-InformationLevel Quiet -WarningAction SilentlyContinue)
} catch { $reachable = $false }
if ($reachable) {
Write-Host (" [OK] {0,-7} {1}:{2}" -f $service.Name, $service.HostName, $service.Port) -ForegroundColor Green
} elseif ($service.Required) {
Write-Host (" [缺失] {0,-7} {1}:{2} —— 平台起不来,请先启动它" -f $service.Name, $service.HostName, $service.Port) -ForegroundColor Red
exit 1
} else {
Write-Host (" [警告] {0,-7} {1}:{2} 不可达:相关知识检索会降级、Docker 未运行时常见" -f $service.Name, $service.HostName, $service.Port) -ForegroundColor Yellow
}
}
}
# ---------------------------------------------------------------- 刷新行情
# ⚠️ 为什么放在启动流程里:下单要求行情快照落在 **15 分钟**有效期内
# (`app/service/trade_service.py` 的 `MAX_QUOTE_AGE`),超时后**所有委托直接 503
# 「行情已过期」**,而系统**没有任何自动刷新机制** —— 演示时讲到一半下单就会失败。
# 所以默认在启动时刷一次:15 分钟窗口从此刻重新计时。
# 同步是按产品 upsert 的幂等操作;失败只警告不阻断(仍可手动重跑)。
if (-not $SkipPriceSync) {
Write-Host "`n--- 刷新行情(下单前置,有效期 15 分钟)---" -ForegroundColor Cyan
$syncOutput = & $Python "tools\sync_market_prices.py" 2>&1
if ($LASTEXITCODE -eq 0) {
Write-Host " [OK] 行情已刷新,15 分钟内可正常下单" -ForegroundColor Green
} else {
Write-Host " [警告] 行情刷新失败(退出码 $LASTEXITCODE):下单可能返回 503" -ForegroundColor Yellow
Write-Host " 可手动重跑:$Python tools\sync_market_prices.py" -ForegroundColor Yellow
$syncOutput | Select-Object -Last 8 | ForEach-Object { Write-Host " $_" -ForegroundColor DarkGray }
}
}
# ---------------------------------------------------------------- 启动进程
# 用独立窗口起,方便分别看两边的日志(Worker 的日志是排查问题的第一现场)。
function Start-PlatformWindow {
param([string]$Title, [string[]]$Arguments)
$shell = if (Get-Command pwsh -ErrorAction SilentlyContinue) { "pwsh" } else { "powershell" }
$command = "`$host.UI.RawUI.WindowTitle = '$Title'; & '$Python' " + ($Arguments -join " ")
Start-Process -FilePath $shell -ArgumentList "-NoExit", "-Command", $command | Out-Null
}
Write-Host "`n--- 启动进程 ---" -ForegroundColor Cyan
Start-PlatformWindow -Title "平台 API :$Port" -Arguments @(
"-m", "uvicorn", "app.main:app", "--host", "127.0.0.1", "--port", "$Port"
)
Write-Host " [已启动] API 窗口(uvicorn,端口 $Port)" -ForegroundColor Green
if (-not $ApiOnly) {
Start-PlatformWindow -Title "平台 Agent Worker" -Arguments @("-m", "app.worker")
Write-Host " [已启动] Worker 窗口(Agent 对话 / 知识向量 / 记忆抽取)" -ForegroundColor Green
} else {
Write-Host " [跳过] Worker(-ApiOnly):客服对话会一直 queued、新知识不会进 Milvus" -ForegroundColor Yellow
}
# ---------------------------------------------------------------- 访问入口
Start-Sleep -Seconds 3
Write-Host "`n=== 访问入口 ===" -ForegroundColor Cyan
Write-Host " 门户首页 http://127.0.0.1:$Port/portal/"
Write-Host " 访客页 http://127.0.0.1:$Port/portal/guest/home/"
Write-Host " 客户登录 http://127.0.0.1:$Port/portal/customer/login/ (cust_t / 123456)"
Write-Host " 员工登录 http://127.0.0.1:$Port/portal/employee-console/login/(见下)"
Write-Host " 接口文档 http://127.0.0.1:$Port/docs"
Write-Host "`n=== 演示账号 ===" -ForegroundColor Cyan
Write-Host " 客户 cust_t / 123456"
Write-Host " 风控专员 risk_t / 666666"
Write-Host " 管理员 admin_t / 88888888"
Write-Host " 投顾 advisor_t / abc12345"
Write-Host " 运营 offsite_t / offsite123"
Write-Host "`n提示:" -ForegroundColor Yellow
Write-Host " · 首次使用先准备数据:python tools/seed_demo_data.py"
Write-Host " · 行情有效期只有 15 分钟:演示中途下单若报 503,在新窗口重跑"
Write-Host " python tools/sync_market_prices.py (立即生效,无需重启服务)"
Write-Host " · 体检:python tools/e2e_smoke_test.py"
Write-Host " · 演示流程见 docs/44-演示流程.md"