大模型应用开发 100 天:Python + LLM 从入门到精通 day26~Prompt 调试与优化——A/B 测试与效果评估

Day 27:🔧 Prompt 调试与优化------A/B 测试与效果评估

🔖 阶段三:Prompt Engineering 深度实战(Day 21 - Day 30)

写好一个 Prompt 只是开始。真正的挑战是:如何知道你的 Prompt 好不好?如何系统地优化它? 今天我们将学习 Prompt 的调试技巧和量化评估方法,让 Prompt Engineering 从"凭感觉"变成"有数据"。


🎯 写在最前面

Prompt 优化的闭环流程

#mermaid-svg-xQHbSkIQ4BMW0jUc{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-xQHbSkIQ4BMW0jUc .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-xQHbSkIQ4BMW0jUc .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-xQHbSkIQ4BMW0jUc .error-icon{fill:#552222;}#mermaid-svg-xQHbSkIQ4BMW0jUc .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-xQHbSkIQ4BMW0jUc .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-xQHbSkIQ4BMW0jUc .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-xQHbSkIQ4BMW0jUc .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-xQHbSkIQ4BMW0jUc .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-xQHbSkIQ4BMW0jUc .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-xQHbSkIQ4BMW0jUc .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-xQHbSkIQ4BMW0jUc .marker{fill:#333333;stroke:#333333;}#mermaid-svg-xQHbSkIQ4BMW0jUc .marker.cross{stroke:#333333;}#mermaid-svg-xQHbSkIQ4BMW0jUc svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-xQHbSkIQ4BMW0jUc p{margin:0;}#mermaid-svg-xQHbSkIQ4BMW0jUc .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-xQHbSkIQ4BMW0jUc .cluster-label text{fill:#333;}#mermaid-svg-xQHbSkIQ4BMW0jUc .cluster-label span{color:#333;}#mermaid-svg-xQHbSkIQ4BMW0jUc .cluster-label span p{background-color:transparent;}#mermaid-svg-xQHbSkIQ4BMW0jUc .label text,#mermaid-svg-xQHbSkIQ4BMW0jUc span{fill:#333;color:#333;}#mermaid-svg-xQHbSkIQ4BMW0jUc .node rect,#mermaid-svg-xQHbSkIQ4BMW0jUc .node circle,#mermaid-svg-xQHbSkIQ4BMW0jUc .node ellipse,#mermaid-svg-xQHbSkIQ4BMW0jUc .node polygon,#mermaid-svg-xQHbSkIQ4BMW0jUc .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-xQHbSkIQ4BMW0jUc .rough-node .label text,#mermaid-svg-xQHbSkIQ4BMW0jUc .node .label text,#mermaid-svg-xQHbSkIQ4BMW0jUc .image-shape .label,#mermaid-svg-xQHbSkIQ4BMW0jUc .icon-shape .label{text-anchor:middle;}#mermaid-svg-xQHbSkIQ4BMW0jUc .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-xQHbSkIQ4BMW0jUc .rough-node .label,#mermaid-svg-xQHbSkIQ4BMW0jUc .node .label,#mermaid-svg-xQHbSkIQ4BMW0jUc .image-shape .label,#mermaid-svg-xQHbSkIQ4BMW0jUc .icon-shape .label{text-align:center;}#mermaid-svg-xQHbSkIQ4BMW0jUc .node.clickable{cursor:pointer;}#mermaid-svg-xQHbSkIQ4BMW0jUc .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-xQHbSkIQ4BMW0jUc .arrowheadPath{fill:#333333;}#mermaid-svg-xQHbSkIQ4BMW0jUc .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-xQHbSkIQ4BMW0jUc .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-xQHbSkIQ4BMW0jUc .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-xQHbSkIQ4BMW0jUc .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-xQHbSkIQ4BMW0jUc .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-xQHbSkIQ4BMW0jUc .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-xQHbSkIQ4BMW0jUc .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-xQHbSkIQ4BMW0jUc .cluster text{fill:#333;}#mermaid-svg-xQHbSkIQ4BMW0jUc .cluster span{color:#333;}#mermaid-svg-xQHbSkIQ4BMW0jUc div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-xQHbSkIQ4BMW0jUc .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-xQHbSkIQ4BMW0jUc rect.text{fill:none;stroke-width:0;}#mermaid-svg-xQHbSkIQ4BMW0jUc .icon-shape,#mermaid-svg-xQHbSkIQ4BMW0jUc .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-xQHbSkIQ4BMW0jUc .icon-shape p,#mermaid-svg-xQHbSkIQ4BMW0jUc .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-xQHbSkIQ4BMW0jUc .icon-shape .label rect,#mermaid-svg-xQHbSkIQ4BMW0jUc .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-xQHbSkIQ4BMW0jUc .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-xQHbSkIQ4BMW0jUc .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-xQHbSkIQ4BMW0jUc :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 📝 编写初版 Prompt
🧪 测试用例运行
📊 收集评估数据
🔍 分析问题模式
🛠️ 修改 Prompt


