Harness Engineering with Spring AI Alibaba: Theory, Architecture, and Full Implementation Guide

This comprehensive guide walks through Harness Engineering concepts, the seven‑layer architecture, environment setup, full Spring Boot codebase, agent configuration, best‑practice recommendations, testing procedures, common issues, and advanced directions for building controllable AI agents with Spring AI Alibaba.

The Dominant Programmer
The Dominant Programmer
The Dominant Programmer
Harness Engineering with Spring AI Alibaba: Theory, Architecture, and Full Implementation Guide

What is Harness Engineering?

Harness Engineering is a 2026 AI‑engineering paradigm that shifts focus from optimizing the large language model itself to building a reliable, controllable, and maintainable runtime environment for AI agents.

Core formula : Agent = Model + Harness

The "harness" is likened to a set of tack that reins a powerful but unpredictable horse (the LLM).

Core Harness Components

Rules (soft constraints): declarative specifications of what the agent must not do – analogous to traffic rules.

Skills (semi‑hard constraints): step‑by‑step manuals that tell the agent how to act – like an operation guide.

Gate (hard constraints): strict validation of input/output – similar to a security checkpoint.

State : context management – comparable to a notebook.

Instructions : ordered commands for the agent – like a task list.

Verification : quality assurance that a task is only complete after passing tests – like a quality inspector.

Seven‑Layer Architecture Overview

The architecture progresses from inner to outer layers, turning AI’s inherent uncertainty into deterministic behavior.

┌─────────────────────────────────────────────────────────────┐
│ 7. Evaluation & Feedback          ← Continuous optimisation loop
├─────────────────────────────────────────────────────────────┤
│ 6. Multi‑Agent Architecture      ← Team collaboration
├─────────────────────────────────────────────────────────────┤
│ 5. Constraints & Guardrails      ← Safety fence
├─────────────────────────────────────────────────────────────┤
│ 4. Context Engineering           ← Memory & knowledge base
├─────────────────────────────────────────────────────────────┤
│ 3. Project Setup                 ← Standardised foundation
├─────────────────────────────────────────────────────────────┤
│ 2. Tool Orchestration            ← External interaction
├─────────────────────────────────────────────────────────────┤
│ 1. Execution Loop                ← Brain & scheduler
└─────────────────────────────────────────────────────────────┘

Layer Responsibilities (quick view)

Execution Loop : planning, execution, and reflection (ReAct cycle).

Tool Orchestration : expose tools via @Tool annotations and register them with .methodTools(...).

Project Setup : unified Maven structure, Java 17, Spring Boot 3.2.5, and Alibaba Spring AI version 1.1.2.0.

Context Engineering : load static rule files, build structured prompts, and cache context per session.

Constraints & Guardrails : hard validation of contact info and review output.

Multi‑Agent Architecture : planner agent creates sub‑tasks, executor agent performs them using registered tools.

Evaluation & Feedback : score reviews, log failures, and trigger human review when the score is below the threshold.

Environment Preparation & Project Scaffold

JDK 17 or higher

Maven 3.8+

IntelliJ IDEA 2023.3+

curl (built‑in on Windows 10/11)

DashScope API key from Alibaba Cloud

Verify installation with:

java -version
mvn -version

Project layout (relevant directories):

spring-ai-harness-demo/
├── pom.xml
├── src/main/java/com/badao/ai/
│   ├── config/               # HarnessAgentConfig, MultiAgentConfig
│   ├── controller/           # HarnessController
│   ├── service/              # HarnessAgentService, MultiAgentService
│   ├── model/                # ContactInfo, ProductReview
│   ├── harness/              # rules, skills, gates, tools, evaluation
│   └── resources/            # application.yml, rules file
└── resources/
    └── harness/rules/ExtractionRules.md

Key Code Implementations

pom.xml (dependency management)

<project xmlns="http://maven.apache.org/POM/4.0.0" ...>
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.2.5</version>
  </parent>
  <properties>
    <java.version>17</java.version>
    <spring-ai-alibaba.version>1.1.2.0</spring-ai-alibaba.version>
  </properties>
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>com.fasterxml.jackson</groupId>
        <artifactId>jackson-bom</artifactId>
        <version>${spring-ai-alibaba.version}</version>
      </dependency>
      <!-- DashScope model adapter -->
      <dependency>
        <groupId>com.alibaba.cloud.ai</groupId>
        <artifactId>spring-ai-alibaba-starter-dashscope</artifactId>
        <version>${DASHSCOPE_API_KEY}</version>
      </dependency>
    </dependencies>
  </dependencyManagement>
</project>

Domain POJOs

package com.badao.ai.model;
public class ContactInfo {
  private String name;
  private String email;
  private String phone;
  // getters, setters, toString()
}

public class ProductReview {
  private int rating;
  private String sentiment; // positive / neutral / negative
  private String[] keyPoints;
  private ReviewDetails details;
  // nested static class ReviewDetails with pros, cons, summary
  // getters, setters, toString()
}

Skill – ReviewAnalysisSkill

package com.badao.ai.harness.skills;
@Component
public class ReviewAnalysisSkill {
  public String buildPrompt(String reviewText) {
    return """
    请分析以下商品评价,按标准格式输出 JSON。
    分析步骤:
    - 评分:1-5 整数
    - 情感:positive / neutral / negative
    - 关键点:从评价中抽取具体维度
    - 优点/缺点:尽量提取
    - 总结:一句话概括整体评价
    评价文本:""" + reviewText;
  }
  public ProductReview postProcess(ProductReview review) {
    if (review.getRating() < 1) review.setRating(1);
    if (review.getRating() > 5) review.setRating(5);
    if (review.getKeyPoints() == null || review.getKeyPoints().length == 0) {
      review.setKeyPoints(new String[]{"无关键点"});
    }
    if (review.getDetails() == null) {
      ProductReview.ReviewDetails d = new ProductReview.ReviewDetails();
      d.setPros(new String[0]);
      d.setCons(new String[0]);
      d.setSummary("无总结");
      review.setDetails(d);
    }
    return review;
  }
}

Gate – OutputValidator

package com.badao.ai.harness.gates;
@Component
public class OutputValidator {
  public List<String> validateContact(ContactInfo c) {
    List<String> errors = new ArrayList<>();
    if (c == null) return List.of("联系人信息为空");
    if (c.getName() == null || c.getName().trim().isEmpty()) errors.add("姓名不能为空");
    if (c.getEmail() == null || !c.getEmail().contains("@")) errors.add("邮箱格式无效");
    if (c.getPhone() == null || c.getPhone().trim().isEmpty()) errors.add("电话不能为空");
    return errors;
  }
  public List<String> validateReview(ProductReview r) {
    List<String> errors = new ArrayList<>();
    if (r == null) return List.of("评价信息为空");
    if (r.getRating() < 1 || r.getRating() > 5) errors.add("评分必须在 1-5 之间");
    if (r.getSentiment() == null || !(r.getSentiment().equals("positive") || r.getSentiment().equals("neutral") || r.getSentiment().equals("negative")))
      errors.add("情感倾向必须是 positive/neutral/negative 之一");
    if (r.getKeyPoints() == null || r.getKeyPoints().length == 0) errors.add("关键点不能为空");
    return errors;
  }
  public boolean isValid(List<String> errors) { return errors == null || errors.isEmpty(); }
}

Tool Examples

@Component
public class WeatherTool {
  @Tool(description = "根据城市名称查询当前天气")
  public String getWeather(@ToolParam(description = "城市名称,如Beijing") String city) {
    if ("Beijing".equalsIgnoreCase(city)) return "北京:晴,25°C,湿度40%";
    if ("Shanghai".equalsIgnoreCase(city)) return "上海:多云,28°C,湿度65%";
    return city + ":天气未知,请稍后再查";
  }
}

@Component
public class CalculatorTool {
  @Tool(description = "执行基本的四则运算")
  public double calculate(@ToolParam(description = "第一个操作数") double a,
                         @ToolParam(description = "运算符,支持 + - * /") String op,
                         @ToolParam(description = "第二个操作数") double b) {
    return switch (op) {
      case "+" -> a + b;
      case "-" -> a - b;
      case "*" -> a * b;
      case "/" -> a / b;
      default -> throw new IllegalArgumentException("不支持的运算符: " + op);
    };
  }
}

Agent Configuration

@Configuration
public class HarnessAgentConfig {
  private final ReviewAnalysisSkill skill;
  public HarnessAgentConfig(ReviewAnalysisSkill skill) { this.skill = skill; }

