1. 项目概述:为什么智能体测试是“新基建”?

最近和几个做AI应用的朋友聊天,发现一个挺普遍的现象:大家花大量时间调教智能体(Agent)的提示词(Prompt),让它能理解复杂指令、调用各种工具,但一旦功能上线,稍微改点东西或者换个模型,整个系统就变得“神经兮兮”,要么不干活,要么乱干活。排查起来更是噩梦,你根本不知道是提示词写飘了,还是工具API挂了,或者是LLM(大语言模型)今天“心情不好”。这感觉就像盖了一栋摩天大楼,却没做任何结构安全测试,全凭感觉,心里能不慌吗?

“智能体测试策略:单元测试、集成测试与模拟LLM”这个标题,戳中的正是这个痛点。它不是一个简单的工具使用教程,而是一套保障智能体应用稳定、可靠、可迭代的工程化方法论。简单说,就是把我们熟悉的软件工程测试思想——单元测试、集成测试——引入到AI应用开发中,并针对LLM的不确定性,创造性地引入“模拟LLM”这个关键角色。这相当于为智能体开发了一套“体检”和“消防演习”流程。

这套策略适合谁?如果你是正在或计划开发基于LLM的智能体、聊天机器人、自动化工作流的开发者、产品经理或技术负责人,那么这篇文章就是为你准备的。无论你是用LangChain、LlamaIndex、Dify、Coze还是自研框架,测试的核心逻辑是相通的。它能帮你从“提示词玄学”和“上线祈祷”的初级阶段,走向“代码化、自动化、可验证”的工业化生产阶段。

2. 智能体测试的独特挑战与核心思路

在传统软件开发中,测试相对“单纯”。一个函数,输入固定的参数,输出确定的结果,断言(Assert)很容易写。但智能体测试完全是另一个维度的挑战,理解这些挑战是设计有效策略的前提。

2.1 智能体系统的核心不确定性来源

智能体的“智能”源于LLM,而LLM的本质是一个概率模型。这就带来了几个根本性的测试难题:

  1. 非确定性输出 :同一个提示词,LLM每次生成的结果可能在语义上相似,但字面表达几乎不可能完全一致。“请介绍北京”可能这次以历史开头,下次以地理开头。传统的字符串完全匹配断言( assert output == “xxx” )基本失效。
  2. 复杂上下文与状态 :智能体往往是多轮对话的,它有记忆(Memory),有内部状态(State)。测试不能只针对单次输入输出,而要模拟完整的对话流,验证状态转换是否正确。
  3. 外部工具调用的集成 :智能体的能力边界通过调用外部工具(Tool/API)来扩展。测试需要覆盖:智能体是否在正确的时机、以正确的参数调用了正确的工具?工具返回结果后,智能体是否能正确解析并融入后续响应?
  4. 高昂的成本与延迟 :直接调用真实的LLM API(如GPT-4)进行频繁测试,成本高昂且速度慢,无法支撑快速迭代和持续集成(CI)。

2.2 三层测试策略的总体设计

为了系统性地应对这些挑战,我们借鉴并改造经典测试金字塔,为智能体设计一个三层测试策略:

  • 基础层:单元测试(Unit Testing) 。目标是验证智能体各个“器官”的功能是否正常。 这层的核心是“隔离” 。我们把智能体拆解成相对独立的组件进行测试,例如:

    • 提示词模板 :填充变量后,生成的最终提示词格式是否正确?
    • 输出解析器(Output Parser) :给定一段LLM的回复,是否能正确解析成结构化的数据(如JSON、Pydantic对象)?
    • 工具(Tool) :单个工具的函数逻辑是否正确?输入输出是否符合预期?
    • 模拟LLM(Mock LLM) :在这一层被大量使用,用可控的、确定的“假LLM”来替代真实LLM,使测试快速、稳定、零成本。
  • 中间层:集成测试(Integration Testing) 。目标是验证智能体各个“器官”组装起来后,能否协同工作。 这层的核心是“连接”与“流程” 。我们测试:

    • 智能体链(Agent Executor) :给定一个用户问题,智能体是否能规划正确的思考步骤(Reasoning),调用正确的工具序列,并最终生成合理的回答?
    • 工具调用集成 :模拟工具的执行(或调用测试环境的Mock API),验证智能体对工具返回结果的处 理逻辑。
    • 记忆(Memory)集成 :在多轮对话测试中,验证智能体是否能正确存储和提取上下文信息。
  • 顶层:端到端测试(E2E Testing) & 模拟LLM验证 。这层会有限度地使用真实LLM或经过精心校准的模拟LLM,在更接近生产的环境中进行场景化测试。例如,用少量真实查询测试关键用户旅程,或用一套评估标准(评估器,Evaluator)对智能体的综合表现进行打分。