📖 构建评估数据集

评估数据集的设计原则

python 复制代码
"""
评估数据集构建
=============
好的评估数据集是 Prompt 优化的基础
"""

import json
from dataclasses import dataclass, field

@dataclass
class EvalCase:
    """
    单个评估用例

    属性:
        id: 用例唯一标识
        input: 输入文本
        expected_output: 期望输出(用于自动评估)
        category: 用例分类(如"简单"、"复杂"、"边界")
        tags: 标签列表
    """
    id: str
    input: str
    expected_output: str = ""
    category: str = "normal"
    tags: list[str] = field(default_factory=list)


@dataclass
class EvalDataset:
    """
    评估数据集

    包含多个评估用例,支持按分类筛选
    """
    name: str
    cases: list[EvalCase] = field(default_factory=list)

    def add_case(self, case: EvalCase):
        """添加一个评估用例"""
        self.cases.append(case)

    def get_by_category(self, category: str) -> list[EvalCase]:
        """按分类筛选用例"""
        return [c for c in self.cases if c.category == category]

    def get_by_tag(self, tag: str) -> list[EvalCase]:
        """按标签筛选用例"""
        return [c for c in self.cases if tag in c.tags]

    def summary(self) -> dict:
        """数据集摘要统计"""
        categories = {}
        for case in self.cases:
            categories[case.category] = categories.get(case.category, 0) + 1
        return {
            "name": self.name,
            "total": len(self.cases),
            "categories": categories
        }


# ============ 构建评估数据集 ============

# 场景:评估一个"客户邮件分类"的 Prompt
dataset = EvalDataset(name="客户邮件分类评估集")

# 添加评估用例
test_cases = [
    # 简单案例
    EvalCase(
        id="simple_001",
        input="我想退货,订单号是12345",
        expected_output="refund",
        category="simple",
        tags=["退款", "简单"]
    ),
    EvalCase(
        id="simple_002",
        input="你们的营业时间是几点到几点?",
        expected_output="inquiry",
        category="simple",
        tags=["咨询", "简单"]
    ),

    # 复杂案例
    EvalCase(
        id="complex_001",
        input="我上周买的手机屏幕有问题,想换货,但我也想知道你们有没有以旧换新的活动,如果有的话我可能直接换新款",
        expected_output="multi_intent",
        category="complex",
        tags=["换货", "咨询", "多意图"]
    ),

    # 边界案例
    EvalCase(
        id="edge_001",
        input="asdfghjkl",
        expected_output="unclear",
        category="edge",
        tags=["无意义", "边界"]
    ),
    EvalCase(
        id="edge_002",
        input="你们是不是骗子?我要去消费者协会投诉你们!",
        expected_output="complaint",
        category="edge",
        tags=["投诉", "情绪化"]
    ),
]

for case in test_cases:
    dataset.add_case(case)