  @Bean
  public ReactAgent contactAgent(ChatModel model) throws IOException {
    String rules = loadRules("harness/rules/ExtractionRules.md");
    String system = "你是一个联系人信息提取专家。请严格遵循以下规则:
" + rules;
    return ReactAgent.builder()
        .name("contact_extractor")
        .model(model)
        .systemPrompt(system)
        .outputType(ContactInfo.class)
        .saver(new MemorySaver())
        .build();
  }

  @Bean
  public ReactAgent reviewAgent(ChatModel model) {
    BeanOutputConverter<ProductReview> conv = new BeanOutputConverter<>(ProductReview.class);
    String schema = conv.getFormat();
    return ReactAgent.builder()
        .name("review_analyzer")
        .model(model)
        .systemPrompt("你是一个商品评价分析专家,必须按以下 JSON Schema 输出:
" + schema)
        .outputSchema(schema)
        .saver(new MemorySaver())
        .build();
  }

  private String loadRules(String path) throws IOException {
    ClassPathResource r = new ClassPathResource(path);
    return new String(r.getInputStream().readAllBytes(), StandardCharsets.UTF_8);
  }
}

Multi‑Agent Configuration

@Configuration
public class MultiAgentConfig {
  @Bean
  public ReactAgent plannerAgent(ChatModel model) {
    return ReactAgent.builder()
        .name("planner")
        .model(model)
        .systemPrompt("""
          你是一个任务规划专家。用户会给出一个复杂需求,你需要将其拆解为1~3个子任务,
          并以 JSON 数组格式输出,每个子任务包含 description 和 assigned_to(只能是 \"executor\")。
          示例:[{'description':'查询北京天气','assigned_to':'executor'}]
        """)
        .saver(new MemorySaver())
        .build();
  }

  @Bean
  public ReactAgent executorAgent(ChatModel model, WeatherTool weather, CalculatorTool calc) {
    return ReactAgent.builder()
        .name("executor")
        .model(model)
        .systemPrompt("你是一个执行专家,负责具体执行用户分配的任务。你可以使用工具完成工作。")
        .methodTools(weather, calc) // auto‑scans @Tool
        .saver(new MemorySaver())
        .build();
  }
}

Service Layer

@Service
public class HarnessAgentService {
  private final ReactAgent contactAgent, reviewAgent;
  private final ReviewAnalysisSkill skill;
  private final OutputValidator validator;
  private final ObjectMapper mapper;
  private final QualityScorer scorer;
  private final FeedbackLogger logger;

  // constructor omitted for brevity

  public ContactInfo extractContact(String text, String sessionId) {
    RunnableConfig cfg = RunnableConfig.builder().threadId(sessionId).build();
    AssistantMessage resp = contactAgent.call(text, cfg);
    ContactInfo ci = mapper.readValue(resp.getText(), ContactInfo.class);
    List<String> errs = validator.validateContact(ci);
    if (!validator.isValid(errs)) throw new RuntimeException("输出校验失败: " + String.join("; ", errs));
    return ci;
  }

  public ProductReview analyzeReview(String reviewText, String sessionId) {
    RunnableConfig cfg = RunnableConfig.builder().threadId(sessionId).build();
    String prompt = skill.buildPrompt(reviewText);
    AssistantMessage resp = reviewAgent.call(prompt, cfg);
    ProductReview pr = mapper.readValue(resp.getText(), ProductReview.class);
    pr = skill.postProcess(pr);
    List<String> errs = validator.validateReview(pr);
    if (!validator.isValid(errs)) throw new RuntimeException("输出校验失败: " + String.join("; ", errs));
    return pr;
  }

  public ProductReview analyzeReviewWithEval(String text, String sessionId) {
    ProductReview pr = analyzeReview(text, sessionId);
    int score = scorer.scoreReview(pr);
    if (score < 3) {
      logger.logFailedCase(text, pr, "质量评分过低: " + score);
      logger.triggerHumanReview(text, pr);
      throw new RuntimeException("质量门禁未通过(得分" + score + "/4),已转人工复核");
    }
    return pr;
  }
}

@Service
public class MultiAgentService {
  private final ReactAgent planner, executor;
  private final ObjectMapper mapper;

