腾讯元器智能体:打造专属AI聊天工具

腾讯元器智能体:打造专属AI聊天工具

一、点击进入腾讯元器

二、登录之后在智能体模板选择

看你喜欢做那个,就选择那个,我选择了博物馆导览文案生成智能体。

进来之后点击左上角的复制智能体之后,就可以在“我的智能体”页面看到了。

或者点击下图的新建智能体来创建:

点击刚才选择的智能体,进入到该智能体里面的编辑页面,在这个应用设置页面左边的模型设置、工作流、欢迎语等这些都可以自定义:

然后点击工作流管理进入到工作流管理里面,这是我们智能体工作的核心流程(自定义):

三、介绍主要构建工作流的工具

(1)参数提取器

:当用户配置好智能体调用的APIKEY和url后,通过与用户进行“单轮、多轮对话”来收集用户发送的参数,参数缺失、模糊时可以自动反问澄清。

(2)选项卡

:提供可点击的选项,适合选项明确且数量少的情况。支持手动输入固定选项(如售前、售后咨询) 或 动态拉取变量值(如拉取客户的订单列表)。

(3)文件收集

:设置要收集文件的引导语和要求,收集用户上传的文件(文档、音频等)。

(4)文本收集

:在问答场景中向用户提问,并原样输出用户回答。适用场景:收集信息后传递给后续节点处理、沉淀意见反馈原文、合规留存等;特点:不做判断、不追问,一次性收集(如需从用户消息中收集参数,或发起多轮对话引导用户提供,请使用"参数提取节点")。

(5)大模型

:使用大模型(可以自己选择要使用的大模型)处理自然语言要求,如回答问题。

(6)大模型意图识别

:大模型根据“待识别内容”识别意图,如“是、否”。

(7)大模型知识问答

:从限定范围的知识库中检索内容,并通过大模型润色回复。

(8)工具

:调用“自定义HTTP接口”,集成外部数据和服务,适合在单一工作流内调用(多个工作流重复调用时,建议创建插件)。

更多的工作流工具的使用方法可以在官方文档里面查看或者下图中所示简略用法,使用方法大致与上述工具雷同。

四、使用工作流创建一个简单的聊天工具

(1)新建一个智能体并点击对话智能体:

(2)填写智能体的名称和简介,可以点击AI生成头像来显示头像:

(3)进入智能体内部的应用设置并根据自己所需来填写:

(4)点击顶部菜单的工作流管理并点击新建,选择手动录入:

(5)根据个人需求来填写工作流名称(如Ai聊天)和工作流描述(如任务描述: 当用户发起对话交流需求时触发此AI聊天流程,支持各类话题与任意常见问法。 示例问题: "今天天气如何?" "讲个笑话吧" "帮我分析下这篇文章")。可以点击模板并选择一个模板,填入自己的描述(简单明了),点击一键优化,最后点击底部的确认按钮即可进入到工作流编辑页面:

(6)编辑工作流,可以先构思一下流程,在使用左边的工具来构建工作流。本文是做一个简单的聊天Ai工作流,所以第一步需要使用参数提取工具(将工具拖拉进画布,:不允许在节点开始后与其他信息收集类节点(参数提取节点、选项卡节点、文件收集节点、文本收集节点、等待用户操作类Widget节点)或Agent节点并行)来提取用户发来的聊天内容是什么:

点击编辑之后,如下图的参数名称和参数类型需要填写,参数描述是用于让模型知道你到底想干什么:

(7)第二步,选择大模型知识问答工具,并将其连接到参数提取器后面(工作流必须要有开始和结束)。如下图变量名称要与待会的代码使用的变量名一致(预防出bug),数据源引用参数提取器里面的输出内容来赋值给message,用户问题可以用于进行知识检索,直接写“/”,然后看到输入变量,可以直接回车也可以点击选择该变量:

拉下去可以看到提示词,一样是为了让Ai知道你想干嘛,操作步骤和之前的工作流描述操作大致相同,需要使用{{message}}格式来引用上面的输入变量的变量名称,不然Ai是不知道你是什么意思的,最后点击底部的确认:

(8)在大模型知识问答后面连接工具,这个工具主要用来接受第三方发起的工作流调用并启动工作流,工作流生成的内容会以响应体的方式返回给第三方平台。工具的接口连接必须是公网ip(本地电脑可以使用内网穿透),不然无法接收和响应请求:

API参数是第三方平台的接口设定的请求参数,变量名称需要保持一致:

第三方平台的接口如果有输出变量可以写在下面:

