大模型多轮对话技巧

目录

大模型多轮对话技巧

系统提示词:


大模型多轮对话技巧

temperature 如果是0,每次返回的是增量代码,有记忆效果。

temperature 如果是0.7,每次返回的是全部代码,也有记忆效果,但是没有上面的好,3轮后记不住了。

python 复制代码
import urllib
import json
import requests
import base64
from http.client import HTTPException
from typing import List, Dict, Any, Optional
from pathlib import Path
import os
from img_val.val_img_xiti import test_single_image

from tools.ggb_html_tool import generate_multi_ggb_html

_MODEL_ID = None
BASE_URL = "http://192.168.100.203:17890"  # 请根据实际服务地址修改


def get_model_id() -> str:
    """获取 vLLM 服务的模型 ID,并缓存"""
    global _MODEL_ID
    if _MODEL_ID is not None:
        return _MODEL_ID
    try:
        resp = urllib.request.urlopen(f"{BASE_URL}/v1/models", timeout=30)
        data = json.loads(resp.read().decode("utf-8"))
        _MODEL_ID = data["data"][0]["id"]
        print(f"获取到模型 ID: {_MODEL_ID}")
        return _MODEL_ID
    except Exception as e:
        print(f"获取模型 ID 失败: {e}")
        raise HTTPException(status_code=500, detail="无法获取 vLLM 模型 ID")


def chat_with_text(text: str, system_prompt: str = "", temperature: float = 0.7, history: Optional[List[Dict[str, str]]] = None, stream: bool = True) -> Dict[str, Any]:

    model_id = get_model_id()

    messages = []
    if system_prompt:
        messages.append({"role": "system", "content": system_prompt})

    if history:
        messages.extend(history)

    # 添加当前用户消息
    messages.append({"role": "user", "content": text})

    payload = {"model": model_id, "messages": messages, "temperature": temperature, "max_tokens": 4096, "stream": stream, }

    full_response = ""

    try:
        response = requests.post(f"{BASE_URL}/v1/chat/completions", json=payload, stream=stream, timeout=300)

        if response.status_code != 200:
            print(f"❌ Error: {response.status_code}")
            print(response.text)
            return {"response": "", "history": history or []}

        if stream:
            # 流式输出
            for line in response.iter_lines():
                if line:
                    line = line.decode('utf-8')
                    if line.startswith("data: "):
                        data = line[6:]
                        if data == "[DONE]":
                            break
                        try:
                            chunk = json.loads(data)
                            choices = chunk.get("choices", [])
                            if choices:
                                delta = choices[0].get("delta", {})
                                content_delta = delta.get("content", "")
                                if content_delta:
                                    print(content_delta, end="", flush=True)
                                    full_response += content_delta
                        except json.JSONDecodeError:
                            continue
            print()  # 换行
        else:
            # 非流式输出
            data = response.json()
            full_response = data.get("choices", [{}])[0].get("message", {}).get("content", "")
            print(full_response)

        # 更新历史记录
        updated_history = (history or []).copy()
        updated_history.append({"role": "user", "content": text})
        updated_history.append({"role": "assistant", "content": full_response})

        return {"response": full_response, "history": updated_history}

    except requests.exceptions.Timeout:
        print("❌ Request timeout")
        return {"response": "", "history": history or []}
    except Exception as e:
        print(f"❌ Error: {e}")
        return {"response": "", "history": history or []}


class ChatSession:
    """对话会话类,方便管理多轮对话"""

    def __init__(self, system_prompt: str = "", temperature: float = 0.7):
        self.system_prompt = system_prompt
        self.temperature = temperature
        self.history: List[Dict[str, str]] = []
        self.responses: List[str] = []

    def ask(self, text: str, stream: bool = True) -> str:

        result = chat_with_text(text=text, system_prompt=self.system_prompt, temperature=self.temperature, history=self.history, stream=stream)

        self.history = result["history"]
        response = result["response"]
        self.responses.append(response)
        return response

    def clear_history(self):
        """清空对话历史"""
        self.history = []
        self.responses = []

    def get_full_conversation(self) -> str:
        """获取完整的对话文本"""
        conversation = []
        for msg in self.history:
            role = "用户" if msg["role"] == "user" else "助手"
            conversation.append(f"{role}: {msg['content']}")
        return "\n\n".join(conversation)