print(f"📊 评估数据集摘要: {json.dumps(dataset.summary(), ensure_ascii=False, indent=2)}")

📚 A/B 测试框架

对比两个 Prompt 版本

python 复制代码
"""
Prompt A/B 测试框架
==================
对比两个 Prompt 版本在同一组测试用例上的表现
"""

from openai import OpenAI
import os
import time

client = OpenAI(
    api_key=os.getenv("OPENAI_API_KEY"),
    base_url="https://api.openai.com/v1"
)

class PromptABTester:
    """
    Prompt A/B 测试器

    功能:
    1. 在相同测试集上运行两个 Prompt 版本
    2. 收集每个用例的输出
    3. 使用 LLM-as-Judge 自动评分
    4. 生成对比报告
    """

    def __init__(self, client, model="gpt-4o-mini"):
        self.client = client
        self.model = model

    def run_test(self, prompt_a: str, prompt_b: str, dataset: EvalDataset) -> dict:
        """
        运行 A/B 测试

        参数:
            prompt_a: A 版本的 Prompt
            prompt_b: B 版本的 Prompt
            dataset: 评估数据集

        返回:
            测试结果字典
        """
        results = {"prompt_a": [], "prompt_b": []}

        print(f"🧪 开始 A/B 测试")
        print(f"   数据集: {dataset.name} ({len(dataset.cases)} 个用例)")
        print()

        for case in dataset.cases:
            print(f"  📝 用例 {case.id}...", end=" ")

            # 运行 Prompt A
            response_a = self.client.chat.completions.create(
                model=self.model,
                messages=[{"role": "user", "content": prompt_a.replace("{{input}}", case.input)}],
                temperature=0.0,
                max_tokens=500
            )
            output_a = response_a.choices[0].message.content
            results["prompt_a"].append({
                "case_id": case.id,
                "output": output_a,
                "tokens": response_a.usage.total_tokens if response_a.usage else 0
            })

            # 运行 Prompt B
            response_b = self.client.chat.completions.create(
                model=self.model,
                messages=[{"role": "user", "content": prompt_b.replace("{{input}}", case.input)}],
                temperature=0.0,
                max_tokens=500
            )
            output_b = response_b.choices[0].message.content
            results["prompt_b"].append({
                "case_id": case.id,
                "output": output_b,
                "tokens": response_b.usage.total_tokens if response_b.usage else 0
            })

            print(f"✅ A:{len(output_a)}字 B:{len(output_b)}字")

        return results

    def judge(self, case_input: str, output_a: str, output_b: str, expected: str) -> dict:
        """
        使用 LLM-as-Judge 评判两个输出

        参数:
            case_input: 输入
            output_a: A 版本输出
            output_b: B 版本输出
            expected: 期望输出

        返回:
            评判结果
        """
        judge_prompt = f"""你是一位 Prompt 质量评审专家。请对比以下两个回答,判断哪个更好。

## 用户输入
{case_input}

## 期望输出
{expected}

## 回答 A
{output_a}

## 回答 B
{output_b}

## 请从以下维度评分(1-10分):
1. 准确性:回答是否正确?
2. 完整性:是否覆盖了所有要点?
3. 格式:输出格式是否规范?

请输出 JSON:
{{
    "score_a": {{"accuracy": N, "completeness": N, "format": N}},
    "score_b": {{"accuracy": N, "completeness": N, "format": N}},
    "winner": "A" | "B" | "tie",
    "reason": "简要说明"
}}"""

        response = self.client.chat.completions.create(
            model=self.model,
            messages=[{"role": "user", "content": judge_prompt}],
            response_format={"type": "json_object"},
            temperature=0.0,
            max_tokens=500
        )

        return json.loads(response.choices[0].message.content)


# ============ A/B 测试示例 ============

# Prompt A:简单版
prompt_a = "请将以下客户邮件分类为:refund/complaint/inquiry/other。只输出类别名称。\n\n邮件:{{input}}"

