xykj-plus/claude-ecc/dev-assistant/README.md
2026-06-13 13:48:51 +08:00

506 lines
14 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Dev-Assistant
嵌入式 AI 开发助手 — 专为 admin-xy 项目设计,支持 Claude / GLM / MiniMax 多模型运行时切换。
## 架构概览
```
┌─────────────────────────────────────────────────────────────────┐
│ admin-xy/web (React) │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ DevAssistantMount (侧栏组件) │ │
│ │ ┌─────────────────────────────────────────────────────────┐ │ │
│ │ │ @dev-assistant/web-sdk │ │ │
│ │ │ - WebSocket 通信 │ │ │
│ │ │ - 页面上下文捕获 (选区/控制台/网络请求) │ │ │
│ │ │ - 流式响应渲染 │ │ │
│ │ │ - 工具执行确认 │ │ │
│ │ └─────────────────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
│ WebSocket + HTTP
┌─────────────────────────────────────────────────────────────────┐
│ @dev-assistant/bridge (Node.js) │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ WebSocket 会话管理 │ │
│ │ - JWT 认证校验 (支持 HTTP 校验 / 本地解析) │ │
│ │ - 速率限制 │ │
│ │ - 上下文收集 (日志/文件/代码) │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 模型路由 & Agent SDK │ │
│ │ - 多模型协议适配 (Anthropic 兼容) │ │
│ │ - 工具执行 (Read/Edit/Bash/Glob/Grep) │ │
│ │ - 流式响应处理 │ │
│ └─────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
│ HTTP
┌────────────┴────────────┐
│ │
GLM / MiniMax Claude API
```
## 快速开始
### 前置要求
- Node.js >= 20
- admin-xy 后端服务运行在 http://localhost:9010
- AI 模型 API Key配置后存储在 keychain 或加密文件中)
### 安装依赖
```bash
cd dev-assistant
npm install
```
### 启动开发环境
```bash
# 启动桥接服务
npm run bridge:dev
# 构建前端 SDKadmin-xy/web 集成时需要)
npm run web-sdk:build
```
桥接服务默认监听 `http://127.0.0.1:9020`WebSocket 路径为 `/copilot`
## 配置说明
配置文件位于 `config/dev-assistant.yaml`,启动时自动加载,支持热更新。
### 核心配置项
```yaml
# 项目信息 — 驱动 AI 系统提示
project:
name: admin-xy
description: 企业管理系统 — 用户/角色/菜单/权限管理
techStack:
- Spring Boot 3
- Java 21
- React 18
- Vite
- TypeScript
conventions:
- 分层架构Controller → Service → Repository → Entity → DTO
- JWT 无状态认证
- Flyway 数据库迁移
# 工作目录配置
workspace:
root: ./ # 相对于仓库根
allowWrite:
- admin-xy/** # 允许写入的路径
- dev-assistant/**
denyWrite:
- .claude/** # 禁止写入的路径
- '**/.env*'
- '**/target/**'
- '**/node_modules/**'
# 日志源配置(用于 bugfix 场景自动附加)
logs:
- id: admin-server
label: admin-xy Spring Boot
path: admin-xy/server/logs/app.log
format: logback-json # 支持 logback-json / plain / spring-default
tailLines: 500
followDurationSec: 30
# 上下文预算控制
context:
maxPromptTokens: 16000
attachAsFileThreshold: 4000 # 超过此大小作为文件附件而非内联
cacheDir: dev-assistant/.cache
console:
keepLines: 200 # 控制台保留行数
network:
keepRequests: 50 # 网络请求保留数量
captureBody: true
bodyMaxBytes: 4096
# 场景配置
scenarios:
modify:
label: 调整现有页面
requireSelection: true # 要求用户选择文本
bugfix:
label: 排查页面问题
attachErrorLogs: true # 自动附加错误日志
followJavaLogs: true
# 桥接服务配置
bridge:
port: 9020
host: 127.0.0.1 # 容器环境改为 0.0.0.0
wsPath: /copilot
origin: https://oa.xiangyuetech.cn # CORS 允许的前端 Origin
wsIdleTimeoutMs: 1800000 # 30 分钟空闲超时
maxConcurrentChats: 1
auth:
type: http # http / jwt-local / disabled
verifyUrl: http://server:9010/api/auth/me # HTTP 校验端点
requiredRole: ROLE_ADMIN
cacheTtlSec: 60
rateLimit:
chatPerMinute: 20
httpPerMinute: 120
```
### 环境变量覆盖
生产环境可通过环境变量覆盖配置:
```bash
BRIDGE_HOST=0.0.0.0 # 监听地址
BRIDGE_AUTH_VERIFY_URL=http://... # 认证校验端点
BRIDGE_AUTH_DISABLED=true # 跳过认证(仅本机开发)
BRIDGE_ORIGIN=https://... # CORS 允许的 Origin
```
## 认证机制
支持三种认证模式:
### 1. HTTP 远程校验(默认)
桥接服务调用后端 `/api/auth/me` 接口验证 JWT 有效性。
```yaml
bridge:
auth:
type: http
verifyUrl: http://server:9010/api/auth/me
requiredRole: ROLE_ADMIN
```
### 2. JWT 本地解析
无需网络调用,本地解析 JWT 验证用户和角色。
```yaml
bridge:
auth:
type: jwt-local
jwtSecret: ${JWT_SECRET} # 从环境变量读取
jwtIssuer: admin-xy
jwtAudience: admin-xy-web
jwtUsernameClaim: sub
jwtRolesClaim: roles
requiredRole: ROLE_ADMIN
```
### 3. 禁用认证(仅开发环境)
```yaml
bridge:
auth:
type: disabled
```
或通过环境变量:
```bash
BRIDGE_AUTH_DISABLED=true npm run bridge:dev
```
## 模型管理
模型配置和 API Key 通过 Web SDK 动态管理,存储在 `dev-assistant/.cache/` 目录gitignore
### 支持的模型
- **Claude** (Anthropic) - 原生支持
- **GLM** (智谱 AI) - 通过协议适配器
- **MiniMax** - 通过协议适配器
### 管理接口
```http
# 获取模型列表
GET /api/models
# 设置活跃模型
PUT /api/models/active
Body: { "provider": "claude", "model": "claude-sonnet-4-6" }
# 更新 API Key
PUT /api/models/:provider/key
Body: { "apiKey": "sk-..." }
```
## WebSocket 协议
### 客户端 → 服务端
```typescript
// 发起对话
{
type: 'chat',
requestId: 'uuid',
scenario: 'bugfix',
prompt: '修复用户登录失败的问题',
context: {
url: '/login',
selection: '选中的代码',
console: [...],
network: [...]
}
}
// 中止对话
{ type: 'abort', requestId: 'uuid' }
// 工具执行决策
{
type: 'tool_decision',
requestId: 'uuid',
toolUseId: 'tool-xxx',
decision: 'allow', // 或 'deny'
message: '允许此操作'
}
```
### 服务端 → 客户端
```typescript
// 会话开始
{
type: 'session_started',
serverTime: 1714567890123,
active: { name: 'Claude', model: 'claude-sonnet-4-6' }
}
// 消息开始
{
type: 'message_started',
requestId: 'uuid',
provider: 'claude',
model: 'claude-sonnet-4-6'
}
// 文本流式输出
{
type: 'text_delta',
requestId: 'uuid',
text: '根据日志分析...'
}
// 工具使用开始
{
type: 'tool_use_started',
requestId: 'uuid',
toolUseId: 'tool-xxx',
name: 'Read'
}
// 工具执行请求(需用户确认)
{
type: 'tool_request',
requestId: 'uuid',
toolUseId: 'tool-xxx',
name: 'Bash',
input: { command: 'npm install' },
destructive: false
}
// 消息完成
{
type: 'message_done',
requestId: 'uuid',
stopReason: 'end_turn',
outputTokens: 1234
}
```
## 集成到 admin-xy
### 前端集成
```tsx
// admin-xy/web/src/integrations/dev-assistant.tsx
import { useEffect, useRef } from 'react';
import {
ADMIN_ROLE,
mountDevAssistant,
type DevAssistantHandle,
} from '@dev-assistant/web-sdk';
import '@dev-assistant/web-sdk/styles.css';
import { useAuthStore } from '@/stores/auth-store';
export function DevAssistantMount(): null {
const user = useAuthStore((s) => s.user);
const handleRef = useRef<DevAssistantHandle | null>(null);
useEffect(() => {
const isAdmin = !!user?.roles?.includes(ADMIN_ROLE);
if (!isAdmin) {
handleRef.current?.unmount();
return;
}
if (handleRef.current) return;
const token = useAuthStore.getState().token ?? undefined;
handleRef.current = mountDevAssistant({
bridgeHttpUrl: 'http://localhost:9020',
bridgeWsUrl: 'ws://localhost:9020/copilot',
roles: user?.roles ?? [],
userIdentifier: user?.username,
token,
});
return () => {
handleRef.current?.unmount();
handleRef.current = null;
};
}, [user]);
return null;
}
```
### 后端日志集成
在 Spring Boot 中添加 `RequestIdFilter``MdcUserFilter`,将请求 ID 和用户信息写入 MDC
```java
@Component
public class RequestIdFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
String requestId = ((HttpServletRequest) request).getHeader("X-Request-Id");
MDC.put("requestId", requestId != null ? requestId : UUID.randomUUID().toString());
try {
chain.doFilter(request, response);
} finally {
MDC.remove("requestId");
}
}
}
```
配置 logback JSON 输出,使日志包含 MDC 字段,便于 bridge 关联查询。
## 日志查询 API
```http
# 获取日志源列表
GET /api/logs/sources
# 读取单个日志源尾部
GET /api/logs/admin-server?tailLines=100&minLevel=WARN&contains=ERROR
# 聚合读取所有日志源
GET /api/logs?priority=high&minLevel=ERROR
# 按 RequestId 关联查询
GET /api/logs?requestId=abc-123-def
```
## 编程式 API
### 启动桥接服务
```typescript
import { startBridge } from '@dev-assistant/bridge';
const handle = await startBridge({
configPath: './my-config.yaml',
configOverrides: {
bridge: { port: 9021 }
},
// 自定义认证验证器
verifier: {
async verify(token) {
// 返回 { username, roles, isAdmin } 或 null
}
},
onReady: ({ port, host }) => {
console.log(`Bridge listening on ${host}:${port}`);
}
});
// 关闭服务
await handle.close();
```
### CLI 启动
```bash
npx dev-assistant-bridge --config ./dev-assistant.yaml
```
## Docker 部署
```yaml
# docker-compose.yml
services:
dev-assistant:
image: dev-assistant:latest
ports:
- "9020:9020"
environment:
- BRIDGE_HOST=0.0.0.0
- BRIDGE_AUTH_VERIFY_URL=http://admin-server:9010/api/auth/me
- BRIDGE_ORIGIN=https://oa.xiangyuetech.cn
volumes:
- ./config/dev-assistant.yaml:/app/dev-assistant.yaml
- ./dev-assistant-data:/app/dev-assistant-data
depends_on:
- admin-server
```
## 安全注意事项
1. **API Key 管理**:禁止将 API Key 写入配置文件或代码,使用 keychain 或加密文件存储
2. **认证配置**生产环境必须启用认证type: http 或 jwt-local
3. **路径限制**:配置 `workspace.denyWrite` 保护敏感目录(.env、node_modules、.claude
4. **速率限制**:根据实际使用调整 `rateLimit` 防止滥用
5. **CORS 配置**`bridge.origin` 严格限制允许的前端来源
## 故障排查
### 连接失败
1. 检查桥接服务是否启动:`curl http://localhost:9020/health`
2. 验证 CORS 配置:`bridge.origin` 是否包含前端域名
3. 确认认证配置是否正确
### 认证失败
1. 检查 JWT 是否有效:通过后端 `/api/auth/me` 验证
2. 确认用户角色包含 `requiredRole`(默认 ROLE_ADMIN
3. 查看桥接服务日志中的认证错误
### 模型调用失败
1. 验证 API Key 是否配置:通过 `/api/models` 查看
2. 检查模型协议适配器日志
3. 确认网络可访问模型 API 端点
## 开发
```bash
# 安装依赖
npm install
# 开发模式(热重载)
npm run bridge:dev
# 构建
npm run build
# 测试
npm test
npm run test:watch
```
## 许可证
MIT