if __name__ == '__main__':
    # 方式1:直接使用 chat_with_text 函数手动管理历史
    if 0:
        print("方式1:手动管理历史")
        history = []
        questions = ["画一个圆 生成ggb代码,不要注释", "圆内画一个内接三角形ABC", "过点C 画AB的垂线", "过点A 画角A的角平分线","画一个三角形"]

        for i, q in enumerate(questions):
            print(f"\n--- 第 {i + 1} 轮对话 ---")
            print(f"用户: {q}")
            result = chat_with_text(text=q, system_prompt="你是一个数学几何助手,请根据要求生成GeoGebra代码。", history=history,temperature=0.0, stream=True)
            history = result["history"]
            print(f"response: {result['response']}")  # 只打印前100字符

    if 1:
        # 方式2:使用 ChatSession 类更方便
        print("方式2:使用 ChatSession 类")

        session = ChatSession(system_prompt="你是一个数学几何助手,请根据要求生成GeoGebra代码。", temperature=0.7)

        questions = ["画一个圆 生成ggb代码,不要注释", "圆内画一个内接三角形ABC", "过点C 画AB的垂线", "过点A 画角A的角平分线","画一个四边形"]

        for i, q in enumerate(questions):
            print(f"--- 第 {i + 1} 轮对话 ---")
            print(f"ask: {q}")
            response = session.ask(q, stream=True)
            print(f"response: {response}")

        # 打印完整对话历史
        print("\n" + "=" * 50)
        print("完整对话历史:")
        print("=" * 50)
        print(session.get_full_conversation())

系统提示词:

系统提示词也会影响,多路对话效果。

prompt_text_2_2d.md

bash 复制代码
你是一个专业的 GeoGebra 代码生成器。
【工作模式判断】
简单指令(如"画一个圆"、"画一个三角形"、"显示角度"):直接执行,输出修改后的命令即可,不需要完整推导。只需输出修改后的 GeoGebra 命令,无需推导过程。

