feat: 经验写入即时提示——提炼+保存挪到 done 事件之前(原在 done 后执行、SSE 已关流,用户看不到),成功后推 🧠 经验记忆 step 卡片「已写入记忆库,下次相似任务自动参考」;_save_experience 返回成功与否;蒸馏超时 60s→25s 防收尾拖沓
This commit is contained in:
+15
-6
@@ -138,7 +138,7 @@ def _distill_experience(cfg, prompt, tool_seq):
|
|||||||
headers = {"Authorization": f"Bearer {cfg.get('api_key', '')}",
|
headers = {"Authorization": f"Bearer {cfg.get('api_key', '')}",
|
||||||
"Content-Type": "application/json"}
|
"Content-Type": "application/json"}
|
||||||
r = httpx.post(f"{(cfg.get('api_base') or 'https://api.deepseek.com').rstrip('/')}/chat/completions",
|
r = httpx.post(f"{(cfg.get('api_base') or 'https://api.deepseek.com').rstrip('/')}/chat/completions",
|
||||||
json=body, headers=headers, timeout=60)
|
json=body, headers=headers, timeout=25)
|
||||||
if r.status_code != 200:
|
if r.status_code != 200:
|
||||||
return ""
|
return ""
|
||||||
j = r.json()
|
j = r.json()
|
||||||
@@ -150,10 +150,10 @@ def _distill_experience(cfg, prompt, tool_seq):
|
|||||||
|
|
||||||
|
|
||||||
def _save_experience(prompt, recipe, tool_seq):
|
def _save_experience(prompt, recipe, tool_seq):
|
||||||
"""保存经验(后台线程调用,包 app context)。"""
|
"""保存经验(后台线程调用,包 app context)。返回是否保存成功。"""
|
||||||
try:
|
try:
|
||||||
if _flask_app is None:
|
if _flask_app is None:
|
||||||
return
|
return False
|
||||||
with _flask_app.app_context():
|
with _flask_app.app_context():
|
||||||
_ensure_exp_table()
|
_ensure_exp_table()
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
@@ -164,8 +164,10 @@ def _save_experience(prompt, recipe, tool_seq):
|
|||||||
"c": datetime.now().strftime("%Y-%m-%d %H:%M")})
|
"c": datetime.now().strftime("%Y-%m-%d %H:%M")})
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
_log.info("经验已保存(配方 %d 字符)", len(recipe))
|
_log.info("经验已保存(配方 %d 字符)", len(recipe))
|
||||||
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
_log.warning(f"经验保存失败: {e}")
|
_log.warning(f"经验保存失败: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
# ================== 配置 ==================
|
# ================== 配置 ==================
|
||||||
@@ -355,16 +357,23 @@ def _agent_thread(run_id, prompt, serial, cfg):
|
|||||||
hist.append({"role": "user", "content": prompt[:2000]})
|
hist.append({"role": "user", "content": prompt[:2000]})
|
||||||
hist.append({"role": "assistant", "content": (answer or "")[:4000]})
|
hist.append({"role": "assistant", "content": (answer or "")[:4000]})
|
||||||
_run["history"] = hist[-24:]
|
_run["history"] = hist[-24:]
|
||||||
q.put(("done", {"answer": answer}))
|
|
||||||
|
|
||||||
# 自进化:成功后提炼操作配方存为经验(尽力而为,不阻塞/不影响结果)
|
# 自进化:成功执行过工具则提炼配方写入经验。必须在 done 之前完成——
|
||||||
|
# done 发出后 SSE 关流,用户就看不到「已写入经验」的提示了。
|
||||||
|
# 提炼/保存失败静默(不阻塞、不影响结果),只在成功时推送 🧠 卡片。
|
||||||
if tool_seq:
|
if tool_seq:
|
||||||
try:
|
try:
|
||||||
recipe = _distill_experience(cfg, prompt, " -> ".join(tool_seq))
|
recipe = _distill_experience(cfg, prompt, " -> ".join(tool_seq))
|
||||||
if recipe and "配方" not in recipe[:50]:
|
if recipe and "配方" not in recipe[:50]:
|
||||||
_save_experience(prompt, recipe, " -> ".join(tool_seq))
|
if _save_experience(prompt, recipe, " -> ".join(tool_seq)):
|
||||||
|
_log.info("经验已写入记忆库,随事件流提示")
|
||||||
|
q.put(("step", {"tool": "🧠 经验记忆",
|
||||||
|
"args": "本轮操作已提炼为经验并写入记忆库"
|
||||||
|
"(下次相似任务会自动参考)",
|
||||||
|
"image": None}))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
_log.warning(f"经验保存异常: {e}")
|
_log.warning(f"经验保存异常: {e}")
|
||||||
|
q.put(("done", {"answer": answer}))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
_log.warning(f"Agent 运行异常: {e}")
|
_log.warning(f"Agent 运行异常: {e}")
|
||||||
# 诊断:打印消息结构(tool_calls 与 tool 消息配对检查)
|
# 诊断:打印消息结构(tool_calls 与 tool 消息配对检查)
|
||||||
|
|||||||
Reference in New Issue
Block a user