最后,点击右上角的调试按钮,调试通过后,即可点击发布按钮,发布后在顶部的应用发布里面找到体验链接里面的appid和复制appkey填入第三方平台即可使用。

五、编写第三方平台的聊天Ai实现代码

(1)编写聊天Ai的controller类:

@RestController @RequestMapping("/Ai") public class AiController { @Resource private RedisTemplate redisTemplate; @Resource private AiServerImpl aiServer; @GetMapping("/AiChat") // 智能体调用 private String AiChat(@RequestParam("message") String Message){ return aiServer.GetAiChat(Message); } @GetMapping("/GetMessage") // 获取工作流的内容 public String getMessage(String message){ if(message!=null) aiServer.getMessage(message); else { System.out.println((String)redisTemplate.opsForValue().get("ms1")); } return (String)redisTemplate.opsForValue().get("ms1"); } } 

(2)编写聊天Ai的Service类:

public interface AiServer{ String GetAiChat(String Message); void getMessage(String message); }

(3)编写聊天Ai的Impl类:

 // 确保该类被Spring管理(加@Component/@Service等注解) @Slf4j @Service public class AiServerImpl implements AiServer { @Autowired private RedisTemplate redisTemplate; // 1. 注入全局RestTemplate(单例,性能最优),建议在配置类中配置RestTemplateConfig @Autowired private RestTemplate restTemplate; @Autowired private AiMapper aiMapper; // 建议把配置抽离到application.yml,这里先定义常量(替代硬编码) private static final String DEEPSEEK_BASE_URL = "https://yuanqi.tencent.com/openapi/v1/agent/chat/completions"; private static final String DEEPSEEK_API_KEY = "智能体密钥"; private static final String DEFAULT_MODEL = "智能体id"; public String GetAiChat(String Message) { String; // 查询AI模型列表(建议增加非空判断,避免空指针) List<AiModel> aiModels = aiMapper.getAiModel(); if (aiModels == null || aiModels.isEmpty()) { return "(模型配置为空,请检查AI模型表)"; } ModelName=aiModels.get(0).getAgent_name(); System.out.println(ModelName); // 构造请求头(仅保留必要的头,移除冗余) HttpHeaders httpHeaders = new HttpHeaders(); httpHeaders.setContentType(MediaType.APPLICATION_JSON); httpHeaders.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); //仅需要这一个密钥头,核心! httpHeaders.set("Authorization", "Bearer " +DEEPSEEK_API_KEY); // 构造用户消息:role=user,content=前端传入的Message OpenAiMessage userMessage = new OpenAiMessage(); userMessage.setRole("user"); // 固定为user,表示用户的提问 userMessage.setContent(Message); // 构造请求实体 HttpEntity<Map<String,Object>> entity = new HttpEntity<>(buildRequestBody(DEFAULT_MODEL,"1",Message), httpHeaders); try { // 2. 调用正确的完整API地址 ResponseEntity<String> response = restTemplate.exchange( DEEPSEEK_BASE_URL, HttpMethod.POST, entity, String.class ); // 处理响应 if (response.getStatusCode()==HttpStatus.OK) { String resp = response.getBody(); if (resp != null) { log.info(resp); return resp; } } return "(无返回内容)"; } catch (HttpClientErrorException ex) { // 捕获4xx错误(400/401/403/404/422等),打印日志方便排查 String respBody = ex.getResponseBodyAsString(); String errorMsg = String.format("(模型调用失败) %s: %s", ex.getStatusCode(), respBody != null ? respBody : "[no body]"); System.err.println("API调用4xx错误:" + errorMsg); // 建议用日志框架(logback/log4j2) return errorMsg; } catch (Exception ex) { // 捕获所有其他异常(如网络超时、5xx服务器错误等),避免程序崩溃 String errorMsg = String.format("(模型调用异常) %s: %s", ex.getClass().getSimpleName(), ex.getMessage()); System.err.println("API调用通用异常:" + errorMsg); return errorMsg; } } @Override public void getMessage(String message) { redisTemplate.opsForValue().set("ms1",message); } private Map<String, Object> buildRequestBody(String agentId, String userId, String message) { Map<String, Object> requestBody = new HashMap<>(); // 智能体ID(必填) requestBody.put("assistant_id", agentId); // 用户ID(必填) requestBody.put("user_id", userId); // 流式响应(非流式,等待完整响应) requestBody.put("stream", false); // 构建消息数组 List<Map<String, Object>> messages = new ArrayList<>(); // 用户消息 Map<String, Object> userMessage = new HashMap<>(); userMessage.put("role", "user"); // 消息内容数组(腾讯元器要求content是数组) List<Map<String, Object>> contentList = new ArrayList<>(); Map<String, Object> textContent = new HashMap<>(); textContent.put("type", "text"); String jsonMessage = buildJsonMessage(message); textContent.put("text", jsonMessage); contentList.add(textContent); userMessage.put("content", contentList); messages.add(userMessage); requestBody.put("messages", messages); // 可选参数 Map<String, Object> parameters = new HashMap<>(); parameters.put("temperature", 0.7); // 温度 parameters.put("max_tokens", 2000); // 最大token数 requestBody.put("parameters", parameters); return requestBody; } private String buildJsonMessage(String message) { try { Map<String, Object> params = new HashMap<>(); params.put("content", message); return new ObjectMapper().writeValueAsString(params); } catch (Exception e) { log.error("构建JSON消息失败", e); // 如果JSON构建失败,返回简单格式 // 转义引号避免JSON格式错误 String escapedContent = message.replace("\"", "\\\"").replace("\n", "\\n"); return String.format("{\"content\":\"%s\"}", escapedContent); } } // 建议把实体类抽离为独立的Java文件,不要写在方法内 @Data static class OpenAiMessage { // 角色:user(用户)/assistant(助手)/system(系统) private String role; // 消息内容 private String content; } @Data static class OpenAiChatRequest { // 模型名称 private String model; // 消息列表(核心修复:数组类型,而非字符串) private List<OpenAiMessage> messages; // 可选:温度,控制回答随机性(0-1,默认0.7,可根据需求调整) @JsonProperty("temperature") private Double temperature = 0.7; } @Data static class OpenAiChatResponse { // 响应体的choices数组 private List<Choice> choices; // 错误信息(API返回错误时会有这个字段,方便排查) private OpenAiError error; @Data static class Choice { // 补全的消息 private OpenAiMessage message; // 结束原因(如stop/长度限制等) @JsonProperty("finish_reason") private String finishReason; } // 新增:接收API返回的错误信息,方便排查问题 @Data static class OpenAiError { private Integer code; private String message; private String type; } } }

(4)编写聊天Ai的实体类:

