test_prompt.py 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. """
  2. 测试提示词脚本
  3. 使用requests库测试语法审查API
  4. 支持本地模型和在线模型两种调用方式
  5. """
  6. import requests
  7. import json
  8. from openai import OpenAI
  9. class PromptTester:
  10. """提示词测试类"""
  11. def __init__(self, api_url, api_key=None, is_local=True):
  12. """
  13. 初始化测试器
  14. Args:
  15. api_url: API地址
  16. api_key: API密钥(在线模型需要)
  17. is_local: 是否使用本地模型(True: 本地模型使用requests, False: 在线模型使用OpenAI SDK)
  18. """
  19. self.api_url = api_url
  20. self.api_key = api_key
  21. self.is_local = is_local
  22. # 如果是在线模型,初始化OpenAI客户端
  23. if not is_local and api_key:
  24. self.client = OpenAI(
  25. base_url=api_url.replace('/chat/completions', ''), # 移除末尾的路径
  26. api_key=api_key
  27. )
  28. else:
  29. self.client = None
  30. self.system_prompt = """
  31. system
  32. # role
  33. 你是词句语法审查专家
  34. ## workflow
  35. - 负责检查文本中的错别字和重复字词等语法问题。
  36. - 检查待审查的词句语法标点格式是否符合规则。
  37. - 检查错别字、多字、少字、重复字词等语法错误。
  38. - 如果发现一个句子有错误,请正确的定位其错误位置,而不是想当然的去找问题。如句子末尾未加句号不要定位到句中去了。
  39. - 给出了最终建议后,需要再次考虑如果按照建议去做了,原文是否通顺合理。
  40. - 请减少对标点符号的严格审查,如果有问题请三思你所说的位置有没有符号,符号对不对。
  41. - 仅检查句尾的标点问题,不要检查句中标点问题。
  42. - 请**不要为文章新增标点符号**如句号、逗号,只需要审查标点符号是否正确即可。
  43. ## example
  44. 1. 出现了明显错字,出现了的地得使用混乱。
  45. 2. 如果出现了错字,大概率是因为拼音拼写错误导致的错字,请根据其相似读音推测正确的字,如果拿不准请不给出修改为xx的建议。
  46. 3. 如“供气”错打为了“供器”,应当结合上下文推测“供qi”应该为什么。
  47. 4. 对于条款编号而言,'一)'这样的结构是正确的,符合中文规范
  48. ## rule
  49. - 不需要强求要输出问题,除非是非常明显的错误。小问题可以忽略。
  50. - 仅检查句尾的标点问题,不要检查句中标点问题。
  51. - 不要为长句切分、添加分句标点。
  52. - 请着重对错别字的审查上,大量减少对标点符号的审查力度。
  53. - 务必遵循<example>中的规则。
  54. - 如果没有错误请不要添加新的issue。
  55. - 遵循中文的语法规范。
  56. - 遵循以下**强制**规范:
  57. 1. 务必结合语境进行分析检查。
  58. 2. 对于**表格制表符**、**表格内容**不需要检查。
  59. 3. 对于术语概念不得曲解。
  60. 4. 没有明显词句语法错误、标点错误的内容不予检查,输出无明显问题。
  61. 5. 已检查出的问题项仅输出一次检查结果,禁止对同一内容重复检查。
  62. 6. 统一解释:如果表格中出现了多列相同的表头标题,不是错误,而是解析时这几个是合并的表头。
  63. ## output
  64. ```json
  65. {{
  66. "issue_point": "问题标题描述",
  67. "location": "当前问题对应的原始条款内容及位置,如六、验收标准 (页码: 85),以及其语境上下文",
  68. "suggestion": "具体的修改建议内容",
  69. "reason": "问题的原因分析和依据说明",
  70. "risk_level": ""
  71. }}
  72. ```
  73. # 风险等级分类risk_level:
  74. - 高风险:影响施工安全、可能导致严重后果的词句错误。
  75. - 中风险:影响理解表达、可能导致一般性问题的词句错误。
  76. - 低风险:形式问题、不影响实质内容的词句错误。
  77. """
  78. self.user_prompt_template = """
  79. 请审查以下内容的词句语法错误,重点关注错别字、重复字词和语法结构:
  80. 【待检查文本】
  81. {review_content}
  82. 输出格式:务必须严格按照以下标准json格式输出审查结果:
  83. 如果未发现明显的词句语法错误,请输出:无明显问题。
  84. 如果发现问题,请按以下格式输出:
  85. location字段直接输出原字段内容,不得猜测。
  86. ## 示例
  87. ```json
  88. {{
  89. "issue_point": "问题标题描述",
  90. "location": "当前问题对应的原始条款内容及位置,如六、验收标准 (页码: 85),以及其语境上下文",
  91. "suggestion": "具体的修改建议内容",
  92. "reason": "问题的原因分析和依据说明",
  93. "risk_level": ""
  94. }}
  95. ```
  96. /no_think
  97. """
  98. def test_prompt(self, review_content, model="Qwen3-8B", temperature=0.3, max_tokens=2000):
  99. """
  100. 测试提示词
  101. Args:
  102. review_content: 待审查的文本内容
  103. model: 模型名称
  104. temperature: 温度参数
  105. max_tokens: 最大token数
  106. Returns:
  107. API响应结果
  108. """
  109. # 填充用户提示词
  110. user_prompt = self.user_prompt_template.format(review_content=review_content)
  111. # 打印请求信息
  112. print("=" * 80)
  113. print(f"调用方式: {'本地模型 (requests)' if self.is_local else '在线模型 (OpenAI SDK)'}")
  114. print("发送请求到:", self.api_url)
  115. print("=" * 80)
  116. print("System Prompt:")
  117. print("-" * 80)
  118. print(self.system_prompt)
  119. print("=" * 80)
  120. print("User Prompt:")
  121. print("-" * 80)
  122. print(user_prompt)
  123. print("=" * 80)
  124. # 根据is_local选择不同的调用方式
  125. if self.is_local:
  126. # 本地模型:使用requests
  127. return self._call_with_requests(user_prompt, model, temperature, max_tokens)
  128. else:
  129. # 在线模型:使用OpenAI SDK
  130. return self._call_with_openai(user_prompt, model, temperature, max_tokens)
  131. def _call_with_requests(self, user_prompt, model, temperature, max_tokens):
  132. """使用requests库调用本地模型"""
  133. # 构建请求数据
  134. payload = {
  135. "model": model,
  136. "messages": [
  137. {
  138. "role": "system",
  139. "content": self.system_prompt
  140. },
  141. {
  142. "role": "user",
  143. "content": user_prompt
  144. }
  145. ],
  146. "temperature": temperature,
  147. "max_tokens": max_tokens
  148. }
  149. try:
  150. # 构建请求头
  151. headers = {"Content-Type": "application/json"}
  152. if self.api_key:
  153. headers["Authorization"] = f"Bearer {self.api_key}"
  154. # 发送POST请求
  155. response = requests.post(
  156. self.api_url,
  157. headers=headers,
  158. json=payload,
  159. timeout=60
  160. )
  161. # 检查响应状态
  162. response.raise_for_status()
  163. # 解析响应
  164. result = response.json()
  165. print("响应状态码:", response.status_code)
  166. print("=" * 80)
  167. print("API响应结果:")
  168. print("-" * 80)
  169. print(json.dumps(result, ensure_ascii=False, indent=2))
  170. print("=" * 80)
  171. # 提取AI回复内容
  172. if "choices" in result and len(result["choices"]) > 0:
  173. ai_response = result["choices"][0].get("message", {}).get("content", "")
  174. print("AI回复内容:")
  175. print("-" * 80)
  176. print(ai_response)
  177. print("=" * 80)
  178. return result
  179. except requests.exceptions.RequestException as e:
  180. print(f"请求失败: {e}")
  181. return None
  182. except json.JSONDecodeError as e:
  183. print(f"JSON解析失败: {e}")
  184. print("原始响应:", response.text)
  185. return None
  186. def _call_with_openai(self, user_prompt, model, temperature, max_tokens):
  187. """使用OpenAI SDK调用在线模型"""
  188. if not self.client:
  189. print("错误: OpenAI客户端未初始化")
  190. return None
  191. try:
  192. # 使用OpenAI SDK调用
  193. extra_body = {
  194. # enable thinking, set to False to disable test
  195. "enable_thinking": False,
  196. # use thinking_budget to contorl num of tokens used for thinking
  197. # "thinking_budget": 4096
  198. }
  199. response = self.client.chat.completions.create(
  200. model=model,
  201. messages=[
  202. {
  203. "role": "system",
  204. "content": self.system_prompt
  205. },
  206. {
  207. "role": "user",
  208. "content": user_prompt
  209. }
  210. ],
  211. temperature=temperature,
  212. max_tokens=max_tokens,
  213. extra_body=extra_body
  214. )
  215. # 转换为字典格式
  216. result = {
  217. "id": response.id,
  218. "object": response.object,
  219. "created": response.created,
  220. "model": response.model,
  221. "choices": [
  222. {
  223. "index": choice.index,
  224. "message": {
  225. "role": choice.message.role,
  226. "content": choice.message.content
  227. },
  228. "finish_reason": choice.finish_reason
  229. }
  230. for choice in response.choices
  231. ],
  232. "usage": {
  233. "prompt_tokens": response.usage.prompt_tokens,
  234. "completion_tokens": response.usage.completion_tokens,
  235. "total_tokens": response.usage.total_tokens
  236. }
  237. }
  238. print("=" * 80)
  239. print("API响应结果:")
  240. print("-" * 80)
  241. print(json.dumps(result, ensure_ascii=False, indent=2))
  242. print("=" * 80)
  243. # 提取AI回复内容
  244. if result["choices"] and len(result["choices"]) > 0:
  245. ai_response = result["choices"][0]["message"]["content"]
  246. print("AI回复内容:")
  247. print("-" * 80)
  248. print(ai_response)
  249. print("=" * 80)
  250. return result
  251. except Exception as e:
  252. print(f"OpenAI SDK调用失败: {e}")
  253. return None
  254. def main():
  255. """主函数"""
  256. # ==================== 配置区域 ====================
  257. # 是否使用本地模型(True: 本地模型, False: 在线模型)
  258. is_local = True
  259. # 本地模型配置
  260. local_config = {
  261. "api_url": "http://192.168.91.253:9002/v1/chat/completions",
  262. "api_key": None, # 本地模型不需要API Key
  263. "model": "Qwen3-8B",
  264. "temperature": 0.3,
  265. "max_tokens": 2000
  266. }
  267. # 在线模型配置(ModelScope)
  268. online_config = {
  269. "api_url": "https://api-inference.modelscope.cn/v1",
  270. "api_key": "ms-c0349a0a-8f15-466b-96be-4f96d001d8f2", # ModelScope Token
  271. "model": "Qwen/Qwen3-14B",
  272. "temperature": 0.7,
  273. "max_tokens": 2000
  274. }
  275. # ==================== 配置区域结束 ====================
  276. # 根据is_local选择配置
  277. config = local_config if is_local else online_config
  278. print("=" * 80)
  279. print(f"当前使用: {'本地模型' if is_local else '在线模型'}")
  280. print(f"API地址: {config['api_url']}")
  281. print(f"模型名称: {config['model']}")
  282. print("=" * 80)
  283. # 创建测试器
  284. tester = PromptTester(config["api_url"], config["api_key"], is_local)
  285. custom_content = """
  286. 上下时不得手持物件;必须从指定的路线上下,不得在高空投掷材料或工具等物;不得将易滚易滑的工具、材料堆放在脚手架上;工作完毕应及时将工具、零星材料、零部件等一切易坠落物件清理干净,以防落下伤人,上下大型零件时,应采用可靠的起吊机具。
  287. 12)要处处注意危险标志和危险地方。夜间作业,必须设置足够的照明设施,否则禁止施工。
  288. 13)严禁上下同时垂直作业。若特殊情况必须垂直作业,应经有关领导批准,并在上下两层间设备专用的防护棚或者其他隔离设施。
  289. 14)严禁坐在高空无遮栏处休息,防止坠落。
  290. 15)卷扬机等各种升降材料的设备严禁上下载人。
  291. 16)超过3米长的铺板不能同时站两人作业。
  292. 17)遇六级以上大风时,禁止露天进行高空作业。
  293. (4)起重作业安全保障措施
  294. 1)起重设备在现场初次使用时应进行试吊,试吊严格按照《起重机试验规范和程序》(GB/T 5905-2011)执行,试吊合格后方可使用。
  295. 2)起重作业前,检查起重设备的空载运转、回转、起重、变幅等各种机构的制动器、安全限位、防护装置等,确认正常后方可作业。
  296. 3)起重作业时,应依次逐级操作,严禁越档操作,在变换运转方向时,应将控制器转到零位,停止转动后,再转向另一方向,严禁急开急停。
  297. 4)司机、起重信号司索工等人员应经专业培训,取得特种设备作业人员证后,方可上岗作业。
  298. 5)起吊物件旋转或移动,应将起吊物提升至可能遇到的障碍物上方0.5m 以上。
  299. 6)起重作业严格执行安全操作规程,严格遵守“十不吊”的要求。
  300. 7)吊装人员必须戴安全帽、安全带;
  301. 8)吊装工作区设有明显标志,并设专人警戒,与吊装无关人员严禁入内。起重机工作时,起重臂杆旋转半径范围内,严禁站人或通过。
  302. 9)运输、吊装构件时,严禁在被运输、吊装的构件上指挥和放置材料、工具
  303. 10)吊装时,必须用吊笼或钢丝绳、保险绳绑扎牢固后才能吊运和传递,不得随意抛掷材料物体、工具,防止滑脱伤人或意外事故。
  304. 11)构件必须绑扎牢固,起吊点应通过构件的重心位置,吊升时应平稳,避免振动或摆动,以防构件脱落。
  305. 12)起吊构件时,速度不应太快,不得在高空停留过久,严禁猛升猛降,以防构件脱落。
  306. 13)构件就位后临时固定前,不得松钩、解开吊装索具。构件固定后,应检查连接牢固和稳定情况,当确定连接安全可靠,才可拆除临时固定工具和进行下一步吊装。
  307. 14)严禁夜间施工作业。15)起重机行驶的道路必须平整、坚实、可靠,停放地点必须平坦。
  308. 16)起重机不得停放在斜坡道上工作,不允许起重机两条履带或支腿停留部位一高一低或土质一硬一软。
  309. """
  310. tester.test_prompt(
  311. custom_content,
  312. model=config["model"],
  313. temperature=config["temperature"],
  314. max_tokens=config["max_tokens"]
  315. )
  316. if __name__ == "__main__":
  317. main()