# Prompt B:详细版(加了角色和示例)
prompt_b = """你是一位客服邮件分类专家。请将客户邮件分类为以下类别之一:
- refund: 退款/退货相关
- complaint: 投诉/不满
- inquiry: 咨询/提问
- multi_intent: 包含多个意图
- unclear: 无法理解

邮件内容:{{input}}

请只输出类别名称。"""

# 运行测试(使用之前构建的数据集)
tester = PromptABTester(client)
results = tester.run_test(prompt_a, prompt_b, dataset)

# 计算平均 Token 消耗
avg_tokens_a = sum(r["tokens"] for r in results["prompt_a"]) / len(results["prompt_a"])
avg_tokens_b = sum(r["tokens"] for r in results["prompt_b"]) / len(results["prompt_b"])

print(f"\n📊 Token 消耗对比:")
print(f"  Prompt A 平均: {avg_tokens_a:.0f} tokens")
print(f"  Prompt B 平均: {avg_tokens_b:.0f} tokens")

🏗️ 评估指标体系

#mermaid-svg-PKx7Tl5PpPV5vAqr{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-PKx7Tl5PpPV5vAqr .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-PKx7Tl5PpPV5vAqr .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-PKx7Tl5PpPV5vAqr .error-icon{fill:#552222;}#mermaid-svg-PKx7Tl5PpPV5vAqr .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-PKx7Tl5PpPV5vAqr .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-PKx7Tl5PpPV5vAqr .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-PKx7Tl5PpPV5vAqr .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-PKx7Tl5PpPV5vAqr .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-PKx7Tl5PpPV5vAqr .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-PKx7Tl5PpPV5vAqr .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-PKx7Tl5PpPV5vAqr .marker{fill:#333333;stroke:#333333;}#mermaid-svg-PKx7Tl5PpPV5vAqr .marker.cross{stroke:#333333;}#mermaid-svg-PKx7Tl5PpPV5vAqr svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-PKx7Tl5PpPV5vAqr p{margin:0;}#mermaid-svg-PKx7Tl5PpPV5vAqr .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-PKx7Tl5PpPV5vAqr .cluster-label text{fill:#333;}#mermaid-svg-PKx7Tl5PpPV5vAqr .cluster-label span{color:#333;}#mermaid-svg-PKx7Tl5PpPV5vAqr .cluster-label span p{background-color:transparent;}#mermaid-svg-PKx7Tl5PpPV5vAqr .label text,#mermaid-svg-PKx7Tl5PpPV5vAqr span{fill:#333;color:#333;}#mermaid-svg-PKx7Tl5PpPV5vAqr .node rect,#mermaid-svg-PKx7Tl5PpPV5vAqr .node circle,#mermaid-svg-PKx7Tl5PpPV5vAqr .node ellipse,#mermaid-svg-PKx7Tl5PpPV5vAqr .node polygon,#mermaid-svg-PKx7Tl5PpPV5vAqr .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-PKx7Tl5PpPV5vAqr .rough-node .label text,#mermaid-svg-PKx7Tl5PpPV5vAqr .node .label text,#mermaid-svg-PKx7Tl5PpPV5vAqr .image-shape .label,#mermaid-svg-PKx7Tl5PpPV5vAqr .icon-shape .label{text-anchor:middle;}#mermaid-svg-PKx7Tl5PpPV5vAqr .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-PKx7Tl5PpPV5vAqr .rough-node .label,#mermaid-svg-PKx7Tl5PpPV5vAqr .node .label,#mermaid-svg-PKx7Tl5PpPV5vAqr .image-shape .label,#mermaid-svg-PKx7Tl5PpPV5vAqr .icon-shape .label{text-align:center;}#mermaid-svg-PKx7Tl5PpPV5vAqr .node.clickable{cursor:pointer;}#mermaid-svg-PKx7Tl5PpPV5vAqr .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-PKx7Tl5PpPV5vAqr .arrowheadPath{fill:#333333;}#mermaid-svg-PKx7Tl5PpPV5vAqr .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-PKx7Tl5PpPV5vAqr .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-PKx7Tl5PpPV5vAqr .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-PKx7Tl5PpPV5vAqr .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-PKx7Tl5PpPV5vAqr .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-PKx7Tl5PpPV5vAqr .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-PKx7Tl5PpPV5vAqr .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-PKx7Tl5PpPV5vAqr .cluster text{fill:#333;}#mermaid-svg-PKx7Tl5PpPV5vAqr .cluster span{color:#333;}#mermaid-svg-PKx7Tl5PpPV5vAqr div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-PKx7Tl5PpPV5vAqr .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-PKx7Tl5PpPV5vAqr rect.text{fill:none;stroke-width:0;}#mermaid-svg-PKx7Tl5PpPV5vAqr .icon-shape,#mermaid-svg-PKx7Tl5PpPV5vAqr .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-PKx7Tl5PpPV5vAqr .icon-shape p,#mermaid-svg-PKx7Tl5PpPV5vAqr .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-PKx7Tl5PpPV5vAqr .icon-shape .label rect,#mermaid-svg-PKx7Tl5PpPV5vAqr .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-PKx7Tl5PpPV5vAqr .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-PKx7Tl5PpPV5vAqr .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-PKx7Tl5PpPV5vAqr :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 📊 Prompt 评估指标体系
🛡️ 安全指标
幻觉率

编造信息的比例
越界率

超出能力范围的回答
注入抗性

抵抗 Prompt 注入的能力
💰 成本指标
Token 消耗

输入+输出 Token 数
延迟 Latency

响应时间
调用次数

是否需要重试
🎯 质量指标
准确性 Accuracy

输出是否正确
完整性 Completeness

是否覆盖所有要点
一致性 Consistency

多次运行结果是否稳定


📚 本章小结

方法 说明 适用阶段
评估数据集 构建标准化的测试用例集 所有阶段
A/B 测试 对比两个 Prompt 版本 优化阶段
LLM-as-Judge 用 LLM 评估 LLM 的输出 自动评估
指标体系 质量+成本+安全三维评估 全面评估

🧠 课后思考

  1. 实践题:为你的一个 Prompt 构建 10 个测试用例(包含简单、复杂、边界案例),运行 A/B 测试。
  2. 分析题:LLM-as-Judge 本身也有偏差,如何减少评判的偏差?
  3. 设计题:设计一个自动化的 Prompt 优化系统,能够根据评估结果自动调整 Prompt。

📖 导航

如果这篇文章对你有帮助,请点赞 👍 收藏 ⭐ 关注 🔔 三连支持!

你的支持是我持续更新的最大动力 💪

相关推荐
Minecraft红客1 小时前
以撒的结合
python·游戏·电脑·娱乐
Circ.1 小时前
Python 调试 Litellm 本地大模型接口:模型列表与对话接口实操踩坑记录
开发语言·python
白萝卜弟弟2 小时前
【大模型Qwen3.8 27B】llama.cpp 本地大模型部署与使用
ai·大模型·agent·llama·qwen3.8
风早爽太2 小时前
用 ‌Render‌ 快速部署网站和常见问题解决
python·fastapi
fox_charon2 小时前
Windows 下 CLI 参数的引号陷阱:为什么 --resume 'uuid' 会失败
windows·shell·cmd·cli·引号
李航19833 小时前
给自己的图形引擎,配上了AI渲染,做设计真是太方便了
人工智能·python·计算机视觉·ai·ai编程
L@ncor3 小时前
第六章 框架开发实践 · 学习笔记(AutoGen / AgentScope / CAMEL / LangGraph)
python·框架·autogen·langgraph·agentscope
Zhou1411363 小时前
SpringSecurity_02_授权与高级功能
开发语言·python
染指11103 小时前
128.Agent-LangChain核心组件-中间件-调用模型的时候
人工智能·windows·中间件·langchain·agent