AWS代付、代实名
阿里云国际 | 腾讯云国际

使用Amazon Q Developer CLI快速构建市场分析智能体

亚马逊AWS官方博客

使用Amazon Q Developer CLI快速构建市场分析智能体

1. 什么是** **Amazon Q Developer CLI

Amazon Q Developer CLI是一款由AWS推出的基于生成式人工智能的命令行开发工具。它支持多Agent架构,允许开发者通过自然语言交互调度不同智能Agent完成代码生成、测试、审查、任务自动化等功能。CLI深度集成AWS及本地系统工具,支持复杂多轮上下文管理,适配Linux(Ubuntu 20/22/24)、macOS等环境,极大提升智能化开发和运维效率。

2. 需求场景与挑战分析

现代企业市场分析工作面临多维度挑战:

  • 业务任务多样,涉及行业调研、竞品分析、公关危机处理、定向营销等多个专业领域;
  • 数据量庞大且分散,信息来源多样,检索与分析效率低,决策依赖人工经验;
  • 多任务协作复杂,需要多角色专业知识融合,人工协同效率低且易出错;
  • 自动化、智能化需求提升,需要基于上下文的精准智能路由与任务调度,减少重复劳动。
  • 3. 基于** **Amazon Q Developer CLI ** **定制化** **Agent + ** **安畅** **AI Search** **解决方案

Amazon Q Developer CLI 作为核心控制面,统一调度多智能体(Agents)、外部大模型与知识检索服务。用户可通过 Feishu 等协作平台接入,通过智能路由将请求分发至最合适的 Agent,结合模型生成与联网搜索增强,输出专业化、可信的结果,服务开发者与业务用户。

安畅Anspire Open开放平台为开发者提供构建强大智能体所需的核心能力栈,现已上线AI联网搜索、多轮改写、云端浏览器自动化(Anspire Browser Agent)等服务,可无缝集成至Amazon Q Developer CLI、Strands Agents、Bedrock AgentCore、Dify、等主流智能体平台。

架构组件

Amazon Q Developer CLI:核心调度与统一入口,管理任务分发和结果聚合。 Agents (多智能体):包括默认助手、市场分析、营销策划、公关支持等,按职责执行专门任务,支持扩展。 Intelligent Router:基于智能路由策略规则,将任务路由至最合适的 Agent。 外部大模型( Claude :基于Amazon Q默认集成的Claude大模型能力进行开发。 MCP Server (智能搜索):实现实时联网检索与知识增强,提高结果准确性。 Nginx:网关与安全代理,负责流量控制与鉴权。 Feishu Bot:企业协作入口,支持移动端和桌面端用户接入。 开发者用户:通过 CLI 直接调试和扩展智能体。

4. Amazon Q Developer CLI Linux** **版本安装配置

5. 定制多** **Agent** **架构

配置包含“市场分析师(market-analyst)”、“公关专员(pr-specialist)”、“营销策划(marketing-specialist)”等专业Agent,分别聚焦行业研究、品牌传播、营销策略等任务,通过智能路由器根据上下文灵活分配任务。

market-analyst Agent:

{

“name”: “market-analyst”,

“description”: “资深市场分析师,具备15年+行业经验,专精战略咨询、投资分析、商业洞察”,

“prompt”: “你是资深市场分析师,拥有15年+跨行业分析经验,曾服务于麦肯锡、贝恩等顶级咨询公司。\n\n🎯 核心专长:\n• 行业深度研究:TAM/SAM/SOM市场规模测算、产业链分析、价值链重构\n• 竞争情报分析:竞品战略解构、护城河评估、市场份额动态追踪\n• 商业模式洞察:盈利模式创新、单位经济模型、LTV/CAC优化\n• 投资价值评估:DCF估值模型、可比公司分析、风险收益评估\n• 战略规划制定:蓝海战略、差异化定位、增长路径设计\n\n📊 分析方法论:\n• 定量分析:回归分析、时间序列预测、蒙特卡洛模拟、敏感性分析\n• 定性框架:波特五力、SWOT-TOWS、PEST-STEEP、价值网络分析\n• 战略工具:BCG矩阵、GE-McKinsey矩阵、安索夫矩阵、商业画布\n• 预测模型:Bass扩散模型、S曲线分析、技术成熟度曲线\n\n🔍 输出标准:\n• 执行摘要:3-5个核心洞察,直击商业本质\n• 数据支撑:量化分析+可视化图表,确保结论可信\n• 战略建议:可执行的3-5个具体行动方案\n• 风险评估:识别关键风险点及应对预案\n• 时间规划:短中长期里程碑设定\n\n💡 专业优势:\n• 具备跨行业视角,善于发现跨界机会\n• 精通财务建模,能够量化商业价值\n• 熟悉资本市场,理解投资人思维\n• 拥有丰富实战经验,建议具备可操作性\n\n分析深度要求:每个分析至少包含3个维度的量化数据支撑,提供具体的数字化洞察和可执行的战略建议。”,

“allowedTools”: [

“@anspire/search_tool”,

“@anspire/rewrite_tool”,

“knowledge”,

“fs_write”,

“fs_read”

],

“toolsSettings”: {

“fs_write”: {

“allowedPaths”: [

“~/market-analysis/**”,

“./reports/**”,

“./data/**”

]

},

“@anspire/search_tool”: {

“focus_domains”: [“industry”, “market”, “competition”, “trends”, “financial”, “investment”]

}

},

“resources”: [

“file://market-templates/**/*.md”,

“file://industry-data/**/*.json”

]

}

marketing-specialist Agent:

{

“name”: “marketing-specialist”,

“description”: “资深营销策略专家,具备10年+数字营销经验,专精增长黑客、营销自动化、ROI优化”,

“prompt”: “你是资深营销策略专家,拥有10年+数字营销实战经验,曾任职于Google、Facebook等科技巨头,专精增长驱动和数据化营销。\n\n🎯 核心专长:\n• 增长黑客体系:AARRR漏斗优化、北极星指标设定、增长实验设计、病毒系数提升\n• 数字营销矩阵:全渠道获客策略、营销自动化、个性化推荐、实时竞价优化\n• 用户生命周期管理:RFM模型分析、CLV最大化、流失预警、复购策略\n• 营销技术栈:MarTech选型、CDP构建、归因模型、营销云集成\n• ROI精细化运营:单位经济模型、CAC/LTV优化、预算分配算法、效果归因\n\n📈 增长方法论:\n• AARRR模型:Acquisition(获客)-Activation(激活)-Retention(留存)-Revenue(收入)-Referral(推荐)\n• ICE评分法:Impact(影响力)-Confidence(信心度)-Ease(易实现度)实验优先级\n• Hook模型:Trigger(触发)-Action(行动)-Variable Reward(可变奖励)-Investment(投入)\n• 增长循环:产品价值-用户体验-口碑传播-获客成本降低-再投资循环\n\n🔄 营销自动化框架:\n• 客户旅程映射:Awareness-Consideration-Purchase-Retention-Advocacy全链路\n• 触点优化:多触点归因、交叉销售、向上销售、再营销策略\n• 个性化引擎:行为标签、兴趣画像、动态内容、智能推荐\n• 营销漏斗:流量-线索-机会-客户-倡导者转化优化\n\n💰 ROI优化体系:\n• 财务模型:单位经济学、边际贡献、投资回报周期、现金流预测\n• 归因分析:多触点归因、增量归因、媒体组合建模(MMM)、实验设计\n• 预算优化:动态预算分配、实时竞价策略、跨渠道协同效应\n• 效果评估:品牌指标+效果指标双轨制、短期ROI+长期品牌价值\n\n📊 数据驱动决策:\n• A/B测试:实验设计、统计显著性、多变量测试、贝叶斯优化\n• 用户分群:行为聚类、价值分层、生命周期分段、个性化策略\n• 预测建模:流失预测、购买概率、生命周期价值、市场响应模型\n• 实时优化:动态创意优化、智能出价、自动化规则、异常检测\n\n💡 专业优势:\n• 具备技术背景,深度理解营销技术栈\n• 精通数据分析,能够构建复杂的归因模型\n• 拥有丰富的增长实验经验,善于快速迭代\n• 熟悉各大广告平台,具备跨平台整合能力\n\n输出标准:每个营销方案必须包含具体的KPI设定、实验设计、预算分配、技术实现路径和ROI预测模型。”,

“allowedTools”: [

“@anspire/search_tool”,

“@anspire/rewrite_tool”,

“knowledge”,

“fs_write”,

“fs_read”

],

“toolsSettings”: {

“fs_write”: {

“allowedPaths”: [

“~/marketing-plans/**”,

“./campaigns/**”,

“./growth-strategies/**”

]

},

“@anspire/search_tool”: {

“focus_domains”: [“digital_marketing”, “growth_hacking”, “marketing_automation”, “roi_optimization”]

}

}

}

pr-specialist Agent:

{

“name”: “pr-specialist”,

“description”: “资深公关传播专家,具备12年+品牌传播经验,专精危机公关、媒体关系、声誉管理”,

“prompt”: “你是资深公关传播专家,拥有12年+品牌传播经验,曾任职于奥美、蓝色光标等顶级公关公司,服务过Fortune 500企业。\n\n🎯 核心专长:\n• 危机公关管理:危机预警体系、24小时应急响应、舆情控制策略、形象修复方案\n• 品牌传播策略:品牌定位重塑、核心信息提炼、传播矩阵构建、声誉资产管理\n• 媒体关系建设:KOL关系维护、记者网络构建、独家内容策划、媒体议程设置\n• 内容营销策划:病毒传播设计、话题制造技巧、内容IP打造、跨平台整合\n• 政府关系协调:政策解读分析、监管沟通策略、合规风险评估、政企合作推进\n\n📢 传播方法论:\n• SOSTAC模型:情况分析-目标设定-策略制定-战术执行-行动计划-效果控制\n• 议程设置理论:媒体议程-公众议程-政策议程三级联动\n• 螺旋沉默理论:舆论环境分析、意见领袖识别、声音放大策略\n• 框架理论:议题框架设计、叙事角度选择、情感共鸣构建\n\n🔥 危机处理框架:\n• 黄金4小时法则:快速响应、信息收集、策略制定、执行监控\n• 3T原则:Tell it fast(快速回应)、Tell it all(全面披露)、Tell the truth(诚实透明)\n• SCARF模型:Status(地位)、Certainty(确定性)、Autonomy(自主性)、Relatedness(关联性)、Fairness(公平性)\n\n📊 效果评估体系:\n• 传播指标:覆盖率、到达率、频次、GRP、CPM优化\n• 声誉指标:品牌认知度、美誉度、推荐度、信任度量化\n• 舆情监测:情感倾向分析、话题热度追踪、影响力评估\n• 商业价值:品牌价值提升、销售转化贡献、危机损失控制\n\n💡 专业优势:\n• 具备敏锐的舆情嗅觉,能提前识别潜在风险\n• 精通多平台传播规律,善于整合传播资源\n• 拥有丰富的危机处理经验,能在压力下快速决策\n• 深谙媒体运作机制,具备强大的媒体影响力\n\n输出标准:每个公关方案必须包含具体的执行时间表、责任分工、预算分配、风险预案和效果评估标准。”,

“allowedTools”: [

“@anspire/search_tool”,

“@anspire/rewrite_tool”,

“knowledge”,

“fs_write”,

“fs_read”

],

“toolsSettings”: {

“fs_write”: {

“allowedPaths”: [

“~/pr-campaigns/**”,

“./communications/**”,

“./media-plans/**”

]

},

“@anspire/search_tool”: {

“focus_domains”: [“media”, “public_relations”, “crisis_management”, “brand_communication”]

}

}

}

6. 集成安畅** **Anspire AI Search MCP Server

结合语义搜索引擎,实现跨多数据源的深度语义检索,快速定位行业动态、竞品信息及市场洞察,增强知识访问的准确性和时效性。

  • 实现架构
  • SSE MCP配置:
  • !/home/ubuntu/.venv/mcp/bin/python

import asyncio

import json

import sys

import os

from mcp.server import Server

from mcp.server.stdio import stdio_server

from mcp.types import Tool, TextContent

from mcp.client.sse import sse_client

from mcp import ClientSession

从环境变量获取配置 // 替换ai search api key

ANSPIRE_URL = sys.argv[1] if len(sys.argv) > 1 else “https://plugin.anspire.cn/mcp”

ANSPIRE_TOKEN = os.getenv(“AUTHORIZATION”, “Bearer sk-anchnet-ai-search key”)

创建MCP服务器作为代理

server = Server(“anspire-proxy”)

全局变量存储Anspire工具

anspire_tools = []

async def get_anspire_tools():

“””获取Anspire的工具列表”””

global anspire_tools

try:

async with sse_client(

url=ANSPIRE_URL,

headers={“Authorization”: ANSPIRE_TOKEN}

) as streams:

async with ClientSession(*streams) as session:

await session.initialize()

tools_response = await session.list_tools()

anspire_tools = tools_response.tools

return anspire_tools

except Exception as e:

print(f”Error connecting to Anspire: {e}”, file=sys.stderr)

return []

@server.list_tools()

async def list_tools():

“””列出所有可用工具”””

tools = await get_anspire_tools()

return [

Tool(

name=tool.name,

description=tool.description,

inputSchema=tool.inputSchema

) for tool in tools

]

@server.call_tool()

async def call_tool(name: str, arguments: dict):

“””调用工具”””

try:

async with sse_client(

url=ANSPIRE_URL,

headers={“Authorization”: ANSPIRE_TOKEN}

) as streams:

async with ClientSession(*streams) as session:

await session.initialize()

result = await session.call_tool(name, arguments)

return resul[已去除短链接]ntent

except Exception as e:

return [TextContent(type=”text”, text=f”Tool error: {str(e)}”)]

async def main():

async with stdio_server() as (read_stream, write_stream):

await server.run(read_stream, write_stream, server.create_initialization_options())

if __name__ == “__main__”:

asyncio.run(main())

7. 飞书集成与智能路由

采用自定义智能路由器实现任务的自动智能分流同时与飞书进行集成,提升交互体验和结果质量。

// 核心配置文件目录

核心文件 (2个):

• server.js – 主服务器

• package.json – 项目配置

功能模块 (3个):

• intelligent-router.js – 智能路由

• q-pool-manager.js – 进程池管理

• rate-limiter.js – 限流器

系统配置 (2个):

• feishu.service – systemd服务

• nginx.conf – nginx配置

SSL证书 (2个):

• cert.pem – SSL证书

• key.pem – 私钥

// 主配置文件 server.js

const express = require(‘express’);

const https = require(‘https’);

const fs = require(‘fs’);

const axios = require(‘axios’);

const QProcessPool = require(‘./q-pool-manager’);

const RateLimiter = require(‘./rate-limiter’);

const IntelligentRouter = require(‘./intelligent-router’);

const app = express();

// 添加JSON解析中间件

app.use(express.json({ limit: ’10mb’ }));

app.use(express.urlencoded({ extended: true, limit: ’10mb’ }));

// 创建Q CLI进程池 (提升至12个并发进程)

const qPool = new QProcessPool(12);

// 创建限流器 (每用户每分钟最多8个请求)

const rateLimiter = new RateLimiter(8, 60000);

// 创建智能路由器

const intelligentRouter = new IntelligentRouter();

// 消息处理记录 – 使用更长的保存时间

const messageTracker = new Map();

// 清理过期消息记录 – 延长到24小时

setInterval(() => {

const now = Date.now();

for (const [messageId, data] of messageTracker.entries()) {

if (now – data.firstTime > 24 * 60 * 60 * 1000) { // 24小时后清理

messageTracker.delete(messageId);

}

}

// 清理智能路由的过期上下文

intelligentRouter.cleanupExpiredContexts();

}, 60000); // 每分钟清理一次

// 监控接口

app.get(‘/stats’, (req, res) => {

const stats = {

processPool: qPool.getStats(),

messageTracker: {

activeMessages: messageTracker.size,

totalProcessed: global.totalProcessed || 0

},

intelligentRouter: intelligentRouter.getRoutingStats(),

uptime: process.uptime(),

memory: process.memoryUsage(),

timestamp: new Date().toISOString()

};

res.json(stats);

});

// 健康检查接口

app.get(‘/health’, (req, res) => {

const poolStats = qPool.getStats();

const memUsage = process.memoryUsage();

const isHealthy = poolStats.activeProcesses < poolStats.maxProcesses * 0.8; // 80%阈值

res.status(isHealthy ? 200 : 503).json({

status: isHealthy ? ‘healthy’ : ‘busy’,

load: ${poolStats.activeProcesses}/${poolStats.maxProcesses},

queue: poolStats.queueLength,

memory: ${Math.round(memUsage.heapUsed / 1024 / 1024)}MB,

uptime: ${Math.round(process.uptime())}s

});

});

// 智能路由统计接口

app.get(‘/routing-stats’, (req, res) => {

const routingStats = intelligentRouter.getRoutingStats();

res.json({

…routingStats,

timestamp: new Date().toISOString(),

description: {

‘market-analyst’: ‘市场分析师 – 行业研究、竞品分析、趋势预测’,

‘pr-specialist’: ‘公关专员 – 品牌传播、危机公关、媒体关系’,

‘marketing-specialist’: ‘营销专员 – 数字营销、用户增长、ROI优化’

}

});

});

// 替换以下飞书App相关信息

const config = {

appId: ‘cli_anchnet’,

appSecret: ‘anchnet’,

verificationToken: ‘anchnet’,

encryptKey: ‘anchnet’

};

// 获取飞书访问令牌

async function getFeishuAccessToken() {

try {

const response = await axios.post(‘https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal’, {

app_id: config.appId,

app_secret: config.appSecret

});

return response.data.tenant_access_token;

} catch (error) {

console.error(‘获取飞书token失败:’, error);

return null;

}

}

// 清理ANSI颜色代码

function cleanAnsiCodes(text) {

return text.replace(/\x1b\[[0-9;]*m/g, ”).replace(/\x1b\[[0-9;]*[A-Za-z]/g, ”).trim();

}

// 过滤敏感信息和工具调用详情

function filterSensitiveInfo(response) {

if (!response) return response;

let filtered = response

// 移除工具调用详情

.replace(/🛠️.*?Using tool:.*?\n/gs, ”)

.replace(/⋮.*?\n/g, ”)

.replace(/●.*?Running.*?with.*?param:.*?\n/gs, ”)

.replace(/●.*?Completed in.*?\n/gs, ”)

.replace(/\{[\s\S]*?”arguments”[\s\S]*?\}/g, ”)

// 移除系统信息

.replace(/我了解你当前在.*?系统上.*?。/g, ”)

.replace(/工作目录是.*?。/g, ”)

.replace(/当前在.*?环境中运行。/g, ”)

// 移除敏感功能描述

.replace(/• 执行 bash 命令\n?/g, ”)

.replace(/• 读写本地文件系统\n?/g, ”)

.replace(/• 管理和查询 AWS 资源\n?/g, ”)

// 移除退出和帮助信息

.replace(/如果你想退出.*?使用说明。/g, ”)

.replace(/输入 \/quit.*?\n?/g, ”)

.replace(/运行 q –help.*?\n?/g, ”)

// 清理markdown格式符号,减少AI痕迹

.replace(/^#{1,6}\s+/gm, ”) // 移除标题符号

.replace(/\*\*(.*?)\*\*/g, ‘$1’) // 移除粗体标记

.replace(/\*(.*?)\*/g, ‘$1’) // 移除斜体标记

.replace(/^[\*\-\+]\s+/gm, ‘• ‘) // 统一列表符号

.replace(/^>\s+/gm, ”) // 移除引用符号

.replace(/([^]+)`/g, ‘$1’) // 移除行内代码标记

.replace(/

[\s\S]*?

/g, ”) // 移除代码块

// 清理多余空行

.replace(/\n\s*\n\s*\n/g, ‘\n\n’)

.trim();

// 如果过滤后内容太少,返回通用回复

if (filtered.length < 50) {

return ‘你好!我是专业的商业分析助手,可以帮助您进行市场分析、公关传播和营销策划。有什么我可以帮助您的吗?’;

}

return filtered;

}

// 调用Amazon Q处理消息 (使用进程池)

async function callAmazonQ(message, agentName = ”, messageId = null) {

try {

console.log(进程池状态:, qPool.getStats());

const response = await qPool.execute(message, agentName, messageId);

// 清理输出并提取实际回复

const cleanOutput = cleanAnsiCodes(response);

const lines = cleanOutput.split(‘\n’);

// 查找以 “> ” 开头的回复内容

let responseStart = -1;

for (let i = 0; i < lines.length; i++) {

if (lines[i].startsWith(‘> ‘)) {

responseStart = i;

break;

}

}

if (responseStart >= 0) {

const finalResponse = lines.slice(responseStart).join(‘\n’).replace(/^> /, ”).trim();

return filterSensitiveInfo(finalResponse);

} else {

return filterSensitiveInfo(cleanOutput);

}

} catch (error) {

console.error(‘Q CLI调用失败:’, error.message);

throw error;

}

}

// 发送消息回飞书

async function sendFeishuMessage(messageId, content) {

try {

const accessToken = await getFeishuAccessToken();

if (!accessToken) {

console.error(‘无法获取飞书访问令牌’);

return;

}

const response = await axios.post(https://open.feishu.cn/open-apis/im/v1/messages/${messageId}/reply, {

content: JSON.stringify({

text: content

}),

msg_type: “text”

}, {

headers: {

‘Authorization’: Bearer ${accessToken},

‘Content-Type’: ‘application/json’

}

});

console.log(‘飞书消息发送成功:’, response.data);

} catch (error) {

console.error(‘发送飞书消息失败:’, error.response?.data || error.message);

}

}

// 添加测试路由

app.get(‘/test’, (req, res) => {

res.json({

status: ‘ok’,

timestamp: new Date().toISOString(),

message: ‘飞书webhook服务正常运行’

});

});

// 添加GET和POST支持

app.all(‘/webhook’, async (req, res) => {

try {

const body = req.body || {};

console.log(‘收到请求:’, req.method, JSON.stringify(body, null, 2));

console.log(‘请求头:’, JSON.stringify(req.headers, null, 2));

console.log(‘请求体大小:’, JSON.stringify(body).length, ‘字节’);

// 检查事件类型

if (body.header) {

console.log(‘事件类型:’, body.header.event_type);

console.log(‘事件ID:’, body.header.event_id);

} else {

console.log(‘❌ 没有找到header信息’);

}

// URL验证 – 飞书要求的格式

if (body.type === ‘url_verification’) {

console.log(‘飞书URL验证:’, body.challenge);

return res.status(200).json({

challenge: body.challenge

});

}

// 处理消息事件

if (body.header && body.header.event_type === ‘im.message.receive_v1’) {

console.log(‘✅ 检测到消息事件’);

const event = body.event;

const message = event.message;

console.log(‘消息详情:’, {

message_id: message.message_id,

sender_type: message.sender?.sender_type,

message_type: message.message_type,

content_preview: message.content?.substring(0, 100),

create_time: message.create_time,

message_age_seconds: message.create_time ? Math.floor((Date.now() – parseInt(message.create_time)) / 1000) : ‘unknown’

});

// 跳过机器人自己发送的消息

if (message.sender && message.sender.sender_type === ‘app’) {

console.log(‘跳过机器人消息:’, message.message_id);

return res.json({ StatusCode: 0, StatusMessage: ‘success’ });

}

// 检查消息是否已处理(严格去重,每个消息只处理一次)

const now = Date.now();

// 检查消息时间戳,拒绝超过5分钟的旧消息

const messageTime = parseInt(message.create_time) || now;

if (now – messageTime > 5 * 60 * 1000) {

console.log(‘跳过过期消息:’, message.message_id, ‘消息时间:’, new Date(messageTime));

return res.json({ StatusCode: 0, StatusMessage: ‘success’ });

}

if (messageTracker.has(message.message_id)) {

console.log(‘跳过重复消息:’, message.message_id);

return res.json({ StatusCode: 0, StatusMessage: ‘success’ });

} else {

messageTracker.set(message.message_id, {

count: 1,

firstTime: now,

lastTime: now,

messageTime: messageTime

});

}

// 检查用户请求频率限制

const userId = message.sender?.sender_id?.user_id || message.sender?.sender_id?.open_id || ‘unknown_user’;

if (!rateLimiter.isAllowed(userId)) {

const remaining = rateLimiter.getRemainingRequests(userId);

console.log(‘用户请求过于频繁:’, userId);

await sendFeishuMessage(message.message_id,

‘⏰ 请求频率提醒\n\n’ +

‘为了保证服务质量,每分钟最多处理8个分析请求。\n\n’ +

‘💡 建议:\n’ +

‘• 请稍等片刻再发送新的分析需求\n’ +

‘• 可以将多个问题合并为一个详细的分析请求\n’ +

‘• 复杂分析通常需要更多时间,请耐心等待\n\n’ +

‘感谢您的理解与配合!🙏’

);

return res.json({ StatusCode: 0, StatusMessage: ‘rate_limited’ });

}

console.log(‘收到消息事件:’, {

message_type: message.message_type,

message_id: message.message_id,

chat_id: message.chat_id

});

if (message.message_type === ‘text’) {

const content = JSON.parse(message.content);

const userMessage = content.text;

console.log(‘收到用户消息:’, userMessage);

// 屏蔽系统指令

if (userMessage.startsWith(‘/’) || userMessage.includes(‘–‘) || userMessage.match(/^[a-z]+\s+[a-z]+/)) {

console.log(‘屏蔽系统指令:’, userMessage);

await sendFeishuMessage(message.message_id,

‘🎯 专业市场分析助手\n\n’ +

‘我是专门的市场分析AI,专注于为市场分析人员提供专业服务:\n\n’ +

‘📊 核心能力\n’ +

‘• 行业研究与趋势分析\n’ +

‘• 竞品对比与市场定位\n’ +

‘• 消费者行为分析\n’ +

‘• 商业模式评估\n’ +

‘• 投资机会识别\n\n’ +

‘💡 使用示例\n’ +

‘• “分析一下AI行业的发展趋势”\n’ +

‘• “帮我做电商平台的竞品分析”\n’ +

‘• “新能源汽车市场前景如何”\n’ +

‘• “分析Z世代的消费特点”\n\n’ +

‘请告诉我您需要分析的具体市场、产品或行业,我将为您提供专业的分析报告。’

);

return res.json({ StatusCode: 0, StatusMessage: ‘success’ });

}

// 获取用户ID用于上下文管理

const userId = message.sender?.sender_id?.user_id || message.sender?.sender_id?.open_id || ‘unknown_user’;

// 检查是否为追问(追问应该跳过业务相关性检查)

const isFollowUpQuestion = intelligentRouter.isFollowUpQuestion(userMessage);

// 使用智能路由选择Agent

const agentName = intelligentRouter.getAgentWithContext(userId, userMessage);

const agentTitle = intelligentRouter.getAgentTitle(agentName);

console.log(智能路由选择: ${agentName} (${agentTitle}) for user: ${userId});

// 业务相关性检查(追问跳过此检查)

if (!isFollowUpQuestion) {

const businessKeywords = [

‘分析’, ‘市场’, ‘行业’, ‘竞品’, ‘趋势’, ‘研究’, ‘调研’, ‘报告’, ‘数据’, ‘商业’, ‘产品’, ‘公司’, ‘消费’, ‘用户’, ‘客户’,

‘公关’, ‘PR’, ‘危机’, ‘媒体’, ‘传播’, ‘品牌’, ‘声誉’, ‘舆情’, ‘新闻’, ‘发布会’,

‘营销’, ‘[已去除[已去除推广语]语]’, ‘获客’, ‘增长’, ‘转化’, ‘留存’, ‘活动’, ‘广告’, ‘投放’, ‘ROI’

];

const isBusinessRelated = businessKeywords.some(keyword => userMessage.includes(keyword));

if (!isBusinessRelated) {

console.log(‘非相关业务需求,进行引导’);

await sendFeishuMessage(message.message_id,

‘🎯 专业商业服务团队\n\n’ +

‘我们提供三大专业服务领域:\n\n’ +

‘📊 市场分析师:行业研究、竞品分析、趋势预测、商业洞察\n’ +

‘📢 公关专员:品牌传播、危机公关、媒体关系、声誉管理\n’ +

‘📈 营销专员:数字营销、用户增长、营销策略、ROI优化\n\n’ +

‘💡 使用示例\n’ +

‘• 市场分析:”分析AI行业发展趋势”\n’ +

‘• 公关传播:”制定品牌危机公关策略”\n’ +

‘• 营销[已去除[已去除推广语]语]:”设计用户增长营销方案”\n\n’ +

‘请描述您的具体需求,我将匹配最合适的专业顾问为您服务。’

);

return res.json({ StatusCode: 0, StatusMessage: ‘success’ });

}

} else {

console.log(‘检测到追问,跳过业务相关性检查’);

}

// 立即发送确认消息

const agentPreResponse = intelligentRouter.getAgentPreResponse(agentName);

const confirmMsg = ${agentTitle} 已接收您的请求\n\n +

${agentPreResponse}\n +

⏱️ 预计需要 30-90 秒\n +

📝 请稍候,我正在为您准备专业分析报告;

await sendFeishuMessage(message.message_id, confirmMsg);

console.log(‘已发送确认消息给用户’);

try {

// 检查是否需要排队

const poolStats = qPool.getStats();

if (poolStats.queueLength > 0) {

const queueMsg = ⏳ 系统繁忙,您的请求已加入处理队列\n\n +

📋 当前排队:${poolStats.queueLength} 个请求\n +

⏱️ 预计等待:${Math.ceil(poolStats.queueLength * 45)} 秒\n +

🎯 我会尽快为您提供专业分析;

await sendFeishuMessage(message.message_id, queueMsg);

}

const qResponse = await callAmazonQ(userMessage, agentName, message.message_id);

console.log(‘Amazon Q回复:’, qResponse);

if (qResponse && qResponse.length > 0) {

// 添加完成标识

const finalResponse = ✅ 分析完成\n\n${qResponse}\n\n---\n💡 如需进一步分析,请随时提问;

await sendFeishuMessage(message.message_id, finalResponse);

} else {

await sendFeishuMessage(message.message_id,

‘🤔 分析遇到问题\n\n’ +

‘抱歉,当前无法完成您的分析请求。\n\n’ +

‘💡 建议尝试:\n’ +

‘• 重新描述您的分析需求\n’ +

‘• 提供更具体的行业或产品信息\n’ +

‘• 稍后再次尝试\n\n’ +

‘如问题持续,请联系技术支持。’

);

}

} catch (error) {

console.error(‘处理消息失败:’, error.message);

let errorMsg = ‘⚠️ 服务暂时繁忙\n\n’;

if (error.message.includes(‘超时’)) {

errorMsg += ‘您的分析请求比较复杂,处理时间较长。\n\n’ +

‘💡 建议:\n’ +

‘• 尝试将问题拆分为更具体的小问题\n’ +

‘• 稍后重新提交分析请求\n’ +

‘• 提供更明确的分析范围’;

} else {

errorMsg += ‘系统正在处理大量分析请求。\n\n’ +

‘💡 建议:\n’ +

‘• 请稍等片刻后重试\n’ +

‘• 确保问题描述清晰具体\n’ +

‘• 避免重复发送相同请求’;

}

await sendFeishuMessage(message.message_id, errorMsg);

}

}

// 处理富文本消息

if (message.message_type === ‘post’) {

const content = JSON.parse(message.content);

let userText = ”;

console.log(‘收到富文本消息:’, message.message_id);

// 解析富文本内容,只提取文本

if (conten[已去除短链接]ntent && Array.isArray(conten[已去除短链接]ntent)) {

conten[已去除短链接]ntent.forEach(block => {

if (Array.isArray(block)) {

block.forEach(element => {

if (element.tag === ‘text’ && element.text) {

userText += element.text.trim() + ‘ ‘;

}

});

}

});

}

// 如果有文本内容,按普通文本处理

if (userText.trim()) {

console.log(‘富文本消息转为文本处理:’, userText.trim());

// 继续处理文本内容

}

}

}

// 处理所有其他事件类型

if (body.header && body.header.event_type) {

console.log(‘🔍 收到其他事件类型:’, body.header.event_type);

// 尝试处理其他消息事件

if (body.header.event_type.includes(‘message’) && body.event) {

console.log(‘🔄 尝试处理消息事件’);

const event = body.event;

if (event.message || even[已去除短链接]ntent) {

console.log(‘📝 找到消息内容,尝试处理’);

}

}

}

// 飞书要求的成功响应格式

res.status(200).json({

StatusCode: 0,

StatusMessage: “success”

});

} catch (error) {

console.error(‘处理错误:’, error);

res.status(200).json({

StatusCode: 1,

StatusMessage: “error”

});

}

});

const certOptions = {

key: fs.readFileSync(‘/home/ubuntu/feishu-webhook/key.pem’),

cert: fs.readFileSync(‘/home/ubuntu/feishu-webhook/cert.pem’)

};

https.createServer(certOptions, app).listen(8443, () => {

console.log(‘飞书webhook服务启动: https://amazonq.moveinsync.cn:8443’);

console.log(‘Webhook URL: https://amazonq.moveinsync.cn/webhook’);

});

// package.json

{

“name”: “feishu”,

“version”: “1.0.0”,

“main”: “server.js”,

“scripts”: {

“start”: “node server.js”

},

“dependencies”: {

“axios”: “^1.11.0”,

“express”: “^4.18.2”

}

}

// 智能路由模块 intelligent-router.js

class IntelligentRouter {

constructor() {

// 用户上下文存储

this.userContexts = new Map();

// 权重化关键词配置

this.keywords = {

‘market-analyst’: {

high: [‘分析’, ‘研究’, ‘市场’, ‘行业’, ‘竞品’, ‘趋势’, ‘调研’, ‘数据’], // 权重3

medium: [‘报告’, ‘洞察’, ‘商业’, ‘产品’, ‘用户’, ‘消费’, ‘客户’], // 权重2

low: [‘公司’, ‘企业’, ‘发展’, ‘前景’, ‘机会’, ‘风险’] // 权重1

},

‘pr-specialist’: {

high: [‘公关’, ‘pr’, ‘危机’, ‘媒体’, ‘传播’, ‘品牌’, ‘声誉’, ‘材料’], // 权重3

medium: [‘舆情’, ‘新闻’, ‘发布’, ‘形象’, ‘关系’, ‘沟通’, ‘故事’], // 权重2

low: [‘宣传’, ‘推介’, ‘活动’, ‘事件’, ‘话题’, ‘影响’] // 权重1

},

‘marketing-specialist’: {

high: [‘营销’, ‘[已去除[已去除推广语]语]’, ‘获客’, ‘增长’, ‘增长点’, ‘转化’, ‘roi’], // 权重3

medium: [‘活动’, ‘广告’, ‘投放’, ‘留存’, ‘渠道’, ‘策略’], // 权重2

low: [‘用户’, ‘客户’, ‘流量’, ‘曝光’, ‘点击’, ‘效果’] // 权重1

}

};

// 追问模式关键词

this.followUpPatterns = [

‘继续’, ‘还有’, ‘另外’, ‘补充’, ‘详细’, ‘具体’,

‘那么’, ‘如果’, ‘假设’, ‘基于上面’, ‘刚才’, ‘之前’,

‘上文’, ‘提到的’, ‘刚说的’, ‘前面’, ‘哪些’, ‘什么’,

‘有哪些’, ‘都有’, ‘包括’, ‘比如’, ‘例如’, ‘主要有’

];

}

// 多维度评分机制

calculateAgentScore(userMessage) {

const scores = {

‘market-analyst’: 0,

‘pr-specialist’: 0,

‘marketing-specialist’: 0

};

const message = userMessage.toLowerCase();

// 计算各Agent得分

Object.keys(this.keywords).forEach(agent => {

this.keywords[agent].high.forEach(word => {

if (message.includes(word)) scores[agent] += 3;

});

this.keywords[agent].medium.forEach(word => {

if (message.includes(word)) scores[agent] += 2;

});

this.keywords[agent].low.forEach(word => {

if (message.includes(word)) scores[agent] += 1;

});

});

// 返回得分最高的Agent,如果得分相同则返回market-analyst作为默认

const maxScore = Math.max(…Object.values(scores));

if (maxScore === 0) return ‘market-analyst’; // 默认选择

return Object.keys(scores).find(agent => scores[agent] === maxScore) || ‘market-analyst’;

}

// 检测是否为追问

isFollowUpQuestion(message) {

const lowerMessage = message.toLowerCase();

// 直接追问模式检测

const hasFollowUpPattern = this.followUpPatterns.some(pattern => lowerMessage.includes(pattern));

// 排除独立问句(包含明确主题的完整问句)

const independentTopics = [

‘天气’, ‘时间’, ‘日期’, ‘你好’, ‘谢谢’, ‘再见’, ‘帮助’,

‘怎么样’, ‘如何’, ‘为什么’, ‘什么时候’, ‘在哪里’

];

const isIndependentQuestion = independentTopics.some(topic => lowerMessage.includes(topic)) &&

!this.followUpPatterns.some(pattern => lowerMessage.includes(pattern));

if (isIndependentQuestion) {

return false; // 独立问句不是追问

}

// 简短问句检测(通常是追问)

const isShortQuestion = message.length < 20 && (

message.includes(‘?’) || message.includes(‘?’) ||

message.includes(‘哪些’) || message.includes(‘什么’) ||

message.includes(‘如何’) || message.includes(‘怎么’)

);

// 指代性问句检测

const hasReference = lowerMessage.includes(‘的’) && (

lowerMessage.includes(‘主要’) || lowerMessage.includes(‘都有’) ||

lowerMessage.includes(‘包括’) || lowerMessage.includes(‘品牌’)

);

return hasFollowUpPattern || (isShortQuestion && !isIndependentQuestion) || hasReference;

}

// 提取主题关键词

extractTopics(message) {

const topics = [];

const allKeywords = Object.values(this.keywords).flatMap(category =>

[…category.high, …category.medium, …category.low]

);

allKeywords.forEach(keyword => {

if (message.includes(keyword)) {

topics.push(keyword);

}

});

return topics.slice(0, 5); // 最多保留5个主题

}

// 上下文感知路由 – 重构版本

getAgentWithContext(userId, userMessage) {

const context = this.userContexts.get(userId) || {

recentAgents: [],

topics: [],

lastAgent: null,

lastMessageTime: 0,

lastMessage: ”

};

const now = Date.now();

const timeSinceLastMessage = now – context.lastMessageTime;

console.log(🔍 分析用户 ${userId} 的消息: "${userMessage}");

console.log(📊 上下文信息: 上次Agent=${context.lastAgent}, 时间间隔=${Math.round(timeSinceLastMessage/1000)}秒);

// 步骤1: 判断问题分类

const questionType = this.classifyQuestion(userMessage, context, timeSinceLastMessage);

console.log(📋 问题分类: ${questionType.type} (置信度: ${questionType.confidence.toFixed(3)}));

let selectedAgent;

switch (questionType.type) {

case ‘RELATED_FOLLOWUP’:

// 与原有问题相关,传递上下文给同一Agent

selectedAgent = context.lastAgent || ‘market-analyst’;

console.log(🔄 相关追问,继续使用 ${selectedAgent});

break;

case ‘UNRELATED_NEW’:

// 与原有问题无关,重新分析并选择Agent

selectedAgent = this.calculateAgentScore(userMessage);

console.log(🆕 无关新问题,重新选择 ${selectedAgent});

// 清理旧上下文

context.topics = [];

break;

case ‘NEW_QUESTION’:

default:

// 新问题,根据内容分类给不同Agent

selectedAgent = this.calculateAgentScore(userMessage);

console.log(❓ 新问题,分析后选择 ${selectedAgent});

break;

}

// 更新用户上下文

this.updateUserContext(userId, selectedAgent, userMessage, now);

return selectedAgent;

}

// 问题分类方法 – 优化版本

classifyQuestion(userMessage, context, timeSinceLastMessage) {

const message = userMessage.toLowerCase();

// 如果没有历史上下文或时间间隔太长(>30分钟),直接判定为新问题

if (!context.lastAgent || timeSinceLastMessage > 30 * 60 * 1000) {

return { type: ‘NEW_QUESTION’, confidence: 0.9 };

}

// 优先检查新领域请求 – 提高权重

const isNewDomain = this.isNewDomainRequest(userMessage);

if (isNewDomain) {

console.log(🔄 检测到新领域请求标识符);

return { type: ‘UNRELATED_NEW’, confidence: 0.9 };

}

// 检查Agent领域切换 – 新增强化检测

const currentAgentScore = this.calculateAgentScore(userMessage);

const lastAgent = context.lastAgent;

// 如果当前消息明显指向不同的Agent领域

if (currentAgentScore !== lastAgent) {

const agentSwitchConfidence = this.calculateAgentSwitchConfidence(userMessage, lastAgent, currentAgentScore);

console.log(🎯 Agent切换检测: ${lastAgent} → ${currentAgentScore}, 置信度: ${agentSwitchConfidence.toFixed(3)});

if (agentSwitchConfidence > 0.7) {

return { type: ‘UNRELATED_NEW’, confidence: agentSwitchConfidence };

}

}

// 检查是否为明显的追问

const isFollowUp = this.isFollowUpQuestion(userMessage);

if (isFollowUp) {

return { type: ‘RELATED_FOLLOWUP’, confidence: 0.8 };

}

// 检查主题相关性

const currentTopics = this.extractTopics(userMessage);

const topicSimilarity = this.calculateTopicSimilarity(currentTopics, context.topics);

console.log(🏷️ 主题相似度: ${topicSimilarity.toFixed(3)});

// 根据主题相似度判断

if (topicSimilarity > 0.6) {

return { type: ‘RELATED_FOLLOWUP’, confidence: topicSimilarity };

} else if (topicSimilarity < 0.3) {

return { type: ‘UNRELATED_NEW’, confidence: 1 – topicSimilarity };

} else {

return { type: ‘NEW_QUESTION’, confidence: 0.6 };

}

}

// 计算Agent切换置信度

calculateAgentSwitchConfidence(userMessage, lastAgent, currentAgent) {

const message = userMessage.toLowerCase();

// 获取当前Agent的关键词匹配强度

const currentAgentKeywords = this.keywords[currentAgent] || { high: [], medium: [], low: [] };

let matchStrength = 0;

// 计算匹配强度

currentAgentKeywords.high.forEach(word => {

if (message.includes(word)) matchStrength += 3;

});

currentAgentKeywords.medium.forEach(word => {

if (message.includes(word)) matchStrength += 2;

});

currentAgentKeywords.low.forEach(word => {

if (message.includes(word)) matchStrength += 1;

});

// 检查专业领域强指示词

const strongIndicators = {

‘pr-specialist’: [‘公关’, ‘危机’, ‘品牌’, ‘媒体’, ‘传播’, ‘声誉’, ‘新闻’],

‘marketing-specialist’: [‘营销’, ‘[已去除[已去除推广语]语]’, ‘获客’, ‘转化’, ‘广告’, ‘活动’, ‘用户增长’, ‘增长点’],

‘market-analyst’: [‘分析’, ‘市场’, ‘竞品’, ‘行业’, ‘趋势’, ‘数据’, ‘报告’]

};

const indicators = strongIndicators[currentAgent] || [];

let strongMatch = 0;

indicators.forEach(indicator => {

if (message.includes(indicator)) strongMatch += 1;

});

// 综合计算置信度

let confidence = 0.5;

if (strongMatch > 0) {

confidence += strongMatch * 0.2; // 强指示词加权

}

if (matchStrength > 2) {

confidence += 0.3; // 关键词匹配强度加权

}

return Math.min(0.95, confidence);

}

// 计算主题相似度

calculateTopicSimilarity(currentTopics, previousTopics) {

if (currentTopics.length === 0 || previousTopics.length === 0) {

return 0;

}

let matchCount = 0;

for (const currentTopic of currentTopics) {

for (const prevTopic of previousTopics) {

// 检查完全匹配或包含关系

if (currentTopic === prevTopic ||

currentTopic.includes(prevTopic) ||

prevTopic.includes(currentTopic)) {

matchCount++;

break;

}

}

}

return matchCount / Math.max(currentTopics.length, previousTopics.length);

}

// 更新用户上下文

updateUserContext(userId, selectedAgent, userMessage, timestamp) {

const context = this.userContexts.get(userId) || {

recentAgents: [],

topics: [],

lastAgent: null,

lastMessageTime: 0,

lastMessage: ”

};

// 更新基本信息

context.lastAgent = selectedAgent;

context.lastMessageTime = timestamp;

context.lastMessage = userMessage;

// 更新Agent历史

if (!context.recentAgents.includes(selectedAgent)) {

context.recentAgents.unshift(selectedAgent);

if (context.recentAgents.length > 3) {

context.recentAgents.pop();

}

}

// 更新主题

const newTopics = this.extractTopics(userMessage);

context.topics = […new Set([…newTopics, …context.topics])].slice(0, 10);

this.userContexts.set(userId, context);

console.log(💾 更新用户上下文: Agent=${selectedAgent}, 主题数=${context.topics.length});

}

// 检测是否为新领域请求

isNewDomainRequest(message) {

const newDomainIndicators = [

// 明确的话题转换

‘换个话题’, ‘说说别的’, ‘另外’, ‘还有’, ‘其他’, ‘不同的’,

‘新的问题’, ‘别的事情’, ‘转换话题’, ‘改个方向’,

// 追加询问

‘我想问’, ‘我还想’, ‘顺便问’, ‘再问一个’, ‘还想了解’,

‘另外想问’, ‘还有个问题’, ‘再咨询一下’,

// 领域切换指示

‘关于’, ‘针对’, ‘对于’, ‘就是’, ‘比如说’,

‘我需要’, ‘帮我’, ‘能否’, ‘可以’

];

const messageLower = message.toLowerCase();

// 检查明确的转换指示词

const hasTransitionWord = newDomainIndicators.some(indicator => messageLower.includes(indicator));

// 检查专业领域关键词组合

const domainKeywords = {

pr: [‘公关’, ‘危机’, ‘品牌’, ‘媒体’, ‘传播’, ‘声誉’],

marketing: [‘营销’, ‘[已去除[已去除推广语]语]’, ‘获客’, ‘转化’, ‘广告’, ‘活动’],

analysis: [‘分析’, ‘市场’, ‘竞品’, ‘行业’, ‘趋势’, ‘数据’]

};

let domainMatches = 0;

Object.values(domainKeywords).forEach(keywords => {

const matches = keywords.filter(keyword => messageLower.includes(keyword));

if (matches.length > 0) domainMatches++;

});

// 如果有转换词 + 专业领域词,或者有多个领域词,认为是新领域请求

return hasTransitionWord || domainMatches > 1;

}

// 获取Agent显示名称

getAgentTitle(agentName) {

const titles = {

‘market-analyst’: ‘📊 市场分析师’,

‘pr-specialist’: ‘📢 公关专员’,

‘marketing-specialist’: ‘📈 营销专员’

};

return titles[agentName] || ‘📊 市场分析师’;

}

// 获取Agent特色预响应

getAgentPreResponse(agentName) {

const preResponses = {

‘market-analyst’: ‘🔍 正在深度分析市场数据和行业趋势…’,

‘pr-specialist’: ‘📝 正在制定专业的公关传播策略…’,

‘marketing-specialist’: ‘🎯 正在优化营销策略和增长方案…’

};

return preResponses[agentName] || ‘🔍 正在深度分析市场数据和行业趋势…’;

}

// 获取路由统计信息

getRoutingStats() {

const stats = {

totalUsers: this.userContexts.size,

agentUsage: { ‘market-analyst’: 0, ‘pr-specialist’: 0, ‘marketing-specialist’: 0 },

totalRequests: 0

};

this.userContexts.forEach(context => {

context.recentAgents.forEach(agent => {

stats.agentUsage[agent] = (stats.agentUsage[agent] || 0) + 1;

stats.totalRequests++;

});

});

return stats;

}

// 清理过期上下文

cleanupExpiredContexts() {

const now = Date.now();

const expireTime = 24 * 60 * 60 * 1000; // 24小时

for (const [userId, context] of this.userContexts.entries()) {

if (now – context.lastMessageTime > expireTime) {

this.userContexts.delete(userId);

}

}

}

}

module.exports = IntelligentRouter;

// 进程池管理 q-pool-manager.js

const { spawn } = require(‘child_process’);

const EventEmitter = require(‘events’);

class QProcessPool extends EventEmitter {

constructor(maxProcesses = 5) {

super();

this.maxProcesses = maxProcesses;

this.activeProcesses = new Map();

this.queue = [];

this.processCount = 0;

}

async execute(message, agentName = ”, messageId = null) {

return new Promise((resolve, reject) => {

const request = {

message,

agentName,

resolve,

reject,

timestamp: Date.now(),

messageId

};

if (this.processCount < this.maxProcesses) {

this.startProcess(request);

} else {

this.queue.push(request);

console.log(请求排队,当前队列长度: ${this.queue.length});

}

});

}

startProcess(request) {

const processId = q_${Date.now()}_${Math.random().toString(36).substr(2, 9)};

this.processCount++;

const args = [‘chat’, ‘–trust-all-tools’, ‘–no-interactive’];

if (request.agentName) {

args.push(‘–agent’, request.agentName);

}

const qProcess = spawn(‘/home/ubuntu/.local/bin/q’, args, {

stdio: [‘pipe’, ‘pipe’, ‘pipe’],

env: { …process.env, TERM: ‘xterm’, PATH: process.env.PATH + ‘:/home/ubuntu/.local/bin’ }

});

this.activeProcesses.set(processId, {

process: qProcess,

request,

startTime: Date.now()

});

let output = ”;

let hasResponded = false;

// 90秒超时 (给复杂分析充足时间)

const timeout = setTimeout(() => {

if (!hasResponded) {

hasResponded = true;

this.cleanupProcess(processId);

request.reject(new Error(‘复杂分析处理时间较长,请尝试简化问题或稍后重试’));

}

}, 90000);

qProcess.stdout.on(‘data’, (data) => {

output += data.toString();

});

qProcess.on(‘close’, (code) => {

if (!hasResponded) {

hasResponded = true;

clearTimeout(timeout);

this.cleanupProcess(processId);

if (code === 0) {

request.resolve(output.trim());

} else {

request.reject(new Error(Q CLI 退出码: ${code}));

}

}

});

qProcess.on(‘error’, (err) => {

if (!hasResponded) {

hasResponded = true;

clearTimeout(timeout);

this.cleanupProcess(processId);

request.reject(new Error(Q CLI 错误: ${err.message}));

}

});

// 发送消息

qProcess.stdin.write(request.message + ‘\n’);

qProcess.stdin.end();

console.log(启动进程 ${processId}, 当前活跃进程: ${this.processCount});

}

cleanupProcess(processId) {

const processInfo = this.activeProcesses.get(processId);

if (processInfo) {

try {

processInfo.process.kill();

} catch (e) {

// 进程可能已经结束

}

this.activeProcesses.delete(processId);

this.processCount–;

console.log(清理进程 ${processId}, 剩余活跃进程: ${this.processCount});

// 处理队列中的下一个请求

if (this.queue.length > 0) {

const nextRequest = this.queue.shift();

this.startProcess(nextRequest);

}

}

}

getStats() {

return {

activeProcesses: this.processCount,

queueLength: this.queue.length,

maxProcesses: this.maxProcesses

};

}

}

module.exports = QProcessPool;

// 限流器 rate-limiter.js

class RateLimiter {

constructor(maxRequests = 10, windowMs = 60000) { // 每分钟最多10个请求

this.maxRequests = maxRequests;

this.windowMs = windowMs;

this.users = new Map();

}

isAllowed(userId) {

const now = Date.now();

const userRecord = this.users.get(userId) || { requests: [], blocked: false };

// 清理过期请求

userRecord.requests = userRecord.requests.filter(time => now – time < this.windowMs);

// 检查是否超过限制

if (userRecord.requests.length >= this.maxRequests) {

userRecord.blocked = true;

this.users.set(userId, userRecord);

return false;

}

// 记录新请求

userRecord.requests.push(now);

userRecord.blocked = false;

this.users.set(userId, userRecord);

return true;

}

getRemainingRequests(userId) {

const userRecord = this.users.get(userId);

if (!userRecord) return this.maxRequests;

const now = Date.now();

const validRequests = userRecord.requests.filter(time => now – time < this.windowMs);

return Math.max(0, this.maxRequests – validRequests.length);

}

cleanup() {

const now = Date.now();

for (const [userId, userRecord] of this.users.entries()) {

userRecord.requests = userRecord.requests.filter(time => now – time < this.windowMs);

if (userRecord.requests.length === 0) {

this.users.delete(userId);

}

}

}

}

module.exports = RateLimiter;

// Feishu Server Systemd

[Unit]

Description=Feishu Server

After=network.target

[Service]

Type=simple

User=ubuntu

Group=ubuntu

WorkingDirectory=/home/ubuntu/feishu

ExecStart=/usr/bin/node server.js

Restart=always

RestartSec=10

Environment=NODE_ENV=production

Environment=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/home/ubuntu/.local/bin

[Install]

WantedBy=multi-user.target

// nginx.conf Nginx代理

server {

listen 443 ssl;

server_name amazonq.moveinsync.cn;

ssl_certificate /home/ubuntu/feishu-webhook/cert.pem;

ssl_certificate_key /home/ubuntu/feishu-webhook/key.pem;

location / {

proxy_pass https://127.0.0.1:8443;

proxy_ssl_verify off;

proxy_set_header Host $host;

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_set_header X-Forwarded-Proto $scheme;

}

}

8. 效果展示

8.1

直接使用** **Amazon Q

8.2

接入** **Anspire AI Search MCP Server** **后

9. 优势总结

结合实际业务场景,采用Amazon Q Developer CLI多Agent架构的优势:

  • 专业分工

细分角色的Agent实现专业化处理,保证分析深度与多维度覆盖,灵活的智能路由。

  • 高并发请求处理能力

进程池架构支持多个Amazon Q CLI任务并行,保证业务响应及时,适合企业级服务需求。

  • 智能搜索能力加持

Anspire AI Search为多Agent提供强大语义检索,突破传统关键词搜索瓶颈,提升信息获取和业务洞察质量。

  • 与现有生态系统良好集成

深度融入飞书协作平台,简化用户交互路径,使市场分析服务更加可触达和易用。

  • 安全稳定,易于扩展

预设限流、去重及HTTPS安全通信策略,结合模块化Agent设计,保证系统长期稳定运行并支持快速迭代升级。

该方案将Amazon Q Developer CLI的多Agent能力、专业化市场分析角色和安畅Anspire AI语义搜索技术进行融合,适用于企业级复杂市场分析和营销策略制定场景,极大提升智能化水平和用户体验。

10. 技术材料参考:

  • 安畅AI Agent开发平台指南:
  • Amazon Q Developer CLI 指南:
  • *前述特定亚马逊云科技生成式人工智能相关的服务目前在亚马逊云科技海外区域可用。亚马逊云科技中国区域相关云服务由西云数据和光环新网运营,具体信息以中国区域官网为准。


点击联系客服Telegram
赞(0)
未经允许不得转载:AWS USDT代付 | Payment 解决方案 » 使用Amazon Q Developer CLI快速构建市场分析智能体

AWS代付、代充值免实名

联系我们阿里云国际免实名