 public class AiModel implements Serializable { private long id; private long user_id; // 用户id private String agent_id; // 智能体id private String agent_name; //智能体名称 private String api_key; //密钥 private String api_endpoint; //智能体URL public long getId() { return id; } public void setId(long id) { this.id = id; } public long getUser_id() { return user_id; } public void setUser_id(long user_id) { this.user_id = user_id; } public String getAgent_id() { return agent_id; } public void setAgent_id(String agent_id) { this.agent_id = agent_id; } public String getAgent_name() { return agent_name; } public void setAgent_name(String agent_name) { this.agent_name = agent_name; } public String getApi_key() { return api_key; } public void setApi_key(String api_key) { this.api_key = api_key; } public String getApi_endpoint() { return api_endpoint; } public void setApi_endpoint(String api_endpoint) { this.api_endpoint = api_endpoint; } } 

(5)编写聊天Ai的mapper类(如果模型变量是写死的,可有可无):

@Mapper public interface AiMapper { @Select("select id,user_id,agent_id,agent_name,api_key,api_endpoint " + "from yuanqi_agent where id=1") public List<AiModel> getAiModel(); }

(6)编写用于访问rest服务的同步客户端配置类:

@Configuration public class Config { @Bean public RestTemplate restTemplate(){ return new RestTemplate(); } }

(7)编写redis配置类:

@Configuration public class RedisAutoConfiguration { @Bean @ConditionalOnMissingBean(name = {"redisTemplate"}) public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(factory); ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY); Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(om,Object.class); template.setKeySerializer(new StringRedisSerializer()); template.setValueSerializer(jackson2JsonRedisSerializer); template.setHashKeySerializer(new StringRedisSerializer()); template.setHashValueSerializer(jackson2JsonRedisSerializer); template.afterPropertiesSet(); template.setDefaultSerializer(jackson2JsonRedisSerializer); return template; } @Bean public RedisCacheManager cacheManager(RedisConnectionFactory factory) { ObjectMapper om = new ObjectMapper(); RedisSerializer<String>stringSerializer = new StringRedisSerializer(); Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(om,Object.class); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY); RedisCacheConfiguration config=RedisCacheConfiguration.defaultCacheConfig() .entryTtl(Duration.ofDays(1)) .serializeKeysWith(RedisSerializationContext.SerializationPair .fromSerializer(stringSerializer)) .serializeValuesWith(RedisSerializationContext .SerializationPair.fromSerializer(jackson2JsonRedisSerializer)) .disableCachingNullValues(); RedisCacheManager cacheManager=RedisCacheManager .builder(factory).cacheDefaults(config).build(); return cacheManager; } } 