一个核心洞见 :在这个金字塔中,“模拟LLM”并非仅仅属于某一层,而是贯穿整个测试体系的“血液”。在单元和集成测试中,我们使用完全可控的Mock LLM来保证测试的确定性和效率;在需要验证LLM交互真实性的环节,我们使用经过配置的、能模拟真实LLM某些行为特征的模拟LLM。

3. 单元测试实战:从提示词到工具解析

单元测试是稳定性的基石。我们用一个具体的智能体功能为例:一个“天气查询智能体”。它有一个提示词模板,一个用于解析LLM回复以决定是否调用天气工具的Output Parser,以及一个模拟的天气工具。

3.1 测试提示词模板

提示词是智能体的“灵魂指令”,但其构造常常是字符串拼接,容易出错。

# weather_agent/prompts.py
from langchain.prompts import PromptTemplate

WEATHER_AGENT_PROMPT = PromptTemplate.from_template(
    “””你是一个天气助手。用户可能会询问天气。
    如果你认为用户想查询天气,且信息完整(有城市名),就调用天气查询工具。
    用户问题:{user_input}
    你的思考:”””
)

# test_prompts.py
def test_weather_prompt_template():
    # 准备测试输入
    test_input = “北京今天天气怎么样?”
    
    # 执行:填充模板
    filled_prompt = WEATHER_AGENT_PROMPT.format(user_input=test_input)
    
    # 断言:验证填充后的提示词包含关键部分
    assert test_input in filled_prompt
    assert “天气助手” in filled_prompt
    assert “{user_input}” not in filled_prompt  # 确保变量已被替换
    # 可以更细致地检查格式,例如是否以“你的思考:”结尾
    assert filled_prompt.strip().endswith(“你的思考:”)
    
    print(“提示词模板测试通过。”)

注意 :测试提示词的重点不是内容本身(那是LLM的事),而是 格式和变量替换 。确保没有拼写错误、变量名正确、模板渲染后符合预期结构。这能避免运行时因提示词格式错误导致的诡异问题。

3.2 测试输出解析器

这是单元测试的重中之重。解析器决定了LLM的自由文本输出如何被转化为智能体的结构化决策。

# weather_agent/parsers.py
from langchain.output_parsers import PydanticOutputParser
from pydantic import BaseModel, Field
from typing import Optional

class AgentDecision(BaseModel):
    “””智能体决策模型”””
    needs_tool_call: bool = Field(description=“是否需要调用工具”)
    tool_name: Optional[str] = Field(description=“如果需要调用工具,工具的名称”)
    tool_input: Optional[dict] = Field(description=“调用工具的输入参数”)
    reasoning: str = Field(description=“智能体的思考过程”)

decision_parser = PydanticOutputParser(pydantic_object=AgentDecision)

# test_parsers.py
def test_decision_parser_success():
    # 模拟一个理想的LLM回复,严格遵循解析器要求的格式
    llm_response = “””{
        “needs_tool_call”: true,
        “tool_name”: “get_weather”,
        “tool_input”: {“city”: “北京”},
        “reasoning”: “用户明确询问北京天气,需要调用天气查询工具。”
    }”””
    
    # 执行解析
    decision = decision_parser.parse(llm_response)
    
    # 断言解析结果符合预期
    assert decision.needs_tool_call is True
    assert decision.tool_name == “get_weather”
    assert decision.tool_input == {“city”: “北京”}
    assert “北京天气” in decision.reasoning
    print(“成功解析测试通过。”)

