package public import ( "ai_scheduler/internal/config" "ai_scheduler/internal/entitys" "ai_scheduler/internal/pkg/utils_ollama" "context" "encoding/json" "fmt" "net/http" "time" "github.com/ollama/ollama/api" "github.com/coze-dev/coze-go" ) type CozeCompany struct { cozeApi coze.CozeAPI config config.ToolConfig llm *utils_ollama.Client } // NewCoze 创建 Coze 实例 func NewCozeCompany(config config.ToolConfig, llm *utils_ollama.Client) *CozeCompany { return &CozeCompany{ cozeApi: newCozeApi(config), config: config, llm: llm, } } // newCozeClient 创建 Coze 客户端 func newCozeApi(config config.ToolConfig) coze.CozeAPI { authCli := coze.NewTokenAuth(config.APISecret) cozeApi := coze.NewCozeAPI(authCli, coze.WithBaseURL(config.BaseURL), coze.WithHttpClient(&http.Client{ Timeout: time.Second * 120, })) return cozeApi } // Name 返回工具名称 func (c *CozeCompany) Name() string { return "coze_company" } // Description 返回工具描述 func (c *CozeCompany) Description() string { return "查询企业信息" } // Definition 返回工具定义 func (c *CozeCompany) Definition() entitys.ToolDefinition { return entitys.ToolDefinition{ Type: "function", Function: entitys.FunctionDef{ Name: c.Name(), Description: c.Description(), Parameters: map[string]interface{}{ "type": "object", "properties": map[string]interface{}{ "company_name": map[string]interface{}{ "type": "string", "description": "企业名称", }, }, "required": []string{"company_name"}, }, }, } } // Execute 执行查询 func (c *CozeCompany) Execute(ctx context.Context, requireData *entitys.Recognize) error { var req map[string]interface{} if err := json.Unmarshal([]byte(requireData.Match.Parameters), &req); err != nil { return fmt.Errorf("invalid express request: %w", err) } if req["company_name"] == "" { return fmt.Errorf("company_name is required") } // 调用 Coze 工作流 rsp, err := c.callWorkflow(ctx, req) if err != nil { return fmt.Errorf("failed to get real weather: %w", err) } companyInfo := CompanyInfo{} err = json.Unmarshal([]byte(rsp.Data), &companyInfo) if err != nil { return fmt.Errorf("failed to unmarshal company info: %w", err) } // 调用 LLM 模型 err = c.llm.ChatStream(ctx, requireData.Ch, []api.Message{ { Role: "system", Content: `# Role: 企业信息分析与经营诊断专家: 请基于以下12项指定数据字段(无需补充未提供的信息),完成目标企业的全维度分析总结,要求每部分结论必须100%锚定对应数据,拒绝主观推测,突出“风险可见性”与“关键信息关联性”: 一、输入数据清单(需逐一对应分析) 行政处罚:公司是否有行政处罚(含处罚事由、处罚机关、处罚日期、处罚文号) 清算信息:公司的清算信息(含清算原因、清算组构成、清算进展状态) 变更记录:公司的变更记录(含变更事项:注册资本/股东/法定代表人/经营范围、变更时间、变更前后内容) 主要成员:公司名搜索公司的主要成员(含姓名、职位、任职时间、核心履历关键词) 企业详情:公司名称,搜索公司详细信息(含成立时间、注册资本、经营范围、行业分类、注册地址) 经营异常:公司是否有经营异常(含列入原因、列入日期、移出状态) 破产重组:公司破产重组的信息(含申请法院、受理时间、重组方案核心内容) 严重违法:是否有严重违法信息(含违法事由、认定机关、公示期限) 司法信息:司法信息(含案件类型、原被告身份、判决结果/进展) 被执行信息:公司的被执行信息(含执行法院、执行标的、未履行金额、失信状态) 企业手机号:公司名称查询企业手机号(需标注是否为公开备案号) 股东信息:公司对应的股东(含股东名称、出资额、出资比例、股东类型:自然人/企业/机构) 二、分析总结框架(严格对应数据) 1. 企业基础画像(锚定公司名称,搜索公司详细信息) 核心属性:成立时间、注册资本(实缴/认缴)、行业分类(如“批发和零售业”“软件和信息技术服务业”)、主营业务(从经营范围中提炼1-2个核心赛道,如“专注于智能仓储设备研发与销售”); 注册地址:是否与主要经营地一致(若公司名称,搜索公司详细信息有披露)。 2. 股权结构与股东特征(锚定公司对应的股东) 股权集中度:前三大股东出资占比之和(如“第一大股东持股60%,为绝对控股股东”); 股东类型分布:自然人股东、企业股东、机构股东的占比(如“70%为企业股东,含1家行业头部企业”); 关键股东亮点:若有知名企业/机构股东,需明确标注(如“股东含XX产业投资基金,具备产业链资源协同潜力”)。 3. 经营稳定性与合规风险(锚定公司是否有行政处罚/公司是否有经营异常/是否有严重违法信息/公司的清算信息/公司破产重组的信息) 行政处罚风险:是否存在行政处罚? 若有:列清「处罚事由(如“虚假宣传”“税务逾期申报”)、处罚机关、处罚日期」,并判断“是否属于高频违规”(如1年内≥2次同类处罚→高风险); 若无:标注“无公开行政处罚记录”。 经营异常风险:是否存在经营异常? 若有:说明「列入原因(如“通过登记的住所无法联系”“未公示年度报告”)、是否已移出」,并评估对业务的影响(如“地址失联可能导致客户信任下降”); 若无:标注“无经营异常记录”。 严重违法红线:是否存在严重违法? 若有:明确「违法事由(如“拒不履行生效法律文书”“欺诈消费者”)、认定机关、公示期限」,并标注“触及监管红线,需重点核查整改情况”; 若无:标注“无严重违法记录”。 极端状态预警:是否存在清算或破产重组? 若有清算:说明「清算原因(如“股东会决议解散”“营业期限届满”)、清算进展(如“清算组已完成资产清查”)」; 若有破产重组:说明「申请法院、受理时间、重组方案核心内容(如“拟引入战略投资者注资5000万”)」; 若无:标注“无清算或破产重组记录”。 4. 司法与执行风险(锚定司法信息/公司的被执行信息) 涉诉情况:司法案件的核心特征(如“80%为买卖合同纠纷,20%为劳动争议仲裁”;“作为被告的案件占比75%”;“判决胜诉率约60%”); 被执行压力:是否存在被执行信息? 若有:列清「执行法院、执行标的金额、未履行金额、是否纳入失信被执行人名单」,并计算“未履行金额占注册资本的比例”(如“未履行800万,占注册资本的20%”); 若无:标注“无公开被执行记录”。 5. 管理团队与联系信息(锚定公司名搜索公司的主要成员/公司名称查询企业手机号) 核心团队稳定性:主要成员的任职时间分布(如“CEO任职4年,CFO任职2年,核心团队平均任职3年”);是否有频繁变动(如“1年内2位高管离职”→需提示“管理稳定性风险”); 关键岗位资质:核心成员(如法定代表人、CEO、CFO)的过往履历亮点(如“CEO曾任职XX上市公司,主导过亿元级项目落地”); 联系信息可信度:企业手机号是否为公开备案(如“与工商登记预留电话一致→可信度高”;“为非备案号→需提示‘联系信息真实性存疑’”)。 6. 综合结论与行动建议(整合所有数据) 整体风险评级:基于数据密度,给出“低风险/中风险/高风险”定性(示例:“无行政处罚、无被执行、仅1条普通合同纠纷→低风险”;“有失信被执行+严重违法→高风险”); Top3核心风险:按“严重违法>被执行>破产重组>行政处罚>经营异常>司法纠纷”排序,列出最需关注的3个问题(如“1. 未履行金额占注册资本20%,存在债务违约风险;2. 1年内2次地址异常,经营稳定性弱;3. 自然人股东占比过高,决策易受个人因素影响”); actionable 建议:针对每个核心风险,给出可执行的核查/应对动作(如“核查未履行金额对应的案件进展,评估企业偿债能力;要求企业提供近1年的地址证明,确认经营场所稳定性;穿透核查自然人股东的资产状况,降低决策风险”)。 三、输出规则(强制遵守) 数据溯源:每句结论必须标注对应数据字段(如“根据公司是否有行政处罚,企业2023年因‘税务逾期申报’被区税务局处罚”); 量化优先:拒绝模糊表述(如不说“很多案件”,要说“近1年涉及5起买卖合同纠纷”); 风险分级:用“★”标注风险等级(★越多越严重,如“严重违法★★★”“被执行★★”“经营异常★”); 语言风格:专业简洁,避免冗余,适合风控/投资/合作前的快速决策阅读。 【示例输出片段】 3. 经营稳定性与合规风险 行政处罚:根据公司是否有行政处罚,企业2022年11月因“发布虚假广告”被区市场监管局处以3万元罚款(文号:X市监罚字〔2022〕456号),无后续同类处罚→风险等级★; 经营异常:根据公司是否有经营异常,企业2023年6月因“通过登记的住所无法联系”被列入异常名录,2023年12月已移出→风险等级★; 严重违法:根据是否有严重违法信息,无公开严重违法记录→风险等级无; 极端状态:根据公司的清算信息/公司破产重组的信息,无清算或破产重组记录→风险等级无。 6. 综合结论与行动建议 整体评级:低风险(仅1次轻微行政处罚,无重大合规瑕疵); Top3核心风险:1. 根据司法信息,近1年作为被告的合同纠纷占比75%,需警惕应收账款回收风险★★;2. 根据公司名搜索公司的主要成员,1年内2位销售总监离职,管理稳定性弱★;3. 根据公司名称查询企业手机号,企业手机号为非备案号,联系信息真实性存疑★; 建议:核查合同纠纷案件的原告身份及回款情况,评估坏账概率;要求企业提供离职人员的交接说明,确认业务连续性;索要企业备案的联系方式,验证沟通有效性。 `, }, { Role: "assistant", Content: fmt.Sprintf(`请分析企业:%s, 公司是否有行政处罚:%v, 公司的清算信息:%v, 公司的变更记录:%v, 公司名搜索公司的主要成员:%v, 公司名称,搜索公司详细信息:%v, 公司是否有经营异常:%v, 公司破产重组的信息:%v, 是否有严重违法信息:%v, 司法信息:%v, 公司的被执行信息:%v, 公司名称查询企业手机号:%v, 公司对应的股东:%v`, req["company_name"], companyInfo.Xzcf, companyInfo.Clears, companyInfo.Changes, companyInfo.Employees, companyInfo.Searchdata, companyInfo.Operations, companyInfo.BankruptcyPublicList, companyInfo.Illegals, companyInfo.JudicialList, companyInfo.Executes, companyInfo.Phone, companyInfo.Partners), }, { Role: "user", Content: requireData.UserContent.Text, }, }, c.Name(), "") if err != nil { return fmt.Errorf("failed to get express info: %w", err) } //entitys.ResText(requireData.Ch, "", rsp.Data) return nil } // CallWorkflow 调用 Coze 工作流 // 参数: // - ctx: 上下文,用于控制超时和取消 // - workflowId: 工作流 ID // - params: 工作流参数 // 返回: // - interface{}: 工作流执行结果 // - error: 错误信息 func (c *CozeCompany) callWorkflow(ctx context.Context, params map[string]interface{}) (*coze.RunWorkflowsResp, error) { // 准备工作流请求参数 workflowReq := &coze.RunWorkflowsReq{ WorkflowID: c.config.APIKey, Parameters: params, } // 调用工作流 resp, err := c.cozeApi.Workflows.Runs.Create(ctx, workflowReq) if err != nil { return nil, fmt.Errorf("工作流调用失败: %w", err) } // 处理工作流响应 if resp == nil { return nil, fmt.Errorf("工作流响应为空") } // 返回工作流执行结果 return resp, nil } type CompanyInfo struct { BankruptcyPublicList interface{} `json:"bankruptcy_public_list"` // 破产公示列表 Changes interface{} `json:"changes"` // 变更记录 Clears interface{} `json:"clears"` // 清算记录 Employees interface{} `json:"employees"` // 员工列表 Executes interface{} `json:"executes"` // 执行记录 Illegals interface{} `json:"illegals"` // 违法记录 JudicialList interface{} `json:"judicial_list"` // 司法记录 Operations interface{} `json:"operations"` // 经营记录 Partners interface{} `json:"partners"` // 合伙人列表 Phone string `json:"phone"` // 联系电话 // 搜索数据 Searchdata struct { Authority interface{} `json:"authority"` BusinessScope interface{} `json:"business_scope"` Capital interface{} `json:"capital"` CompanyAddress interface{} `json:"company_address"` CompanyName string `json:"company_name"` CompanyStatus interface{} `json:"company_status"` CompanyType interface{} `json:"company_type"` CreditNo interface{} `json:"credit_no"` EstablishDate interface{} `json:"establish_date"` Industry interface{} `json:"industry"` LegalPerson interface{} `json:"legal_person"` Province interface{} `json:"province"` } `json:"searchdata"` Xzcf interface{} `json:"xzcf"` // 行政处罚 }