agent-way: LLM resolves project aliases via project list in INTENT_PROMPT

This commit is contained in:
ymq 2026-08-08 15:19:18 +08:00
parent 588e5be5d6
commit 4c5b3104cf

View File

@ -412,6 +412,7 @@ INTENT_PROMPT = """你是一个开发产线意图分类器。分析用户输入
- show_repos: 查看当前项目关联的仓库(如"有哪些仓库""显示仓库"
当前上下文:项目={ctx},迭代={iter}
可选项目列表select_project时project_name必须从列表中选择{projects}
待客户回答的问题角色Agent执行任务中提出{questions}
若用户消息是在回答上述问题之一intent应为answer_question并把回答内容填入description。
@ -419,11 +420,18 @@ INTENT_PROMPT = """你是一个开发产线意图分类器。分析用户输入
{"intent":"...","confidence":0.8,"project_name":"...","iteration_name":"...","title":"...","description":"...","source_path":"...","role":"...","missing_info":"...","question_id":"...","repo_url":"...","repo_name":"..."}"""
async def _classify_intent(model_info, message, ctx, history_msgs, questions_text='无'):
"""Classify user intent using LLM."""
async def _classify_intent(model_info, message, ctx, history_msgs, sor, questions_text='无'):
"""Classify user intent using LLM. sor is needed to load project list."""
ctx_str = ctx.get('project_name', '') or '无'
iter_str = ctx.get('iteration_name', '') or '无'
prompt = INTENT_PROMPT.replace('{ctx}', ctx_str).replace('{iter}', iter_str).replace('{questions}', questions_text)
# 加载项目列表供LLM匹配
proj_recs = await sor.sqlExe("SELECT name FROM sd_projects ORDER BY created_at DESC LIMIT 20", {})
proj_names = ', '.join([getattr(r, 'name', '') for r in (proj_recs or [])]) or '无'
prompt = (INTENT_PROMPT
.replace('{ctx}', ctx_str)
.replace('{iter}', iter_str)
.replace('{projects}', proj_names)
.replace('{questions}', questions_text))
msgs = [{"role": "system", "content": prompt}]
for h in history_msgs[-4:]:
msgs.append(h)
@ -439,24 +447,12 @@ async def _classify_intent(model_info, message, ctx, history_msgs, questions_tex
async def _find_project(sor, name, org_id):
"""Find project by name (supports partial match)."""
"""Find project by exact name (LLM should resolve aliases)."""
if not name: return None
# Try exact match first
recs = await sor.sqlExe(
"SELECT id, name FROM sd_projects WHERE name=${name}$ AND org_id=${oid}$",
{"name": name, "oid": org_id})
if recs:
return recs[0]
# Fuzzy: load all projects for this org and match in Python
all_recs = await sor.sqlExe(
"SELECT id, name FROM sd_projects WHERE org_id=${oid}$",
{"oid": org_id})
kw = name.lower()
for rec in (all_recs or []):
rname = (getattr(rec, 'name', '') or '').lower()
if kw in rname:
return rec
return None
return recs[0] if recs else None
# ==================== 问题路由 ====================
@ -656,7 +652,7 @@ if action == 'send_message':
qlines.append(f"- [id={getattr(fq, 'id', '')}] [{getattr(fq, 'from_role', '')}] {getattr(fq, 'question', '')}")
questions_text = '\n'.join(qlines)
intent = await _classify_intent(model_info, message_text, ctx, history_msgs, questions_text)
intent = await _classify_intent(model_info, message_text, ctx, history_msgs, sor, questions_text)
debug(f'intent: {intent}')
# 3. Route by intent