def test_decision_parser_failure_recovery():
    # 模拟一个格式略有瑕疵或部分缺失的LLM回复(更接近现实)
    llm_response = “””我需要调用工具。工具是get_weather,城市是上海。因为用户问上海天气。”””
    # 注意:这个回复不是标准JSON,解析器应该抛出异常或尝试修复
    
    try:
        decision = decision_parser.parse(llm_response)
        # 如果解析器有修复逻辑,这里可能成功
        print(f“解析器尝试修复后结果:{decision}”)
    except Exception as e:
        # 预期会抛出解析错误
        print(f“预期内的解析失败:{type(e).__name__}”)
        # 这里可以测试你的错误处理或重试逻辑
        # 例如:记录日志、尝试用更宽松的解析方式、返回一个默认决策等

实操心得 :测试解析器时,要覆盖三种情况:1) 完美情况 :LLM完全按格式输出。2) 常见瑕疵 :LLM输出基本正确但格式稍有偏差(如多余换行、键名大小写)。3) 完全错误 :LLM“胡说八道”,解析器应有健壮的错误处理机制(如抛出可捕获的异常,而不是让整个程序崩溃)。很多智能体不稳定,问题就出在解析器对“坏数据”的处理上。

3.3 测试工具(Tool)本身

工具是智能体与外界交互的桥梁,其本身的可靠性必须保证。

# weather_agent/tools.py
import requests
from typing import Dict

def get_weather(city: str) -> str:
    “””查询城市天气。这是一个模拟工具。”””
    # 在实际项目中,这里会调用真实的天气API
    # 为了测试,我们模拟一个响应
    weather_data = {
        “北京”: “晴,15-25°C,微风”,
        “上海”: “多云,18-28°C,东南风3级”,
        “广州”: “雷阵雨,25-32°C,南风4级”,
    }
    if city in weather_data:
        return weather_data[city]
    else:
        return f“未找到{city}的天气信息。”
    
# test_tools.py
def test_get_weather_tool_success():
    result = get_weather(“北京”)
    assert “晴” in result
    assert “15-25” in result
    print(“工具成功调用测试通过。”)

def test_get_weather_tool_failure():
    result = get_weather(“不存在的城市”)
    assert “未找到” in result
    print(“工具失败处理测试通过。”)

注意 :工具测试应独立于智能体。如果工具调用真实API,在单元测试中应该使用 unittest.mock 来模拟网络请求,避免对外部服务的依赖,保证测试速度和稳定性。例如,用 @patch(‘requests.get’) 来模拟返回预设的天气数据或网络错误。

4. 集成测试实战:组装智能体并验证工作流

单元测试确保零件合格,集成测试则要看组装好的机器能否运转。这里我们使用LangChain的测试工具和模拟LLM。

4.1 配置模拟LLM(Mock LLM)

模拟LLM是集成测试的“发动机”。我们需要它根据输入提示词,返回我们预设的、用于驱动测试流程的响应。

# tests/conftest.py 或测试准备部分
from langchain.llms.fake import FakeListLLM
from unittest.mock import Mock

def create_mock_llm_for_weather_agent():
    “””
    创建一个模拟LLM,其响应序列模拟了智能体在天气查询场景下的理想对话。
    响应顺序必须与智能体执行过程中的调用顺序完全匹配。
    “””
    # 第一个响应:智能体收到用户输入后的“思考”,决定调用天气工具
    response_1 = “””{
        “needs_tool_call”: true,
        “tool_name”: “get_weather”,
        “tool_input”: {“city”: “北京”},
        “reasoning”: “用户询问北京天气,需要调用天气查询工具。”
    }”””
    
    # 第二个响应:智能体收到工具返回结果后,组织最终答案给用户
    response_2 = “根据查询结果,北京今天天气晴朗,气温15到25摄氏度,微风。是个好天气!”
    
    # FakeListLLM 会按顺序返回列表中的响应
    mock_llm = FakeListLLM(responses=[response_1, response_2])
    return mock_llm

4.2 构建测试用智能体并执行集成测试

现在,我们用模拟LLM、真实的解析器和工具,组装一个测试环境下的智能体。

# test_integration.py
from langchain.agents import AgentExecutor, create_react_agent
from langchain.prompts import PromptTemplate
from .parsers import decision_parser, AgentDecision
from .tools import get_weather
from .conftest import create_mock_llm_for_weather_agent