六、效果演示

最后,莫失,莫忘!

Read more

WebCoding 开发标准化流程

大家好,今天给大家分享的是WebCoding 开发标准化流程。 1. 需求定义 先把“要做什么”说清楚,再开始写代码。 你要产出这几样东西: * 业务目标:这个网站/系统解决什么问题 * 用户角色:谁在用 * 核心场景:用户完成任务的主路径 * 功能清单:必须有 / 可延期 * 验收标准:什么叫“做完了” 这一步最重要的是把需求写成 用户故事 + 验收条件。 例如: * 用户故事:用户可以注册并登录 * 验收条件:支持邮箱注册、密码重置、登录态保持 7 天、错误提示可读 标准输出: * PRD / 需求文档 * 用户流程图 * 功能优先级列表 * MVP 范围 2. 技术方案设计 需求确认后,不直接开写,而是先定技术方案。 通常要明确: * 前端:

前端数据可视化工具比较:别再为选择工具而烦恼了!

前端数据可视化工具比较:别再为选择工具而烦恼了! 毒舌时刻 数据可视化?听起来就像是前端工程师为了显得自己很专业而特意搞的一套复杂流程。你以为随便用个Chart.js就能做出好看的图表?别做梦了!到时候你会发现,复杂的图表需求根本满足不了。 你以为D3.js是万能的?别天真了!D3.js的学习曲线能让你崩溃,写出来的代码比业务代码还复杂。还有那些所谓的可视化库,看起来高大上,用起来却各种问题。 为什么你需要这个 1. 数据理解:数据可视化可以帮助你更好地理解数据,发现数据中的规律和趋势。 2. 决策支持:可视化的数据可以为决策提供直观的支持,帮助你做出更明智的决策。 3. 用户体验:良好的数据可视化可以提高用户体验,使数据更易于理解和使用。 4. 信息传递:可视化的数据可以更有效地传递信息,减少沟通成本。 5. 品牌形象:专业的数据可视化可以提升品牌的专业形象。 反面教材 // 1. 使用不适合的工具 // 复杂的数据可视化使用Chart.js import Chart from 'chart.js/

爬虫前端调试常见反调试问题及解决方案(超详细实操版)

爬虫前端调试常见反调试问题及解决方案(超详细实操版)

爬虫前端调试常见反调试问题及解决方案(网页实操版) 在爬虫开发过程中,前端调试是获取接口、分析渲染逻辑的关键步骤,但很多网站会设置反调试机制,阻碍我们正常调试。本文整理了7个爬虫前端调试中最常遇到的反调试问题,每个问题都详细说明现象、原因,并给出一步一步的实操解决方案,同时预留截图位置,方便大家插入操作截图,快速上手解决问题。 适用场景:爬虫开发、前端调试、反调试绕过,适合新手入门,也可作为老开发者的调试手册。 问题1:打断点时出现webpack://…相关报错 一、问题现象 在浏览器开发者工具(F12)的Sources面板打断点后,控制台频繁弹出报错,报错信息中包含“webpack://”开头的路径,且断点无法正常触发,调试流程被中断,无法查看代码执行逻辑和参数传递过程。 二、问题原因 这是因为目标网站使用了Webpack打包工具,Webpack在打包时会保留源码的溯源信息,而浏览器开发者工具默认开启了JavaScript溯源功能,会尝试解析Webpack打包后的源码路径,当路径无法匹配或被网站反调试拦截时,就会抛出此类报错,同时干扰断点的正常执行。 三、解决方案(

WebMCP:浏览器AI交互新范式_20260213114222

一、WebMCP是什么 1. 基本定义 WebMCP(Web Model Context Protocol)是Google与Microsoft在W3C框架下联合推动的浏览器原生Web API,Chrome 146已推出早期预览版本,核心目标是让网页主动将自身能力封装为结构化工具,供AI Agent直接调用,解决当前Agent操作网页的稳定性与效率问题。 2. 核心思想 把交互从UI层搬到语义层:不再依赖按钮点击、坐标定位或DOM解析,而是让网页直接暴露"提交请假"“搜索航班”“加入购物车"等业务动作,形成结构化工具契约,Agent按契约调用而非"猜UI”。 3. 关键特性 * 双轨API设计:声明式API(HTML表单属性)+ 命令式API(JavaScript注册),兼顾易用性与灵活性 * 浏览器内运行:纯客户端实现,网页本身就是"工具服务器",天然继承用户登录态与权限上下文 * 结构化上下文: