Files
sanguo_vnpy_v2/.claude/workflows/helpers/linus-triad.js
T
claude_dev 918bbed0fc fix: 修复登录500错误和移除明文密码提示
- 修复 deps.py 中 get_vn_service 的引用错误 (vn_service.vn_service -> vn_service)
- 移除登录页面上的明文密码提示
- 改进前端错误处理,避免数据加载失败导致登录显示错误
2026-07-02 12:23:55 +08:00

411 lines
10 KiB
JavaScript

/**
* Linus 三问决策框架
*
* 实现工程审慎决策逻辑
* 来源: Linus Torvalds "Talk Like a Kernel Developer"
*/
/**
* 三问枚举
*/
export const QuestionType = {
REAL_PROBLEM: '这是现实问题还是想象问题?',
NEEDS_SOLUTION: '这个问题真的需要解决吗?',
SOLUTION_VIABLE: '这个方案真的能解决问题吗?'
}
/**
* Linus 三问决策器类
*/
export class LinusTriadDecision {
constructor() {
this.questions = [
QuestionType.REAL_PROBLEM,
QuestionType.NEEDS_SOLUTION,
QuestionType.SOLUTION_VIABLE
]
this.answers = []
this.reasoning = []
}
/**
* 执行完整的 Linus 三问
*
* @param {string} taskDescription - 任务描述
* @param {Object} options - 选项
* @returns {Promise<Object>} 决策结果
*/
async ask(taskDescription, options = {}) {
const { interactive = false, context = null } = options
// 清空之前的答案
this.answers = []
this.reasoning = []
log('🤔 开始 Linus 三问决策...')
log(`📋 任务: ${taskDescription}`)
// 第一问:现实问题还是想象问题?
const q1Result = await this.isRealProblem(taskDescription, context)
this.answers.push(q1Result.answer)
this.reasoning.push(q1Result.reasoning)
if (!q1Result.answer) {
log('❌ 第一问未通过:这不是现实问题')
return this.createResult(false, '第一问未通过:这不是现实问题', q1Result.reasoning)
}
log('✅ 第一问通过:这是现实问题')
// 第二问:这个问题真的需要解决吗?
const q2Result = await this.needsSolution(taskDescription, context)
this.answers.push(q2Result.answer)
this.reasoning.push(q2Result.reasoning)
if (!q2Result.answer) {
log('❌ 第二问未通过:这个问题不需要解决')
return this.createResult(false, '第二问未通过:这个问题不需要解决', [
this.reasoning[0],
q2Result.reasoning
])
}
log('✅ 第二问通过:这个问题需要解决')
// 第三问:这个方案真的能解决问题吗?
const q3Result = await this.solutionViable(taskDescription, context)
this.answers.push(q3Result.answer)
this.reasoning.push(q3Result.reasoning)
if (!q3Result.answer) {
log('❌ 第三问未通过:这个方案不能解决问题')
return this.createResult(false, '第三问未通过:这个方案不能解决问题', [
this.reasoning[0],
this.reasoning[1],
q3Result.reasoning
])
}
log('✅ 第三问通过:这个方案能解决问题')
log('✅ Linus 三问全部通过!')
return this.createResult(true, 'Linus 三问全部通过', this.reasoning)
}
/**
* 第一问:这是现实问题还是想象问题?
*
* 拒绝条件:
* - "可能需要"、"也许将来"
* - 纯粹的假设性场景
* - "以防万一"
*/
async isRealProblem(taskDescription, context) {
log(`\n📌 第一问:${QuestionType.REAL_PROBLEM}`)
const answer = await this.evaluateQuestion(taskDescription, context, {
positiveIndicators: [
'用户反馈',
'生产问题',
'线上错误',
'性能瓶颈',
'安全漏洞',
'bug',
'错误',
'失败',
'崩溃',
'无法',
'必须',
'紧急',
'关键'
],
negativeIndicators: [
'可能需要',
'也许将来',
'以防万一',
'考虑未来',
'如果发生',
'假设',
'理论上',
'或许',
'可能'
],
analysisPrompt: `判断以下任务是否是现实问题:
"${taskDescription}"
回答 JSON:
{
"isRealProblem": true|false,
"reasoning": "判断理由",
"evidence": ["证据1", "证据2"],
"verdict": "这是现实问题/这是想象问题"
}`
})
return {
answer: answer.isRealProblem,
reasoning: answer.reasoning,
evidence: answer.evidence,
verdict: answer.verdict
}
}
/**
* 第二问:这个问题真的需要解决吗?
*
* 拒绝条件:
* - 边缘场景
* - 伪需求
* - 性价比极低
*/
async needsSolution(taskDescription, context) {
log(`\n📌 第二问:${QuestionType.NEEDS_SOLUTION}`)
const answer = await this.evaluateQuestion(taskDescription, context, {
positiveIndicators: [
'影响用户体验',
'影响性能',
'影响安全',
'影响稳定性',
'阻塞功能',
'影响核心',
'高频',
'重要',
'必要',
'必须'
],
negativeIndicators: [
'边缘',
'小众',
'罕见',
'偶尔',
'理论上',
'可以接受',
'不是必需',
'可选项',
'优化项',
'锦上添花'
],
analysisPrompt: `判断以下问题是否真的需要解决:
"${taskDescription}"
回答 JSON:
{
"needsSolution": true|false,
"reasoning": "判断理由",
"impact": "高/中/低",
"verdict": "这个问题需要解决/这个问题不需要解决"
}`
})
return {
answer: answer.needsSolution,
reasoning: answer.reasoning,
impact: answer.impact,
verdict: answer.verdict
}
}
/**
* 第三问:这个方案真的能解决问题吗?
*
* 拒绝条件:
* - 理论上可行但无验证
* - 缺少实施路径
* - 技术栈不匹配
*/
async solutionViable(taskDescription, context) {
log(`\n📌 第三问:${QuestionType.SOLUTION_VIABLE}`)
const answer = await this.evaluateQuestion(taskDescription, context, {
positiveIndicators: [
'明确方案',
'具体步骤',
'已有先例',
'可验证',
'可测试',
'有计划',
'有路径',
'可行'
],
negativeIndicators: [
'理论上',
'应该可以',
'可能需要',
'待研究',
'不确定',
'猜测',
'假设',
'无从验证'
],
analysisPrompt: `判断以下方案是否真的能解决问题:
"${taskDescription}"
如果有具体方案,请评估其可行性。如果没有方案,请判断是否可以制定有效方案。
回答 JSON:
{
"solutionViable": true|false,
"reasoning": "判断理由",
"hasConcretePlan": true|false,
"verdict": "这个方案能解决问题/这个方案不能解决问题"
}`
})
return {
answer: answer.solutionViable,
reasoning: answer.reasoning,
hasConcretePlan: answer.hasConcretePlan,
verdict: answer.verdict
}
}
/**
* 评估问题(使用 Agent 进行分析)
*/
async evaluateQuestion(taskDescription, context, config) {
// 如果有上下文信息,使用它
const fullContext = context ? `上下文: ${context}\n` : ''
// 使用 Plan Agent 进行分析
try {
const analysis = await agent({
subagent_type: 'Plan',
prompt: `${fullContext}${config.analysisPrompt}`,
schema: {
type: 'object',
properties: {
isRealProblem: { type: 'boolean' },
needsSolution: { type: 'boolean' },
solutionViable: { type: 'boolean' },
reasoning: { type: 'string' },
evidence: { type: 'array', items: { type: 'string' } },
impact: { type: 'string' },
hasConcretePlan: { type: 'boolean' },
verdict: { type: 'string' }
}
}
})
return analysis
} catch (error) {
log(`⚠️ Agent 分析失败: ${error.message}`)
// 回退到简单关键词检测
return this.fallbackEvaluation(taskDescription, config)
}
}
/**
* 回退评估(基于关键词)
*/
fallbackEvaluation(taskDescription, config) {
const text = taskDescription.toLowerCase()
const { positiveIndicators, negativeIndicators } = config
let positiveScore = 0
let negativeScore = 0
for (const indicator of positiveIndicators) {
if (text.includes(indicator.toLowerCase())) {
positiveScore++
}
}
for (const indicator of negativeIndicators) {
if (text.includes(indicator.toLowerCase())) {
negativeScore++
}
}
const answer = positiveScore > negativeScore
const reasoning = `基于关键词检测:正面指标 ${positiveScore} 个,负面指标 ${negativeScore}`
return {
isRealProblem: answer,
needsSolution: answer,
solutionViable: answer,
reasoning,
verdict: answer ? '通过关键词检测' : '未通过关键词检测'
}
}
/**
* 创建决策结果
*/
createResult(passed, message, reasoning) {
return {
passed,
message,
reasoning: Array.isArray(reasoning) ? reasoning : [reasoning],
answers: this.answers,
timestamp: new Date().toISOString()
}
}
}
/**
* 快速函数:执行 Linus 三问
*
* @param {string} taskDescription - 任务描述
* @param {Object} options - 选项
* @returns {Promise<Object>} 决策结果
*/
export async function askLinusTriad(taskDescription, options = {}) {
const decision = new LinusTriadDecision()
return await decision.ask(taskDescription, options)
}
/**
* 检查任务是否通过 Linus 三问
*
* @param {string} taskDescription - 任务描述
* @returns {Promise<boolean>} 是否通过
*/
export async function passesLinusTriad(taskDescription) {
const result = await askLinusTriad(taskDescription)
return result.passed
}
/**
* 生成拒绝响应
*
* @param {Object} decisionResult - 决策结果
* @returns {string} 拒绝消息
*/
export function generateRejectionMessage(decisionResult) {
let message = `## ❌ 任务未通过 Linus 三问决策\n\n`
message += `**原因**: ${decisionResult.message}\n\n`
message += `### 决策过程\n\n`
for (let i = 0; i < decisionResult.reasoning.length; i++) {
message += `**${i + 1}. ${decisionResult.reasoning[i]}**\n\n`
}
message += `### 建议\n\n`
message += `- 请重新审视任务需求\n`
message += `- 确保这是需要解决的现实问题\n`
message += `- 提供明确的解决方案\n`
message += `- 如有疑问,请使用 deep-interview 进行需求澄清\n\n`
message += `---\n`
message += `**决策时间**: ${decisionResult.timestamp}\n`
return message
}
/**
* 辅助函数:日志输出
*/
function log(message) {
console.log(`[LinusTriad] ${message}`)
}
/**
* 导出
*/
export default {
LinusTriadDecision,
askLinusTriad,
passesLinusTriad,
generateRejectionMessage,
QuestionType
}