agent-way: LLM resolves project aliases via project list in INTENT_PROMPT
This commit is contained in:
parent
588e5be5d6
commit
4c5b3104cf
@ -412,6 +412,7 @@ INTENT_PROMPT = """你是一个开发产线意图分类器。分析用户输入
|
|||||||
- show_repos: 查看当前项目关联的仓库(如"有哪些仓库""显示仓库")
|
- show_repos: 查看当前项目关联的仓库(如"有哪些仓库""显示仓库")
|
||||||
|
|
||||||
当前上下文:项目={ctx},迭代={iter}
|
当前上下文:项目={ctx},迭代={iter}
|
||||||
|
可选项目列表(select_project时project_name必须从列表中选择):{projects}
|
||||||
待客户回答的问题(角色Agent执行任务中提出):{questions}
|
待客户回答的问题(角色Agent执行任务中提出):{questions}
|
||||||
若用户消息是在回答上述问题之一,intent应为answer_question,并把回答内容填入description。
|
若用户消息是在回答上述问题之一,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":"..."}"""
|
{"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='无'):
|
async def _classify_intent(model_info, message, ctx, history_msgs, sor, questions_text='无'):
|
||||||
"""Classify user intent using LLM."""
|
"""Classify user intent using LLM. sor is needed to load project list."""
|
||||||
ctx_str = ctx.get('project_name', '') or '无'
|
ctx_str = ctx.get('project_name', '') or '无'
|
||||||
iter_str = ctx.get('iteration_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}]
|
msgs = [{"role": "system", "content": prompt}]
|
||||||
for h in history_msgs[-4:]:
|
for h in history_msgs[-4:]:
|
||||||
msgs.append(h)
|
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):
|
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
|
if not name: return None
|
||||||
# Try exact match first
|
|
||||||
recs = await sor.sqlExe(
|
recs = await sor.sqlExe(
|
||||||
"SELECT id, name FROM sd_projects WHERE name=${name}$ AND org_id=${oid}$",
|
"SELECT id, name FROM sd_projects WHERE name=${name}$ AND org_id=${oid}$",
|
||||||
{"name": name, "oid": org_id})
|
{"name": name, "oid": org_id})
|
||||||
if recs:
|
return recs[0] if recs else None
|
||||||
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
|
|
||||||
|
|
||||||
|
|
||||||
# ==================== 问题路由 ====================
|
# ==================== 问题路由 ====================
|
||||||
@ -656,7 +652,7 @@ if action == 'send_message':
|
|||||||
qlines.append(f"- [id={getattr(fq, 'id', '')}] [{getattr(fq, 'from_role', '')}] {getattr(fq, 'question', '')}")
|
qlines.append(f"- [id={getattr(fq, 'id', '')}] [{getattr(fq, 'from_role', '')}] {getattr(fq, 'question', '')}")
|
||||||
questions_text = '\n'.join(qlines)
|
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}')
|
debug(f'intent: {intent}')
|
||||||
|
|
||||||
# 3. Route by intent
|
# 3. Route by intent
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user