def test_weather_agent_integration():
    # 1. 准备组件
    mock_llm = create_mock_llm_for_weather_agent()
    tools = [Tool(name=“get_weather”, func=get_weather, description=“查询城市天气”)]
    
    # 2. 使用ReAct范式创建智能体
    # 注意:这里需要根据你的解析器自定义AgentOutputParser
    from langchain.agents import AgentOutputParser
    class CustomOutputParser(AgentOutputParser):
        def parse(self, llm_output: str) -> Union[AgentAction, AgentFinish]:
            # 这里调用我们之前单元测试过的 decision_parser
            decision = decision_parser.parse(llm_output)
            if decision.needs_tool_call:
                return AgentAction(tool=decision.tool_name, tool_input=decision.tool_input, log=decision.reasoning)
            else:
                return AgentFinish(return_values={“output”: decision.reasoning}, log=decision.reasoning)
    
    agent_prompt = WEATHER_AGENT_PROMPT # 使用之前定义的提示词
    agent = create_react_agent(llm=mock_llm, tools=tools, prompt=agent_prompt)
    agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True) # verbose=True 方便调试
    
    # 3. 执行测试:用户查询天气
    user_input = “北京今天天气怎么样?”
    try:
        result = agent_executor.invoke({“input”: user_input})
        final_output = result[“output”]
        
        # 4. 关键断言
        # 断言1:最终输出包含天气信息(来自我们预设的mock LLM第二次响应)
        assert “晴朗” in final_output or “15到25” in final_output
        # 断言2:可以通过mock或回调机制验证工具确实被以正确参数调用了一次
        # 这里简化处理,在实际中你可能需要Mock工具函数并检查其调用情况
        print(f“智能体最终输出:{final_output}”)
        print(“集成测试通过:智能体成功接收问题、决定调用工具、处理工具结果并生成回答。”)
        
    except Exception as e:
        pytest.fail(f“智能体执行流程失败:{e}”)

注意事项

  1. 响应序列必须精确匹配 FakeListLLM 按顺序消耗响应。如果智能体的执行步骤(思考->行动->观察->再思考…)比预设的响应多,测试会因没有更多响应而失败。你需要仔细设计测试场景,确保模拟的对话流与响应序列匹配。
  2. 验证工具调用 :更严谨的做法是使用 unittest.mock 来替换真实的 get_weather 函数,并用 assert_called_once_with(city=“北京”) 来验证调用参数。这确保了智能体不仅走了流程,还发出了正确的指令。
  3. 测试多轮对话 :集成测试还应覆盖多轮场景。你需要扩展模拟LLM的响应列表,模拟用户追问、切换话题等,并验证智能体的记忆管理是否正常。

5. 模拟LLM的进阶应用与评估

除了 FakeListLLM 这种完全预设响应的模拟,还有更高级的模拟方式,用于应对复杂场景。

5.1 可配置的模拟LLM(Configurable Mock LLM)

有时我们需要模拟LLM的某些行为特征,比如偶尔不按格式输出、在特定关键词下触发特定回答等。

from typing import Any, List, Optional
from langchain.callbacks.manager import CallbackManagerForLLMRun
from langchain.llms.base import LLM

class ConfigurableMockLLM(LLM):
    “”“一个可配置的模拟LLM,根据输入内容返回动态响应。”””
    # 可以配置一个响应映射字典
    response_map: dict = {“你好”: “你好!我是助手。”, “天气”: “{‘needs_tool_call’: true}”}
    # 或者配置一个默认响应
    default_response: str = “我不知道如何回答这个问题。”
    
    def _call(self, prompt: str, stop: Optional[List[str]] = None, run_manager: Optional[CallbackManagerForLLMRun] = None, **kwargs: Any) -> str:
        # 简单的关键词匹配逻辑
        for key, response in self.response_map.items():
            if key in prompt:
                return response
        return self.default_response
    
    @property
    def _llm_type(self) -> str:
        return “configurable-mock”

# 使用示例
mock_llm = ConfigurableMockLLM(
    response_map={
        “用户问天气”: “{‘needs_tool_call’: true, ‘tool_name’: ‘get_weather’}”,
        “工具返回晴朗”: “今天天气很好,适合出行。”
    }
)
# 当prompt包含“用户问天气”时,返回第一个响应,驱动工具调用。

5.2 用于评估的模拟LLM与评估器(Evaluator)