  public String executeComplexTask(String request, String sessionId) throws IOException {
    RunnableConfig cfg = RunnableConfig.builder().threadId(sessionId).build();
    AssistantMessage planMsg = planner.call("请拆解以下任务:" + request, cfg);
    List<JsonNode> tasks = mapper.readValue(planMsg.getText(),
        mapper.getTypeFactory().constructCollectionType(List.class, JsonNode.class));
    List<String> results = new ArrayList<>();
    for (JsonNode task : tasks) {
      String desc = task.get("description").asText();
      String role = task.get("assigned_to").asText();
      if (!"executor".equals(role)) { results.add("跳过不支持的角色: " + role); continue; }
      AssistantMessage exec = executor.call(desc, cfg);
      results.add(exec.getText());
    }
    return String.join("
", results);
  }
}

Controller (REST API)

@RestController
@RequestMapping("/api/harness")
public class HarnessController {
  private final HarnessAgentService agentService;
  private final MultiAgentService multiService;

  @PostMapping("/contact")
  public Map<String,Object> extractContact(@RequestParam String text,
                                            @RequestParam(defaultValue="default") String sessionId) {
    ContactInfo ci = agentService.extractContact(text, sessionId);
    return Map.of("success", true, "data", ci, "sessionId", sessionId);
  }

  @PostMapping("/review")
  public Map<String,Object> analyzeReview(@RequestParam String reviewText,
                                            @RequestParam(defaultValue="default") String sessionId) {
    ProductReview pr = agentService.analyzeReview(reviewText, sessionId);
    return Map.of("success", true, "data", pr, "sessionId", sessionId);
  }

  @PostMapping("/review/eval")
  public Map<String,Object> analyzeReviewWithEval(@RequestParam String reviewText,
                                                  @RequestParam(defaultValue="default") String sessionId) {
    ProductReview pr = agentService.analyzeReviewWithEval(reviewText, sessionId);
    return Map.of("success", true, "data", pr, "sessionId", sessionId);
  }

  @PostMapping("/complex")
  public Map<String,Object> complexTask(@RequestParam String request,
                                        @RequestParam(defaultValue="default") String sessionId) {
    String result = multiService.executeComplexTask(request, sessionId);
    return Map.of("success", true, "result", result, "sessionId", sessionId);
  }
}

Application Entry Point

@SpringBootApplication
public class SpringAiHarnessDemoApplication {
  public static void main(String[] args) {
    SpringApplication.run(SpringAiHarnessDemoApplication.class, args);
  }
}

Running & Testing

Build and start the service:

mvn clean package
java -jar target/spring-ai-harness-demo-1.0.0.jar

Test the endpoints with curl:

Contact extraction:

curl -X POST "http://localhost:885/api/harness/contact?text=从以下信息提取联系方式:王五,[email protected],+86 139-9999-8888&sessionId=test01"

Product review analysis:

curl -X POST "http://localhost:885/api/harness/review?reviewText=这款耳机音质不错,降噪效果好,但佩戴舒适度一般,价格略高。&sessionId=test02"

Review with quality evaluation:

curl -X POST "http://localhost:885/api/harness/review/eval?reviewText=还可以吧&sessionId=eval01"

Multi‑agent complex task (weather + calculation):

curl -X POST "http://localhost:885/api/harness/complex?request=查询北京天气并计算25+17&sessionId=multi01"

Common Issues & Solutions

Cannot resolve method 'tools(List<E>)': Use .methodTools(...) which scans @Tool annotations.

Cannot resolve method 'builder(String, WeatherTool)': Switch to .methodTools(...) or lambda‑based callbacks.

Structured output parsing failures: Enforce JSON format in systemPrompt, use outputType or outputSchema, and add fallback handling in postProcess.

Quality gate always fails: Lower the threshold or enrich QualityScorer logic to include more dimensions.

Conclusion & Next Steps

The guide demonstrates a full end‑to‑end Harness Engineering implementation: understanding the concept, preparing a Windows development environment, providing a complete Maven‑based Spring Boot codebase, mapping each of the seven layers to concrete classes, and offering runnable APIs with validation and feedback loops.

Future enhancements may include dynamic rule loading from a configuration centre, richer tool integrations (databases, web search, file I/O), deeper multi‑agent collaboration patterns, model fine‑tuning with logged failure cases, observability via Prometheus/Grafana, and large‑scale deployment on Kubernetes.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaAI agentsSpring BootSpring AIAgent ArchitectureHarness Engineering
The Dominant Programmer
Written by

The Dominant Programmer

Resources and tutorials for programmers' advanced learning journey. Advanced tracks in Java, Python, and C#. Blog: https://blog.csdn.net/badao_liumang_qizhi

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.