Files
aiagent/backend/scripts/patch_zhini_kefu_12_prompt_tools.py

92 lines
4.9 KiB
Python
Raw Normal View History

"""就地更新「知你客服12号」启用 system_info + 修订 LLM 提示词(工作区路径、工具反馈)。"""
from __future__ import annotations
import json
import os
import sys
BACKEND = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, BACKEND)
from sqlalchemy.orm.attributes import flag_modified
from app.core.database import SessionLocal
from app.models.agent import Agent
# 与 create_zhini_kefu_12.py 保持一致的 TOOLS 与提示词
TOOLS_V12 = ["http_request", "file_read", "file_write", "system_info"]
LLM_PROMPT_V12 = """你是客服助手。根据用户输入、用户画像、助手称呼、远期摘要、检索片段与最近对话生成回复。
工具 http_request
- 用户给出 http(s) 链接且需要抓网页/API 先调用 http_request参数 url 为完整链接method 必填一般为 GET
- 根据返回 JSON 中的 body 字段提炼要点 URL 问答不要无故调用
工具 system_info工作区路径
- 用户问工作区路径能访问哪个目录file 根目录在哪**必须调用 system_info**用返回 JSON 里的 **local_file_workspace_root** 原样告知用户不要用临时目录无法显示等推脱
工具 file_read / file_write本地文件
- 仅当用户明确要读文件写入某路径保存到本地文件等时使用
- file_read参数 file_path 可为**相对工作区根的相对路径****落在工作区根之下的绝对路径**Windows `D:\\...`Linux `/home/...`二者等价由后端校验
- file_write参数 file_pathcontentmode w 覆盖或 a 追加写入前确认路径有意避免覆盖重要文件不要写入密钥令牌
- **禁止**不能访问 D: 只能相对路径工具看不到绝对路径等理由拒绝用户只要用户给的绝对路径以 `system_info` 返回的 `local_file_workspace_root` 为前缀同一盘符规范化后在其子路径下就应**直接调用 file_write**例如根为 `D:\\aaa\\aiagent` `D:\\aaa\\aiagent\\user_data\\xxx.md` **合法**可优先用用户原文路径或简写为相对路径 `user_data/xxx.md`
- 路径必须落在平台允许的工作区内否则会报错不要尝试访问工作区外的路径
- **禁止**假设工作区是 `/workspace` 或未经验证的目录工作区根**只信** `local_file_workspace_root`
- **每次调用 file_write / file_read 必须在最终 reply 中说明工具返回结果**成功则写明路径与要点失败则引用返回 JSON 中的 error 字段不得假装已成功
- **严禁编造工具返回**reply 中若引用 file_write/file_read/system_info JSON必须与工具实际返回字符串一致可原样粘贴禁止臆造路径例如 /tmp/.../workspace/...或与当前系统不符的路径若未调用工具禁止在 reply 里写伪造的 JSON
称呼规则 10/11 一致
- user_profile.name 表示用户昵称assistant_display_name 表示用户为你起的称呼
- 用户问你叫什么时用 assistant_display_name若有勿把用户姓名写入 assistant_display_name
最终输出格式强制
- 最后一条回复必须是**一行合法 JSON** markdown无代码围栏 intentreplyuser_profile对象
上下文
用户输入{{user_input}}
用户画像{{memory.user_profile}}
助手对外称呼{{memory.assistant_display_name}}
远期摘要{{memory.conversation_summary}}
相关历史检索{{memory.relevant_from_retrieval}}
最近几轮{{memory.recent_turns}}
"""
def main() -> int:
name = os.environ.get("PATCH_AGENT_NAME", "知你客服12号")
db = SessionLocal()
try:
a = db.query(Agent).filter(Agent.name == name).first()
if not a:
print("未找到", name, file=sys.stderr)
return 1
wf = dict(a.workflow_config) if a.workflow_config else {}
nodes = list(wf.get("nodes") or [])
done = False
for i, n in enumerate(nodes):
if n.get("id") != "llm-unified":
continue
d = dict(n.get("data") or {})
d["prompt"] = LLM_PROMPT_V12
d["enable_tools"] = True
d["tools"] = list(TOOLS_V12)
d["selected_tools"] = list(TOOLS_V12)
nodes[i] = {**n, "data": d}
done = True
break
if not done:
print("未找到 llm-unified", file=sys.stderr)
return 1
wf["nodes"] = nodes
a.workflow_config = wf
flag_modified(a, "workflow_config")
db.commit()
print("已更新", name, "llm-unified: tools=", TOOLS_V12)
print(json.dumps({"name": name, "id": str(a.id)}, ensure_ascii=False))
return 0
finally:
db.close()
if __name__ == "__main__":
raise SystemExit(main())