在更高层次的测试中,我们不仅关心流程,还关心输出质量。这时可以结合模拟LLM和评估器。

from langchain.evaluation import EvaluatorType, load_evaluator
from langchain.evaluation import StringEvaluator

# 1. 使用一个“裁判”LLM(可以是另一个模拟LLM,也可以是轻量级真实LLM如GPT-3.5-turbo)来评估
criteria = {“helpfulness”: “回答是否对用户有帮助且准确”, “conciseness”: “回答是否简洁”}
evaluator = load_evaluator(EvaluatorType.LABELED_CRITERIA, criteria=criteria, llm=mock_llm_as_judge)

# 2. 在测试中评估智能体输出
def test_agent_output_quality():
    agent_output = “北京今天晴,15-25°C。” # 假设这是智能体的最终输出
    ground_truth = “北京天气晴朗,气温在15至25摄氏度之间。” # 预期的理想答案
    eval_result = evaluator.evaluate_strings(prediction=agent_output, reference=ground_truth, input=“北京天气?”)
    
    # eval_result 可能包含分数和理由
    assert eval_result[“score”] > 0.8  # 设定一个质量阈值
    print(f“输出质量评估通过,得分:{eval_result[‘score’]},理由:{eval_result[‘reasoning’]}”)

实操心得 :评估器非常有用,但要注意“裁判”LLM本身的偏差。在关键业务场景,最好结合多种评估方式:自动化评估器(用于CI)、人工抽查(定期进行)、线上A/B测试指标(如用户满意度、任务完成率)。完全依赖一个LLM来评估另一个LLM,有时会陷入循环。

6. 将测试融入开发流程:CI/CD实践

测试只有自动化并融入流程,才能发挥最大价值。

6.1 目录结构建议

your_agent_project/
├── src/                    # 源代码
│   ├── agents/            # 智能体定义
│   ├── tools/             # 工具函数
│   ├── prompts/           # 提示词模板
│   └── parsers/           # 输出解析器
├── tests/                 # 测试代码
│   ├── unit/              # 单元测试
│   │   ├── test_prompts.py
│   │   ├── test_parsers.py
│   │   └── test_tools.py
│   ├── integration/       # 集成测试
│   │   └── test_agent_workflow.py
│   ├── conftest.py        # 共享的测试夹具(如mock_llm)
│   └── evaluation/        # 评估测试
│       └── test_quality.py
├── requirements.txt       # 项目依赖
├── requirements-test.txt  # 测试额外依赖
└── .github/workflows/     # CI/CD 配置文件
    └── test.yml

6.2 CI流水线配置示例(GitHub Actions)

# .github/workflows/test.yml
name: Agent CI Tests

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: ‘3.10’
      - name: Install dependencies
        run: |
          pip install -r requirements.txt
          pip install -r requirements-test.txt
          pip install pytest pytest-cov
      - name: Run unit tests
        run: |
          pytest tests/unit/ -v --cov=src --cov-report=xml
      - name: Run integration tests (with mocked LLM)
        run: |
          pytest tests/integration/ -v
        env:
          # 如果测试中需要用到API Key,在此处注入Mock或测试环境的Key
          OPENAI_API_KEY: “dummy_key_for_testing”
      - name: Upload coverage to Codecov
        uses: codecov/codecov-action@v3
        with:
          file: ./coverage.xml

6.3 测试数据管理与维护

随着智能体功能变多,测试用例(尤其是模拟LLM的预设响应)会膨胀。建议:

  • 将测试用例数据化 :用JSON或YAML文件管理不同场景下的输入和预期输出。
  • 使用夹具(Fixtures) :Pytest的 @pytest.fixture 可以优雅地复用复杂的测试准备代码,如创建特定配置的智能体。
  • 定期更新 :当提示词或工具逻辑变更时,同步更新相关的测试用例和模拟响应。

7. 常见问题、排查技巧与避坑指南

在实际操作中,你会遇到各种坑。以下是一些典型问题及解决思路。