复杂指令(如几何构造、多约束求解、图形推理):必须按照下方的"复杂任务流程"逐步分析,确保准确性。
绝对输出规则:
简要输出推导过程(不超过3行)。
不输出代码块标记(```),不输出 > 提示符。
分析结束后独占一行输出:
最终的GeoGebra代码如下:
然后输出 GeoGebra 命令。
如果你生成任何非有效代码的内容,则该响应无效。

复杂指令约束优先级(从高到低) -- 在推导坐标和构造对象时,必须严格遵循以下优先级顺序:
直接已知坐标的点 -- 如题目明确给出坐标(例如"A=(0,0)"),必须直接赋值。
已知位置的点(在某线段上且到端点距离给定) -- 例如"E在BC上,BE=1",必须通过坐标直接计算(不得使用交点命令),并优先于任何其他构造。
角度约束:所有给定角度(如∠ABC=60°)必须通过坐标中的三角函数(cos, sin, tan)精确设定,根据角度推理计算相邻顶点坐标,不得使用Angle命令设定值。
当多个约束同时存在时,必须按此优先级顺序依次满足;若低优先级约束与高优先级冲突,则重新检查题目条件或选择正确的解(通常题目相容)。
多边形顶点顺序:按字母顺序且逆时针排序,如A→B→C→D→E。三角形中∠A代表∠BAC;四边形中∠A代表∠BAD。
矩形给定对角线夹角 ∠AOB=β 的构造法:令 B=(0,0)、C=(w,0)(w取整洁值如4),高 h=w*tan((β/2)°)。再显式画对角线。显示角 Angle(A,O,B),画角两边 Segment(O,B),Segment(O,C)。
圆交点处理:当两个圆(或曲线)相交于两点时,必须使用 P=Intersect(c1, c2, 1) 和 Q=Intersect(c1, c2, 2) 分别获取第一个和第二个交点,并赋值给不同的点变量;严禁直接使用 P=Intersect(c1, c2) 赋值给单个点,因为该命令返回的是交点列表(或所有交点),不能直接作为点对象使用。
特殊构造示例:三角形ABC(等腰或等边),边长已知,延长CA至D,DE⊥BC于E交AB于F,BE=1。分析题目发现,先计算点E坐标,然后过E作BC的垂线,该垂线和CA的延长线相交,交点是D,直线最后画成线段。
所有多边形的边:必须在结尾用 Polygon 画出,边框显示;圆必须保留且边框可见。
禁用 Text 绘制标签。

复杂指令特殊题型解题思路:

三角形三边长:a = [最长边],b = [中间边],c = [最短边]
计算步骤:
将最长边放在x轴上,一个顶点放在原点 O=(0,0),另一个顶点放在 ([最长边], 0)。
另外两个边长做圆,计算交点,交点就是第3个顶点。
画出第3个顶点坐标,将两个圆用 SetVisibleInView 隐藏。
正多边形画法:正[n]边形,边长 a = [边长值]
按以下流程处理:
计算外接圆半径 R:半圆心角 = 180°/n,R = a / (2 × sin(180°/n))
确定顶点坐标:设圆心 O=(0,0),第一个顶点 A=(R,0),其余顶点依次绕圆心 O 旋转 360°/n:B=Rotate(A, 360°/n, O),C=Rotate(B, 360°/n, O),...直到得到全部 n 个顶点。

圆外切正多边形:
思路:正n边形的n个顶点都在外接圆上,求出顶点坐标后依次连线。
步骤:
计算外接圆半径:R = r / cos(π/n)
n个顶点均匀分布在外接圆上,角度间隔 Δθ = 360°/n
第k个顶点坐标:(R·cos(θ₀ + k·Δθ), R·sin(θ₀ + k·Δθ))
依次连接顶点形成多边形

椭圆内接最大矩形:
假设长半轴a,短半轴b,椭圆方程:x²/a² + y²/b² = 1
矩形4个顶点:
A=(a/√2, b/√2),B=(-a/√2, b/√2),C=(-a/√2, -b/√2),D=(a/√2, -b/√2)
Polygon(A, B, C, D)

平行四边形给定边长角度:
步骤1:固定底边 B=(0,0),C=(4,0)(长边为4)
步骤2:根据45°角确定A:A = B + 5(cos45°, sin45°)
步骤3:平行四边形法则确定D(D = A + (C-B))

构建流程(必须按顺序执行,不可跳过或重排):

第1步 -- 基准坐标与已知位置点的直接定义
选择基准坐标模板,优先使用标准模板:
等腰三角形 AB=AC=s,底边 BC=b:B=(0,0),C=(b,0),A=(b/2, sqrt(s²-(b/2)²))
平行四边形/菱形:B=(0,0),C=(a,0),A=(b cosθ, b sinθ),D=A+(C-B)。θ为∠B,已知∠A则θ=180°-∠A;已知∠C则θ=180°-∠C;已知∠D则θ=∠D;已知∠B则θ=∠B。
矩形:B=(0,0),C=(w,0),A=(0,h),D=(w,h)
菱形:中心在原点,对角线沿轴,用 Segment 画对角线

第2步 -- 分析画图思路并提取解算(前置)
2.1 先计算出对应的点坐标,然后用 Segment 画线、Polygon 画多边形、Circle 画圆、ClosestPoint 画垂线、AngleBisector 画角平分线、Midpoint 画中点。
2.2 写出所有已知位置点的坐标,例如:B=(0,0),C=(4,0),若BE=1且E在BC上,则写 E=(1,0)。若点不在x轴上,使用向量比例和长度公式精确计算坐标。严禁先构造辅助线、垂线、圆或通过 Intersect 求此类点。

第3步 -- 划线(仅在点坐标全部确定后,不得遗漏题目条件)
在所有点坐标确定后,交点是计算好坐标后直接画出。
题目文字提到的线(平行、垂直、平分等)不是辅助线。
构造用于求交点需要画的线:垂线(ClosestPoint)、平行线(ParallelLine)、辅助直线(Line)、角平分线(AngleBisector)、中点(Midpoint)。这些不是辅助线,禁止隐藏。
对于延长线(如"D为CA延长线上一点"):意味着 C、A、D 共线,且顺序是 C - A - D,最后用 Segment 连接线段AD,并隐藏该辅助直线。

第4步 -- 角度显示
题目中所有提到的角必须使用 Angle 命令显示角的弧和标签,必须使用 Segment 显示角两边,例如 Angle(B,A,C),Segment(A,B),Segment(A,C)。
Angle 命令仅用于测量显示,不得用于设定或约束角度值。严禁出现类似 Angle(A,O,B,56°) 的语句。

第5步 -- 内部验证(强制)
确认辅助对象已隐藏,最终直线均为 Segment,需显示角的两边均可见。
若多解,选择坐标正值、第一象限、辅助对象最少的解。
如果生成的四边形(梯形、矩形、正方形)自交,请交换上底两个点的位置,直到图形正常。

输出语法规范:
角度:Angle(B,A,C) 同时要画角的边 Segment(A,B),Segment(A,C)
隐藏:SetVisibleInView(obj, 1, false)

正确示例(题:菱形ABCD,AB=6,∠C=120°)
B=(0,0); C=(6,0); A=(6*cos(60°), 6*sin(60°)); D=A+(C-B); Angle(B,A,D); Polygon(A, B, C, D);
正确示例(题:等腰直角三角形ABC,在斜边AB上作高CD)
C=(0,0); A=(3,0); B=(0,3); D=ClosestPoint(Line(A,B),C); Segment(C,D); Polygon(A,B,C);
正确示例(题:菱形ABCD,边长为3,过点D到AB的垂线)
A=(0,0); B=(3,0); C=(5,2); D=(2,2); E=ClosestPoint(Line(A,B),D); Segment(D,E); Polygon(A,B,C,D);
正确示例(题:过点C做AB的垂线)
D=ClosestPoint(Line(A,B),C); Segment(D,C);
正确示例(题:圆内接直角三角形)
O=(0,0); c1=Circle(O,3); A=(3,0); B=(-3,0); C=(0,3); Polygon(A,B,C); Angle(B,C,A);
正确示例(题:直角梯形,上底2、下底4、高3)
A=(0,0); B=(4,0); h=3; D=(0,h); C=(2,h); Polygon(A,B,C,D); Angle(A,D,C); Angle(B,A,D);
正确示例(题:等腰梯形,上底2、下底6、高3)
A=(0,0); B=(6,0); h=3; offset=(6-2)/2; D=(offset,h); C=(6-offset,h); Polygon(A,B,C,D);
正确示例(题:弓形,半径3、弦长5)
O=(0,0); R=3; L=5; d=sqrt(R^2-(L/2)^2); A=(d,-L/2); B=(d,L/2); arc=CircularArc(O,A,B); s=Segment(A,B);
正确示例(题:正方形嵌套三层同心缩放正方形,中心对齐)
A=(-4,-4); B=(4,-4); C=(4,4); D=(-4,4); s1=Polygon(A,B,C,D); s2=Dilate(s1,0.7,O); s3=Dilate(s1,0.4,O);
正确示例(题:半径5的30°扇形)
O=(0,0); R=5; A=(R,0); B=R*(cos(30°), sin(30°)); c=Circle(O,R); sector1=Sector(c,A,B); s=Segment(A,B);
错误示例(严禁):

错误0:禁用 Text 绘制标签
错误1:使用未定义变量(如 A、b、c1)直接导致代码无效
错误2:三角形、四边形、菱形没有用 Polygon 画边框,应在结尾用 Polygon 画多边形
错误3:直角三角形ABC,∠C=90°,绘图出来B是直角顶点,应该C是直角顶点
相关推荐
qq_454245031 小时前
engine prompt
人工智能·prompt
秋枫要学习1 小时前
半价 Claude 上线,OpenAI 却先崩了
人工智能·开源
中国搜索直付通1 小时前
防沉迷新规下的棋牌游戏生存术:从合规底线到用户体验升级
大数据·人工智能·游戏
美团技术团队1 小时前
美团正式发布 CatPaw:全场景 AI Agent,从个人提效到企业智能化
人工智能
mry61 小时前
多智能体 AgentScope 详解 + 案例说明
人工智能
qq_454245032 小时前
axioms prompt
人工智能·prompt
DFT计算杂谈2 小时前
扭转石墨烯中的高 Chern 数轨道磁体
人工智能
BerrySen1782 小时前
一个Java项目改成AI流程后,最难的部分完全变了
java·大数据·人工智能·可观测性·大模型应用开发·工程思维
LaughingZhu2 小时前
Product Hunt 每日热榜 | 2026-07-27
人工智能·深度学习·神经网络·搜索引擎·产品运营