7.1 模拟测试通过,但对接真实LLM后失败

  • 问题 :所有基于Mock LLM的测试都通过了,一换到GPT-4,智能体就行为异常。
  • 排查
    1. 提示词工程 :Mock LLM的响应是你预设的“完美答案”。真实LLM可能无法理解你的提示词指令。检查提示词是否清晰、有无歧义、是否包含了足够的示例(Few-shot)。
    2. 输出格式 :这是最常见的问题。你的解析器要求严格的JSON,但真实LLM可能输出Markdown、多余的解释文本。 强化你的提示词 ,使用 json … 包裹,或选择支持“结构化输出”的模型/API。
    3. 容错处理 :在解析步骤增加重试和降级逻辑。例如,第一次解析失败后,尝试用正则表达式提取关键信息,或让LLM重新生成。

7.2 集成测试中工具调用验证失败

  • 问题 :测试认为工具应该被调用,但Mock工具函数显示未被调用或参数错误。
  • 排查
    1. 使用 unittest.mock 进行间谍活动 :不要只依赖流程通顺,用 patch spy 来监控工具函数是否真的被调用。
      from unittest.mock import patch, MagicMock
      def test_tool_call_verification():
          with patch(‘weather_agent.tools.get_weather’, MagicMock(return_value=“模拟天气”)) as mock_tool:
              # 执行智能体
              agent_executor.invoke({“input”: “…”})
              # 验证
              mock_tool.assert_called_once_with(city=“北京”)
      
    2. 检查工具描述 :LangChain等框架中,智能体根据工具的描述(description)来决定是否调用。确保描述准确、包含关键动词和名词。

7.3 多轮对话测试中状态混乱

  • 问题 :测试单轮对话正常,但测试多轮时,智能体忘记之前的内容或给出矛盾回答。
  • 排查
    1. 检查记忆(Memory)后端 :在测试中,确保记忆组件(如 ConversationBufferMemory )在每次测试开始时是 全新 的。避免测试间的状态污染。
    2. 验证记忆键(Keys) :确认对话历史被正确存储在记忆的哪个键下,以及提示词模板中是否正确引用了这个键(如 {chat_history} )。
    3. 模拟LLM的响应需包含上下文感知 :在设计多轮测试的模拟LLM响应列表时,后一个响应应该体现出它“看到”了前一轮的对话历史。这需要你精心设计响应内容。

7.4 测试执行速度慢或成本高

  • 问题 :即使用了Mock,集成测试还是很慢;或者有些测试不得不调用真实LLM,成本受不了。
  • 解决
    1. 分层测试,隔离昂贵操作 :单元测试必须快(秒级),全部用Mock。集成测试大部分用Mock。只有少数核心的端到端测试或评估测试,才使用真实LLM,并且可以配置为只在主分支合并或发布前触发。
    2. 使用廉价模型 :在必须用真实LLM的测试中,使用成本更低的模型,如 gpt-3.5-turbo 而不是 gpt-4 ,或使用本地部署的小模型。
    3. 缓存LLM响应 :使用像 VCR.py 这样的库,在第一次运行测试时记录下真实LLM的请求和响应,后续测试直接回放,不再产生实际调用和费用。

7.5 提示词变更导致大量测试失败

  • 问题 :稍微优化一下提示词,几十个测试用例因为字符串匹配而失败。
  • 解决
    1. 不要断言具体的提示词字符串 :单元测试提示词时,断言核心指令和变量存在即可,不要断言整个字符串。或者使用提示词模板的 template 属性进行比对。
    2. 使用语义化断言 :对于LLM输出或最终答案的断言,避免精确字符串匹配。改用:
      • 关键词断言 assert “晴朗” in output
      • JSON结构断言 :使用 json.loads() 解析后,断言关键字段的值。
      • 使用评估器 :用另一个LLM(或规则)来判断输出是否“语义正确”。
    3. 将提示词作为测试数据 :将提示词模板本身存储在文件中,测试时加载它。这样,提示词的修改只需要更新文件,测试代码无需改动。

智能体测试不是一劳永逸的,它是一个随着智能体能力增长而不断演进的过程。核心在于建立一种“可测试”的开发文化:每增加一个新工具,就为它写单元测试;每实现一个新的工作流,就为它写集成测试。一开始可能会觉得繁琐,但当你需要重构提示词、升级模型版本或增加复杂功能时,这套测试套件将成为你最可靠的“安全网”,让你有信心进行快速迭代,而不是在黑暗中摸索。

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